109 static char kernel[LEN], pertname[LEN];
111 const double var_dh = 100.;
113 static double hyam[
NZ], hybm[
NZ], kz[NSHAPE], kw[NSHAPE];
117 static int init, ncid, dimid, varid, track0, track1, nk;
137 ERRMSG(
"Give parameters: <ctl> <model> <model.nc> <pert.nc>"
138 " <wave_airs.tab> <wave_model.tab> <wave_airs.nc> <wave_model.nc>");
141 read_ctl(argc, argv, &ctl);
142 scan_ctl(argc, argv,
"PERTNAME", -1,
"4mu", pertname);
143 scan_ctl(argc, argv,
"KERNEL", -1,
"-", kernel);
144 const int extpol = (int) scan_ctl(argc, argv,
"EXTPOL", -1,
"0", NULL);
145 const int slant = (int) scan_ctl(argc, argv,
"SLANT", -1,
"1", NULL);
146 const double t_ovp = scan_ctl(argc, argv,
"T_OVP", -1,
"", NULL);
152 tbl_t *tbl = read_tbl(&ctl);
164 printf(
"Read %s data: %s\n", argv[2], argv[3]);
165 NC(nc_open(argv[3], NC_NOWRITE, &ncid));
168 LOG(2,
"Check time...");
169 if (nc_inq_dimid(ncid,
"time", &dimid) != NC_NOERR)
170 NC(nc_inq_dimid(ncid,
"time", &dimid));
171 NC(nc_inq_dimlen(ncid, dimid, &rs));
173 ERRMSG(
"Only one time step is allowed!");
176 LOG(2,
"Read latitudes...");
177 if (nc_inq_dimid(ncid,
"lat", &dimid) != NC_NOERR)
178 NC(nc_inq_dimid(ncid,
"latitude", &dimid));
179 NC(nc_inq_dimlen(ncid, dimid, &rs));
180 model->
nlat = (int) rs;
182 ERRMSG(
"Too many latitudes!");
183 if (nc_inq_varid(ncid,
"lat", &varid) != NC_NOERR)
184 NC(nc_inq_varid(ncid,
"latitude", &varid));
185 NC(nc_get_var_double(ncid, varid, model->
lat));
188 LOG(2,
"Read longitudes...");
189 if (nc_inq_dimid(ncid,
"lon", &dimid) != NC_NOERR)
190 NC(nc_inq_dimid(ncid,
"longitude", &dimid));
191 NC(nc_inq_dimlen(ncid, dimid, &rs));
192 model->
nlon = (int) rs;
194 ERRMSG(
"Too many longitudes!");
195 if (nc_inq_varid(ncid,
"lon", &varid))
196 NC(nc_inq_varid(ncid,
"longitude", &varid));
197 NC(nc_get_var_double(ncid, varid, model->
lon));
200 if (strcasecmp(argv[2],
"icon") == 0) {
203 LOG(2,
"Read levels...");
204 NC(nc_inq_dimid(ncid,
"height", &dimid));
205 NC(nc_inq_dimlen(ncid, dimid, &rs));
206 model->
nz = (int) rs;
208 ERRMSG(
"Too many altitudes!");
211 LOG(2,
"Read height...");
212 NC(nc_inq_varid(ncid,
"z_mc", &varid));
213 NC(nc_get_var_float(ncid, varid, help));
214 for (
int ilon = 0; ilon < model->
nlon; ilon++)
215 for (
int ilat = 0; ilat < model->
nlat; ilat++)
216 for (
int iz = 0; iz < model->
nz; iz++)
217 model->
z[ilon][ilat][iz] =
218 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
222 LOG(2,
"Read temperature...");
223 NC(nc_inq_varid(ncid,
"temp", &varid));
224 NC(nc_get_var_float(ncid, varid, help));
225 for (
int ilon = 0; ilon < model->
nlon; ilon++)
226 for (
int ilat = 0; ilat < model->
nlat; ilat++)
227 for (
int iz = 0; iz < model->
nz; iz++)
228 model->
t[ilon][ilat][iz] =
229 help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
232 LOG(2,
"Read pressure...");
233 NC(nc_inq_varid(ncid,
"pres", &varid));
234 NC(nc_get_var_float(ncid, varid, help));
235 for (
int ilon = 0; ilon < model->
nlon; ilon++)
236 for (
int ilat = 0; ilat < model->
nlat; ilat++)
237 for (
int iz = 0; iz < model->
nz; iz++)
238 model->
p[ilon][ilat][iz] =
239 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
244 else if (strcasecmp(argv[2],
"ifs") == 0) {
247 LOG(2,
"Read levels...");
248 NC(nc_inq_dimid(ncid,
"lev_2", &dimid));
249 NC(nc_inq_dimlen(ncid, dimid, &rs));
250 model->
nz = (int) rs;
252 ERRMSG(
"Too many altitudes!");
255 LOG(2,
"Read height...");
256 NC(nc_inq_varid(ncid,
"gh", &varid));
257 NC(nc_get_var_float(ncid, varid, help));
258 for (
int ilon = 0; ilon < model->
nlon; ilon++)
259 for (
int ilat = 0; ilat < model->
nlat; ilat++)
260 for (
int iz = 0; iz < model->
nz; iz++)
261 model->
z[ilon][ilat][iz] =
262 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
266 LOG(2,
"Read temperature...");
267 NC(nc_inq_varid(ncid,
"t", &varid));
268 NC(nc_get_var_float(ncid, varid, help));
269 for (
int ilon = 0; ilon < model->
nlon; ilon++)
270 for (
int ilat = 0; ilat < model->
nlat; ilat++)
271 for (
int iz = 0; iz < model->
nz; iz++)
272 model->
t[ilon][ilat][iz] =
273 help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
276 LOG(2,
"Read surface pressure...");
277 NC(nc_inq_varid(ncid,
"lnsp", &varid));
278 NC(nc_get_var_float(ncid, varid, help));
279 for (
int ilon = 0; ilon < model->
nlon; ilon++)
280 for (
int ilat = 0; ilat < model->
nlat; ilat++)
281 model->
ps[ilon][ilat] = (
float) exp(help[ilat * model->
nlon + ilon]);
284 LOG(2,
"Read grid coefficients...");
285 NC(nc_inq_varid(ncid,
"hyam", &varid));
286 NC(nc_get_var_double(ncid, varid, hyam));
287 NC(nc_inq_varid(ncid,
"hybm", &varid));
288 NC(nc_get_var_double(ncid, varid, hybm));
291 LOG(2,
"Calculate pressure...");
292 for (
int ilon = 0; ilon < model->
nlon; ilon++)
293 for (
int ilat = 0; ilat < model->
nlat; ilat++)
294 for (
int iz = 0; iz < model->
nz; iz++)
295 model->
p[ilon][ilat][iz]
296 = (
float) ((hyam[iz] + hybm[iz] * model->
ps[ilon][ilat]) / 100.);
300 else if (strcasecmp(argv[2],
"um") == 0) {
303 LOG(2,
"Read levels...");
304 if (nc_inq_dimid(ncid,
"RHO_TOP_eta_rho", &dimid) != NC_NOERR)
305 NC(nc_inq_dimid(ncid,
"RHO_eta_rho", &dimid));
306 NC(nc_inq_dimlen(ncid, dimid, &rs));
307 model->
nz = (int) rs;
309 ERRMSG(
"Too many altitudes!");
312 LOG(2,
"Read height...");
313 if (nc_inq_varid(ncid,
"STASH_m01s15i102_2", &varid) != NC_NOERR)
314 NC(nc_inq_varid(ncid,
"STASH_m01s15i102", &varid));
315 NC(nc_get_var_float(ncid, varid, help));
316 for (
int ilon = 0; ilon < model->
nlon; ilon++)
317 for (
int ilat = 0; ilat < model->
nlat; ilat++)
318 for (
int iz = 0; iz < model->
nz; iz++)
319 model->
z[ilon][ilat][iz] =
320 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
324 LOG(2,
"Read temperature...");
325 NC(nc_inq_varid(ncid,
"STASH_m01s30i004", &varid));
326 NC(nc_get_var_float(ncid, varid, help));
327 for (
int ilon = 0; ilon < model->
nlon; ilon++)
328 for (
int ilat = 0; ilat < model->
nlat; ilat++)
329 for (
int iz = 0; iz < model->
nz; iz++)
330 model->
t[ilon][ilat][iz] =
331 help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
334 LOG(2,
"Read pressure...");
335 NC(nc_inq_varid(ncid,
"STASH_m01s00i407", &varid));
336 NC(nc_get_var_float(ncid, varid, help));
337 for (
int ilon = 0; ilon < model->
nlon; ilon++)
338 for (
int ilat = 0; ilat < model->
nlat; ilat++)
339 for (
int iz = 0; iz < model->
nz; iz++)
340 model->
p[ilon][ilat][iz] =
341 0.01f * help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
345 else if (strcasecmp(argv[2],
"wrf") == 0) {
348 LOG(2,
"Read levels...");
349 NC(nc_inq_dimid(ncid,
"bottom_top", &dimid));
350 NC(nc_inq_dimlen(ncid, dimid, &rs));
351 model->
nz = (int) rs;
353 ERRMSG(
"Too many altitudes!");
356 LOG(2,
"Read height...");
357 NC(nc_inq_varid(ncid,
"z", &varid));
358 NC(nc_get_var_float(ncid, varid, help));
359 for (
int ilon = 0; ilon < model->
nlon; ilon++)
360 for (
int ilat = 0; ilat < model->
nlat; ilat++)
361 for (
int iz = 0; iz < model->
nz; iz++)
362 model->
z[ilon][ilat][iz] =
363 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
367 LOG(2,
"Read temperature...");
368 NC(nc_inq_varid(ncid,
"tk", &varid));
369 NC(nc_get_var_float(ncid, varid, help));
370 for (
int ilon = 0; ilon < model->
nlon; ilon++)
371 for (
int ilat = 0; ilat < model->
nlat; ilat++)
372 for (
int iz = 0; iz < model->
nz; iz++)
373 model->
t[ilon][ilat][iz] =
374 help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
377 LOG(2,
"Read pressure...");
378 NC(nc_inq_varid(ncid,
"p", &varid));
379 NC(nc_get_var_float(ncid, varid, help));
380 for (
int ilon = 0; ilon < model->
nlon; ilon++)
381 for (
int ilat = 0; ilat < model->
nlat; ilat++)
382 for (
int iz = 0; iz < model->
nz; iz++)
383 model->
p[ilon][ilat][iz] =
384 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
389 ERRMSG(
"Model type not supported!");
398 LOG(2,
"Checking...");
399 for (
int ilon = 0; ilon < model->
nlon; ilon++)
400 for (
int ilat = 0; ilat < model->
nlat; ilat++)
401 for (
int iz = 0; iz < model->
nz; iz++)
402 if (model->
t[ilon][ilat][iz] <= 100
403 || model->
t[ilon][ilat][iz] >= 400) {
404 model->
p[ilon][ilat][iz] = GSL_NAN;
405 model->
t[ilon][ilat][iz] = GSL_NAN;
406 model->
z[ilon][ilat][iz] = GSL_NAN;
410 LOG(2,
"Smoothing...");
414 for (
int iz = 0; iz < model->
nz; iz++)
415 printf(
"section_height: %d %g %g %g %g %g\n", iz,
416 model->
z[model->
nlon / 2][model->
nlat / 2][iz],
418 model->
p[model->
nlon / 2][model->
nlat / 2][iz],
419 model->
t[model->
nlon / 2][model->
nlat / 2][iz]);
420 for (
int ilon = 0; ilon < model->
nlon; ilon++)
421 printf(
"section_west_east: %d %g %g %g %g %g\n", ilon,
422 model->
z[ilon][model->
nlat / 2][model->
nz / 2],
423 model->
lon[ilon], model->
lat[model->
nlat / 2],
424 model->
p[ilon][model->
nlat / 2][model->
nz / 2],
425 model->
t[ilon][model->
nlat / 2][model->
nz / 2]);
426 for (
int ilat = 0; ilat < model->
nlat; ilat++)
427 printf(
"section_north_south: %d %g %g %g %g %g\n", ilat,
428 model->
z[model->
nlon / 2][ilat][model->
nz / 2],
429 model->
lon[model->
nlon / 2], model->
lat[ilat],
430 model->
p[model->
nlon / 2][ilat][model->
nz / 2],
431 model->
t[model->
nlon / 2][ilat][model->
nz / 2]);
438 ALLOC(atm, atm_t, 1);
439 ALLOC(obs, obs_t, 1);
447 for (
int itrack = 0; itrack < pert->
ntrack; itrack++) {
448 if (pert->
time[itrack][44] < t_ovp - 720 || itrack == 0)
451 if (pert->
time[itrack][44] > t_ovp + 720)
473 for (
int itrack = track0; itrack <= track1; itrack++)
474 for (
int ixtrack = 0; ixtrack < pert->
nxtrack; ixtrack++) {
478 printf(
"Compute track %d / %d ...\n", itrack - track0 + 1,
479 track1 - track0 + 1);
484 obs->obslon[0] = pert->
lon[itrack][44];
485 obs->obslat[0] = pert->
lat[itrack][44];
487 obs->vplon[0] = pert->
lon[itrack][ixtrack];
488 obs->vplat[0] = pert->
lat[itrack][ixtrack];
491 double xm[3], xo[3], xs[3];
492 geo2cart(obs->obsz[0], obs->obslon[0], obs->obslat[0], xo);
493 geo2cart(obs->vpz[0], obs->vplon[0], obs->vplat[0], xs);
498 for (
double f = 0.0; f <= 1.0; f += 0.0002) {
499 xm[0] = f * xo[0] + (1 - f) * xs[0];
500 xm[1] = f * xo[1] + (1 - f) * xs[1];
501 xm[2] = f * xo[2] + (1 - f) * xs[2];
502 cart2geo(xm, &atm->z[atm->np], &atm->lon[atm->np],
504 atm->time[atm->np] = pert->
time[itrack][ixtrack];
505 if (atm->z[atm->np] < 10)
507 else if (atm->z[atm->np] > 90)
509 else if ((++atm->np) >= NP)
510 ERRMSG(
"Too many ray path data points!");
514 for (
double f = 10.0; f <= 90.0; f += 0.2) {
515 atm->time[atm->np] = pert->
time[itrack][ixtrack];
517 atm->lon[atm->np] = pert->
lon[itrack][ixtrack];
518 atm->lat[atm->np] = pert->
lat[itrack][ixtrack];
519 if ((++atm->np) >= NP)
520 ERRMSG(
"Too many ray path data points!");
525 climatology(&ctl, atm);
528 for (
int ip = 0; ip < atm->np; ip++)
529 intpol(model, atm->
z[ip], atm->lon[ip], atm->lat[ip],
530 &atm->p[ip], &atm->t[ip]);
534 for (
int ip = 0; ip < atm->np; ip++)
535 if (!gsl_finite(atm->p[ip]) || !gsl_finite(atm->t[ip]))
538 pert->
bt[itrack][ixtrack] = GSL_NAN;
542 if (kernel[0] !=
'-') {
547 read_shape(kernel, kz, kw, &nk);
549 ERRMSG(
"Kernel function must be ascending!");
554 pert->
bt[itrack][ixtrack] = 0;
555 for (
int ip = 0; ip < atm->np; ip++)
556 if (atm->z[ip] >= kz[0] && atm->z[ip] <= kz[nk - 1]) {
557 const int iz = locate_irr(kz, nk, atm->z[ip]);
559 LIN(kz[iz], kw[iz], kz[iz + 1], kw[iz + 1], atm->z[ip]);
560 pert->
bt[itrack][ixtrack] += w * atm->t[ip];
563 pert->
bt[itrack][ixtrack] /= wsum;
570 formod(&ctl, tbl, atm, obs);
573 pert->
bt[itrack][ixtrack] = 0;
574 for (
int id = 0;
id < ctl.nd;
id++)
575 pert->
bt[itrack][ixtrack] += obs->rad[
id][0] / ctl.nd;
582 for (
int itrack = track0; itrack <= track1; itrack++) {
583 for (
int ixtrack = 1; ixtrack < pert->
nxtrack; ixtrack++)
584 if (!gsl_finite(pert->
bt[itrack][ixtrack]))
585 pert->
bt[itrack][ixtrack] = pert->
bt[itrack][ixtrack - 1];
586 for (
int ixtrack = pert->
nxtrack - 2; ixtrack >= 0; ixtrack--)
587 if (!gsl_finite(pert->
bt[itrack][ixtrack]))
588 pert->
bt[itrack][ixtrack] = pert->
bt[itrack][ixtrack + 1];
633 if (model->
lon[model->
nlon - 1] > 180)
638 if (lon < model->lon[0]
639 || lon > model->
lon[model->
nlon - 1]
640 || lat < GSL_MIN(model->
lat[0], model->
lat[model->
nlat - 1])
641 || lat > GSL_MAX(model->
lat[0], model->
lat[model->
nlat - 1])) {
648 int ilon = locate_irr(model->
lon, model->
nlon, lon);
649 int ilat = locate_irr(model->
lat, model->
nlat, lat);
652 if (!gsl_finite(model->
z[ilon][ilat][0])
653 || !gsl_finite(model->
z[ilon][ilat][model->
nz - 1])
654 || !gsl_finite(model->
z[ilon][ilat + 1][model->
nz - 1])
655 || !gsl_finite(model->
z[ilon][ilat + 1][model->
nz - 1])
656 || !gsl_finite(model->
z[ilon + 1][ilat][model->
nz - 1])
657 || !gsl_finite(model->
z[ilon + 1][ilat][model->
nz - 1])
658 || !gsl_finite(model->
z[ilon + 1][ilat + 1][model->
nz - 1])
659 || !gsl_finite(model->
z[ilon + 1][ilat + 1][model->
nz - 1])) {
667 GSL_MAX(model->
z[ilon][ilat][0], model->
z[ilon][ilat][model->
nz - 1])
668 || z < GSL_MIN(model->
z[ilon][ilat][0],
669 model->
z[ilon][ilat][model->
nz - 1])
670 || z > GSL_MAX(model->
z[ilon][ilat + 1][0],
671 model->
z[ilon][ilat + 1][model->
nz - 1])
672 || z < GSL_MIN(model->
z[ilon][ilat + 1][0],
673 model->
z[ilon][ilat + 1][model->
nz - 1])
674 || z > GSL_MAX(model->
z[ilon + 1][ilat][0],
675 model->
z[ilon + 1][ilat][model->
nz - 1])
676 || z < GSL_MIN(model->
z[ilon + 1][ilat][0],
677 model->
z[ilon + 1][ilat][model->
nz - 1])
678 || z > GSL_MAX(model->
z[ilon + 1][ilat + 1][0],
679 model->
z[ilon + 1][ilat + 1][model->
nz - 1])
680 || z < GSL_MIN(model->
z[ilon + 1][ilat + 1][0],
681 model->
z[ilon + 1][ilat + 1][model->
nz - 1]))
685 for (iz = 0; iz < model->
nz; iz++)
686 zd[iz] = model->
z[ilon][ilat][iz];
687 iz = locate_irr(zd, model->
nz, z);
688 double p00 = LIN(model->
z[ilon][ilat][iz], model->
p[ilon][ilat][iz],
689 model->
z[ilon][ilat][iz + 1], model->
p[ilon][ilat][iz + 1],
691 double t00 = LIN(model->
z[ilon][ilat][iz], model->
t[ilon][ilat][iz],
692 model->
z[ilon][ilat][iz + 1], model->
t[ilon][ilat][iz + 1],
695 for (iz = 0; iz < model->
nz; iz++)
696 zd[iz] = model->
z[ilon][ilat + 1][iz];
697 iz = locate_irr(zd, model->
nz, z);
698 double p01 = LIN(model->
z[ilon][ilat + 1][iz], model->
p[ilon][ilat + 1][iz],
699 model->
z[ilon][ilat + 1][iz + 1],
700 model->
p[ilon][ilat + 1][iz + 1], z);
701 double t01 = LIN(model->
z[ilon][ilat + 1][iz], model->
t[ilon][ilat + 1][iz],
702 model->
z[ilon][ilat + 1][iz + 1],
703 model->
t[ilon][ilat + 1][iz + 1],
706 for (iz = 0; iz < model->
nz; iz++)
707 zd[iz] = model->
z[ilon + 1][ilat][iz];
708 iz = locate_irr(zd, model->
nz, z);
709 double p10 = LIN(model->
z[ilon + 1][ilat][iz], model->
p[ilon + 1][ilat][iz],
710 model->
z[ilon + 1][ilat][iz + 1],
711 model->
p[ilon + 1][ilat][iz + 1], z);
712 double t10 = LIN(model->
z[ilon + 1][ilat][iz], model->
t[ilon + 1][ilat][iz],
713 model->
z[ilon + 1][ilat][iz + 1],
714 model->
t[ilon + 1][ilat][iz + 1],
717 for (iz = 0; iz < model->
nz; iz++)
718 zd[iz] = model->
z[ilon + 1][ilat + 1][iz];
719 iz = locate_irr(zd, model->
nz, z);
721 LIN(model->
z[ilon + 1][ilat + 1][iz], model->
p[ilon + 1][ilat + 1][iz],
722 model->
z[ilon + 1][ilat + 1][iz + 1],
723 model->
p[ilon + 1][ilat + 1][iz + 1], z);
725 LIN(model->
z[ilon + 1][ilat + 1][iz], model->
t[ilon + 1][ilat + 1][iz],
726 model->
z[ilon + 1][ilat + 1][iz + 1],
727 model->
t[ilon + 1][ilat + 1][iz + 1], z);
730 p00 = LIN(model->
lon[ilon], p00, model->
lon[ilon + 1], p10, lon);
731 p11 = LIN(model->
lon[ilon], p01, model->
lon[ilon + 1], p11, lon);
732 *p = LIN(model->
lat[ilat], p00, model->
lat[ilat + 1], p11, lat);
734 t00 = LIN(model->
lon[ilon], t00, model->
lon[ilon + 1], t10, lon);
735 t11 = LIN(model->
lon[ilon], t01, model->
lon[ilon + 1], t11, lon);
736 *t = LIN(model->
lat[ilat], t00, model->
lat[ilat + 1], t11, lat);
749 const double fwhm = 20.0;
751 static double wy[
DLAT + 1];
754 const double dy = RE * M_PI / 180. * fabs(model->
lat[1] - model->
lat[0]);
755 for (
int ilat = 0; ilat <=
DLAT; ilat++)
756 wy[ilat] = exp(-0.5 * POW2(ilat * dy * 2.35482 / fwhm));
759 for (
int iz = 0; iz < model->
nz; iz++) {
762 printf(
"Smoothing level %d / %d ...\n", iz + 1, model->
nz);
765#pragma omp parallel for collapse(2)
766 for (
int ilon = 0; ilon < model->
nlon; ilon++)
767 for (
int ilat = 0; ilat < model->
nlat; ilat++) {
768 hp[ilon][ilat] = model->
p[ilon][ilat][iz];
769 ht[ilon][ilat] = model->
t[ilon][ilat][iz];
770 hz[ilon][ilat] = model->
z[ilon][ilat][iz];
780 for (
int ilat = 0; ilat < model->
nlat; ilat++) {
784 RE * M_PI / 180. * cos(model->
lat[ilat] * M_PI / 180.) *
785 fabs(model->
lon[1] - model->
lon[0]);
787 for (
int ilon = 0; ilon <=
DLON; ilon++)
788 wx[ilon] = exp(-0.5 * POW2(ilon * dx * 2.35482 / fwhm));
791 for (
int ilon = 0; ilon < model->
nlon; ilon++) {
793 model->
p[ilon][ilat][iz] = 0;
794 model->
t[ilon][ilat][iz] = 0;
795 model->
z[ilon][ilat][iz] = 0;
797 const int ilo0 = (ilon -
DLON > 0) ? ilon -
DLON : 0;
800 const int ila0 = (ilat -
DLAT > 0) ? ilat -
DLAT : 0;
804 for (
int ilon2 = ilo0; ilon2 <= ilo1; ++ilon2) {
805 const double wxh = wx[abs(ilon2 - ilon)];
806 for (
int ilat2 = ila0; ilat2 <= ila1; ++ilat2) {
807 const float w = (float) (wxh * wy[abs(ilat2 - ilat)]);
808 model->
p[ilon][ilat][iz] += w * hp[ilon2][ilat2];
809 model->
t[ilon][ilat][iz] += w * ht[ilon2][ilat2];
810 model->
z[ilon][ilat][iz] += w * hz[ilon2][ilat2];
815 model->
p[ilon][ilat][iz] /= wsum;
816 model->
t[ilon][ilat][iz] /= wsum;
817 model->
z[ilon][ilat][iz] /= wsum;
830 static double help[
WX *
WY];
832 int ncid, dimid[10], lon_id, lat_id, bt_id, pt_id, var_id;
835 NC(nc_create(filename, NC_CLOBBER, &ncid));
838 NC(nc_def_dim(ncid,
"NTRACK", (
size_t) wave->
ny, &dimid[0]));
839 NC(nc_def_dim(ncid,
"NXTRACK", (
size_t) wave->
nx, &dimid[1]));
842 NC(nc_def_var(ncid,
"lon", NC_DOUBLE, 2, dimid, &lon_id));
843 add_att(ncid, lon_id,
"deg",
"footprint longitude");
844 NC(nc_def_var(ncid,
"lat", NC_DOUBLE, 2, dimid, &lat_id));
845 add_att(ncid, lat_id,
"deg",
"footprint latitude");
846 NC(nc_def_var(ncid,
"bt", NC_FLOAT, 2, dimid, &bt_id));
847 add_att(ncid, bt_id,
"K",
"brightness temperature");
848 NC(nc_def_var(ncid,
"bt_pt", NC_FLOAT, 2, dimid, &pt_id));
849 add_att(ncid, pt_id,
"K",
"brightness temperature perturbation");
850 NC(nc_def_var(ncid,
"bt_var", NC_FLOAT, 2, dimid, &var_id));
851 add_att(ncid, var_id,
"K^2",
"brightness temperature variance");
857 for (
int ix = 0; ix < wave->
nx; ix++)
858 for (
int iy = 0; iy < wave->
ny; iy++)
859 help[iy * wave->
nx + ix] = wave->
lon[ix][iy];
860 NC(nc_put_var_double(ncid, lon_id, help));
861 for (
int ix = 0; ix < wave->
nx; ix++)
862 for (
int iy = 0; iy < wave->
ny; iy++)
863 help[iy * wave->
nx + ix] = wave->
lat[ix][iy];
864 NC(nc_put_var_double(ncid, lat_id, help));
865 for (
int ix = 0; ix < wave->
nx; ix++)
866 for (
int iy = 0; iy < wave->
ny; iy++)
867 help[iy * wave->
nx + ix] = wave->
temp[ix][iy];
868 NC(nc_put_var_double(ncid, bt_id, help));
869 for (
int ix = 0; ix < wave->
nx; ix++)
870 for (
int iy = 0; iy < wave->
ny; iy++)
871 help[iy * wave->
nx + ix] = wave->
pt[ix][iy];
872 NC(nc_put_var_double(ncid, pt_id, help));
873 for (
int ix = 0; ix < wave->
nx; ix++)
874 for (
int iy = 0; iy < wave->
ny; iy++)
875 help[iy * wave->
nx + ix] = wave->
var[ix][iy];
876 NC(nc_put_var_double(ncid, var_id, help));
#define NC(cmd)
Execute netCDF library command and check result.
int main(int argc, char *argv[])
void intpol(model_t *model, double z, double lon, double lat, double *p, double *t)
Interpolation of model data.
void write_nc(char *filename, wave_t *wave)
Write wave struct to netCDF file.
#define NZ
Maximum number of model levels.
void smooth(model_t *model)
Smoothing of model data.
#define NLAT
Maximum number of model latitudes.
#define NLON
Maximum number of model longitudes.
void add_att(int ncid, int varid, const char *unit, const char *long_name)
Add variable attributes to netCDF file.
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 write_wave(char *filename, wave_t *wave)
Write wave analysis data.
AIRS Code Collection library declarations.
#define WX
Across-track size of wave analysis data.
#define WY
Along-track size of wave analysis data.
double lat[NLAT]
Latitude [deg].
float t[NLON][NLAT][NZ]
Temperature [K].
double lon[NLON]
Longitude [deg].
float ps[NLON][NLAT]
Surface pressure [hPa].
int nz
Number of vertical levels.
float z[NLON][NLAT][NZ]
Height [km].
int nlon
Number of longitudes.
int nlat
Number of latitudes.
float p[NLON][NLAT][NZ]
Pressure [hPa].
double time[PERT_NTRACK][PERT_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
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 temp[WX][WY]
Temperature [K].
double lon[WX][WY]
Longitude [deg].
double lat[WX][WY]
Latitude [deg].
double pt[WX][WY]
Perturbation [K].