111 const double var_dh = 100.;
113 static double xo[3], xs[3], xm[3], hyam[
NZ], hybm[
NZ], kz[
NSHAPE],
118 static int init, ncid, dimid, varid, track0, track1, nk;
138 ERRMSG(
"Give parameters: <ctl> <model> <model.nc> <pert.nc>"
139 " <wave_airs.tab> <wave_model.tab> <wave_airs.nc> <wave_model.nc>");
143 scan_ctl(argc, argv,
"PERTNAME", -1,
"4mu", pertname);
145 const int extpol = (int)
scan_ctl(argc, argv,
"EXTPOL", -1,
"0", NULL);
146 const int slant = (int)
scan_ctl(argc, argv,
"SLANT", -1,
"1", NULL);
147 const double t_ovp =
scan_ctl(argc, argv,
"T_OVP", -1,
"", NULL);
162 printf(
"Read %s data: %s\n", argv[2], argv[3]);
163 NC(nc_open(argv[3], NC_NOWRITE, &ncid));
166 LOG(2,
"Check time...");
167 if (nc_inq_dimid(ncid,
"time", &dimid) != NC_NOERR)
168 NC(nc_inq_dimid(ncid,
"time", &dimid));
169 NC(nc_inq_dimlen(ncid, dimid, &rs));
171 ERRMSG(
"Only one time step is allowed!");
174 LOG(2,
"Read latitudes...");
175 if (nc_inq_dimid(ncid,
"lat", &dimid) != NC_NOERR)
176 NC(nc_inq_dimid(ncid,
"latitude", &dimid));
177 NC(nc_inq_dimlen(ncid, dimid, &rs));
178 model->
nlat = (int) rs;
180 ERRMSG(
"Too many latitudes!");
181 if (nc_inq_varid(ncid,
"lat", &varid) != NC_NOERR)
182 NC(nc_inq_varid(ncid,
"latitude", &varid));
183 NC(nc_get_var_double(ncid, varid, model->
lat));
186 LOG(2,
"Read longitudes...");
187 if (nc_inq_dimid(ncid,
"lon", &dimid) != NC_NOERR)
188 NC(nc_inq_dimid(ncid,
"longitude", &dimid));
189 NC(nc_inq_dimlen(ncid, dimid, &rs));
190 model->
nlon = (int) rs;
192 ERRMSG(
"Too many longitudes!");
193 if (nc_inq_varid(ncid,
"lon", &varid))
194 NC(nc_inq_varid(ncid,
"longitude", &varid));
195 NC(nc_get_var_double(ncid, varid, model->
lon));
198 if (strcasecmp(argv[2],
"icon") == 0) {
201 LOG(2,
"Read levels...");
202 NC(nc_inq_dimid(ncid,
"height", &dimid));
203 NC(nc_inq_dimlen(ncid, dimid, &rs));
204 model->
nz = (int) rs;
206 ERRMSG(
"Too many altitudes!");
209 LOG(2,
"Read height...");
210 NC(nc_inq_varid(ncid,
"z_mc", &varid));
211 NC(nc_get_var_float(ncid, varid, help));
212 for (
int ilon = 0; ilon < model->
nlon; ilon++)
213 for (
int ilat = 0; ilat < model->
nlat; ilat++)
214 for (
int iz = 0; iz < model->
nz; iz++)
215 model->
z[ilon][ilat][iz] =
216 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
220 LOG(2,
"Read temperature...");
221 NC(nc_inq_varid(ncid,
"temp", &varid));
222 NC(nc_get_var_float(ncid, varid, help));
223 for (
int ilon = 0; ilon < model->
nlon; ilon++)
224 for (
int ilat = 0; ilat < model->
nlat; ilat++)
225 for (
int iz = 0; iz < model->
nz; iz++)
226 model->
t[ilon][ilat][iz] =
227 help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
230 LOG(2,
"Read pressure...");
231 NC(nc_inq_varid(ncid,
"pres", &varid));
232 NC(nc_get_var_float(ncid, varid, help));
233 for (
int ilon = 0; ilon < model->
nlon; ilon++)
234 for (
int ilat = 0; ilat < model->
nlat; ilat++)
235 for (
int iz = 0; iz < model->
nz; iz++)
236 model->
p[ilon][ilat][iz] =
237 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
242 else if (strcasecmp(argv[2],
"ifs") == 0) {
245 LOG(2,
"Read levels...");
246 NC(nc_inq_dimid(ncid,
"lev_2", &dimid));
247 NC(nc_inq_dimlen(ncid, dimid, &rs));
248 model->
nz = (int) rs;
250 ERRMSG(
"Too many altitudes!");
253 LOG(2,
"Read height...");
254 NC(nc_inq_varid(ncid,
"gh", &varid));
255 NC(nc_get_var_float(ncid, varid, help));
256 for (
int ilon = 0; ilon < model->
nlon; ilon++)
257 for (
int ilat = 0; ilat < model->
nlat; ilat++)
258 for (
int iz = 0; iz < model->
nz; iz++)
259 model->
z[ilon][ilat][iz] =
260 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
264 LOG(2,
"Read temperature...");
265 NC(nc_inq_varid(ncid,
"t", &varid));
266 NC(nc_get_var_float(ncid, varid, help));
267 for (
int ilon = 0; ilon < model->
nlon; ilon++)
268 for (
int ilat = 0; ilat < model->
nlat; ilat++)
269 for (
int iz = 0; iz < model->
nz; iz++)
270 model->
t[ilon][ilat][iz] =
271 help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
274 LOG(2,
"Read surface pressure...");
275 NC(nc_inq_varid(ncid,
"lnsp", &varid));
276 NC(nc_get_var_float(ncid, varid, help));
277 for (
int ilon = 0; ilon < model->
nlon; ilon++)
278 for (
int ilat = 0; ilat < model->
nlat; ilat++)
279 model->
ps[ilon][ilat] = (
float) exp(help[ilat * model->
nlon + ilon]);
282 LOG(2,
"Read grid coefficients...");
283 NC(nc_inq_varid(ncid,
"hyam", &varid));
284 NC(nc_get_var_double(ncid, varid, hyam));
285 NC(nc_inq_varid(ncid,
"hybm", &varid));
286 NC(nc_get_var_double(ncid, varid, hybm));
289 LOG(2,
"Calculate pressure...");
290 for (
int ilon = 0; ilon < model->
nlon; ilon++)
291 for (
int ilat = 0; ilat < model->
nlat; ilat++)
292 for (
int iz = 0; iz < model->
nz; iz++)
293 model->
p[ilon][ilat][iz]
294 = (
float) ((hyam[iz] + hybm[iz] * model->
ps[ilon][ilat]) / 100.);
298 else if (strcasecmp(argv[2],
"um") == 0) {
301 LOG(2,
"Read levels...");
302 if (nc_inq_dimid(ncid,
"RHO_TOP_eta_rho", &dimid) != NC_NOERR)
303 NC(nc_inq_dimid(ncid,
"RHO_eta_rho", &dimid));
304 NC(nc_inq_dimlen(ncid, dimid, &rs));
305 model->
nz = (int) rs;
307 ERRMSG(
"Too many altitudes!");
310 LOG(2,
"Read height...");
311 if (nc_inq_varid(ncid,
"STASH_m01s15i102_2", &varid) != NC_NOERR)
312 NC(nc_inq_varid(ncid,
"STASH_m01s15i102", &varid));
313 NC(nc_get_var_float(ncid, varid, help));
314 for (
int ilon = 0; ilon < model->
nlon; ilon++)
315 for (
int ilat = 0; ilat < model->
nlat; ilat++)
316 for (
int iz = 0; iz < model->
nz; iz++)
317 model->
z[ilon][ilat][iz] =
318 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
322 LOG(2,
"Read temperature...");
323 NC(nc_inq_varid(ncid,
"STASH_m01s30i004", &varid));
324 NC(nc_get_var_float(ncid, varid, help));
325 for (
int ilon = 0; ilon < model->
nlon; ilon++)
326 for (
int ilat = 0; ilat < model->
nlat; ilat++)
327 for (
int iz = 0; iz < model->
nz; iz++)
328 model->
t[ilon][ilat][iz] =
329 help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
332 LOG(2,
"Read pressure...");
333 NC(nc_inq_varid(ncid,
"STASH_m01s00i407", &varid));
334 NC(nc_get_var_float(ncid, varid, help));
335 for (
int ilon = 0; ilon < model->
nlon; ilon++)
336 for (
int ilat = 0; ilat < model->
nlat; ilat++)
337 for (
int iz = 0; iz < model->
nz; iz++)
338 model->
p[ilon][ilat][iz] =
339 0.01f * help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
343 else if (strcasecmp(argv[2],
"wrf") == 0) {
346 LOG(2,
"Read levels...");
347 NC(nc_inq_dimid(ncid,
"bottom_top", &dimid));
348 NC(nc_inq_dimlen(ncid, dimid, &rs));
349 model->
nz = (int) rs;
351 ERRMSG(
"Too many altitudes!");
354 LOG(2,
"Read height...");
355 NC(nc_inq_varid(ncid,
"z", &varid));
356 NC(nc_get_var_float(ncid, varid, help));
357 for (
int ilon = 0; ilon < model->
nlon; ilon++)
358 for (
int ilat = 0; ilat < model->
nlat; ilat++)
359 for (
int iz = 0; iz < model->
nz; iz++)
360 model->
z[ilon][ilat][iz] =
361 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
365 LOG(2,
"Read temperature...");
366 NC(nc_inq_varid(ncid,
"tk", &varid));
367 NC(nc_get_var_float(ncid, varid, help));
368 for (
int ilon = 0; ilon < model->
nlon; ilon++)
369 for (
int ilat = 0; ilat < model->
nlat; ilat++)
370 for (
int iz = 0; iz < model->
nz; iz++)
371 model->
t[ilon][ilat][iz] =
372 help[(iz * model->
nlat + ilat) * model->
nlon + ilon];
375 LOG(2,
"Read pressure...");
376 NC(nc_inq_varid(ncid,
"p", &varid));
377 NC(nc_get_var_float(ncid, varid, help));
378 for (
int ilon = 0; ilon < model->
nlon; ilon++)
379 for (
int ilat = 0; ilat < model->
nlat; ilat++)
380 for (
int iz = 0; iz < model->
nz; iz++)
381 model->
p[ilon][ilat][iz] =
382 (
float) (help[(iz * model->
nlat + ilat) * model->
nlon + ilon] /
387 ERRMSG(
"Model type not supported!");
396 LOG(2,
"Checking...");
397 for (
int ilon = 0; ilon < model->
nlon; ilon++)
398 for (
int ilat = 0; ilat < model->
nlat; ilat++)
399 for (
int iz = 0; iz < model->
nz; iz++)
400 if (model->
t[ilon][ilat][iz] <= 100
401 || model->
t[ilon][ilat][iz] >= 400) {
402 model->
p[ilon][ilat][iz] = GSL_NAN;
403 model->
t[ilon][ilat][iz] = GSL_NAN;
404 model->
z[ilon][ilat][iz] = GSL_NAN;
408 LOG(2,
"Smoothing...");
412 for (
int iz = 0; iz < model->
nz; iz++)
413 printf(
"section_height: %d %g %g %g %g %g\n", iz,
414 model->
z[model->
nlon / 2][model->
nlat / 2][iz],
416 model->
p[model->
nlon / 2][model->
nlat / 2][iz],
417 model->
t[model->
nlon / 2][model->
nlat / 2][iz]);
418 for (
int ilon = 0; ilon < model->
nlon; ilon++)
419 printf(
"section_west_east: %d %g %g %g %g %g\n", ilon,
420 model->
z[ilon][model->
nlat / 2][model->
nz / 2],
421 model->
lon[ilon], model->
lat[model->
nlat / 2],
422 model->
p[ilon][model->
nlat / 2][model->
nz / 2],
423 model->
t[ilon][model->
nlat / 2][model->
nz / 2]);
424 for (
int ilat = 0; ilat < model->
nlat; ilat++)
425 printf(
"section_north_south: %d %g %g %g %g %g\n", ilat,
426 model->
z[model->
nlon / 2][ilat][model->
nz / 2],
427 model->
lon[model->
nlon / 2], model->
lat[ilat],
428 model->
p[model->
nlon / 2][ilat][model->
nz / 2],
429 model->
t[model->
nlon / 2][ilat][model->
nz / 2]);
445 for (
int itrack = 0; itrack < pert->
ntrack; itrack++) {
446 if (pert->
time[itrack][44] < t_ovp - 720 || itrack == 0)
449 if (pert->
time[itrack][44] > t_ovp + 720)
471 for (
int itrack = track0; itrack <= track1; itrack++)
472 for (
int ixtrack = 0; ixtrack < pert->
nxtrack; ixtrack++) {
476 printf(
"Compute track %d / %d ...\n", itrack - track0 + 1,
477 track1 - track0 + 1);
485 obs->
vplon[0] = pert->
lon[itrack][ixtrack];
486 obs->
vplat[0] = pert->
lat[itrack][ixtrack];
495 for (
double f = 0.0; f <= 1.0; f += 0.0002) {
496 xm[0] = f * xo[0] + (1 - f) * xs[0];
497 xm[1] = f * xo[1] + (1 - f) * xs[1];
498 xm[2] = f * xo[2] + (1 - f) * xs[2];
501 atm->
time[atm->
np] = pert->
time[itrack][ixtrack];
502 if (atm->
z[atm->
np] < 10)
504 else if (atm->
z[atm->
np] > 90)
506 else if ((++atm->
np) >=
NP)
507 ERRMSG(
"Too many altitudes!");
511 for (
double f = 10.0; f <= 90.0; f += 0.2) {
512 atm->
time[atm->
np] = pert->
time[itrack][ixtrack];
514 atm->
lon[atm->
np] = pert->
lon[itrack][ixtrack];
515 atm->
lat[atm->
np] = pert->
lat[itrack][ixtrack];
516 if ((++atm->
np) >=
NP)
517 ERRMSG(
"Too many altitudes!");
525 for (
int ip = 0; ip < atm->
np; ip++)
527 &atm->
p[ip], &atm->
t[ip]);
531 for (
int ip = 0; ip < atm->
np; ip++)
532 if (!gsl_finite(atm->
p[ip]) || !gsl_finite(atm->
t[ip]))
535 pert->
bt[itrack][ixtrack] = GSL_NAN;
546 ERRMSG(
"Kernel function must be ascending!");
550 pert->
bt[itrack][ixtrack] = wsum = 0;
551 for (
int ip = 0; ip < atm->
np; ip++)
552 if (atm->
z[ip] >= kz[0] && atm->
z[ip] <= kz[nk - 1]) {
555 LIN(kz[iz], kw[iz], kz[iz + 1], kw[iz + 1], atm->
z[ip]);
556 pert->
bt[itrack][ixtrack] += w * atm->
t[ip];
559 pert->
bt[itrack][ixtrack] /= wsum;
569 pert->
bt[itrack][ixtrack] = 0;
570 for (
int id = 0;
id < ctl.
nd;
id++)
571 pert->
bt[itrack][ixtrack] += obs->
rad[
id][0] / ctl.
nd;
578 for (
int itrack = track0; itrack <= track1; itrack++) {
579 for (
int ixtrack = 1; ixtrack < pert->
nxtrack; ixtrack++)
580 if (!gsl_finite(pert->
bt[itrack][ixtrack]))
581 pert->
bt[itrack][ixtrack] = pert->
bt[itrack][ixtrack - 1];
582 for (
int ixtrack = pert->
nxtrack - 2; ixtrack >= 0; ixtrack--)
583 if (!gsl_finite(pert->
bt[itrack][ixtrack]))
584 pert->
bt[itrack][ixtrack] = pert->
bt[itrack][ixtrack + 1];
628 if (model->
lon[model->
nlon - 1] > 180)
633 if (lon < model->lon[0]
634 || lon > model->
lon[model->
nlon - 1]
635 || lat < GSL_MIN(model->
lat[0], model->
lat[model->
nlat - 1])
636 || lat > GSL_MAX(model->
lat[0], model->
lat[model->
nlat - 1])) {
647 if (!gsl_finite(model->
z[ilon][ilat][0])
648 || !gsl_finite(model->
z[ilon][ilat][model->
nz - 1])
649 || !gsl_finite(model->
z[ilon][ilat + 1][model->
nz - 1])
650 || !gsl_finite(model->
z[ilon][ilat + 1][model->
nz - 1])
651 || !gsl_finite(model->
z[ilon + 1][ilat][model->
nz - 1])
652 || !gsl_finite(model->
z[ilon + 1][ilat][model->
nz - 1])
653 || !gsl_finite(model->
z[ilon + 1][ilat + 1][model->
nz - 1])
654 || !gsl_finite(model->
z[ilon + 1][ilat + 1][model->
nz - 1])) {
662 GSL_MAX(model->
z[ilon][ilat][0], model->
z[ilon][ilat][model->
nz - 1])
663 || z < GSL_MIN(model->
z[ilon][ilat][0],
664 model->
z[ilon][ilat][model->
nz - 1])
665 || z > GSL_MAX(model->
z[ilon][ilat + 1][0],
666 model->
z[ilon][ilat + 1][model->
nz - 1])
667 || z < GSL_MIN(model->
z[ilon][ilat + 1][0],
668 model->
z[ilon][ilat + 1][model->
nz - 1])
669 || z > GSL_MAX(model->
z[ilon + 1][ilat][0],
670 model->
z[ilon + 1][ilat][model->
nz - 1])
671 || z < GSL_MIN(model->
z[ilon + 1][ilat][0],
672 model->
z[ilon + 1][ilat][model->
nz - 1])
673 || z > GSL_MAX(model->
z[ilon + 1][ilat + 1][0],
674 model->
z[ilon + 1][ilat + 1][model->
nz - 1])
675 || z < GSL_MIN(model->
z[ilon + 1][ilat + 1][0],
676 model->
z[ilon + 1][ilat + 1][model->
nz - 1]))
680 for (iz = 0; iz < model->
nz; iz++)
681 zd[iz] = model->
z[ilon][ilat][iz];
683 double p00 =
LIN(model->
z[ilon][ilat][iz], model->
p[ilon][ilat][iz],
684 model->
z[ilon][ilat][iz + 1], model->
p[ilon][ilat][iz + 1],
686 double t00 =
LIN(model->
z[ilon][ilat][iz], model->
t[ilon][ilat][iz],
687 model->
z[ilon][ilat][iz + 1], model->
t[ilon][ilat][iz + 1],
690 for (iz = 0; iz < model->
nz; iz++)
691 zd[iz] = model->
z[ilon][ilat + 1][iz];
693 double p01 =
LIN(model->
z[ilon][ilat + 1][iz], model->
p[ilon][ilat + 1][iz],
694 model->
z[ilon][ilat + 1][iz + 1],
695 model->
p[ilon][ilat + 1][iz + 1], z);
696 double t01 =
LIN(model->
z[ilon][ilat + 1][iz], model->
t[ilon][ilat + 1][iz],
697 model->
z[ilon][ilat + 1][iz + 1],
698 model->
t[ilon][ilat + 1][iz + 1],
701 for (iz = 0; iz < model->
nz; iz++)
702 zd[iz] = model->
z[ilon + 1][ilat][iz];
704 double p10 =
LIN(model->
z[ilon + 1][ilat][iz], model->
p[ilon + 1][ilat][iz],
705 model->
z[ilon + 1][ilat][iz + 1],
706 model->
p[ilon + 1][ilat][iz + 1], z);
707 double t10 =
LIN(model->
z[ilon + 1][ilat][iz], model->
t[ilon + 1][ilat][iz],
708 model->
z[ilon + 1][ilat][iz + 1],
709 model->
t[ilon + 1][ilat][iz + 1],
712 for (iz = 0; iz < model->
nz; iz++)
713 zd[iz] = model->
z[ilon + 1][ilat + 1][iz];
716 LIN(model->
z[ilon + 1][ilat + 1][iz], model->
p[ilon + 1][ilat + 1][iz],
717 model->
z[ilon + 1][ilat + 1][iz + 1],
718 model->
p[ilon + 1][ilat + 1][iz + 1], z);
720 LIN(model->
z[ilon + 1][ilat + 1][iz], model->
t[ilon + 1][ilat + 1][iz],
721 model->
z[ilon + 1][ilat + 1][iz + 1],
722 model->
t[ilon + 1][ilat + 1][iz + 1], z);
725 p00 =
LIN(model->
lon[ilon], p00, model->
lon[ilon + 1], p10, lon);
726 p11 =
LIN(model->
lon[ilon], p01, model->
lon[ilon + 1], p11, lon);
727 *p =
LIN(model->
lat[ilat], p00, model->
lat[ilat + 1], p11, lat);
729 t00 =
LIN(model->
lon[ilon], t00, model->
lon[ilon + 1], t10, lon);
730 t11 =
LIN(model->
lon[ilon], t01, model->
lon[ilon + 1], t11, lon);
731 *t =
LIN(model->
lat[ilat], t00, model->
lat[ilat + 1], t11, lat);
741 static double wx[10], wy[10];
743 const int dlon = 3, dlat = 3;
746 const double dy =
RE * M_PI / 180. * fabs(model->
lat[1] - model->
lat[0]);
747 for (
int ilat = 0; ilat <= dlat; ilat++)
748 wy[ilat] = exp(-0.5 *
POW2(ilat * dy * 2.35482 / 20.));
751 for (
int iz = 0; iz < model->
nz; iz++) {
754 printf(
"Smoothing level %d / %d ...\n", iz + 1, model->
nz);
757 for (
int ilon = 0; ilon < model->
nlon; ilon++)
758 for (
int ilat = 0; ilat < model->
nlat; ilat++) {
759 hp[ilon][ilat] = model->
p[ilon][ilat][iz];
760 ht[ilon][ilat] = model->
t[ilon][ilat][iz];
761 hz[ilon][ilat] = model->
z[ilon][ilat][iz];
765 for (
int ilat = 0; ilat < model->
nlat; ilat++) {
769 RE * M_PI / 180. * cos(model->
lat[ilat] * M_PI / 180.) *
770 fabs(model->
lon[1] - model->
lon[0]);
771 for (
int ilon = 0; ilon <= dlon; ilon++)
772 wx[ilon] = exp(-0.5 *
POW2(ilon * dx * 2.35482 / 20.));
775 for (
int ilon = 0; ilon < model->
nlon; ilon++) {
777 model->
p[ilon][ilat][iz] = 0;
778 model->
t[ilon][ilat][iz] = 0;
779 model->
z[ilon][ilat][iz] = 0;
780 for (
int ilon2 = GSL_MAX(ilon - dlon, 0);
781 ilon2 <= GSL_MIN(ilon + dlon, model->
nlon - 1); ilon2++)
782 for (
int ilat2 = GSL_MAX(ilat - dlat, 0);
783 ilat2 <= GSL_MIN(ilat + dlat, model->
nlat - 1); ilat2++) {
784 float w = (float) (wx[abs(ilon2 - ilon)] * wy[abs(ilat2 - ilat)]);
785 model->
p[ilon][ilat][iz] += w * hp[ilon2][ilat2];
786 model->
t[ilon][ilat][iz] += w * ht[ilon2][ilat2];
787 model->
z[ilon][ilat][iz] += w * hz[ilon2][ilat2];
790 model->
p[ilon][ilat][iz] /= wsum;
791 model->
t[ilon][ilat][iz] /= wsum;
792 model->
z[ilon][ilat][iz] /= wsum;
804 static double help[
WX *
WY];
806 int ncid, dimid[10], lon_id, lat_id, bt_id, pt_id, var_id;
809 NC(nc_create(filename, NC_CLOBBER, &ncid));
812 NC(nc_def_dim(ncid,
"NTRACK", (
size_t) wave->
ny, &dimid[0]));
813 NC(nc_def_dim(ncid,
"NXTRACK", (
size_t) wave->
nx, &dimid[1]));
816 NC(nc_def_var(ncid,
"lon", NC_DOUBLE, 2, dimid, &lon_id));
817 add_att(ncid, lon_id,
"deg",
"footprint longitude");
818 NC(nc_def_var(ncid,
"lat", NC_DOUBLE, 2, dimid, &lat_id));
819 add_att(ncid, lat_id,
"deg",
"footprint latitude");
820 NC(nc_def_var(ncid,
"bt", NC_FLOAT, 2, dimid, &bt_id));
821 add_att(ncid, bt_id,
"K",
"brightness temperature");
822 NC(nc_def_var(ncid,
"bt_pt", NC_FLOAT, 2, dimid, &pt_id));
823 add_att(ncid, pt_id,
"K",
"brightness temperature perturbation");
824 NC(nc_def_var(ncid,
"bt_var", NC_FLOAT, 2, dimid, &var_id));
825 add_att(ncid, var_id,
"K^2",
"brightness temperature variance");
831 for (
int ix = 0; ix < wave->
nx; ix++)
832 for (
int iy = 0; iy < wave->
ny; iy++)
833 help[iy * wave->
nx + ix] = wave->
lon[ix][iy];
834 NC(nc_put_var_double(ncid, lon_id, help));
835 for (
int ix = 0; ix < wave->
nx; ix++)
836 for (
int iy = 0; iy < wave->
ny; iy++)
837 help[iy * wave->
nx + ix] = wave->
lat[ix][iy];
838 NC(nc_put_var_double(ncid, lat_id, help));
839 for (
int ix = 0; ix < wave->
nx; ix++)
840 for (
int iy = 0; iy < wave->
ny; iy++)
841 help[iy * wave->
nx + ix] = wave->
temp[ix][iy];
842 NC(nc_put_var_double(ncid, bt_id, help));
843 for (
int ix = 0; ix < wave->
nx; ix++)
844 for (
int iy = 0; iy < wave->
ny; iy++)
845 help[iy * wave->
nx + ix] = wave->
pt[ix][iy];
846 NC(nc_put_var_double(ncid, pt_id, help));
847 for (
int ix = 0; ix < wave->
nx; ix++)
848 for (
int iy = 0; iy < wave->
ny; iy++)
849 help[iy * wave->
nx + ix] = wave->
var[ix][iy];
850 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 read_ctl(int argc, char *argv[], ctl_t *ctl)
Read forward model control parameters.
int locate_irr(const double *xx, const int n, const double x)
Find array index for irregular grid.
void formod(const ctl_t *ctl, atm_t *atm, obs_t *obs)
Determine ray paths and compute radiative transfer.
void cart2geo(const double *x, double *z, double *lon, double *lat)
Convert Cartesian coordinates to geolocation.
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 read_shape(const char *filename, double *x, double *y, int *n)
Read shape function.
void climatology(const ctl_t *ctl, atm_t *atm)
Interpolate climatological data.
void geo2cart(const double z, const double lon, const double lat, double *x)
Convert geolocation to Cartesian coordinates.
void kernel(ctl_t *ctl, atm_t *atm, obs_t *obs, gsl_matrix *k)
Compute Jacobians.
#define LEN
Maximum length of ASCII data lines.
#define RE
Mean radius of Earth [km].
#define POW2(x)
Compute x^2.
#define ERRMSG(...)
Print error message and quit program.
#define NSHAPE
Maximum number of shape function grid points.
#define ALLOC(ptr, type, n)
Allocate memory.
#define NP
Maximum number of atmospheric data points.
#define LOG(level,...)
Print log message.
#define LIN(x0, y0, x1, y1, x)
Compute linear interpolation.
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 time[NP]
Time (seconds since 2000-01-01T00:00Z).
double lat[NP]
Latitude [deg].
double lon[NP]
Longitude [deg].
double t[NP]
Temperature [K].
int np
Number of data points.
double z[NP]
Altitude [km].
double p[NP]
Pressure [hPa].
Forward model control parameters.
int nd
Number of radiance channels.
int write_bbt
Use brightness temperature instead of radiance (0=no, 1=yes).
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].
Observation geometry and radiance data.
double rad[ND][NR]
Radiance [W/(m^2 sr cm^-1)].
double vpz[NR]
View point altitude [km].
double vplat[NR]
View point latitude [deg].
double obslon[NR]
Observer longitude [deg].
double obslat[NR]
Observer latitude [deg].
double obsz[NR]
Observer altitude [km].
double vplon[NR]
View point longitude [deg].
int nr
Number of ray paths.
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].