38 {
39
41
42 static pert_t *pert_4mu, *pert_15mu_low, *pert_15mu_high;
43
44 const double var_dh2 = 100. * 100.;
45
48
49 const int list_4mu[
N4]
50 = { 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283,
51 284, 285, 286, 288, 289, 291, 292, 294, 295, 296, 297, 298, 299, 300,
52 302, 303, 304, 305, 306, 307, 318, 319, 321, 322, 323, 324, 325, 326,
53 328, 330, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341
54 };
55
56 const int list_15mu_low[
N15_LOW]
57 = { 5, 8, 10, 13, 15, 17, 23, 34, 36, 39, 41, 44, 46, 49, 51 };
58
59 const int list_15mu_high[
N15_HIGH] = { 31 };
60
61 const int list_8mu[
N8] = { 36 };
62
63 const int list_10mu[
N10] = { 502 };
64
65 const int dtrack = 3, dxtrack = 3;
66
67 static int dimid[3], n, ncid, track0,
68 time_varid, lon_varid, lat_varid, bt_4mu_varid, init,
69 bt_4mu_pt_varid, bt_4mu_var_varid, bt_8mu_varid, bt_10mu_varid,
70 bt_15mu_low_varid, bt_15mu_low_pt_varid, bt_15mu_low_var_varid,
71 bt_15mu_high_varid, bt_15mu_high_pt_varid, bt_15mu_high_var_varid;
72
73
74 if (argc < 4)
75 ERRMSG(
"Give parameters: <ctl> <pert.nc> <l1b_file1> [<l1b_file2> ...]");
76
77
78 const int apo = (int)
scan_ctl(argc, argv,
"APO", -1,
"0", NULL);
79
80
84
85
86
87
88
89
90 for (int iarg = 3; iarg < argc; iarg++) {
91
92
94 continue;
95
96
97 if (!init) {
98 init = 1;
99
100
101 LOG(2,
"4.3 micron channels:");
102 n = 0;
103 nu = 0;
104 for (
int i = 0; i <
N4; i++) {
105 nu += l1.
nu_sw[list_4mu[i]];
106 n++;
107 LOG(2,
" count= %2d | channel index= SW_%03d | nu= %.4f cm^-1", n,
108 list_4mu[i], l1.
nu_sw[list_4mu[i]]);
109 }
110 LOG(2,
" nu_mean= %.4f cm^-1", nu / n);
111
112
113 LOG(2,
"15 micron low channels:");
114 n = 0;
115 nu = 0;
116 for (
int i = 0; i <
N15_LOW; i++) {
117 nu += l1.
nu_lw[list_15mu_low[i]];
118 n++;
119 LOG(2,
" count= %2d | channel index= LW_%03d | nu= %.4f cm^-1", n,
120 list_15mu_low[i], l1.
nu_lw[list_15mu_low[i]]);
121 }
122 LOG(2,
" nu_mean= %.4f cm^-1", nu / n);
123
124
125 LOG(2,
"15 micron high channels:");
126 n = 0;
127 nu = 0;
128 for (
int i = 0; i <
N15_HIGH; i++) {
129 nu += l1.
nu_lw[list_15mu_high[i]];
130 n++;
131 LOG(2,
" count= %2d | channel index= LW_%03d | nu= %.4f cm^-1", n,
132 list_15mu_high[i], l1.
nu_lw[list_15mu_high[i]]);
133 }
134 LOG(2,
" nu_mean= %.4f cm^-1", nu / n);
135
136
137 LOG(2,
"8.1 micron channels:");
138 n = 0;
139 nu = 0;
140 for (
int i = 0; i <
N8; i++) {
141 nu += l1.
nu_mw[list_8mu[i]];
142 n++;
143 LOG(2,
" count= %2d | channel index= MW_%03d | nu= %.4f cm^-1", n,
144 list_8mu[i], l1.
nu_mw[list_8mu[i]]);
145 }
146 LOG(2,
" nu_mean= %.4f cm^-1", nu / n);
147
148
149 LOG(2,
"10.4 micron channels:");
150 n = 0;
151 nu = 0;
152 for (
int i = 0; i <
N10; i++) {
153 nu += l1.
nu_lw[list_10mu[i]];
154 n++;
155 LOG(2,
" count= %2d | channel index= LW_%03d | nu= %.4f cm^-1", n,
156 list_10mu[i], l1.
nu_lw[list_10mu[i]]);
157 }
158 LOG(2,
" nu_mean= %.4f cm^-1", nu / n);
159 }
160
161
164 ERRMSG(
"Too many granules!");
167 ERRMSG(
"Too many tracks!");
170 ERRMSG(
"Too many field of views!");
172 pert_4mu->
time[track0 + track][xtrack][ifov]
173 = l1.
time[track][xtrack] - 220838400.;
174 pert_4mu->
lon[track0 + track][xtrack][ifov]
175 = l1.
lon[track][xtrack][ifov];
176 pert_4mu->
lat[track0 + track][xtrack][ifov]
177 = l1.
lat[track][xtrack][ifov];
178 }
179
180
182 pert_4mu->
dc[track0 + track][xtrack][ifov]
183 =
BRIGHT(l1.
rad_mw[track][xtrack][ifov][list_8mu[0]] * 1e-3,
184 l1.
nu_mw[list_8mu[0]]);
185
186
188 pert_15mu_high->
dc[track0 + track][xtrack][ifov]
189 =
BRIGHT(l1.
rad_lw[track][xtrack][ifov][list_10mu[0]] * 1e-3,
190 l1.
nu_lw[list_10mu[0]]);
191
192
194 n = 0;
195 nu = rad = 0;
196 for (
int i = 0; i <
N4; i++)
197 if (gsl_finite(l1.
rad_sw[track][xtrack][ifov][list_4mu[i]])) {
198 rad += l1.
rad_sw[track][xtrack][ifov][list_4mu[i]] * 1e-3;
199 nu += l1.
nu_sw[list_4mu[i]];
200 n++;
201 }
203 pert_4mu->
bt[track0 + track][xtrack][ifov] =
BRIGHT(rad / n, nu / n);
204 else
205 pert_4mu->
bt[track0 + track][xtrack][ifov] = GSL_NAN;
206 }
207
208
210 n = 0;
211 nu = rad = 0;
212 for (
int i = 0; i <
N15_LOW; i++)
213 if (gsl_finite(l1.
rad_lw[track][xtrack][ifov][list_15mu_low[i]])) {
214 rad += l1.
rad_lw[track][xtrack][ifov][list_15mu_low[i]] * 1e-3;
215 nu += l1.
nu_lw[list_15mu_low[i]];
216 n++;
217 }
219 pert_15mu_low->
bt[track0 + track][xtrack][ifov] =
221 else
222 pert_15mu_low->
bt[track0 + track][xtrack][ifov] = GSL_NAN;
223 }
224
225
227 n = 0;
228 nu = rad = 0;
230 if (gsl_finite(l1.
rad_lw[track][xtrack][ifov][list_15mu_high[i]])) {
231 rad += l1.
rad_lw[track][xtrack][ifov][list_15mu_high[i]] * 1e-3;
232 nu += l1.
nu_lw[list_15mu_high[i]];
233 n++;
234 }
236 pert_15mu_high->
bt[track0 + track][xtrack][ifov] =
238 else
239 pert_15mu_high->
bt[track0 + track][xtrack][ifov] = GSL_NAN;
240 }
241
242
244 }
245
246
247
248
249
250
251 LOG(1,
"Calculate perturbations...");
252
253
254 for (
int track = 0; track < pert_4mu->
ntrack; track++)
255 for (
int ifov = 0; ifov <
L1_NFOV; ifov++) {
256
257
258 pert_4mu->
dc[track][0][ifov] = GSL_NAN;
260 pert_15mu_high->
dc[track][0][ifov] = GSL_NAN;
261 pert_15mu_high->
dc[track][
L1_NXTRACK - 1][ifov] = GSL_NAN;
262 pert_4mu->
bt[track][0][ifov] = GSL_NAN;
264 pert_15mu_low->
bt[track][0][ifov] = GSL_NAN;
265 pert_15mu_low->
bt[track][
L1_NXTRACK - 1][ifov] = GSL_NAN;
266 pert_15mu_high->
bt[track][0][ifov] = GSL_NAN;
267 pert_15mu_high->
bt[track][
L1_NXTRACK - 1][ifov] = GSL_NAN;
268
269
270 for (
int xtrack = 0; xtrack <
L1_NXTRACK; xtrack++) {
271 x[xtrack] = (double) xtrack;
272 y[xtrack] = pert_4mu->
bt[track][xtrack][ifov];
273 }
275 for (
int xtrack = 0; xtrack <
L1_NXTRACK; xtrack++)
276 pert_4mu->
pt[track][xtrack][ifov] =
277 pert_4mu->
bt[track][xtrack][ifov] - y[xtrack];
278
279
280 for (
int xtrack = 0; xtrack <
L1_NXTRACK; xtrack++) {
281 x[xtrack] = (double) xtrack;
282 y[xtrack] = pert_15mu_low->
bt[track][xtrack][ifov];
283 }
285 for (
int xtrack = 0; xtrack <
L1_NXTRACK; xtrack++)
286 pert_15mu_low->
pt[track][xtrack][ifov] =
287 pert_15mu_low->
bt[track][xtrack][ifov] - y[xtrack];
288
289
290 for (
int xtrack = 0; xtrack <
L1_NXTRACK; xtrack++) {
291 x[xtrack] = (double) xtrack;
292 y[xtrack] = pert_15mu_high->
bt[track][xtrack][ifov];
293 }
295 for (
int xtrack = 0; xtrack <
L1_NXTRACK; xtrack++)
296 pert_15mu_high->
pt[track][xtrack][ifov] =
297 pert_15mu_high->
bt[track][xtrack][ifov] - y[xtrack];
298 }
299
300
301
302
303
304
305 LOG(1,
"Calculate variances...");
306
307
309
310
312 pert_4mu->
lat[track][xtrack][ifov], x0);
313
314
315 int n_4mu = 0, n_15mu_low = 0, n_15mu_high = 0;
316 double mean_4mu = 0, mean_15mu_low = 0, mean_15mu_high = 0;
317 double var_4mu = 0, var_15mu_low = 0, var_15mu_high = 0;
318
319
320 for (int track2 = track - dtrack; track2 <= track + dtrack; track2++)
321 for (int xtrack2 = xtrack - dxtrack; xtrack2 <= xtrack + dxtrack;
322 xtrack2++)
323 for (
int ifov2 = 0; ifov2 <
L1_NFOV; ifov2++)
324 if (track2 >= 0 && track2 < pert_4mu->ntrack
326
327
328 geo2cart(0.0, pert_4mu->
lon[track2][xtrack2][ifov2],
329 pert_4mu->
lat[track2][xtrack2][ifov2], x1);
330 if (
DIST2(x0, x1) > var_dh2)
331 continue;
332
333
334 if (gsl_finite(pert_4mu->
pt[track2][xtrack2][ifov2])) {
335 mean_4mu += pert_4mu->
pt[track2][xtrack2][ifov2];
336 var_4mu += gsl_pow_2(pert_4mu->
pt[track2][xtrack2][ifov2]);
337 n_4mu++;
338 }
339
340 if (gsl_finite(pert_15mu_low->
pt[track2][xtrack2][ifov2])) {
341 mean_15mu_low += pert_15mu_low->
pt[track2][xtrack2][ifov2];
342 var_15mu_low +=
343 gsl_pow_2(pert_15mu_low->
pt[track2][xtrack2][ifov2]);
344 n_15mu_low++;
345 }
346
347 if (gsl_finite(pert_15mu_high->
pt[track2][xtrack2][ifov2])) {
348 mean_15mu_high += pert_15mu_high->
pt[track2][xtrack2][ifov2];
349 var_15mu_high +=
350 gsl_pow_2(pert_15mu_high->
pt[track2][xtrack2][ifov2]);
351 n_15mu_high++;
352 }
353 }
354
355
356 if (n_4mu > 0 && xtrack > 0 && xtrack <
L1_NXTRACK - 1)
357 pert_4mu->
var[track][xtrack][ifov] =
358 var_4mu / n_4mu - gsl_pow_2(mean_4mu / n_4mu);
359 else
360 pert_4mu->
var[track][xtrack][ifov] = GSL_NAN;
361
362 if (n_15mu_low > 0 && xtrack > 0 && xtrack <
L1_NXTRACK - 1)
363 pert_15mu_low->
var[track][xtrack][ifov] =
364 var_15mu_low / n_15mu_low - gsl_pow_2(mean_15mu_low / n_15mu_low);
365 else
366 pert_15mu_low->
var[track][xtrack][ifov] = GSL_NAN;
367
368 if (n_15mu_high > 0 && xtrack > 0 && xtrack <
L1_NXTRACK - 1)
369 pert_15mu_high->
var[track][xtrack][ifov] =
370 var_15mu_high / n_15mu_high - gsl_pow_2(mean_15mu_high / n_15mu_high);
371 else
372 pert_15mu_high->
var[track][xtrack][ifov] = GSL_NAN;
373 }
374
375
376
377
378
379
380 LOG(1,
"Write perturbation data file: %s", argv[2]);
381
382
383 NC(nc_create(argv[2], NC_CLOBBER, &ncid));
384
385
386 NC(nc_def_dim(ncid,
"NTRACK", (
size_t) pert_4mu->
ntrack, &dimid[0]));
388 NC(nc_def_dim(ncid,
"NFOV",
L1_NFOV, &dimid[2]));
389
390
391 NC(nc_def_var(ncid,
"time", NC_DOUBLE, 3, dimid, &time_varid));
392 add_att(ncid, time_varid,
"s",
"time (seconds since 2000-01-01T00:00Z)");
393 NC(nc_def_var(ncid,
"lon", NC_DOUBLE, 3, dimid, &lon_varid));
394 add_att(ncid, lon_varid,
"deg",
"footprint longitude");
395 NC(nc_def_var(ncid,
"lat", NC_DOUBLE, 3, dimid, &lat_varid));
396 add_att(ncid, lat_varid,
"deg",
"footprint latitude");
397
398 NC(nc_def_var(ncid,
"bt_8mu", NC_FLOAT, 3, dimid, &bt_8mu_varid));
399 add_att(ncid, bt_8mu_varid,
"K",
"brightness temperature at 8.1 micron");
400
401 NC(nc_def_var(ncid,
"bt_10mu", NC_FLOAT, 3, dimid, &bt_10mu_varid));
402 add_att(ncid, bt_10mu_varid,
"K",
"brightness temperature at 10.4 micron");
403
404 NC(nc_def_var(ncid,
"bt_4mu", NC_FLOAT, 3, dimid, &bt_4mu_varid));
405 add_att(ncid, bt_4mu_varid,
"K",
"brightness temperature" " at 4.3 micron");
406 NC(nc_def_var(ncid,
"bt_4mu_pt", NC_FLOAT, 3, dimid, &bt_4mu_pt_varid));
407 add_att(ncid, bt_4mu_pt_varid,
"K",
"brightness temperature perturbation"
408 " at 4.3 micron");
409 NC(nc_def_var(ncid,
"bt_4mu_var", NC_FLOAT, 3, dimid, &bt_4mu_var_varid));
410 add_att(ncid, bt_4mu_var_varid,
"K^2",
"brightness temperature variance"
411 " at 4.3 micron");
412
413 NC(nc_def_var(ncid,
"bt_15mu_low", NC_FLOAT, 3, dimid, &bt_15mu_low_varid));
414 add_att(ncid, bt_15mu_low_varid,
"K",
"brightness temperature"
415 " at 15 micron (low altitudes)");
416 NC(nc_def_var(ncid,
"bt_15mu_low_pt", NC_FLOAT, 3, dimid,
417 &bt_15mu_low_pt_varid));
418 add_att(ncid, bt_15mu_low_pt_varid,
"K",
419 "brightness temperature perturbation"
420 " at 15 micron (low altitudes)");
422 (ncid, "bt_15mu_low_var", NC_FLOAT, 3, dimid, &bt_15mu_low_var_varid));
423 add_att(ncid, bt_15mu_low_var_varid,
"K^2",
424 "brightness temperature variance" " at 15 micron (low altitudes)");
425
426 NC(nc_def_var(ncid,
"bt_15mu_high", NC_FLOAT, 3, dimid,
427 &bt_15mu_high_varid));
428 add_att(ncid, bt_15mu_high_varid,
"K",
"brightness temperature"
429 " at 15 micron (high altitudes)");
430 NC(nc_def_var(ncid,
"bt_15mu_high_pt", NC_FLOAT, 3, dimid,
431 &bt_15mu_high_pt_varid));
432 add_att(ncid, bt_15mu_high_pt_varid,
"K",
433 "brightness temperature perturbation"
434 " at 15 micron (high altitudes)");
436 (ncid, "bt_15mu_high_var", NC_FLOAT, 3, dimid, &bt_15mu_high_var_varid));
437 add_att(ncid, bt_15mu_high_var_varid,
"K^2",
438 "brightness temperature variance" " at 15 micron (high altitudes)");
439
440
442
443
444 n = 0;
446 help[n++] = pert_4mu->time[track][xtrack][ifov];
447 NC(nc_put_var_double(ncid, time_varid, help));
448
449 n = 0;
451 help[n++] = pert_4mu->lon[track][xtrack][ifov];
452 NC(nc_put_var_double(ncid, lon_varid, help));
453
454 n = 0;
456 help[n++] = pert_4mu->lat[track][xtrack][ifov];
457 NC(nc_put_var_double(ncid, lat_varid, help));
458
459 n = 0;
461 help[n++] = pert_4mu->dc[track][xtrack][ifov];
462 NC(nc_put_var_double(ncid, bt_8mu_varid, help));
463
464 n = 0;
466 help[n++] = pert_15mu_high->dc[track][xtrack][ifov];
467 NC(nc_put_var_double(ncid, bt_10mu_varid, help));
468
469 n = 0;
471 help[n++] = pert_4mu->bt[track][xtrack][ifov];
472 NC(nc_put_var_double(ncid, bt_4mu_varid, help));
473
474 n = 0;
476 help[n++] = pert_4mu->pt[track][xtrack][ifov];
477 NC(nc_put_var_double(ncid, bt_4mu_pt_varid, help));
478
479 n = 0;
481 help[n++] = pert_4mu->var[track][xtrack][ifov];
482 NC(nc_put_var_double(ncid, bt_4mu_var_varid, help));
483
484 n = 0;
486 help[n++] = pert_15mu_low->bt[track][xtrack][ifov];
487 NC(nc_put_var_double(ncid, bt_15mu_low_varid, help));
488
489 n = 0;
491 help[n++] = pert_15mu_low->pt[track][xtrack][ifov];
492 NC(nc_put_var_double(ncid, bt_15mu_low_pt_varid, help));
493
494 n = 0;
496 help[n++] = pert_15mu_low->var[track][xtrack][ifov];
497 NC(nc_put_var_double(ncid, bt_15mu_low_var_varid, help));
498
499 n = 0;
501 help[n++] = pert_15mu_high->bt[track][xtrack][ifov];
502 NC(nc_put_var_double(ncid, bt_15mu_high_varid, help));
503
504 n = 0;
506 help[n++] = pert_15mu_high->pt[track][xtrack][ifov];
507 NC(nc_put_var_double(ncid, bt_15mu_high_pt_varid, help));
508
509 n = 0;
511 help[n++] = pert_15mu_high->var[track][xtrack][ifov];
512 NC(nc_put_var_double(ncid, bt_15mu_high_var_varid, help));
513
514
516
517
518 free(pert_4mu);
519 free(pert_15mu_low);
520 free(pert_15mu_high);
521
522 return EXIT_SUCCESS;
523}
double scan_ctl(int argc, char *argv[], const char *varname, int arridx, const char *defvalue, char *value)
Search control parameter file for variable entry.
void geo2cart(const double z, const double lon, const double lat, double *x)
Convert geolocation to Cartesian coordinates.
#define BRIGHT(rad, nu)
Compute brightness temperature.
#define ERRMSG(...)
Print error message and quit program.
#define ALLOC(ptr, type, n)
Allocate memory.
#define LOG(level,...)
Print log message.
#define DIST2(a, b)
Compute squared distance between two vectors.
void background_poly_help(const double *xx, double *yy, const int n, const int dim)
Get background based on polynomial fits.
int read_cris_l1(char *filename, cris_l1_t *l1, int apo)
Read CrIS Level-1 data.
void add_att(const int ncid, const int varid, const char *unit, const char *long_name)
Add variable attributes to netCDF file.
#define NC(cmd)
Execute netCDF library command and check result.
#define PERT_NXTRACK
Across-track size of perturbation data.
#define L1_NTRACK
Along-track size of CrIS radiance granule.
#define PERT_NTRACK
Along-track size of perturbation data.
#define PERT_NFOV
Number of field of views of perturbation data.
#define N15_LOW
Number of 15 micron low channels:
#define N10
Number of 10.4 micron channels:
#define N4
Number of 4.3 micron channels:
#define N8
Number of 8.1 micron channels:
#define N15_HIGH
Number of 15 micron high channels:
#define LOOP_ALL(ntrack)
Loop over all footprints.
double nu_sw[L1_NCHAN_SW]
Shortwave channel frequencies [cm^-1].
float rad_mw[L1_NTRACK][L1_NXTRACK][L1_NFOV][L1_NCHAN_MW]
Midwave radiance [W/(m^2 sr cm^-1)].
double nu_mw[L1_NCHAN_MW]
Midwave channel frequencies [cm^-1].
float rad_sw[L1_NTRACK][L1_NXTRACK][L1_NFOV][L1_NCHAN_SW]
Shortwave radiance [W/(m^2 sr cm^-1)].
double lon[L1_NTRACK][L1_NXTRACK][L1_NFOV]
Footprint longitude [deg].
float rad_lw[L1_NTRACK][L1_NXTRACK][L1_NFOV][L1_NCHAN_LW]
Longwave radiance [W/(m^2 sr cm^-1)].
double time[L1_NTRACK][L1_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
double nu_lw[L1_NCHAN_LW]
Longwave channel frequencies [cm^-1].
double lat[L1_NTRACK][L1_NXTRACK][L1_NFOV]
Footprint latitude [deg].
double dc[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Brightness temperature (cloud channel) [K].
double lat[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Latitude [deg].
int nfov
Number of field of views.
double pt[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Brightness temperature perturbation (4 or 15 micron) [K].
int ntrack
Number of along-track values.
double var[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Brightness temperature variance (4 or 15 micron) [K].
double time[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Time (seconds since 2000-01-01T00:00Z).
double bt[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Brightness temperature (4.3 or 15 micron) [K].
int nxtrack
Number of across-track values.
double lon[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Longitude [deg].