30 {
31
33
35
36 static FILE *in, *out;
37
38 static char pertname[
LEN], ncfile[
LEN];
39
40 static double ebt, emu, enoise, evar, wbt, wmu, wnoise, wvar, etime, wtime,
41 aux;
42
43 static int orb_old =
44 -1, en, wn, ncid, time_varid, track_varid, np_east_varid,
45 var_east_varid, np_west_varid, var_west_varid, year_varid, doy_varid,
46 track, year, mon, day, doy, iaux;
47
48 static size_t count[2] = { 1, 1 }, start[2];
49
50
51 if (argc < 4)
52 ERRMSG(
"Give parameters: <ctl> <var.tab> <pert1.nc> [<pert2.nc> ...]");
53
54
55 scan_ctl(argc, argv,
"PERTNAME", -1,
"4mu", pertname);
56 const double lon0 =
scan_ctl(argc, argv,
"LON0", -1,
"", NULL);
57 const double lat0 =
scan_ctl(argc, argv,
"LAT0", -1,
"", NULL);
58 const double dlon =
scan_ctl(argc, argv,
"DLON", -1,
"", NULL);
59 const double dlat =
scan_ctl(argc, argv,
"DLAT", -1,
"", NULL);
60 const double offset =
scan_ctl(argc, argv,
"OFFSET", -1,
"1", NULL);
61 const int bg_poly_x =
62 (int)
scan_ctl(argc, argv,
"BG_POLY_X", -1,
"0", NULL);
63 const int bg_poly_y =
64 (int)
scan_ctl(argc, argv,
"BG_POLY_Y", -1,
"0", NULL);
65 const int bg_smooth_x =
66 (int)
scan_ctl(argc, argv,
"BG_SMOOTH_X", -1,
"0", NULL);
67 const int bg_smooth_y =
68 (int)
scan_ctl(argc, argv,
"BG_SMOOTH_Y", -1,
"0", NULL);
69 const double gauss_fwhm =
scan_ctl(argc, argv,
"GAUSS_FWHM", -1,
"0", NULL);
70 const double var_dh =
scan_ctl(argc, argv,
"VAR_DH", -1,
"0", NULL);
71 const double orblat =
scan_ctl(argc, argv,
"ORBLAT", -1,
"0", NULL);
72 const double dt230 =
scan_ctl(argc, argv,
"DT230", -1,
"0.16", NULL);
73 const double nu =
scan_ctl(argc, argv,
"NU", -1,
"2345.0", NULL);
74 scan_ctl(argc, argv,
"NCFILE", -1,
"-", ncfile);
75
76
78
79
80 printf("Write variance statistics: %s\n", argv[2]);
81 if (!(out = fopen(argv[2], "w")))
82 ERRMSG(
"Cannot create file!");
83
84
85 fprintf(out,
86 "# $1 = time [s]\n"
87 "# $2 = orbit number\n"
88 "# $3 = eastern box: number of footprints\n"
89 "# $4 = eastern box: variance [K^2]\n"
90 "# $5 = eastern box: mean background temperature [K]\n"
91 "# $6 = eastern box: noise estimate [K]\n"
92 "# $7 = western box: number of footprints\n"
93 "# $8 = western box: variance [K^2]\n"
94 "# $9 = western box: mean background temperature [K]\n"
95 "# $10 = western box: noise estimate [K]\n\n");
96
97
98 if (ncfile[0] != '-') {
99
100
101 printf("Write variance statistics: %s\n", ncfile);
102 NC(nc_create(ncfile, NC_CLOBBER, &ncid));
103
104
105 static int dimid[2];
106 NC(nc_def_dim(ncid,
"NP", NC_UNLIMITED, &dimid[0]));
107
108
109 aux = lon0;
110 nc_put_att_double(ncid, NC_GLOBAL, "box_east_lon0", NC_DOUBLE, 1, &aux);
111 aux = lon0 + dlon;
112 nc_put_att_double(ncid, NC_GLOBAL, "box_east_lon1", NC_DOUBLE, 1, &aux);
113 aux = lat0 - 0.5 * dlat;
114 nc_put_att_double(ncid, NC_GLOBAL, "box_east_lat0", NC_DOUBLE, 1, &aux);
115 aux = lat0 + 0.5 * dlat;
116 nc_put_att_double(ncid, NC_GLOBAL, "box_east_lat1", NC_DOUBLE, 1, &aux);
117 aux = lon0 - dlon - offset;
118 nc_put_att_double(ncid, NC_GLOBAL, "box_west_lon0", NC_DOUBLE, 1, &aux);
119 aux = lon0 - offset;
120 nc_put_att_double(ncid, NC_GLOBAL, "box_west_lon1", NC_DOUBLE, 1, &aux);
121 aux = lat0 - 0.5 * dlat;
122 nc_put_att_double(ncid, NC_GLOBAL, "box_west_lat0", NC_DOUBLE, 1, &aux);
123 aux = lat0 + 0.5 * dlat;
124 nc_put_att_double(ncid, NC_GLOBAL, "box_west_lat1", NC_DOUBLE, 1, &aux);
125
126
127 NC(nc_def_var(ncid,
"time", NC_DOUBLE, 1, dimid, &time_varid));
128 add_att(ncid, time_varid,
"s",
"time (seconds since 2000-01-01T00:00Z)");
129 NC(nc_def_var(ncid,
"year", NC_INT, 1, dimid, &year_varid));
130 add_att(ncid, year_varid,
"1",
"year");
131 NC(nc_def_var(ncid,
"doy", NC_INT, 1, dimid, &doy_varid));
132 add_att(ncid, doy_varid,
"1",
"day of year");
133 NC(nc_def_var(ncid,
"track", NC_INT, 1, dimid, &track_varid));
134 add_att(ncid, track_varid,
"1",
"along-track index");
135 NC(nc_def_var(ncid,
"var_east", NC_DOUBLE, 1, dimid, &var_east_varid));
136 add_att(ncid, var_east_varid,
"K^2",
"BT variance (east)");
137 NC(nc_def_var(ncid,
"var_west", NC_DOUBLE, 1, dimid, &var_west_varid));
138 add_att(ncid, var_west_varid,
"K^2",
"BT variance (west)");
139 NC(nc_def_var(ncid,
"np_east", NC_INT, 1, dimid, &np_east_varid));
140 add_att(ncid, np_east_varid,
"1",
"number of footprints (east)");
141 NC(nc_def_var(ncid,
"np_west", NC_INT, 1, dimid, &np_west_varid));
142 add_att(ncid, np_west_varid,
"1",
"number of footprints (west)");
143
144
146 }
147
148
149 for (int iarg = 3; iarg < argc; iarg++) {
150
151
152 if (!strcmp(argv[iarg], ncfile))
153 continue;
154
155
156 int orb = 0;
157
158
159 if (!(in = fopen(argv[iarg], "r")))
160 continue;
161 else {
162 fclose(in);
164 }
165
166
167 if (bg_poly_x > 0 || bg_poly_y > 0 ||
168 bg_smooth_x > 0 || bg_smooth_y > 0 || gauss_fwhm > 0 || var_dh > 0) {
169
170
172
173
175
176
179
180
181 gauss(wave, gauss_fwhm);
182
183
185
186
187 for (
int ix = 0; ix < wave->
nx; ix++)
188 for (
int iy = 0; iy < wave->
ny; iy++) {
189 pert->
pt[iy][ix] = wave->
pt[ix][iy];
190 pert->
var[iy][ix] = wave->
var[ix][iy];
191 }
192
193
194 free(wave);
195 }
196
197
198 for (
int itrack = 0; itrack < pert->
ntrack; itrack++)
199 for (
int ixtrack = 0; ixtrack < pert->
nxtrack; ixtrack++) {
200
201
202 if (pert->
time[itrack][ixtrack] < 0
203 || pert->
lon[itrack][ixtrack] < -180
204 || pert->
lon[itrack][ixtrack] > 180
205 || pert->
lat[itrack][ixtrack] < -90
206 || pert->
lat[itrack][ixtrack] > 90
207 || pert->
pt[itrack][ixtrack] < -100
208 || pert->
pt[itrack][ixtrack] > 100
209 || !gsl_finite(pert->
bt[itrack][ixtrack])
210 || !gsl_finite(pert->
pt[itrack][ixtrack])
211 || !gsl_finite(pert->
var[itrack][ixtrack])
212 || !gsl_finite(pert->
dc[itrack][ixtrack]))
213 continue;
214
215
216 if (itrack > 0 && ixtrack == pert->
nxtrack / 2)
217 if (pert->
lat[itrack - 1][ixtrack] <= orblat
218 && pert->
lat[itrack][ixtrack] >= orblat)
219 orb++;
220 if (orb != orb_old) {
221
222
223 orb_old = orb;
224
225
226 if (en > 0 && wn > 0) {
227
228
229 if (dt230 > 0) {
230 const double nesr =
232 enoise =
BRIGHT(
PLANCK(ebt / en, nu) + nesr, nu) - ebt / en;
233 wnoise =
BRIGHT(
PLANCK(wbt / wn, nu) + nesr, nu) - wbt / wn;
234 }
235
236
237 fprintf(out, "%.2f %d %d %g %g %g %d %g %g %g\n", etime / en, orb,
238 en, evar / en - gsl_pow_2(emu / en), ebt / en, enoise,
239 wn, wvar / wn - gsl_pow_2(wmu / wn), wbt / wn, wnoise);
240
241
242 if (ncfile[0] != '-') {
243
244
245 jsec2time(etime / en, &year, &mon, &day, &iaux, &iaux, &iaux,
246 &aux);
248
249
250 track = 0;
251 for (
int itrack2 = 0; itrack2 < pert->
ntrack; itrack2++)
252 if (fabs(pert->
time[itrack2][0] - etime / en)
253 < fabs(pert->
time[track][0] - etime / en))
254 track = itrack2;
255
256
257 aux = etime / en;
258 NC(nc_put_vara_double(ncid, time_varid, start, count, &aux));
259 NC(nc_put_vara_int(ncid, year_varid, start, count, &year));
260 NC(nc_put_vara_int(ncid, doy_varid, start, count, &doy));
261 NC(nc_put_vara_int(ncid, track_varid, start, count, &track));
262 NC(nc_put_vara_int(ncid, np_east_varid, start, count, &en));
263 aux = evar / en - gsl_pow_2(emu / en) - gsl_pow_2(enoise);
264 NC(nc_put_vara_double
265 (ncid, var_east_varid, start, count, &aux));
266 NC(nc_put_vara_int(ncid, np_west_varid, start, count, &wn));
267 aux = wvar / wn - gsl_pow_2(wmu / wn) - gsl_pow_2(wnoise);
268 NC(nc_put_vara_double
269 (ncid, var_west_varid, start, count, &aux));
270
271
272 start[0]++;
273 }
274 }
275
276
277 etime = wtime = 0;
278 evar = wvar = 0;
279 emu = wmu = 0;
280 ebt = wbt = 0;
281 en = wn = 0;
282 }
283
284
285 if (pert->
lon[itrack][ixtrack] >= lon0
286 && pert->
lon[itrack][ixtrack] <= lon0 + dlon
287 && pert->
lat[itrack][ixtrack] >= lat0 - dlat / 2.
288 && pert->
lat[itrack][ixtrack] <= lat0 + dlat / 2.) {
289
290 etime += pert->
time[itrack][ixtrack];
291 emu += pert->
pt[itrack][ixtrack];
292 evar += gsl_pow_2(pert->
pt[itrack][ixtrack]);
293 ebt += pert->
bt[itrack][ixtrack];
294 en++;
295 }
296
297
298 if (pert->
lon[itrack][ixtrack] >= lon0 - offset - dlon
299 && pert->
lon[itrack][ixtrack] <= lon0 - offset
300 && pert->
lat[itrack][ixtrack] >= lat0 - dlat / 2.
301 && pert->
lat[itrack][ixtrack] <= lat0 + dlat / 2.) {
302
303 wtime += pert->
time[itrack][ixtrack];
304 wmu += pert->
pt[itrack][ixtrack];
305 wvar += gsl_pow_2(pert->
pt[itrack][ixtrack]);
306 wbt += pert->
bt[itrack][ixtrack];
307 wn++;
308 }
309 }
310
311
312 if (en > 0 && wn > 0) {
313
314
315 if (dt230 > 0) {
316 const double nesr =
PLANCK(230.0 + dt230, nu) -
PLANCK(230.0, nu);
317 enoise =
BRIGHT(
PLANCK(ebt / en, nu) + nesr, nu) - ebt / en;
318 wnoise =
BRIGHT(
PLANCK(wbt / wn, nu) + nesr, nu) - wbt / wn;
319 }
320
321
322 fprintf(out, "%.2f %d %d %g %g %g %d %g %g %g\n", etime / en, orb,
323 en, evar / en - gsl_pow_2(emu / en), ebt / en, enoise,
324 wn, wvar / wn - gsl_pow_2(wmu / wn), wbt / wn, wnoise);
325
326
327 if (ncfile[0] != '-') {
328
329
330 jsec2time(etime / en, &year, &mon, &day, &iaux, &iaux, &iaux, &aux);
332
333
334 track = 0;
335 for (
int itrack2 = 0; itrack2 < pert->
ntrack; itrack2++)
336 if (fabs(pert->
time[itrack2][0] - etime / en)
337 < fabs(pert->
time[track][0] - etime / en))
338 track = itrack2;
339
340
341 aux = etime / en;
342 NC(nc_put_vara_double(ncid, time_varid, start, count, &aux));
343 NC(nc_put_vara_int(ncid, year_varid, start, count, &year));
344 NC(nc_put_vara_int(ncid, doy_varid, start, count, &doy));
345 NC(nc_put_vara_int(ncid, track_varid, start, count, &track));
346 NC(nc_put_vara_int(ncid, np_east_varid, start, count, &en));
347 aux = evar / en - gsl_pow_2(emu / en) - gsl_pow_2(enoise);
348 NC(nc_put_vara_double(ncid, var_east_varid, start, count, &aux));
349 NC(nc_put_vara_int(ncid, np_west_varid, start, count, &wn));
350 aux = wvar / wn - gsl_pow_2(wmu / wn) - gsl_pow_2(wnoise);
351 NC(nc_put_vara_double(ncid, var_west_varid, start, count, &aux));
352
353
354 start[0]++;
355 }
356 }
357 }
358
359
360 fclose(out);
361
362
363 if (ncfile[0] != '-')
365
366
367 free(pert);
368
369 return EXIT_SUCCESS;
370}
#define NC(cmd)
Execute netCDF library command and check result.
void jsec2time(const double jsec, int *year, int *mon, int *day, int *hour, int *min, int *sec, double *remain)
Convert seconds to date.
double scan_ctl(int argc, char *argv[], const char *varname, int arridx, const char *defvalue, char *value)
Search control parameter file for variable entry.
#define LEN
Maximum length of ASCII data lines.
#define BRIGHT(rad, nu)
Compute brightness temperature.
#define ERRMSG(...)
Print error message and quit program.
#define ALLOC(ptr, type, n)
Allocate memory.
#define PLANCK(T, nu)
Compute Planck function.
void background_smooth(wave_t *wave, int npts_x, int npts_y)
Smooth background.
void add_att(int ncid, int varid, const char *unit, const char *long_name)
Add variable attributes to netCDF file.
void day2doy(int year, int mon, int day, int *doy)
Get day of year from date.
void background_poly(wave_t *wave, int dim_x, int dim_y)
Get background based on polynomial fits.
void variance(wave_t *wave, double dh)
Compute local variance.
void pert2wave(pert_t *pert, wave_t *wave, int track0, int track1, int xtrack0, int xtrack1)
Convert radiance perturbation data to wave analysis struct.
void read_pert(char *filename, char *pertname, pert_t *pert)
Read radiance perturbation data.
void gauss(wave_t *wave, double fwhm)
Apply Gaussian filter to perturbations...
double var[PERT_NTRACK][PERT_NXTRACK]
Brightness temperature variance (4 or 15 micron) [K].
double pt[PERT_NTRACK][PERT_NXTRACK]
Brightness temperature perturbation (4 or 15 micron) [K].
double time[PERT_NTRACK][PERT_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
double dc[PERT_NTRACK][PERT_NXTRACK]
Brightness temperature (8 micron) [K].
int ntrack
Number of along-track values.
int nxtrack
Number of across-track values.
double lon[PERT_NTRACK][PERT_NXTRACK]
Longitude [deg].
double bt[PERT_NTRACK][PERT_NXTRACK]
Brightness temperature (4 or 15 micron) [K].
double lat[PERT_NTRACK][PERT_NXTRACK]
Latitude [deg].
int nx
Number of across-track values.
int ny
Number of along-track values.
double var[WX][WY]
Variance [K].
double pt[WX][WY]
Perturbation [K].