34 const char *long_name) {
37 NC(nc_put_att_text(ncid, varid,
"long_name", strlen(long_name), long_name));
40 NC(nc_put_att_text(ncid, varid,
"units", strlen(unit), unit));
56 if (nc_inq_varid(ncid, varname, varid) != NC_NOERR) {
59 NC(nc_def_var(ncid, varname, type, ndims, dimid, varid));
63 (ncid, *varid,
"long_name", strlen(longname), longname));
66 NC(nc_put_att_text(ncid, *varid,
"units", strlen(unit), unit));
83 for (i = 0; i < (size_t) n; i++)
84 if (gsl_finite(yy[i])) {
89 if ((
int) n2 < dim || n2 < 0.9 * n) {
90 for (i = 0; i < (size_t) n; i++)
96 gsl_multifit_linear_workspace *work
97 = gsl_multifit_linear_alloc((
size_t) n2, (
size_t) dim);
98 gsl_matrix *cov = gsl_matrix_alloc((
size_t) dim, (
size_t) dim);
99 gsl_matrix *X = gsl_matrix_alloc((
size_t) n2, (
size_t) dim);
100 gsl_vector *c = gsl_vector_alloc((
size_t) dim);
101 gsl_vector *x = gsl_vector_alloc((
size_t) n2);
102 gsl_vector *y = gsl_vector_alloc((
size_t) n2);
105 for (i = 0; i < (size_t) n2; i++) {
106 gsl_vector_set(x, i, xx2[i]);
107 gsl_vector_set(y, i, yy2[i]);
108 for (i2 = 0; i2 < (size_t) dim; i2++)
109 gsl_matrix_set(X, i, i2, pow(gsl_vector_get(x, i), (
double) i2));
111 gsl_multifit_linear(X, y, c, cov, &chisq, work);
112 for (i = 0; i < (size_t) n; i++)
113 yy[i] = gsl_poly_eval(c->data, (
int) dim, xx[i]);
116 gsl_multifit_linear_free(work);
117 gsl_matrix_free(cov);
132 if (dim_x <= 0 && dim_y <= 0)
136 for (
int ix = 0; ix < wave->
nx; ix++)
137 for (
int iy = 0; iy < wave->
ny; iy++) {
138 wave->
bg[ix][iy] = wave->
temp[ix][iy];
139 wave->
pt[ix][iy] = 0;
144 for (
int iy = 0; iy < wave->
ny; iy++) {
146 for (
int ix = 0; ix < wave->
nx; ix++) {
148 y[ix] = wave->
bg[ix][iy];
151 for (
int ix = 0; ix < wave->
nx; ix++)
152 wave->
bg[ix][iy] = y[ix];
157 for (
int ix = 0; ix < wave->
nx; ix++) {
159 for (
int iy = 0; iy < wave->
ny; iy++) {
161 y[iy] = wave->
bg[ix][iy];
164 for (
int iy = 0; iy < wave->
ny; iy++)
165 wave->
bg[ix][iy] = y[iy];
169 for (
int ix = 0; ix < wave->
nx; ix++)
170 for (
int iy = 0; iy < wave->
ny; iy++)
171 wave->
pt[ix][iy] = wave->
temp[ix][iy] - wave->
bg[ix][iy];
181 const double dmax = 2500.0;
183 static double help[
WX][
WY];
186 if (npts_x <= 0 && npts_y <= 0)
190 for (
int ix = 0; ix < wave->
nx; ix++)
191 for (
int iy = 0; iy < wave->
ny; iy++) {
198 const int dx = GSL_MIN(GSL_MIN(npts_x, ix), wave->
nx - 1 - ix);
199 const int dy = GSL_MIN(GSL_MIN(npts_y, iy), wave->
ny - 1 - iy);
202 for (
int i = ix - dx; i <= ix + dx; i++)
203 for (
int j = iy - dy; j <= iy + dy; j++)
204 if (fabs(wave->
x[ix] - wave->
x[i]) < dmax &&
205 fabs(wave->
y[iy] - wave->
y[j]) < dmax) {
206 help[ix][iy] += wave->
bg[i][j];
214 help[ix][iy] = GSL_NAN;
218 for (
int ix = 0; ix < wave->
nx; ix++)
219 for (
int iy = 0; iy < wave->
ny; iy++) {
220 wave->
bg[ix][iy] = help[ix][iy];
221 wave->
pt[ix][iy] = wave->
temp[ix][iy] - wave->
bg[ix][iy];
231 for (
int ix = 0; ix < wave->
nx; ix++)
232 for (
int iy = 0; iy < wave->
ny; iy++) {
235 wave->
bg[ix][iy] = 235.626 + 5.38165e-6 * gsl_pow_2(wave->
x[ix]
241 - 1.78519e-12 * gsl_pow_4(wave->
x[ix] -
242 0.5 * (wave->
x[0] + wave->
x[wave->
nx - 1]));
245 wave->
pt[ix][iy] = 0;
248 wave->
temp[ix][iy] = wave->
bg[ix][iy];
260 gsl_rng *r = gsl_rng_alloc(gsl_rng_default);
261 gsl_rng_set(r, (
unsigned long int) time(NULL));
265 for (
int ix = 0; ix < wave->
nx; ix++)
266 for (
int iy = 0; iy < wave->
ny; iy++)
267 wave->
temp[ix][iy] += gsl_ran_gaussian(r, nedt);
284 for (
int ix = 0; ix < wave->
nx; ix++)
285 for (
int iy = 0; iy < wave->
ny; iy++) {
288 wave->
pt[ix][iy] = amp * cos((lx != 0 ? 2 * M_PI / lx : 0) * wave->
x[ix]
290 0 ? 2 * M_PI / ly : 0) * wave->
y[iy]
292 * (fwhm > 0 ? exp(-0.5 * gsl_pow_2((wave->
x[ix]) / (lx * fwhm) * 2.35)
294 0.5 * gsl_pow_2((wave->
y[iy]) / (ly * fwhm) *
298 wave->
temp[ix][iy] += wave->
pt[ix][iy];
316 for (
int ix = 0; ix < wave->
nx; ix++)
317 for (
int iy = 0; iy < wave->
ny; iy++) {
319 = amp * cos(kx * wave->
x[ix] + ky * wave->
y[iy]
320 - phi * M_PI / 180.);
321 *chisq += POW2(wave->
fit[ix][iy] - wave->
pt[ix][iy]);
325 *chisq /= (double) (wave->
nx * wave->
ny);
335 double data[2 *
PMAX];
339 ERRMSG(
"Too many data points!");
342 gsl_fft_complex_wavetable *wavetable
343 = gsl_fft_complex_wavetable_alloc((
size_t) n);
344 gsl_fft_complex_workspace *workspace
345 = gsl_fft_complex_workspace_alloc((
size_t) n);
348 for (
int i = 0; i < n; i++) {
349 data[2 * i] = fcReal[i];
350 data[2 * i + 1] = fcImag[i];
354 gsl_fft_complex_forward(data, 1, (
size_t) n, wavetable, workspace);
357 for (
int i = 0; i < n; i++) {
358 fcReal[i] = data[2 * i];
359 fcImag[i] = data[2 * i + 1];
363 gsl_fft_complex_wavetable_free(wavetable);
364 gsl_fft_complex_workspace_free(workspace);
384 int imin = 9999, jmin = 9999;
385 int imax = -9999, jmax = -9999;
386 for (
int i = 0; i < wave->
nx; i++)
387 for (
int j = 0; j < wave->
ny; j++)
388 if (gsl_finite(wave->
var[i][j])) {
389 imin = GSL_MIN(imin, i);
390 imax = GSL_MAX(imax, i);
391 jmin = GSL_MIN(jmin, j);
392 jmax = GSL_MAX(jmax, j);
394 const int nx = imax - imin + 1;
395 const int ny = jmax - jmin + 1;
398 for (
int i = imin; i <= imax; i++)
399 for (
int j = jmin; j <= jmax; j++) {
400 if (gsl_finite(wave->
pt[i][j]))
401 boxReal[i - imin][j - jmin] = wave->
pt[i][j];
403 boxReal[i - imin][j - jmin] = 0.0;
404 boxImag[i - imin][j - jmin] = 0.0;
408 for (
int i = 0; i < nx; i++) {
409 for (
int j = 0; j < ny; j++) {
410 cutReal[j] = boxReal[i][j];
411 cutImag[j] = boxImag[i][j];
414 for (
int j = 0; j < ny; j++) {
415 boxReal[i][j] = cutReal[j];
416 boxImag[i][j] = cutImag[j];
421 for (
int j = 0; j < ny; j++) {
422 for (
int i = 0; i < nx; i++) {
423 cutReal[i] = boxReal[i][j];
424 cutImag[i] = boxImag[i][j];
427 for (
int i = 0; i < nx; i++) {
428 boxReal[i][j] = cutReal[i];
429 boxImag[i][j] = cutImag[i];
434 for (
int i = 0; i < nx; i++)
435 kx[i] = 2. * M_PI * ((i < nx / 2) ? (
double) i : -(
double) (nx - i))
436 / (nx * fabs(wave->
x[imax] - wave->
x[imin]) / (nx - 1.0));
437 for (
int j = 0; j < ny; j++)
438 ky[j] = 2. * M_PI * ((j < ny / 2) ? (double) j : -(
double) (ny - j))
439 / (ny * fabs(wave->
y[jmax] - wave->
y[jmin]) / (ny - 1.0));
440 for (
int i = 0; i < nx; i++)
441 for (
int j = 0; j < ny; j++) {
443 = (i == 0 && j == 0 ? 1.0 : 2.0) / (nx * ny)
444 * sqrt(gsl_pow_2(boxReal[i][j]) + gsl_pow_2(boxImag[i][j]));
446 = 180. / M_PI * atan2(boxImag[i][j], boxReal[i][j]);
450 for (
int i = 0; i < nx; i++)
451 for (
int j = 0; j < ny; j++)
452 if (kx[i] == 0 || ky[j] == 0) {
459 for (
int i = 0; i < nx; i++)
460 for (
int j = 0; j < ny / 2; j++)
461 if (gsl_finite(A[i][j]) && A[i][j] > *Amax) {
469 *lhmax = 2 * M_PI / sqrt(gsl_pow_2(*kxmax) + gsl_pow_2(*kymax));
472 *alphamax = 90. - 180. / M_PI * atan2(*kxmax, *kymax);
478 atan2(wave->
lat[wave->
nx / 2 >
479 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
480 - wave->
lat[wave->
nx / 2 <
481 wave->
nx - 1 ? wave->
nx / 2 +
482 1 : wave->
nx / 2][wave->
ny / 2],
483 wave->
lon[wave->
nx / 2 >
484 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
485 - wave->
lon[wave->
nx / 2 <
486 wave->
nx - 1 ? wave->
nx / 2 +
487 1 : wave->
nx / 2][wave->
ny / 2]);
490 if (filename != NULL) {
493 printf(
"Write FFT data: %s\n", filename);
497 if (!(out = fopen(filename,
"w")))
498 ERRMSG(
"Cannot create file!");
502 "# $1 = altitude [km]\n"
503 "# $2 = wavelength in x-direction [km]\n"
504 "# $3 = wavelength in y-direction [km]\n"
505 "# $4 = wavenumber in x-direction [1/km]\n"
506 "# $5 = wavenumber in y-direction [1/km]\n"
507 "# $6 = amplitude [K]\n" "# $7 = phase [rad]\n");
510 for (
int i = nx - 1; i > 0; i--) {
512 for (
int j = ny / 2; j > 0; j--) {
513 int i2 = (i == nx / 2 ? 0 : i);
514 int j2 = (j == ny / 2 ? 0 : j);
515 fprintf(out,
"%g %g %g %g %g %g %g\n", wave->
z,
516 (kx[i2] != 0 ? 2 * M_PI / kx[i2] : 0),
517 (ky[j2] != 0 ? 2 * M_PI / ky[j2] : 0),
518 kx[i2], ky[j2], A[i2][j2], phi[i2][j2]);
533 static double help[
WX][
WY];
540 const double sigma2 = gsl_pow_2(fwhm / 2.3548);
543 for (
int ix = 0; ix < wave->
nx; ix++)
544 for (
int iy = 0; iy < wave->
ny; iy++) {
551 for (
int ix2 = 0; ix2 < wave->
nx; ix2++)
552 for (
int iy2 = 0; iy2 < wave->
ny; iy2++) {
553 const double d2 = gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
554 + gsl_pow_2(wave->
y[iy] - wave->
y[iy2]);
555 if (d2 <= 9 * sigma2) {
556 const double w = exp(-d2 / (2 * sigma2));
558 help[ix][iy] += w * wave->
pt[ix2][iy2];
563 wave->
pt[ix][iy] = help[ix][iy] / wsum;
573 static double help[
WX][
WY];
576 for (
int iter = 0; iter < niter; iter++) {
579 for (
int ix = 0; ix < wave->
nx; ix++)
580 for (
int iy = 0; iy < wave->
ny; iy++)
582 = 0.23 * wave->
pt[ix > 0 ? ix - 1 : ix][iy]
583 + 0.54 * wave->
pt[ix][iy]
584 + 0.23 * wave->
pt[ix < wave->nx - 1 ? ix + 1 : ix][iy];
587 for (
int ix = 0; ix < wave->
nx; ix++)
588 for (
int iy = 0; iy < wave->
ny; iy++)
590 = 0.23 * help[ix][iy > 0 ? iy - 1 : iy]
591 + 0.54 * help[ix][iy]
592 + 0.23 * help[ix][iy < wave->ny - 1 ? iy + 1 : iy];
602 double dummy, x[
WX], xc[
WX][3], xc2[
WX][3], y[
WX];
608 ERRMSG(
"Too many data points!");
611 for (
int i = 0; i < n; i++)
612 x[i] = LIN(0.0, wave->
x[0], n - 1.0, wave->
x[wave->
nx - 1], i);
615 gsl_interp_accel *acc = gsl_interp_accel_alloc();
617 = gsl_spline_alloc(gsl_interp_cspline, (
size_t) wave->
nx);
620 for (
int iy = 0; iy < wave->
ny; iy++) {
623 for (
int ix = 0; ix < wave->
nx; ix++)
624 geo2cart(0, wave->
lon[ix][iy], wave->
lat[ix][iy], xc[ix]);
625 for (
int ic = 0; ic < 3; ic++) {
626 for (
int ix = 0; ix < wave->
nx; ix++)
628 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
629 for (
int i = 0; i < n; i++)
630 xc2[i][ic] = gsl_spline_eval(spline, x[i], acc);
632 for (
int i = 0; i < n; i++)
633 cart2geo(xc2[i], &dummy, &wave->
lon[i][iy], &wave->
lat[i][iy]);
636 for (
int ix = 0; ix < wave->
nx; ix++)
637 y[ix] = wave->
temp[ix][iy];
638 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
639 for (
int i = 0; i < n; i++)
640 wave->
temp[i][iy] = gsl_spline_eval(spline, x[i], acc);
643 for (
int ix = 0; ix < wave->
nx; ix++)
644 y[ix] = wave->
bg[ix][iy];
645 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
646 for (
int i = 0; i < n; i++)
647 wave->
bg[i][iy] = gsl_spline_eval(spline, x[i], acc);
650 for (
int ix = 0; ix < wave->
nx; ix++)
651 y[ix] = wave->
pt[ix][iy];
652 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
653 for (
int i = 0; i < n; i++)
654 wave->
pt[i][iy] = gsl_spline_eval(spline, x[i], acc);
657 for (
int ix = 0; ix < wave->
nx; ix++)
658 y[ix] = wave->
var[ix][iy];
659 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
660 for (
int i = 0; i < n; i++)
661 wave->
var[i][iy] = gsl_spline_eval(spline, x[i], acc);
665 gsl_spline_free(spline);
666 gsl_interp_accel_free(acc);
669 for (
int i = 0; i < n; i++)
680 static double data[
WX *
WY], help[
WX][
WY];
687 for (
int ix = 0; ix < wave->
nx; ix++)
688 for (
int iy = 0; iy < wave->
ny; iy++) {
694 for (
int ix2 = GSL_MAX(ix - dx, 0);
695 ix2 < GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
696 for (
int iy2 = GSL_MAX(iy - dx, 0);
697 iy2 < GSL_MIN(iy + dx, wave->
ny - 1); iy2++) {
698 data[n] = wave->
pt[ix2][iy2];
703 gsl_sort(data, 1, n);
704 help[ix][iy] = gsl_stats_median_from_sorted_data(data, 1, n);
708 for (
int ix = 0; ix < wave->
nx; ix++)
709 for (
int iy = 0; iy < wave->
ny; iy++)
710 wave->
pt[ix][iy] = help[ix][iy];
720 if (wave1->
nx != wave2->
nx)
721 ERRMSG(
"Across-track sizes do not match!");
722 if (wave1->
ny + wave2->
ny >
WY)
723 ERRMSG(
"Too many data points!");
727 wave1->
y[wave1->
ny - 1] + (wave1->
y[wave1->
ny - 1] -
728 wave1->
y[0]) / (wave1->
ny - 1);
731 for (
int ix = 0; ix < wave2->
nx; ix++)
732 for (
int iy = 0; iy < wave2->
ny; iy++) {
733 wave1->
y[wave1->
ny + iy] = y + wave2->
y[iy];
734 wave1->
lon[ix][wave1->
ny + iy] = wave2->
lon[ix][iy];
735 wave1->
lat[ix][wave1->
ny + iy] = wave2->
lat[ix][iy];
736 wave1->
temp[ix][wave1->
ny + iy] = wave2->
temp[ix][iy];
737 wave1->
bg[ix][wave1->
ny + iy] = wave2->
bg[ix][iy];
738 wave1->
pt[ix][wave1->
ny + iy] = wave2->
pt[ix][iy];
739 wave1->
var[ix][wave1->
ny + iy] = wave2->
var[ix][iy];
743 wave1->
ny += wave2->
ny;
759 for (
int ix = 1; ix < wave->
nx - 1; ix++)
760 for (
int iy = 1; iy < wave->
ny - 1; iy++) {
764 for (
int ix2 = ix - 1; ix2 <= ix + 1; ix2++)
765 for (
int iy2 = iy - 1; iy2 <= iy + 1; iy2++)
766 if (!gsl_finite(wave->
temp[ix2][iy2]))
773 *mu += wave->
temp[ix][iy];
774 *sig += gsl_pow_2(+4. / 6. * wave->
temp[ix][iy]
775 - 2. / 6. * (wave->
temp[ix - 1][iy]
776 + wave->
temp[ix + 1][iy]
777 + wave->
temp[ix][iy - 1]
778 + wave->
temp[ix][iy + 1])
779 + 1. / 6. * (wave->
temp[ix - 1][iy - 1]
780 + wave->
temp[ix + 1][iy - 1]
781 + wave->
temp[ix - 1][iy + 1]
782 + wave->
temp[ix + 1][iy + 1]));
787 *sig = sqrt(*sig / (
double) n);
810 int imin, imax, jmin, jmax, lmax = 0, mmax = 0;
813 for (
double lx = -lxymax; lx <= lxymax; lx += dlxy) {
814 kx[lmax] = (lx != 0 ? 2 * M_PI / lx : 0);
815 for (
int i = 0; i < wave->
nx; i++) {
816 cx[lmax][i] = cos(kx[lmax] * wave->
x[i]);
817 sx[lmax][i] = sin(kx[lmax] * wave->
x[i]);
820 ERRMSG(
"Too many wavenumbers for periodogram!");
822 for (
double ly = 0; ly <= lxymax; ly += dlxy) {
823 ky[mmax] = (ly != 0 ? 2 * M_PI / ly : 0);
824 for (
int j = 0; j < wave->
ny; j++) {
825 cy[mmax][j] = cos(ky[mmax] * wave->
y[j]);
826 sy[mmax][j] = sin(ky[mmax] * wave->
y[j]);
829 ERRMSG(
"Too many wavenumbers for periodogram!");
835 for (
int i = 0; i < wave->
nx; i++)
836 for (
int j = 0; j < wave->
ny; j++)
837 if (gsl_finite(wave->
var[i][j])) {
838 imin = GSL_MIN(imin, i);
839 imax = GSL_MAX(imax, i);
840 jmin = GSL_MIN(jmin, j);
841 jmax = GSL_MAX(jmax, j);
846 M_PI / fabs((wave->
x[imax] - wave->
x[imin]) /
847 ((
double) imax - (
double) imin));
849 M_PI / fabs((wave->
y[jmax] - wave->
y[jmin]) /
850 ((
double) jmax - (
double) jmin));
853 for (
int l = 0; l < lmax; l++)
854 for (
int m = 0; m < mmax; m++) {
857 if (kx[l] == 0 || fabs(kx[l]) > kx_ny ||
858 ky[m] == 0 || fabs(ky[m]) > ky_ny) {
865 double a = 0, b = 0, c = 0;
866 for (
int i = imin; i <= imax; i++)
867 for (
int j = jmin; j <= jmax; j++)
868 if (gsl_finite(wave->
var[i][j])) {
869 a += wave->
pt[i][j] * (cx[l][i] * cy[m][j] - sx[l][i] * sy[m][j]);
870 b += wave->
pt[i][j] * (sx[l][i] * cy[m][j] + cx[l][i] * sy[m][j]);
877 A[l][m] = sqrt(gsl_pow_2(a) + gsl_pow_2(b));
878 phi[l][m] = atan2(b, a) * 180. / M_PI;
883 for (
int l = 0; l < lmax; l++)
884 for (
int m = 0; m < mmax; m++)
885 if (gsl_finite(A[l][m]) && A[l][m] > *Amax) {
893 *lhmax = 2 * M_PI / sqrt(gsl_pow_2(*kxmax) + gsl_pow_2(*kymax));
896 *alphamax = 90. - 180. / M_PI * atan2(*kxmax, *kymax);
902 atan2(wave->
lat[wave->
nx / 2 >
903 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
904 - wave->
lat[wave->
nx / 2 <
905 wave->
nx - 1 ? wave->
nx / 2 +
906 1 : wave->
nx / 2][wave->
ny / 2],
907 wave->
lon[wave->
nx / 2 >
908 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
909 - wave->
lon[wave->
nx / 2 <
910 wave->
nx - 1 ? wave->
nx / 2 +
911 1 : wave->
nx / 2][wave->
ny / 2]);
914 if (filename != NULL) {
917 printf(
"Write periodogram data: %s\n", filename);
920 if (!(out = fopen(filename,
"w")))
921 ERRMSG(
"Cannot create file!");
925 "# $1 = altitude [km]\n"
926 "# $2 = wavelength in x-direction [km]\n"
927 "# $3 = wavelength in y-direction [km]\n"
928 "# $4 = wavenumber in x-direction [1/km]\n"
929 "# $5 = wavenumber in y-direction [1/km]\n"
930 "# $6 = amplitude [K]\n" "# $7 = phase [rad]\n");
933 for (
int l = 0; l < lmax; l++) {
935 for (
int m = 0; m < mmax; m++)
936 fprintf(out,
"%g %g %g %g %g %g %g\n", wave->
z,
937 (kx[l] != 0 ? 2 * M_PI / kx[l] : 0),
938 (ky[m] != 0 ? 2 * M_PI / ky[m] : 0),
939 kx[l], ky[m], A[l][m], phi[l][m]);
960 track0 = GSL_MIN(GSL_MAX(track0, 0), pert->
ntrack - 1);
961 track1 = GSL_MIN(GSL_MAX(track1, 0), pert->
ntrack - 1);
962 xtrack0 = GSL_MIN(GSL_MAX(xtrack0, 0), pert->
nxtrack - 1);
963 xtrack1 = GSL_MIN(GSL_MAX(xtrack1, 0), pert->
nxtrack - 1);
966 wave->
nx = xtrack1 - xtrack0 + 1;
968 ERRMSG(
"Too many across-track values!");
969 wave->
ny = track1 - track0 + 1;
971 ERRMSG(
"Too many along-track values!");
974 for (
int itrack = track0; itrack <= track1; itrack++)
975 for (
int ixtrack = xtrack0; ixtrack <= xtrack1; ixtrack++) {
978 if (itrack == track0) {
980 if (ixtrack > xtrack0) {
981 geo2cart(0, pert->
lon[itrack][ixtrack - 1],
982 pert->
lat[itrack][ixtrack - 1], x0);
983 geo2cart(0, pert->
lon[itrack][ixtrack],
984 pert->
lat[itrack][ixtrack], x1);
985 wave->
x[ixtrack - xtrack0] =
986 wave->
x[ixtrack - xtrack0 - 1] + DIST(x0, x1);
989 if (ixtrack == xtrack0) {
991 if (itrack > track0) {
992 geo2cart(0, pert->
lon[itrack - 1][ixtrack],
993 pert->
lat[itrack - 1][ixtrack], x0);
994 geo2cart(0, pert->
lon[itrack][ixtrack],
995 pert->
lat[itrack][ixtrack], x1);
996 wave->
y[itrack - track0] =
997 wave->
y[itrack - track0 - 1] + DIST(x0, x1);
1002 wave->
time = pert->
time[(track0 + track1) / 2][(xtrack0 + xtrack1) / 2];
1004 wave->
lon[ixtrack - xtrack0][itrack - track0] =
1005 pert->
lon[itrack][ixtrack];
1006 wave->
lat[ixtrack - xtrack0][itrack - track0] =
1007 pert->
lat[itrack][ixtrack];
1010 wave->
temp[ixtrack - xtrack0][itrack - track0]
1011 = pert->
bt[itrack][ixtrack];
1012 wave->
bg[ixtrack - xtrack0][itrack - track0]
1013 = pert->
bt[itrack][ixtrack] - pert->
pt[itrack][ixtrack];
1014 wave->
pt[ixtrack - xtrack0][itrack - track0]
1015 = pert->
pt[itrack][ixtrack];
1016 wave->
var[ixtrack - xtrack0][itrack - track0]
1017 = pert->
var[itrack][ixtrack];
1030 printf(
"Read AIRS Level-1 file: %s\n", filename);
1031 NC(nc_open(filename, NC_NOWRITE, &ncid));
1034 NC(nc_inq_varid(ncid,
"l1_time", &varid));
1035 NC(nc_get_var_double(ncid, varid, l1->
time[0]));
1036 NC(nc_inq_varid(ncid,
"l1_lon", &varid));
1037 NC(nc_get_var_double(ncid, varid, l1->
lon[0]));
1038 NC(nc_inq_varid(ncid,
"l1_lat", &varid));
1039 NC(nc_get_var_double(ncid, varid, l1->
lat[0]));
1040 NC(nc_inq_varid(ncid,
"l1_sat_z", &varid));
1041 NC(nc_get_var_double(ncid, varid, l1->
sat_z));
1042 NC(nc_inq_varid(ncid,
"l1_sat_lon", &varid));
1043 NC(nc_get_var_double(ncid, varid, l1->
sat_lon));
1044 NC(nc_inq_varid(ncid,
"l1_sat_lat", &varid));
1045 NC(nc_get_var_double(ncid, varid, l1->
sat_lat));
1046 NC(nc_inq_varid(ncid,
"l1_nu", &varid));
1047 NC(nc_get_var_double(ncid, varid, l1->
nu));
1048 NC(nc_inq_varid(ncid,
"l1_rad", &varid));
1049 NC(nc_get_var_float(ncid, varid, l1->
rad[0][0]));
1064 printf(
"Read AIRS Level-2 file: %s\n", filename);
1065 NC(nc_open(filename, NC_NOWRITE, &ncid));
1068 NC(nc_inq_varid(ncid,
"l2_time", &varid));
1069 NC(nc_get_var_double(ncid, varid, l2->
time[0]));
1070 NC(nc_inq_varid(ncid,
"l2_z", &varid));
1071 NC(nc_get_var_double(ncid, varid, l2->
z[0][0]));
1072 NC(nc_inq_varid(ncid,
"l2_lon", &varid));
1073 NC(nc_get_var_double(ncid, varid, l2->
lon[0]));
1074 NC(nc_inq_varid(ncid,
"l2_lat", &varid));
1075 NC(nc_get_var_double(ncid, varid, l2->
lat[0]));
1076 NC(nc_inq_varid(ncid,
"l2_press", &varid));
1077 NC(nc_get_var_double(ncid, varid, l2->
p));
1078 NC(nc_inq_varid(ncid,
"l2_temp", &varid));
1079 NC(nc_get_var_double(ncid, varid, l2->
t[0][0]));
1092 static char varname[LEN];
1094 static int dimid[2], ncid, varid;
1096 static size_t ntrack, nxtrack, start[2] = { 0, 0 }, count[2] = { 1, 1 };
1099 printf(
"Read perturbation data: %s\n", filename);
1102 NC(nc_open(filename, NC_NOWRITE, &ncid));
1105 NC(nc_inq_dimid(ncid,
"NTRACK", &dimid[0]));
1106 NC(nc_inq_dimid(ncid,
"NXTRACK", &dimid[1]));
1107 NC(nc_inq_dimlen(ncid, dimid[0], &ntrack));
1108 NC(nc_inq_dimlen(ncid, dimid[1], &nxtrack));
1110 ERRMSG(
"Too many tracks!");
1112 ERRMSG(
"Too many scans!");
1113 pert->
ntrack = (int) ntrack;
1114 pert->
nxtrack = (int) nxtrack;
1118 NC(nc_inq_varid(ncid,
"time", &varid));
1119 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
1121 NC(nc_get_vara_double(ncid, varid, start, count, pert->
time[itrack]));
1124 NC(nc_inq_varid(ncid,
"lon", &varid));
1125 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
1127 NC(nc_get_vara_double(ncid, varid, start, count, pert->
lon[itrack]));
1130 NC(nc_inq_varid(ncid,
"lat", &varid));
1131 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
1133 NC(nc_get_vara_double(ncid, varid, start, count, pert->
lat[itrack]));
1136 NC(nc_inq_varid(ncid,
"bt_8mu", &varid));
1137 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
1139 NC(nc_get_vara_double(ncid, varid, start, count, pert->
dc[itrack]));
1142 sprintf(varname,
"bt_%s", pertname);
1143 NC(nc_inq_varid(ncid, varname, &varid));
1144 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
1146 NC(nc_get_vara_double(ncid, varid, start, count, pert->
bt[itrack]));
1149 sprintf(varname,
"bt_%s_pt", pertname);
1150 NC(nc_inq_varid(ncid, varname, &varid));
1151 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
1153 NC(nc_get_vara_double(ncid, varid, start, count, pert->
pt[itrack]));
1156 sprintf(varname,
"bt_%s_var", pertname);
1157 NC(nc_inq_varid(ncid, varname, &varid));
1158 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
1160 NC(nc_get_vara_double(ncid, varid, start, count, pert->
var[itrack]));
1173 static double help[
NDS *
NPG];
1175 int dimid, ids, ncid, varid;
1177 size_t nds, np, ntrack, nxtrack;
1180 printf(
"Read retrieval data: %s\n", filename);
1183 NC(nc_open(filename, NC_NOWRITE, &ncid));
1186 if (nc_inq_dimid(ncid,
"L1_NTRACK", &dimid) == NC_NOERR) {
1189 NC(nc_inq_dimid(ncid,
"RET_NP", &dimid));
1190 NC(nc_inq_dimlen(ncid, dimid, &np));
1193 ERRMSG(
"Too many data points!");
1195 NC(nc_inq_dimid(ncid,
"L1_NTRACK", &dimid));
1196 NC(nc_inq_dimlen(ncid, dimid, &ntrack));
1197 NC(nc_inq_dimid(ncid,
"L1_NXTRACK", &dimid));
1198 NC(nc_inq_dimlen(ncid, dimid, &nxtrack));
1199 ret->
nds = (int) (ntrack * nxtrack);
1201 ERRMSG(
"Too many data sets!");
1204 NC(nc_inq_varid(ncid,
"l1_time", &varid));
1205 NC(nc_get_var_double(ncid, varid, help));
1207 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1208 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1209 for (
int ip = 0; ip < ret->
np; ip++)
1210 ret->
time[ids][ip] = help[ids];
1215 NC(nc_inq_varid(ncid,
"ret_z", &varid));
1216 NC(nc_get_var_double(ncid, varid, help));
1218 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1219 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1220 for (
int ip = 0; ip < ret->
np; ip++)
1221 ret->
z[ids][ip] = help[ip];
1226 NC(nc_inq_varid(ncid,
"l1_lon", &varid));
1227 NC(nc_get_var_double(ncid, varid, help));
1229 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1230 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1231 for (
int ip = 0; ip < ret->
np; ip++)
1232 ret->
lon[ids][ip] = help[ids];
1237 NC(nc_inq_varid(ncid,
"l1_lat", &varid));
1238 NC(nc_get_var_double(ncid, varid, help));
1240 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1241 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1242 for (
int ip = 0; ip < ret->
np; ip++)
1243 ret->
lat[ids][ip] = help[ids];
1248 NC(nc_inq_varid(ncid,
"ret_temp", &varid));
1249 NC(nc_get_var_double(ncid, varid, help));
1251 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1252 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1253 for (
int ip = 0; ip < ret->
np; ip++)
1255 help[(itrack * nxtrack + ixtrack) * (size_t) np + (
size_t) ip];
1261 if (nc_inq_dimid(ncid,
"np", &dimid) == NC_NOERR) {
1264 NC(nc_inq_dimid(ncid,
"np", &dimid));
1265 NC(nc_inq_dimlen(ncid, dimid, &np));
1268 ERRMSG(
"Too many data points!");
1270 NC(nc_inq_dimid(ncid,
"nds", &dimid));
1271 NC(nc_inq_dimlen(ncid, dimid, &nds));
1272 ret->
nds = (int) nds;
1274 ERRMSG(
"Too many data sets!");
1277 NC(nc_inq_varid(ncid,
"time", &varid));
1278 NC(nc_get_var_double(ncid, varid, help));
1281 NC(nc_inq_varid(ncid,
"z", &varid));
1282 NC(nc_get_var_double(ncid, varid, help));
1285 NC(nc_inq_varid(ncid,
"lon", &varid));
1286 NC(nc_get_var_double(ncid, varid, help));
1289 NC(nc_inq_varid(ncid,
"lat", &varid));
1290 NC(nc_get_var_double(ncid, varid, help));
1293 NC(nc_inq_varid(ncid,
"press", &varid));
1294 NC(nc_get_var_double(ncid, varid, help));
1297 NC(nc_inq_varid(ncid,
"temp", &varid));
1298 NC(nc_get_var_double(ncid, varid, help));
1301 NC(nc_inq_varid(ncid,
"temp_apr", &varid));
1302 NC(nc_get_var_double(ncid, varid, help));
1305 NC(nc_inq_varid(ncid,
"temp_total", &varid));
1306 NC(nc_get_var_double(ncid, varid, help));
1309 NC(nc_inq_varid(ncid,
"temp_noise", &varid));
1310 NC(nc_get_var_double(ncid, varid, help));
1313 NC(nc_inq_varid(ncid,
"temp_formod", &varid));
1314 NC(nc_get_var_double(ncid, varid, help));
1317 NC(nc_inq_varid(ncid,
"temp_cont", &varid));
1318 NC(nc_get_var_double(ncid, varid, help));
1321 NC(nc_inq_varid(ncid,
"temp_res", &varid));
1322 NC(nc_get_var_double(ncid, varid, help));
1325 NC(nc_inq_varid(ncid,
"chisq", &varid));
1326 NC(nc_get_var_double(ncid, varid, ret->
chisq));
1343 for (
int ip = 0; ip < np; ip++)
1344 for (
int ids = 0; ids < nds; ids++)
1345 mat[ids][ip] = help[n++];
1358 double rtime, rz, rlon, rlat, rx, ry, ryold = -1e10,
1359 rtemp, rbg, rpt, rvar, rfit;
1366 printf(
"Read wave data: %s\n", filename);
1369 if (!(in = fopen(filename,
"r")))
1370 ERRMSG(
"Cannot open file!");
1373 while (fgets(line, LEN, in))
1374 if (sscanf(line,
"%lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg", &rtime,
1375 &rz, &rlon, &rlat, &rx, &ry, &rtemp, &rbg, &rpt,
1376 &rvar, &rfit) == 11) {
1380 if ((++wave->
ny >=
WY))
1381 ERRMSG(
"Too many y-values!");
1383 }
else if ((++wave->
nx) >=
WX)
1384 ERRMSG(
"Too many x-values!");
1390 wave->
lon[wave->
nx][wave->
ny] = rlon;
1391 wave->
lat[wave->
nx][wave->
ny] = rlat;
1392 wave->
x[wave->
nx] = rx;
1393 wave->
y[wave->
ny] = ry;
1394 wave->
temp[wave->
nx][wave->
ny] = rtemp;
1395 wave->
bg[wave->
nx][wave->
ny] = rbg;
1396 wave->
pt[wave->
nx][wave->
ny] = rpt;
1397 wave->
var[wave->
nx][wave->
ny] = rvar;
1398 wave->
fit[wave->
nx][wave->
ny] = rfit;
1412 airs_rad_gran_t *gran,
1417 double x0[3], x1[3];
1419 int ichan[AIRS_RAD_CHANNEL];
1422 for (
int id = 0;
id < nd;
id++) {
1423 for (ichan[
id] = 0; ichan[id] < AIRS_RAD_CHANNEL; ichan[id]++)
1424 if (fabs(gran->nominal_freq[ichan[
id]] - nu[
id]) < 0.1)
1426 if (ichan[
id] >= AIRS_RAD_CHANNEL)
1427 ERRMSG(
"Could not find channel!");
1431 wave->
nx = AIRS_RAD_GEOXTRACK;
1432 wave->
ny = AIRS_RAD_GEOTRACK;
1433 if (wave->
nx >
WX || wave->
ny >
WY)
1434 ERRMSG(
"Wave struct too small!");
1437 geo2cart(0, gran->Longitude[0][0], gran->Latitude[0][0], x0);
1438 for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
1439 geo2cart(0, gran->Longitude[0][xtrack], gran->Latitude[0][xtrack], x1);
1440 wave->
x[xtrack] = DIST(x0, x1);
1442 for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++) {
1443 geo2cart(0, gran->Longitude[track][0], gran->Latitude[track][0], x1);
1444 wave->
y[track] = DIST(x0, x1);
1449 gran->Time[AIRS_RAD_GEOTRACK / 2][AIRS_RAD_GEOXTRACK / 2] - 220838400;
1451 for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++)
1452 for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
1453 wave->
lon[xtrack][track] = gran->Longitude[track][xtrack];
1454 wave->
lat[xtrack][track] = gran->Latitude[track][xtrack];
1458 for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++)
1459 for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
1460 wave->
temp[xtrack][track] = 0;
1461 wave->
bg[xtrack][track] = 0;
1462 wave->
pt[xtrack][track] = 0;
1463 wave->
var[xtrack][track] = 0;
1464 for (
int id = 0;
id < nd;
id++) {
1465 if ((gran->state[track][xtrack] != 0)
1466 || (gran->ExcludedChans[ichan[
id]] > 2)
1467 || (gran->CalChanSummary[ichan[
id]] & 8)
1468 || (gran->CalChanSummary[ichan[
id]] & (32 + 64))
1469 || (gran->CalFlag[track][ichan[
id]] & 16))
1470 wave->
temp[xtrack][track] = GSL_NAN;
1472 wave->
temp[xtrack][track]
1473 += BRIGHT(gran->radiances[track][xtrack][ichan[
id]] * 1e-3,
1474 gran->nominal_freq[ichan[
id]]) / nd;
1490 ERRMSG(
"Too many across-track values!");
1493 ERRMSG(
"Too many along-track values!");
1494 if (ip < 0 || ip >= ret->
np)
1495 ERRMSG(
"Altitude index out of range!");
1498 for (
int ids = 0; ids < ret->
nds; ids++) {
1501 const int ix = ids % 90;
1502 const int iy = ids / 90;
1505 double x0[3], x1[3];
1507 geo2cart(0.0, ret->
lon[0][0], ret->
lat[0][0], x0);
1508 geo2cart(0.0, ret->
lon[ids][ip], ret->
lat[ids][ip], x1);
1509 wave->
x[ix] = DIST(x0, x1);
1512 geo2cart(0.0, ret->
lon[0][0], ret->
lat[0][0], x0);
1513 geo2cart(0.0, ret->
lon[ids][ip], ret->
lat[ids][ip], x1);
1514 wave->
y[iy] = DIST(x0, x1);
1519 if (ix == 0 && iy == 0)
1520 wave->
z = ret->
z[ids][ip];
1521 wave->
lon[ix][iy] = ret->
lon[ids][ip];
1522 wave->
lat[ix][iy] = ret->
lat[ids][ip];
1526 wave->
temp[ix][iy] = ret->
t[ids][ip];
1527 else if (dataset == 2)
1528 wave->
temp[ix][iy] = ret->
t_apr[ids][ip];
1543 const double dh2 = gsl_pow_2(dh);
1547 (int) (dh / fabs(wave->
x[wave->
nx - 1] - wave->
x[0]) * (wave->
nx - 1.0) +
1550 (int) (dh / fabs(wave->
y[wave->
ny - 1] - wave->
y[0]) * (wave->
ny - 1.0) +
1554 for (
int ix = 0; ix < wave->
nx; ix++)
1555 for (
int iy = 0; iy < wave->
ny; iy++) {
1558 double mu = 0, help = 0;
1562 for (
int ix2 = GSL_MAX(ix - dx, 0);
1563 ix2 <= GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
1564 for (
int iy2 = GSL_MAX(iy - dy, 0);
1565 iy2 <= GSL_MIN(iy + dy, wave->
ny - 1); iy2++)
1566 if ((gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
1567 + gsl_pow_2(wave->
y[iy] - wave->
y[iy2])) <= dh2)
1568 if (gsl_finite(wave->
pt[ix2][iy2])) {
1569 mu += wave->
pt[ix2][iy2];
1570 help += gsl_pow_2(wave->
pt[ix2][iy2]);
1576 wave->
var[ix][iy] = help / n - gsl_pow_2(mu / n);
1578 wave->
var[ix][iy] = GSL_NAN;
1588 int dimid[10], ncid, time_id, lon_id, lat_id,
1589 sat_z_id, sat_lon_id, sat_lat_id, nu_id, rad_id;
1592 printf(
"Write AIRS Level-1 file: %s\n", filename);
1593 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
1594 NC(nc_create(filename, NC_CLOBBER, &ncid));
1600 if (nc_inq_dimid(ncid,
"L1_NTRACK", &dimid[0]) != NC_NOERR)
1601 NC(nc_def_dim(ncid,
"L1_NTRACK",
L1_NTRACK, &dimid[0]));
1602 if (nc_inq_dimid(ncid,
"L1_NXTRACK", &dimid[1]) != NC_NOERR)
1603 NC(nc_def_dim(ncid,
"L1_NXTRACK",
L1_NXTRACK, &dimid[1]));
1604 if (nc_inq_dimid(ncid,
"L1_NCHAN", &dimid[2]) != NC_NOERR)
1605 NC(nc_def_dim(ncid,
"L1_NCHAN",
L1_NCHAN, &dimid[2]));
1608 add_var(ncid,
"l1_time",
"s",
"time (seconds since 2000-01-01T00:00Z)",
1609 NC_DOUBLE, dimid, &time_id, 2);
1610 add_var(ncid,
"l1_lon",
"deg",
"longitude", NC_DOUBLE, dimid, &lon_id, 2);
1611 add_var(ncid,
"l1_lat",
"deg",
"latitude", NC_DOUBLE, dimid, &lat_id, 2);
1612 add_var(ncid,
"l1_sat_z",
"km",
"satellite altitude",
1613 NC_DOUBLE, dimid, &sat_z_id, 1);
1614 add_var(ncid,
"l1_sat_lon",
"deg",
"satellite longitude",
1615 NC_DOUBLE, dimid, &sat_lon_id, 1);
1616 add_var(ncid,
"l1_sat_lat",
"deg",
"satellite latitude",
1617 NC_DOUBLE, dimid, &sat_lat_id, 1);
1618 add_var(ncid,
"l1_nu",
"cm^-1",
"channel wavenumber",
1619 NC_DOUBLE, &dimid[2], &nu_id, 1);
1620 add_var(ncid,
"l1_rad",
"W/(m^2 sr cm^-1)",
"channel radiance",
1621 NC_FLOAT, dimid, &rad_id, 3);
1624 NC(nc_enddef(ncid));
1627 NC(nc_put_var_double(ncid, time_id, l1->
time[0]));
1628 NC(nc_put_var_double(ncid, lon_id, l1->
lon[0]));
1629 NC(nc_put_var_double(ncid, lat_id, l1->
lat[0]));
1630 NC(nc_put_var_double(ncid, sat_z_id, l1->
sat_z));
1631 NC(nc_put_var_double(ncid, sat_lon_id, l1->
sat_lon));
1632 NC(nc_put_var_double(ncid, sat_lat_id, l1->
sat_lat));
1633 NC(nc_put_var_double(ncid, nu_id, l1->
nu));
1634 NC(nc_put_var_float(ncid, rad_id, l1->
rad[0][0]));
1646 int dimid[10], ncid, time_id, z_id, lon_id, lat_id, p_id, t_id;
1649 printf(
"Write AIRS Level-2 file: %s\n", filename);
1650 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
1651 NC(nc_create(filename, NC_CLOBBER, &ncid));
1657 if (nc_inq_dimid(ncid,
"L2_NTRACK", &dimid[0]) != NC_NOERR)
1658 NC(nc_def_dim(ncid,
"L2_NTRACK",
L2_NTRACK, &dimid[0]));
1659 if (nc_inq_dimid(ncid,
"L2_NXTRACK", &dimid[1]) != NC_NOERR)
1660 NC(nc_def_dim(ncid,
"L2_NXTRACK",
L2_NXTRACK, &dimid[1]));
1661 if (nc_inq_dimid(ncid,
"L2_NLAY", &dimid[2]) != NC_NOERR)
1662 NC(nc_def_dim(ncid,
"L2_NLAY",
L2_NLAY, &dimid[2]));
1665 add_var(ncid,
"l2_time",
"s",
"time (seconds since 2000-01-01T00:00Z)",
1666 NC_DOUBLE, dimid, &time_id, 2);
1667 add_var(ncid,
"l2_z",
"km",
"altitude", NC_DOUBLE, dimid, &z_id, 3);
1668 add_var(ncid,
"l2_lon",
"deg",
"longitude", NC_DOUBLE, dimid, &lon_id, 2);
1669 add_var(ncid,
"l2_lat",
"deg",
"latitude", NC_DOUBLE, dimid, &lat_id, 2);
1670 add_var(ncid,
"l2_press",
"hPa",
"pressure",
1671 NC_DOUBLE, &dimid[2], &p_id, 1);
1672 add_var(ncid,
"l2_temp",
"K",
"temperature", NC_DOUBLE, dimid, &t_id, 3);
1675 NC(nc_enddef(ncid));
1678 NC(nc_put_var_double(ncid, time_id, l2->
time[0]));
1679 NC(nc_put_var_double(ncid, z_id, l2->
z[0][0]));
1680 NC(nc_put_var_double(ncid, lon_id, l2->
lon[0]));
1681 NC(nc_put_var_double(ncid, lat_id, l2->
lat[0]));
1682 NC(nc_put_var_double(ncid, p_id, l2->
p));
1683 NC(nc_put_var_double(ncid, t_id, l2->
t[0][0]));
1698 printf(
"Write wave data: %s\n", filename);
1701 if (!(out = fopen(filename,
"w")))
1702 ERRMSG(
"Cannot create file!");
1706 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
1707 "# $2 = altitude [km]\n"
1708 "# $3 = longitude [deg]\n"
1709 "# $4 = latitude [deg]\n"
1710 "# $5 = across-track distance [km]\n"
1711 "# $6 = along-track distance [km]\n"
1712 "# $7 = temperature [K]\n"
1713 "# $8 = background [K]\n"
1714 "# $9 = perturbation [K]\n"
1715 "# $10 = variance [K^2]\n" "# $11 = fitting model [K]\n");
1718 for (
int j = 0; j < wave->
ny; j++) {
1720 for (
int i = 0; i < wave->
nx; i++)
1721 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %g\n",
1722 wave->
time, wave->
z, wave->
lon[i][j], wave->
lat[i][j],
1723 wave->
x[i], wave->
y[j], wave->
temp[i][j], wave->
bg[i][j],
1724 wave->
pt[i][j], wave->
var[i][j], wave->
fit[i][j]);
#define NC(cmd)
Execute netCDF library command and check result.
void merge_y(wave_t *wave1, wave_t *wave2)
Merge wave structs in y-direction.
void fit_wave(wave_t *wave, double amp, double phi, double kx, double ky, double *chisq)
Evaluate wave fit...
void create_wave(wave_t *wave, double amp, double lx, double ly, double phi, double fwhm)
Add linear wave pattern...
void read_l1(char *filename, airs_l1_t *l1)
Read AIRS Level-1 data.
void background_poly_help(double *xx, double *yy, int n, int dim)
Get background based on polynomial fits.
void fft_help(double *fcReal, double *fcImag, int n)
Calculate 1-D FFT...
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 intpol_x(wave_t *wave, int n)
Interpolate to regular grid in x-direction.
void fft(wave_t *wave, double *Amax, double *phimax, double *lhmax, double *kxmax, double *kymax, double *alphamax, double *betamax, char *filename)
Calculate 2-D FFT...
void noise(wave_t *wave, double *mu, double *sig)
Estimate noise.
void read_retr_help(double *help, int nds, int np, double mat[NDS][NPG])
Convert array.
void ret2wave(retr_t *ret, wave_t *wave, int dataset, int ip)
Convert AIRS retrieval results to wave analysis struct.
void hamming(wave_t *wave, int niter)
Apply Hamming filter to perturbations...
void rad2wave(airs_rad_gran_t *gran, double *nu, int nd, wave_t *wave)
Convert AIRS radiance data to wave analysis struct.
void background_poly(wave_t *wave, int dim_x, int dim_y)
Get background based on polynomial fits.
void create_noise(wave_t *wave, double nedt)
Add noise to perturbations and temperatures...
void variance(wave_t *wave, double dh)
Compute local variance.
void write_l2(char *filename, airs_l2_t *l2)
Write AIRS Level-2 data.
void read_l2(char *filename, airs_l2_t *l2)
Read AIRS Level-2 data.
void add_var(int ncid, const char *varname, const char *unit, const char *longname, int type, int dimid[], int *varid, int ndims)
Add variable to netCDF file.
void read_retr(char *filename, retr_t *ret)
Read AIRS retrieval data.
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 create_background(wave_t *wave)
Set background...
void read_wave(char *filename, wave_t *wave)
Read wave analysis data.
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...
void write_l1(char *filename, airs_l1_t *l1)
Write AIRS Level-1 data.
void median(wave_t *wave, int dx)
Apply median filter to perturbations...
void write_wave(char *filename, wave_t *wave)
Write wave analysis data.
void period(wave_t *wave, double lxymax, double dlxy, double *Amax, double *phimax, double *lhmax, double *kxmax, double *kymax, double *alphamax, double *betamax, char *filename)
Compute periodogram.
AIRS Code Collection library declarations.
#define PERT_NXTRACK
Across-track size of perturbation data.
#define PMAX
Maximum number of data points for spectral analysis.
#define WX
Across-track size of wave analysis data.
#define PERT_NTRACK
Along-track size of perturbation data.
#define NDS
Maximum number of data sets per granule.
#define NPG
Maximum number of data points per granule.
#define WY
Along-track size of wave analysis data.
double lon[L1_NTRACK][L1_NXTRACK]
Footprint longitude [deg].
double nu[L1_NCHAN]
Channel frequencies [cm^-1].
double sat_lon[L1_NTRACK]
Satellite longitude [deg].
double time[L1_NTRACK][L1_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
float rad[L1_NTRACK][L1_NXTRACK][L1_NCHAN]
Radiance [W/(m^2 sr cm^-1)].
double sat_z[L1_NTRACK]
Satellite altitude [km].
double lat[L1_NTRACK][L1_NXTRACK]
Footprint latitude [deg].
double sat_lat[L1_NTRACK]
Satellite latitude [deg].
double time[L2_NTRACK][L2_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
double p[L2_NLAY]
Pressure [hPa].
double z[L2_NTRACK][L2_NXTRACK][L2_NLAY]
Geopotential height [km].
double t[L2_NTRACK][L2_NXTRACK][L2_NLAY]
Temperature [K].
double lat[L2_NTRACK][L2_NXTRACK]
Latitude [deg].
double lon[L2_NTRACK][L2_NXTRACK]
Longitude [deg].
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].
double lat[NDS][NPG]
Latitude [deg].
double t_noise[NDS][NPG]
Temperature (noise error) [K].
double p[NDS][NPG]
Pressure [hPa].
double time[NDS][NPG]
Time (seconds since 2000-01-01T00:00Z).
double lon[NDS][NPG]
Longitude [deg].
double t_fm[NDS][NPG]
Temperature (forward model error) [K].
int np
Number of data points.
double t_res[NDS][NPG]
Temperature (resolution).
double z[NDS][NPG]
Altitude [km].
double t_cont[NDS][NPG]
Temperature (measurement content).
int nds
Number of data sets.
double t_tot[NDS][NPG]
Temperature (total error) [K].
double t_apr[NDS][NPG]
Temperature (a priori data) [K].
double t[NDS][NPG]
Temperature [K].
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 x[WX]
Across-track distance [km].
double lon[WX][WY]
Longitude [deg].
double y[WY]
Along-track distance [km].
double lat[WX][WY]
Latitude [deg].
double bg[WX][WY]
Background [K].
double fit[WX][WY]
Fit [K].
double time
Time (seconds since 2000-01-01T00:00Z).
double pt[WX][WY]
Perturbation [K].