9 const char *long_name) {
12 NC(nc_put_att_text(ncid, varid,
"long_name", strlen(long_name), long_name));
15 NC(nc_put_att_text(ncid, varid,
"units", strlen(unit), unit));
31 if (nc_inq_varid(ncid, varname, varid) != NC_NOERR) {
34 NC(nc_def_var(ncid, varname, type, ndims, dimid, varid));
38 (ncid, *varid,
"long_name", strlen(longname), longname));
41 NC(nc_put_att_text(ncid, *varid,
"units", strlen(unit), unit));
58 for (
size_t i = 0; i < (size_t) n; i++)
59 if (gsl_finite(yy[i])) {
64 if ((
int) n2 < dim || n2 < 0.9 * n) {
65 for (
size_t i = 0; i < (size_t) n; i++)
71 gsl_multifit_linear_workspace *work =
72 gsl_multifit_linear_alloc((
size_t) n2, (
size_t) dim);
73 gsl_matrix *cov = gsl_matrix_alloc((
size_t) dim, (
size_t) dim);
74 gsl_matrix *X = gsl_matrix_alloc((
size_t) n2, (
size_t) dim);
75 gsl_vector *c = gsl_vector_alloc((
size_t) dim);
76 gsl_vector *x = gsl_vector_alloc((
size_t) n2);
77 gsl_vector *y = gsl_vector_alloc((
size_t) n2);
80 for (
size_t i = 0; i < (size_t) n2; i++) {
81 gsl_vector_set(x, i, xx2[i]);
82 gsl_vector_set(y, i, yy2[i]);
83 for (
size_t i2 = 0; i2 < (size_t) dim; i2++)
84 gsl_matrix_set(X, i, i2, pow(gsl_vector_get(x, i), (
double) i2));
86 gsl_multifit_linear(X, y, c, cov, &chisq, work);
87 for (
size_t i = 0; i < (size_t) n; i++)
88 yy[i] = gsl_poly_eval(c->data, (
int) dim, xx[i]);
91 gsl_multifit_linear_free(work);
107 if (dim_x <= 0 && dim_y <= 0)
111 for (
int ix = 0; ix < wave->
nx; ix++)
112 for (
int iy = 0; iy < wave->
ny; iy++) {
113 wave->
bg[ix][iy] = wave->
temp[ix][iy];
114 wave->
pt[ix][iy] = 0;
119 for (
int iy = 0; iy < wave->
ny; iy++) {
121 for (
int ix = 0; ix < wave->
nx; ix++) {
123 y[ix] = wave->
bg[ix][iy];
126 for (
int ix = 0; ix < wave->
nx; ix++)
127 wave->
bg[ix][iy] = y[ix];
132 for (
int ix = 0; ix < wave->
nx; ix++) {
134 for (
int iy = 0; iy < wave->
ny; iy++) {
136 y[iy] = wave->
bg[ix][iy];
139 for (
int iy = 0; iy < wave->
ny; iy++)
140 wave->
bg[ix][iy] = y[iy];
144 for (
int ix = 0; ix < wave->
nx; ix++)
145 for (
int iy = 0; iy < wave->
ny; iy++)
146 wave->
pt[ix][iy] = wave->
temp[ix][iy] - wave->
bg[ix][iy];
156 const double dmax = 2500.;
158 static double help[
WX][
WY];
163 if (npts_x <= 0 && npts_y <= 0)
167 for (
int ix = 0; ix < wave->
nx; ix++)
168 for (
int iy = 0; iy < wave->
ny; iy++) {
175 int dx = GSL_MIN(GSL_MIN(npts_x, ix), wave->
nx - 1 - ix);
176 int dy = GSL_MIN(GSL_MIN(npts_y, iy), wave->
ny - 1 - iy);
179 for (
int i = ix - dx; i <= ix + dx; i++)
180 for (
int j = iy - dy; j <= iy + dy; j++)
181 if (fabs(wave->
x[ix] - wave->
x[i]) < dmax &&
182 fabs(wave->
y[iy] - wave->
y[j]) < dmax) {
183 help[ix][iy] += wave->
bg[i][j];
191 help[ix][iy] = GSL_NAN;
195 for (
int ix = 0; ix < wave->
nx; ix++)
196 for (
int iy = 0; iy < wave->
ny; iy++) {
197 wave->
bg[ix][iy] = help[ix][iy];
198 wave->
pt[ix][iy] = wave->
temp[ix][iy] - wave->
bg[ix][iy];
208 for (
int ix = 0; ix < wave->
nx; ix++)
209 for (
int iy = 0; iy < wave->
ny; iy++) {
213 235.626 + 5.38165e-6 * gsl_pow_2(wave->
x[ix] -
215 wave->
x[wave->
nx - 1])) -
216 1.78519e-12 * gsl_pow_4(wave->
x[ix] -
217 0.5 * (wave->
x[0] + wave->
x[wave->
nx - 1]));
220 wave->
pt[ix][iy] = 0;
223 wave->
temp[ix][iy] = wave->
bg[ix][iy];
235 gsl_rng *r = gsl_rng_alloc(gsl_rng_default);
236 gsl_rng_set(r, (
unsigned long int) time(NULL));
240 for (
int ix = 0; ix < wave->
nx; ix++)
241 for (
int iy = 0; iy < wave->
ny; iy++)
242 wave->
temp[ix][iy] += gsl_ran_gaussian(r, nedt);
259 for (
int ix = 0; ix < wave->
nx; ix++)
260 for (
int iy = 0; iy < wave->
ny; iy++) {
263 wave->
pt[ix][iy] = amp * cos((lx != 0 ? 2 * M_PI / lx : 0) * wave->
x[ix]
265 0 ? 2 * M_PI / ly : 0) * wave->
y[iy]
267 * (fwhm > 0 ? exp(-0.5 * gsl_pow_2((wave->
x[ix]) / (lx * fwhm) * 2.35)
269 0.5 * gsl_pow_2((wave->
y[iy]) / (ly * fwhm) *
273 wave->
temp[ix][iy] += wave->
pt[ix][iy];
286 d0[12] = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
287 d0l[12] = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
290 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
291 *doy = d0l[mon - 1] + day - 1;
293 *doy = d0[mon - 1] + day - 1;
305 d0[12] = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
306 d0l[12] = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
311 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
312 for (i = 11; i > 0; i--)
316 *day = doy - d0l[i] + 1;
318 for (i = 11; i > 0; i--)
322 *day = doy - d0[i] + 1;
340 for (
int ix = 0; ix < wave->
nx; ix++)
341 for (
int iy = 0; iy < wave->
ny; iy++) {
343 = amp * cos(kx * wave->
x[ix] + ky * wave->
y[iy]
344 - phi * M_PI / 180.);
345 *chisq +=
POW2(wave->
fit[ix][iy] - wave->
pt[ix][iy]);
349 *chisq /= (double) (wave->
nx * wave->
ny);
359 double data[2 *
PMAX];
363 ERRMSG(
"Too many data points!");
366 gsl_fft_complex_wavetable *wavetable =
367 gsl_fft_complex_wavetable_alloc((
size_t) n);
368 gsl_fft_complex_workspace *workspace =
369 gsl_fft_complex_workspace_alloc((
size_t) n);
372 for (
int i = 0; i < n; i++) {
373 data[2 * i] = fcReal[i];
374 data[2 * i + 1] = fcImag[i];
378 gsl_fft_complex_forward(data, 1, (
size_t) n, wavetable, workspace);
381 for (
int i = 0; i < n; i++) {
382 fcReal[i] = data[2 * i];
383 fcImag[i] = data[2 * i + 1];
387 gsl_fft_complex_wavetable_free(wavetable);
388 gsl_fft_complex_workspace_free(workspace);
407 int imin, imax, jmin, jmax;
412 for (
int i = 0; i < wave->
nx; i++)
413 for (
int j = 0; j < wave->
ny; j++)
414 if (gsl_finite(wave->
var[i][j])) {
415 imin = GSL_MIN(imin, i);
416 imax = GSL_MAX(imax, i);
417 jmin = GSL_MIN(jmin, j);
418 jmax = GSL_MAX(jmax, j);
420 const int nx = imax - imin + 1;
421 const int ny = jmax - jmin + 1;
424 for (
int i = imin; i <= imax; i++)
425 for (
int j = jmin; j <= jmax; j++) {
426 if (gsl_finite(wave->
pt[i][j]))
427 boxReal[i - imin][j - jmin] = wave->
pt[i][j];
429 boxReal[i - imin][j - jmin] = 0.0;
430 boxImag[i - imin][j - jmin] = 0.0;
434 for (
int i = 0; i < nx; i++) {
435 for (
int j = 0; j < ny; j++) {
436 cutReal[j] = boxReal[i][j];
437 cutImag[j] = boxImag[i][j];
440 for (
int j = 0; j < ny; j++) {
441 boxReal[i][j] = cutReal[j];
442 boxImag[i][j] = cutImag[j];
447 for (
int j = 0; j < ny; j++) {
448 for (
int i = 0; i < nx; i++) {
449 cutReal[i] = boxReal[i][j];
450 cutImag[i] = boxImag[i][j];
453 for (
int i = 0; i < nx; i++) {
454 boxReal[i][j] = cutReal[i];
455 boxImag[i][j] = cutImag[i];
460 for (
int i = 0; i < nx; i++)
461 kx[i] = 2. * M_PI * ((i < nx / 2) ? (
double) i : -(
double) (nx - i))
462 / (nx * fabs(wave->
x[imax] - wave->
x[imin]) / (nx - 1.0));
463 for (
int j = 0; j < ny; j++)
464 ky[j] = 2. * M_PI * ((j < ny / 2) ? (double) j : -(
double) (ny - j))
465 / (ny * fabs(wave->
y[jmax] - wave->
y[jmin]) / (ny - 1.0));
466 for (
int i = 0; i < nx; i++)
467 for (
int j = 0; j < ny; j++) {
469 = (i == 0 && j == 0 ? 1.0 : 2.0) / (nx * ny)
470 * sqrt(gsl_pow_2(boxReal[i][j]) + gsl_pow_2(boxImag[i][j]));
472 = 180. / M_PI * atan2(boxImag[i][j], boxReal[i][j]);
476 for (
int i = 0; i < nx; i++)
477 for (
int j = 0; j < ny; j++)
478 if (kx[i] == 0 || ky[j] == 0) {
485 for (
int i = 0; i < nx; i++)
486 for (
int j = 0; j < ny / 2; j++)
487 if (gsl_finite(A[i][j]) && A[i][j] > *Amax) {
495 *lhmax = 2 * M_PI / sqrt(gsl_pow_2(*kxmax) + gsl_pow_2(*kymax));
498 *alphamax = 90. - 180. / M_PI * atan2(*kxmax, *kymax);
504 atan2(wave->
lat[wave->
nx / 2 >
505 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
506 - wave->
lat[wave->
nx / 2 <
507 wave->
nx - 1 ? wave->
nx / 2 +
508 1 : wave->
nx / 2][wave->
ny / 2],
509 wave->
lon[wave->
nx / 2 >
510 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
511 - wave->
lon[wave->
nx / 2 <
512 wave->
nx - 1 ? wave->
nx / 2 +
513 1 : wave->
nx / 2][wave->
ny / 2]);
516 if (filename != NULL) {
519 LOG(1,
"Write FFT data: %s", filename);
523 if (!(out = fopen(filename,
"w")))
524 ERRMSG(
"Cannot create file!");
528 "# $1 = altitude [km]\n"
529 "# $2 = wavelength in x-direction [km]\n"
530 "# $3 = wavelength in y-direction [km]\n"
531 "# $4 = wavenumber in x-direction [1/km]\n"
532 "# $5 = wavenumber in y-direction [1/km]\n"
533 "# $6 = amplitude [K]\n" "# $7 = phase [rad]\n");
536 for (
int i = nx - 1; i > 0; i--) {
538 for (
int j = ny / 2; j > 0; j--) {
539 int i2 = (i == nx / 2 ? 0 : i);
540 int j2 = (j == ny / 2 ? 0 : j);
541 fprintf(out,
"%g %g %g %g %g %g %g\n", wave->
z,
542 (kx[i2] != 0 ? 2 * M_PI / kx[i2] : 0),
543 (ky[j2] != 0 ? 2 * M_PI / ky[j2] : 0),
544 kx[i2], ky[j2], A[i2][j2], phi[i2][j2]);
559 static double help[
WX][
WY];
566 const double sigma2 = gsl_pow_2(fwhm / 2.3548);
569 for (
int ix = 0; ix < wave->
nx; ix++)
570 for (
int iy = 0; iy < wave->
ny; iy++) {
577 for (
int ix2 = 0; ix2 < wave->
nx; ix2++)
578 for (
int iy2 = 0; iy2 < wave->
ny; iy2++) {
579 double d2 = gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
580 + gsl_pow_2(wave->
y[iy] - wave->
y[iy2]);
581 if (d2 <= 9 * sigma2) {
582 double w = exp(-d2 / (2 * sigma2));
584 help[ix][iy] += w * wave->
pt[ix2][iy2];
589 wave->
pt[ix][iy] = help[ix][iy] / wsum;
599 static double help[
WX][
WY];
602 for (
int iter = 0; iter < niter; iter++) {
605 for (
int ix = 0; ix < wave->
nx; ix++)
606 for (
int iy = 0; iy < wave->
ny; iy++)
608 = 0.23 * wave->
pt[ix > 0 ? ix - 1 : ix][iy]
609 + 0.54 * wave->
pt[ix][iy]
610 + 0.23 * wave->
pt[ix < wave->nx - 1 ? ix + 1 : ix][iy];
613 for (
int ix = 0; ix < wave->
nx; ix++)
614 for (
int iy = 0; iy < wave->
ny; iy++)
616 = 0.23 * help[ix][iy > 0 ? iy - 1 : iy]
617 + 0.54 * help[ix][iy]
618 + 0.23 * help[ix][iy < wave->ny - 1 ? iy + 1 : iy];
628 double dummy, x[
WX], xc[
WX][3], xc2[
WX][3], y[
WX];
634 ERRMSG(
"Too many data points!");
637 for (
int i = 0; i < n; i++)
638 x[i] =
LIN(0.0, wave->
x[0], n - 1.0, wave->
x[wave->
nx - 1], i);
641 gsl_interp_accel *acc = gsl_interp_accel_alloc();
643 gsl_spline_alloc(gsl_interp_cspline, (
size_t) wave->
nx);
646 for (
int iy = 0; iy < wave->
ny; iy++) {
649 for (
int ix = 0; ix < wave->
nx; ix++)
651 for (
int ic = 0; ic < 3; ic++) {
652 for (
int ix = 0; ix < wave->
nx; ix++)
654 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
655 for (
int i = 0; i < n; i++)
656 xc2[i][ic] = gsl_spline_eval(spline, x[i], acc);
658 for (
int i = 0; i < n; i++)
662 for (
int ix = 0; ix < wave->
nx; ix++)
663 y[ix] = wave->
temp[ix][iy];
664 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
665 for (
int i = 0; i < n; i++)
666 wave->
temp[i][iy] = gsl_spline_eval(spline, x[i], acc);
669 for (
int ix = 0; ix < wave->
nx; ix++)
670 y[ix] = wave->
bg[ix][iy];
671 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
672 for (
int i = 0; i < n; i++)
673 wave->
bg[i][iy] = gsl_spline_eval(spline, x[i], acc);
676 for (
int ix = 0; ix < wave->
nx; ix++)
677 y[ix] = wave->
pt[ix][iy];
678 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
679 for (
int i = 0; i < n; i++)
680 wave->
pt[i][iy] = gsl_spline_eval(spline, x[i], acc);
683 for (
int ix = 0; ix < wave->
nx; ix++)
684 y[ix] = wave->
var[ix][iy];
685 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
686 for (
int i = 0; i < n; i++)
687 wave->
var[i][iy] = gsl_spline_eval(spline, x[i], acc);
691 gsl_spline_free(spline);
692 gsl_interp_accel_free(acc);
695 for (
int i = 0; i < n; i++)
706 static double data[
WX *
WY], help[
WX][
WY];
715 for (
int ix = 0; ix < wave->
nx; ix++)
716 for (
int iy = 0; iy < wave->
ny; iy++) {
722 for (
int ix2 = GSL_MAX(ix - dx, 0);
723 ix2 < GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
724 for (
int iy2 = GSL_MAX(iy - dx, 0);
725 iy2 < GSL_MIN(iy + dx, wave->
ny - 1); iy2++) {
726 data[n] = wave->
pt[ix2][iy2];
731 gsl_sort(data, 1, n);
732 help[ix][iy] = gsl_stats_median_from_sorted_data(data, 1, n);
736 for (
int ix = 0; ix < wave->
nx; ix++)
737 for (
int iy = 0; iy < wave->
ny; iy++)
738 wave->
pt[ix][iy] = help[ix][iy];
748 if (wave1->
nx != wave2->
nx)
749 ERRMSG(
"Across-track sizes do not match!");
750 if (wave1->
ny + wave2->
ny >
WY)
751 ERRMSG(
"Too many data points!");
755 wave1->
y[wave1->
ny - 1] + (wave1->
y[wave1->
ny - 1] -
756 wave1->
y[0]) / (wave1->
ny - 1);
759 for (
int ix = 0; ix < wave2->
nx; ix++)
760 for (
int iy = 0; iy < wave2->
ny; iy++) {
761 wave1->
y[wave1->
ny + iy] = y + wave2->
y[iy];
762 wave1->
lon[ix][wave1->
ny + iy] = wave2->
lon[ix][iy];
763 wave1->
lat[ix][wave1->
ny + iy] = wave2->
lat[ix][iy];
764 wave1->
temp[ix][wave1->
ny + iy] = wave2->
temp[ix][iy];
765 wave1->
bg[ix][wave1->
ny + iy] = wave2->
bg[ix][iy];
766 wave1->
pt[ix][wave1->
ny + iy] = wave2->
pt[ix][iy];
767 wave1->
var[ix][wave1->
ny + iy] = wave2->
var[ix][iy];
771 wave1->
ny += wave2->
ny;
788 for (
int ix = 1; ix < wave->
nx - 1; ix++)
789 for (
int iy = 1; iy < wave->
ny - 1; iy++) {
793 for (
int ix2 = ix - 1; ix2 <= ix + 1; ix2++)
794 for (
int iy2 = iy - 1; iy2 <= iy + 1; iy2++)
795 if (!gsl_finite(wave->
temp[ix2][iy2]))
802 *mu += wave->
temp[ix][iy];
803 *sig += gsl_pow_2(+4. / 6. * wave->
temp[ix][iy]
804 - 2. / 6. * (wave->
temp[ix - 1][iy]
805 + wave->
temp[ix + 1][iy]
806 + wave->
temp[ix][iy - 1]
807 + wave->
temp[ix][iy + 1])
808 + 1. / 6. * (wave->
temp[ix - 1][iy - 1]
809 + wave->
temp[ix + 1][iy - 1]
810 + wave->
temp[ix - 1][iy + 1]
811 + wave->
temp[ix + 1][iy + 1]));
816 *sig = sqrt(*sig / (
double) n);
835 for (
int track = track0; track < track1; track++)
836 for (
int xtrack = 0; xtrack < pert->
nxtrack; xtrack++) {
840 for (
int ifov = 0; ifov < pert->
nfov; ifov++)
841 if (!(gsl_finite(pert->
bt[track][xtrack][ifov])
842 && gsl_finite(pert->
pt[track][xtrack][ifov])))
849 *mu += pert->
bt[track][xtrack][4];
850 *sig += gsl_pow_2(+4. / 6. * pert->
pt[track][xtrack][4]
851 - 2. / 6. * (pert->
pt[track][xtrack][1]
852 + pert->
pt[track][xtrack][3]
853 + pert->
pt[track][xtrack][5]
854 + pert->
pt[track][xtrack][7])
855 + 1. / 6. * (pert->
pt[track][xtrack][0]
856 + pert->
pt[track][xtrack][2]
857 + pert->
pt[track][xtrack][6]
858 + pert->
pt[track][xtrack][8]));
863 *sig = sqrt(*sig / (
double) n);
884 int imin, imax, jmin, jmax, lmax = 0, mmax = 0;
887 for (
double lx = -lxymax; lx <= lxymax; lx += dlxy) {
888 kx[lmax] = (lx != 0 ? 2 * M_PI / lx : 0);
889 for (
int i = 0; i < wave->
nx; i++) {
890 cx[lmax][i] = cos(kx[lmax] * wave->
x[i]);
891 sx[lmax][i] = sin(kx[lmax] * wave->
x[i]);
894 ERRMSG(
"Too many wavenumbers for periodogram!");
896 for (
double ly = 0; ly <= lxymax; ly += dlxy) {
897 ky[mmax] = (ly != 0 ? 2 * M_PI / ly : 0);
898 for (
int j = 0; j < wave->
ny; j++) {
899 cy[mmax][j] = cos(ky[mmax] * wave->
y[j]);
900 sy[mmax][j] = sin(ky[mmax] * wave->
y[j]);
903 ERRMSG(
"Too many wavenumbers for periodogram!");
909 for (
int i = 0; i < wave->
nx; i++)
910 for (
int j = 0; j < wave->
ny; j++)
911 if (gsl_finite(wave->
var[i][j])) {
912 imin = GSL_MIN(imin, i);
913 imax = GSL_MAX(imax, i);
914 jmin = GSL_MIN(jmin, j);
915 jmax = GSL_MAX(jmax, j);
920 M_PI / fabs((wave->
x[imax] - wave->
x[imin]) /
921 ((
double) imax - (
double) imin));
923 M_PI / fabs((wave->
y[jmax] - wave->
y[jmin]) /
924 ((
double) jmax - (
double) jmin));
927 for (
int l = 0; l < lmax; l++)
928 for (
int m = 0; m < mmax; m++) {
931 if (kx[l] == 0 || fabs(kx[l]) > kx_ny ||
932 ky[m] == 0 || fabs(ky[m]) > ky_ny) {
940 for (
int i = imin; i <= imax; i++)
941 for (
int j = jmin; j <= jmax; j++)
942 if (gsl_finite(wave->
var[i][j])) {
943 a += wave->
pt[i][j] * (cx[l][i] * cy[m][j] - sx[l][i] * sy[m][j]);
944 b += wave->
pt[i][j] * (sx[l][i] * cy[m][j] + cx[l][i] * sy[m][j]);
951 A[l][m] = sqrt(gsl_pow_2(a) + gsl_pow_2(b));
952 phi[l][m] = atan2(b, a) * 180. / M_PI;
957 for (
int l = 0; l < lmax; l++)
958 for (
int m = 0; m < mmax; m++)
959 if (gsl_finite(A[l][m]) && A[l][m] > *Amax) {
967 *lhmax = 2 * M_PI / sqrt(gsl_pow_2(*kxmax) + gsl_pow_2(*kymax));
970 *alphamax = 90. - 180. / M_PI * atan2(*kxmax, *kymax);
976 atan2(wave->
lat[wave->
nx / 2 >
977 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
978 - wave->
lat[wave->
nx / 2 <
979 wave->
nx - 1 ? wave->
nx / 2 +
980 1 : wave->
nx / 2][wave->
ny / 2],
981 wave->
lon[wave->
nx / 2 >
982 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
983 - wave->
lon[wave->
nx / 2 <
984 wave->
nx - 1 ? wave->
nx / 2 +
985 1 : wave->
nx / 2][wave->
ny / 2]);
988 if (filename != NULL) {
991 LOG(1,
"Write periodogram data: %s", filename);
995 if (!(out = fopen(filename,
"w")))
996 ERRMSG(
"Cannot create file!");
1000 "# $1 = altitude [km]\n"
1001 "# $2 = wavelength in x-direction [km]\n"
1002 "# $3 = wavelength in y-direction [km]\n"
1003 "# $4 = wavenumber in x-direction [1/km]\n"
1004 "# $5 = wavenumber in y-direction [1/km]\n"
1005 "# $6 = amplitude [K]\n" "# $7 = phase [rad]\n");
1008 for (
int l = 0; l < lmax; l++) {
1010 for (
int m = 0; m < mmax; m++)
1011 fprintf(out,
"%g %g %g %g %g %g %g\n", wave->
z,
1012 (kx[l] != 0 ? 2 * M_PI / kx[l] : 0),
1013 (ky[m] != 0 ? 2 * M_PI / ky[m] : 0),
1014 kx[l], ky[m], A[l][m], phi[l][m]);
1033 double x0[3], x1[3];
1036 track0 = GSL_MIN(GSL_MAX(track0, 0), pert->
ntrack - 1);
1037 track1 = GSL_MIN(GSL_MAX(track1, 0), pert->
ntrack - 1);
1038 xtrack0 = GSL_MIN(GSL_MAX(xtrack0, 0), pert->
nxtrack - 1);
1039 xtrack1 = GSL_MIN(GSL_MAX(xtrack1, 0), pert->
nxtrack - 1);
1042 wave->
nx = xtrack1 - xtrack0 + 1;
1044 ERRMSG(
"Too many across-track values!");
1045 wave->
ny = track1 - track0 + 1;
1047 ERRMSG(
"Too many along-track values!");
1050 for (
int itrack = track0; itrack <= track1; itrack++)
1051 for (
int ixtrack = xtrack0; ixtrack <= xtrack1; ixtrack++) {
1054 if (itrack == track0) {
1056 if (ixtrack > xtrack0) {
1058 pert->
lat[itrack][ixtrack - 1], x0);
1060 pert->
lat[itrack][ixtrack], x1);
1061 wave->
x[ixtrack - xtrack0] =
1062 wave->
x[ixtrack - xtrack0 - 1] +
DIST(x0, x1);
1065 if (ixtrack == xtrack0) {
1067 if (itrack > track0) {
1069 pert->
lat[itrack - 1][ixtrack], x0);
1071 pert->
lat[itrack][ixtrack], x1);
1072 wave->
y[itrack - track0] =
1073 wave->
y[itrack - track0 - 1] +
DIST(x0, x1);
1078 wave->
time = pert->
time[(track0 + track1) / 2][(xtrack0 + xtrack1) / 2];
1080 wave->
lon[ixtrack - xtrack0][itrack - track0] =
1081 pert->
lon[itrack][ixtrack];
1082 wave->
lat[ixtrack - xtrack0][itrack - track0] =
1083 pert->
lat[itrack][ixtrack];
1086 wave->
temp[ixtrack - xtrack0][itrack - track0]
1087 = pert->
bt[itrack][ixtrack];
1088 wave->
bg[ixtrack - xtrack0][itrack - track0]
1089 = pert->
bt[itrack][ixtrack] - pert->
pt[itrack][ixtrack];
1090 wave->
pt[ixtrack - xtrack0][itrack - track0]
1091 = pert->
pt[itrack][ixtrack];
1092 wave->
var[ixtrack - xtrack0][itrack - track0]
1093 = pert->
var[itrack][ixtrack];
1105 int ncid, varid, dimid;
1110 LOG(1,
"Read CrIS Level-1B file: %s", filename);
1113 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
1114 WARN(
"Cannot open file!");
1119 NC(nc_inq_dimid(ncid,
"atrack", &dimid));
1120 NC(nc_inq_dimlen(ncid, dimid, &n));
1122 ERRMSG(
"Level-1B file dimension mismatch!");
1124 NC(nc_inq_dimid(ncid,
"xtrack", &dimid));
1125 NC(nc_inq_dimlen(ncid, dimid, &n));
1127 ERRMSG(
"Level-1B file dimension mismatch!");
1129 NC(nc_inq_dimid(ncid,
"fov", &dimid));
1130 NC(nc_inq_dimlen(ncid, dimid, &n));
1132 ERRMSG(
"Level-1B file dimension mismatch!");
1134 NC(nc_inq_dimid(ncid,
"wnum_lw", &dimid));
1135 NC(nc_inq_dimlen(ncid, dimid, &n));
1137 ERRMSG(
"Level-1B file dimension mismatch!");
1139 NC(nc_inq_dimid(ncid,
"wnum_mw", &dimid));
1140 NC(nc_inq_dimlen(ncid, dimid, &n));
1142 ERRMSG(
"Level-1B file dimension mismatch!");
1144 NC(nc_inq_dimid(ncid,
"wnum_sw", &dimid));
1145 NC(nc_inq_dimlen(ncid, dimid, &n));
1147 ERRMSG(
"Level-1B file dimension mismatch!");
1150 NC(nc_inq_varid(ncid,
"obs_time_tai93", &varid));
1151 NC(nc_get_var_double(ncid, varid, l1->
time[0]));
1152 NC(nc_inq_varid(ncid,
"lon", &varid));
1153 NC(nc_get_var_double(ncid, varid, l1->
lon[0][0]));
1154 NC(nc_inq_varid(ncid,
"lat", &varid));
1155 NC(nc_get_var_double(ncid, varid, l1->
lat[0][0]));
1156 NC(nc_inq_varid(ncid,
"sat_alt", &varid));
1157 NC(nc_get_var_double(ncid, varid, l1->
sat_z));
1158 NC(nc_inq_varid(ncid,
"subsat_lon", &varid));
1159 NC(nc_get_var_double(ncid, varid, l1->
sat_lon));
1160 NC(nc_inq_varid(ncid,
"subsat_lat", &varid));
1161 NC(nc_get_var_double(ncid, varid, l1->
sat_lat));
1164 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1165 l1->
sat_z[itrack] /= 1e3;
1168 NC(nc_inq_varid(ncid,
"wnum_lw", &varid));
1169 NC(nc_get_var_double(ncid, varid, l1->
nu_lw));
1170 NC(nc_inq_varid(ncid,
"rad_lw", &varid));
1171 NC(nc_get_var_float(ncid, varid, l1->
rad_lw[0][0][0]));
1172 NC(nc_inq_varid(ncid,
"wnum_mw", &varid));
1173 NC(nc_get_var_double(ncid, varid, l1->
nu_mw));
1174 NC(nc_inq_varid(ncid,
"rad_mw", &varid));
1175 NC(nc_get_var_float(ncid, varid, l1->
rad_mw[0][0][0]));
1176 NC(nc_inq_varid(ncid,
"wnum_sw", &varid));
1177 NC(nc_get_var_double(ncid, varid, l1->
nu_sw));
1178 NC(nc_inq_varid(ncid,
"rad_sw", &varid));
1179 NC(nc_get_var_float(ncid, varid, l1->
rad_sw[0][0][0]));
1182 NC(nc_inq_varid(ncid,
"nedn_lw", &varid));
1183 NC(nc_get_var_float(ncid, varid, l1->
nedn_lw[0]));
1184 NC(nc_inq_varid(ncid,
"nedn_mw", &varid));
1185 NC(nc_get_var_float(ncid, varid, l1->
nedn_mw[0]));
1186 NC(nc_inq_varid(ncid,
"nedn_sw", &varid));
1187 NC(nc_get_var_float(ncid, varid, l1->
nedn_sw[0]));
1190 NC(nc_inq_varid(ncid,
"rad_lw_qc", &varid));
1191 NC(nc_get_var_short(ncid, varid, l1->
qual_lw[0][0]));
1192 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1193 for (
int ixtrack = 0; ixtrack <
L1_NXTRACK; ixtrack++)
1194 for (
int ifov = 0; ifov <
L1_NFOV; ifov++)
1195 if (l1->
qual_lw[itrack][ixtrack][ifov] > 1)
1197 l1->
rad_lw[itrack][ixtrack][ifov][ichan] = GSL_NAN;
1199 NC(nc_inq_varid(ncid,
"rad_mw_qc", &varid));
1200 NC(nc_get_var_short(ncid, varid, l1->
qual_mw[0][0]));
1201 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1202 for (
int ixtrack = 0; ixtrack <
L1_NXTRACK; ixtrack++)
1203 for (
int ifov = 0; ifov <
L1_NFOV; ifov++)
1204 if (l1->
qual_mw[itrack][ixtrack][ifov] > 1)
1206 l1->
rad_mw[itrack][ixtrack][ifov][ichan] = GSL_NAN;
1208 NC(nc_inq_varid(ncid,
"rad_sw_qc", &varid));
1209 NC(nc_get_var_short(ncid, varid, l1->
qual_sw[0][0]));
1210 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1211 for (
int ixtrack = 0; ixtrack <
L1_NXTRACK; ixtrack++)
1212 for (
int ifov = 0; ifov <
L1_NFOV; ifov++)
1213 if (l1->
qual_sw[itrack][ixtrack][ifov] > 1)
1215 l1->
rad_sw[itrack][ixtrack][ifov][ichan] = GSL_NAN;
1219 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1220 for (
int ixtrack = 0; ixtrack <
L1_NXTRACK; ixtrack++)
1221 for (
int ifov = 0; ifov <
L1_NFOV; ifov++) {
1226 for (
int ichan = 1; ichan <
L1_NCHAN_LW - 1; ichan++)
1228 = 0.23 * l1->
rad_lw[itrack][ixtrack][ifov][ichan - 1]
1229 + 0.54 * l1->
rad_lw[itrack][ixtrack][ifov][ichan]
1230 + 0.23 * l1->
rad_lw[itrack][ixtrack][ifov][ichan + 1];
1231 for (
int ichan = 1; ichan <
L1_NCHAN_LW - 1; ichan++)
1232 l1->
rad_lw[itrack][ixtrack][ifov][ichan] = (
float) help[ichan];
1233 l1->
rad_lw[itrack][ixtrack][ifov][0] =
1238 for (
int ichan = 1; ichan <
L1_NCHAN_MW - 1; ichan++)
1240 = 0.23 * l1->
rad_mw[itrack][ixtrack][ifov][ichan - 1]
1241 + 0.54 * l1->
rad_mw[itrack][ixtrack][ifov][ichan]
1242 + 0.23 * l1->
rad_mw[itrack][ixtrack][ifov][ichan + 1];
1243 for (
int ichan = 1; ichan <
L1_NCHAN_MW - 1; ichan++)
1244 l1->
rad_mw[itrack][ixtrack][ifov][ichan] = (
float) help[ichan];
1245 l1->
rad_mw[itrack][ixtrack][ifov][0] =
1250 for (
int ichan = 1; ichan <
L1_NCHAN_SW - 1; ichan++)
1252 = 0.23 * l1->
rad_sw[itrack][ixtrack][ifov][ichan - 1]
1253 + 0.54 * l1->
rad_sw[itrack][ixtrack][ifov][ichan]
1254 + 0.23 * l1->
rad_sw[itrack][ixtrack][ifov][ichan + 1];
1255 for (
int ichan = 1; ichan <
L1_NCHAN_SW - 1; ichan++)
1256 l1->
rad_sw[itrack][ixtrack][ifov][ichan] = (
float) help[ichan];
1257 l1->
rad_sw[itrack][ixtrack][ifov][0] =
1276 static char varname[
LEN];
1280 static int dimid[3], ncid, varid;
1282 static size_t ntrack, nxtrack, nfov, start[3] = { 0, 0, 0 }, count[3] =
1286 LOG(1,
"Read perturbation data: %s", filename);
1289 NC(nc_open(filename, NC_NOWRITE, &ncid));
1292 NC(nc_inq_dimid(ncid,
"NTRACK", &dimid[0]));
1293 NC(nc_inq_dimlen(ncid, dimid[0], &ntrack));
1295 ERRMSG(
"Too many scans!");
1297 NC(nc_inq_dimid(ncid,
"NXTRACK", &dimid[1]));
1298 NC(nc_inq_dimlen(ncid, dimid[1], &nxtrack));
1300 ERRMSG(
"Too many tracks!");
1302 NC(nc_inq_dimid(ncid,
"NFOV", &dimid[2]));
1303 NC(nc_inq_dimlen(ncid, dimid[2], &nfov));
1305 ERRMSG(
"Too many field of views!");
1307 pert->
ntrack = (int) ntrack;
1308 pert->
nxtrack = (int) nxtrack;
1309 pert->
nfov = (int) nfov;
1313 NC(nc_inq_varid(ncid,
"time", &varid));
1314 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1315 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1318 NC(nc_get_vara_double
1319 (ncid, varid, start, count, pert->
time[itrack][ixtrack]));
1322 NC(nc_inq_varid(ncid,
"lon", &varid));
1323 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1324 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1327 NC(nc_get_vara_double
1328 (ncid, varid, start, count, pert->
lon[itrack][ixtrack]));
1331 NC(nc_inq_varid(ncid,
"lat", &varid));
1332 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1333 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1336 NC(nc_get_vara_double
1337 (ncid, varid, start, count, pert->
lat[itrack][ixtrack]));
1340 NC(nc_inq_varid(ncid,
"bt_8mu", &varid));
1341 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1342 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1345 NC(nc_get_vara_double
1346 (ncid, varid, start, count, pert->
dc[itrack][ixtrack]));
1349 NC(nc_inq_varid(ncid,
"bt_10mu", &varid));
1350 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1351 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1354 NC(nc_get_vara_double
1355 (ncid, varid, start, count, help[itrack][ixtrack]));
1358 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1359 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++)
1360 for (
size_t ifov = 0; ifov < nfov; ifov++)
1362 || (dc == 0 && !gsl_finite(pert->
dc[itrack][ixtrack][ifov])))
1363 pert->
dc[itrack][ixtrack][ifov] = help[itrack][ixtrack][ifov];
1365 sprintf(varname,
"bt_%s", pertname);
1366 NC(nc_inq_varid(ncid, varname, &varid));
1367 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1368 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1371 NC(nc_get_vara_double
1372 (ncid, varid, start, count, pert->
bt[itrack][ixtrack]));
1375 sprintf(varname,
"bt_%s_pt", pertname);
1376 NC(nc_inq_varid(ncid, varname, &varid));
1377 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1378 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1381 NC(nc_get_vara_double
1382 (ncid, varid, start, count, pert->
pt[itrack][ixtrack]));
1385 sprintf(varname,
"bt_%s_var", pertname);
1386 NC(nc_inq_varid(ncid, varname, &varid));
1387 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1388 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1391 NC(nc_get_vara_double
1392 (ncid, varid, start, count, pert->
var[itrack][ixtrack]));
1405 static double help[
NDS *
NPG];
1407 int dimid, ids, ncid, varid;
1409 size_t nds, np, ntrack, nxtrack;
1412 LOG(1,
"Read retrieval data: %s", filename);
1415 NC(nc_open(filename, NC_NOWRITE, &ncid));
1418 if (nc_inq_dimid(ncid,
"L1_NTRACK", &dimid) == NC_NOERR) {
1421 NC(nc_inq_dimid(ncid,
"RET_NP", &dimid));
1422 NC(nc_inq_dimlen(ncid, dimid, &np));
1425 ERRMSG(
"Too many data points!");
1427 NC(nc_inq_dimid(ncid,
"L1_NTRACK", &dimid));
1428 NC(nc_inq_dimlen(ncid, dimid, &ntrack));
1429 NC(nc_inq_dimid(ncid,
"L1_NXTRACK", &dimid));
1430 NC(nc_inq_dimlen(ncid, dimid, &nxtrack));
1431 ret->
nds = (int) (ntrack * nxtrack);
1433 ERRMSG(
"Too many data sets!");
1436 NC(nc_inq_varid(ncid,
"l1_time", &varid));
1437 NC(nc_get_var_double(ncid, varid, help));
1439 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1440 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1441 for (
int ip = 0; ip < ret->
np; ip++)
1442 ret->
time[ids][ip] = help[ids];
1447 NC(nc_inq_varid(ncid,
"ret_z", &varid));
1448 NC(nc_get_var_double(ncid, varid, help));
1450 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1451 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1452 for (
int ip = 0; ip < ret->
np; ip++)
1453 ret->
z[ids][ip] = help[ip];
1458 NC(nc_inq_varid(ncid,
"l1_lon", &varid));
1459 NC(nc_get_var_double(ncid, varid, help));
1461 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1462 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1463 for (
int ip = 0; ip < ret->
np; ip++)
1464 ret->
lon[ids][ip] = help[ids];
1469 NC(nc_inq_varid(ncid,
"l1_lat", &varid));
1470 NC(nc_get_var_double(ncid, varid, help));
1472 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1473 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1474 for (
int ip = 0; ip < ret->
np; ip++)
1475 ret->
lat[ids][ip] = help[ids];
1480 NC(nc_inq_varid(ncid,
"ret_temp", &varid));
1481 NC(nc_get_var_double(ncid, varid, help));
1483 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1484 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1485 for (
int ip = 0; ip < ret->
np; ip++)
1487 help[(itrack * nxtrack + ixtrack) * (size_t) np + (
size_t) ip];
1493 if (nc_inq_dimid(ncid,
"np", &dimid) == NC_NOERR) {
1496 NC(nc_inq_dimid(ncid,
"np", &dimid));
1497 NC(nc_inq_dimlen(ncid, dimid, &np));
1500 ERRMSG(
"Too many data points!");
1502 NC(nc_inq_dimid(ncid,
"nds", &dimid));
1503 NC(nc_inq_dimlen(ncid, dimid, &nds));
1504 ret->
nds = (int) nds;
1506 ERRMSG(
"Too many data sets!");
1509 NC(nc_inq_varid(ncid,
"time", &varid));
1510 NC(nc_get_var_double(ncid, varid, help));
1513 NC(nc_inq_varid(ncid,
"z", &varid));
1514 NC(nc_get_var_double(ncid, varid, help));
1517 NC(nc_inq_varid(ncid,
"lon", &varid));
1518 NC(nc_get_var_double(ncid, varid, help));
1521 NC(nc_inq_varid(ncid,
"lat", &varid));
1522 NC(nc_get_var_double(ncid, varid, help));
1525 NC(nc_inq_varid(ncid,
"press", &varid));
1526 NC(nc_get_var_double(ncid, varid, help));
1529 NC(nc_inq_varid(ncid,
"temp", &varid));
1530 NC(nc_get_var_double(ncid, varid, help));
1533 NC(nc_inq_varid(ncid,
"temp_apr", &varid));
1534 NC(nc_get_var_double(ncid, varid, help));
1537 NC(nc_inq_varid(ncid,
"temp_total", &varid));
1538 NC(nc_get_var_double(ncid, varid, help));
1541 NC(nc_inq_varid(ncid,
"temp_noise", &varid));
1542 NC(nc_get_var_double(ncid, varid, help));
1545 NC(nc_inq_varid(ncid,
"temp_formod", &varid));
1546 NC(nc_get_var_double(ncid, varid, help));
1549 NC(nc_inq_varid(ncid,
"temp_cont", &varid));
1550 NC(nc_get_var_double(ncid, varid, help));
1553 NC(nc_inq_varid(ncid,
"temp_res", &varid));
1554 NC(nc_get_var_double(ncid, varid, help));
1557 NC(nc_inq_varid(ncid,
"chisq", &varid));
1558 NC(nc_get_var_double(ncid, varid, ret->
chisq));
1575 for (
int ip = 0; ip < np; ip++)
1576 for (
int ids = 0; ids < nds; ids++)
1577 mat[ids][ip] = help[n++];
1590 double rtime, rz, rlon, rlat, rx, ry, ryold = -1e10,
1591 rtemp, rbg, rpt, rvar, rfit;
1598 LOG(1,
"Read wave data: %s", filename);
1601 if (!(in = fopen(filename,
"r")))
1602 ERRMSG(
"Cannot open file!");
1605 while (fgets(line,
LEN, in))
1606 if (sscanf(line,
"%lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg", &rtime,
1607 &rz, &rlon, &rlat, &rx, &ry, &rtemp, &rbg, &rpt,
1608 &rvar, &rfit) == 11) {
1612 if ((++wave->
ny >=
WY))
1613 ERRMSG(
"Too many y-values!");
1615 }
else if ((++wave->
nx) >=
WX)
1616 ERRMSG(
"Too many x-values!");
1622 wave->
lon[wave->
nx][wave->
ny] = rlon;
1623 wave->
lat[wave->
nx][wave->
ny] = rlat;
1624 wave->
x[wave->
nx] = rx;
1625 wave->
y[wave->
ny] = ry;
1626 wave->
temp[wave->
nx][wave->
ny] = rtemp;
1627 wave->
bg[wave->
nx][wave->
ny] = rbg;
1628 wave->
pt[wave->
nx][wave->
ny] = rpt;
1629 wave->
var[wave->
nx][wave->
ny] = rvar;
1630 wave->
var[wave->
nx][wave->
ny] = rfit;
1650 double x0[3], x1[3];
1652 int ichan[AIRS_RAD_CHANNEL];
1655 for (
int id = 0;
id < nd;
id++) {
1656 for (ichan[
id] = 0; ichan[id] < AIRS_RAD_CHANNEL; ichan[id]++)
1657 if (fabs(gran->nominal_freq[ichan[
id]] - nu[
id]) < 0.1)
1659 if (ichan[
id] >= AIRS_RAD_CHANNEL)
1660 ERRMSG(
"Could not find channel!");
1664 wave->
nx = AIRS_RAD_GEOXTRACK;
1665 wave->
ny = AIRS_RAD_GEOTRACK;
1666 if (wave->
nx >
WX || wave->
ny >
WY)
1667 ERRMSG(
"Wave struct too small!");
1670 geo2cart(0, gran->Longitude[0][0], gran->Latitude[0][0], x0);
1671 for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
1672 geo2cart(0, gran->Longitude[0][xtrack], gran->Latitude[0][xtrack], x1);
1673 wave->
x[xtrack] =
DIST(x0, x1);
1675 for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++) {
1676 geo2cart(0, gran->Longitude[track][0], gran->Latitude[track][0], x1);
1677 wave->
y[track] =
DIST(x0, x1);
1682 gran->Time[AIRS_RAD_GEOTRACK / 2][AIRS_RAD_GEOXTRACK / 2] - 220838400;
1684 for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++)
1685 for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
1686 wave->
lon[xtrack][track] = gran->Longitude[track][xtrack];
1687 wave->
lat[xtrack][track] = gran->Latitude[track][xtrack];
1691 for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++)
1692 for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
1693 wave->
temp[xtrack][track] = 0;
1694 wave->
bg[xtrack][track] = 0;
1695 wave->
pt[xtrack][track] = 0;
1696 wave->
var[xtrack][track] = 0;
1697 for (
int id = 0;
id < nd;
id++) {
1698 if ((gran->state[track][xtrack] != 0)
1699 || (gran->ExcludedChans[ichan[
id]] > 2)
1700 || (gran->CalChanSummary[ichan[
id]] & 8)
1701 || (gran->CalChanSummary[ichan[
id]] & (32 + 64))
1702 || (gran->CalFlag[track][ichan[
id]] & 16))
1703 wave->
temp[xtrack][track] = GSL_NAN;
1705 wave->
temp[xtrack][track]
1706 += brightness(gran->radiances[track][xtrack][ichan[
id]] * 1e-3,
1707 gran->nominal_freq[ichan[
id]]) / nd;
1721 double x0[3], x1[3];
1726 ERRMSG(
"Too many across-track values!");
1729 ERRMSG(
"Too many along-track values!");
1730 if (ip < 0 || ip >= ret->
np)
1731 ERRMSG(
"Altitude index out of range!");
1734 for (
int ids = 0; ids < ret->
nds; ids++) {
1744 wave->
x[ix] =
DIST(x0, x1);
1749 wave->
y[iy] =
DIST(x0, x1);
1754 if (ix == 0 && iy == 0)
1755 wave->
z = ret->
z[ids][ip];
1756 wave->
lon[ix][iy] = ret->
lon[ids][ip];
1757 wave->
lat[ix][iy] = ret->
lat[ids][ip];
1761 wave->
temp[ix][iy] = ret->
t[ids][ip];
1762 else if (dataset == 2)
1763 wave->
temp[ix][iy] = ret->
t_apr[ids][ip];
1778 const double dh2 = gsl_pow_2(dh);
1782 (int) (dh / fabs(wave->
x[wave->
nx - 1] - wave->
x[0]) * (wave->
nx - 1.0) +
1785 (int) (dh / fabs(wave->
y[wave->
ny - 1] - wave->
y[0]) * (wave->
ny - 1.0) +
1789 for (
int ix = 0; ix < wave->
nx; ix++)
1790 for (
int iy = 0; iy < wave->
ny; iy++) {
1793 double mu = 0, help = 0;
1797 for (
int ix2 = GSL_MAX(ix - dx, 0);
1798 ix2 <= GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
1799 for (
int iy2 = GSL_MAX(iy - dy, 0);
1800 iy2 <= GSL_MIN(iy + dy, wave->
ny - 1); iy2++)
1801 if ((gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
1802 + gsl_pow_2(wave->
y[iy] - wave->
y[iy2])) <= dh2)
1803 if (gsl_finite(wave->
pt[ix2][iy2])) {
1804 mu += wave->
pt[ix2][iy2];
1805 help += gsl_pow_2(wave->
pt[ix2][iy2]);
1811 wave->
var[ix][iy] = help / n - gsl_pow_2(mu / n);
1813 wave->
var[ix][iy] = GSL_NAN;
1826 LOG(1,
"Write wave data: %s", filename);
1829 if (!(out = fopen(filename,
"w")))
1830 ERRMSG(
"Cannot create file!");
1834 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
1835 "# $2 = altitude [km]\n"
1836 "# $3 = longitude [deg]\n"
1837 "# $4 = latitude [deg]\n"
1838 "# $5 = across-track distance [km]\n"
1839 "# $6 = along-track distance [km]\n"
1840 "# $7 = temperature [K]\n"
1841 "# $8 = background [K]\n"
1842 "# $9 = perturbation [K]\n"
1843 "# $10 = variance [K^2]\n" "# $11 = fitting model [K]\n");
1846 for (
int j = 0; j < wave->
ny; j++) {
1848 for (
int i = 0; i < wave->
nx; i++)
1849 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %g\n",
1850 wave->
time, wave->
z, wave->
lon[i][j], wave->
lat[i][j],
1851 wave->
x[i], wave->
y[j], wave->
temp[i][j], wave->
bg[i][j],
1852 wave->
pt[i][j], wave->
var[i][j], wave->
fit[i][j]);
void cart2geo(const double *x, double *z, double *lon, double *lat)
Convert Cartesian coordinates to geolocation.
void geo2cart(const double z, const double lon, const double lat, double *x)
Convert geolocation to Cartesian coordinates.
#define LEN
Maximum length of ASCII data lines.
#define POW2(x)
Compute x^2.
#define ERRMSG(...)
Print error message and quit program.
#define WARN(...)
Print warning message.
#define LOG(level,...)
Print log message.
#define DIST(a, b)
Compute Cartesian distance between two vectors.
#define LIN(x0, y0, x1, y1, x)
Compute linear interpolation.
void day2doy(const int year, const int mon, const int day, int *doy)
Get day of year from date.
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 noise_pert(pert_t *pert, int track0, int track1, double *mu, double *sig)
Estimate noise from perurbations.
void background_poly_help(const double *xx, double *yy, const int n, const 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 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 hamming(wave_t *wave, int niter)
Apply Hamming filter to perturbations...
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...
int read_cris_l1(char *filename, cris_l1_t *l1, int apo)
Read CrIS Level-1 data.
void variance(wave_t *wave, double dh)
Compute local variance.
void ret2wave(ret_t *ret, wave_t *wave, int dataset, int ip)
Convert CrIS retrieval results to wave analysis struct.
void add_att(const int ncid, const int varid, const char *unit, const char *long_name)
Add variable attributes to netCDF file.
void read_retr(char *filename, ret_t *ret)
Read CrIS retrieval data.
void doy2day(const int year, const int doy, int *mon, int *day)
Get date from day of year.
void create_background(wave_t *wave)
Set background...
void read_pert(char *filename, char *pertname, int dc, pert_t *pert)
Read radiance perturbation data.
void read_wave(char *filename, wave_t *wave)
Read wave analysis data.
void gauss(wave_t *wave, double fwhm)
Apply Gaussian filter to perturbations...
void add_var(const 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 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.
#define NC(cmd)
Execute netCDF library command and check result.
void rad2wave(cris_l1_t *cris_l1, double *nu, int nd, wave_t *wave)
Convert CrIS radiance data to wave analysis struct.
#define PERT_NXTRACK
Across-track size of perturbation data.
#define PMAX
Maximum number of data points for spectral analysis.
#define L1_NCHAN_LW
Number of CrIS longwave radiance channels.
#define L1_NXTRACK
Across-track size of CrIS radiance granule.
#define L1_NTRACK
Along-track size of CrIS radiance granule.
#define L1_NFOV
Number of field of views of CrIS radiance granule.
#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.
void pert2wave(pert_t *pert, wave_t *wave, int track0, int track1, int xtrack0, int xtrack1)
Convert radiance perturbation data to wave analysis struct.
#define L1_NCHAN_MW
Number of CrIS midwave radiance channels.
#define L1_NCHAN_SW
Number of CrIS shortwave radiance channels.
#define NPG
Maximum number of data points per granule.
#define PERT_NFOV
Number of field of views of perturbation data.
#define WY
Along-track size of wave analysis data.
double nu_sw[L1_NCHAN_SW]
Shortwave channel frequencies [cm^-1].
double sat_z[L1_NTRACK]
Satellite altitude [km].
float nedn_sw[L1_NFOV][L1_NCHAN_SW]
Longwave radiance noise [W/(m^2 sr cm^-1)].
float rad_mw[L1_NTRACK][L1_NXTRACK][L1_NFOV][L1_NCHAN_MW]
Midwave radiance [W/(m^2 sr cm^-1)].
float nedn_mw[L1_NFOV][L1_NCHAN_MW]
Midwave radiance noise [W/(m^2 sr cm^-1)].
double nu_mw[L1_NCHAN_MW]
Midwave channel frequencies [cm^-1].
float rad_sw[L1_NTRACK][L1_NXTRACK][L1_NFOV][L1_NCHAN_SW]
Shortwave radiance [W/(m^2 sr cm^-1)].
float nedn_lw[L1_NFOV][L1_NCHAN_LW]
Longwave radiance noise [W/(m^2 sr cm^-1)].
short qual_mw[L1_NTRACK][L1_NXTRACK][L1_NFOV]
Midwave quality flag (0=best, 1=good, 2=don't use).
double lon[L1_NTRACK][L1_NXTRACK][L1_NFOV]
Footprint longitude [deg].
float rad_lw[L1_NTRACK][L1_NXTRACK][L1_NFOV][L1_NCHAN_LW]
Longwave radiance [W/(m^2 sr cm^-1)].
double sat_lat[L1_NTRACK]
Satellite latitude [deg].
double time[L1_NTRACK][L1_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
short qual_sw[L1_NTRACK][L1_NXTRACK][L1_NFOV]
Shortwave quality flag (0=best, 1=good, 2=don't use).
double sat_lon[L1_NTRACK]
Satellite longitude [deg].
double nu_lw[L1_NCHAN_LW]
Longwave channel frequencies [cm^-1].
double lat[L1_NTRACK][L1_NXTRACK][L1_NFOV]
Footprint latitude [deg].
short qual_lw[L1_NTRACK][L1_NXTRACK][L1_NFOV]
Longwave quality flag (0=best, 1=good, 2=don't use).
double dc[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Brightness temperature (cloud channel) [K].
double lat[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Latitude [deg].
int nfov
Number of field of views.
double pt[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Brightness temperature perturbation (4 or 15 micron) [K].
int ntrack
Number of along-track values.
double var[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Brightness temperature variance (4 or 15 micron) [K].
double time[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Time (seconds since 2000-01-01T00:00Z).
double bt[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Brightness temperature (4.3 or 15 micron) [K].
int nxtrack
Number of across-track values.
double lon[PERT_NTRACK][PERT_NXTRACK][PERT_NFOV]
Longitude [deg].
double t_apr[NDS][NPG]
Temperature (a priori data) [K].
double t_noise[NDS][NPG]
Temperature (noise error) [K].
double lat[NDS][NPG]
Latitude [deg].
double t_cont[NDS][NPG]
Temperature (measurement content).
double t[NDS][NPG]
Temperature [K].
double t_fm[NDS][NPG]
Temperature (forward model error) [K].
double p[NDS][NPG]
Pressure [hPa].
double z[NDS][NPG]
Altitude [km].
double t_res[NDS][NPG]
Temperature (resolution).
int nds
Number of data sets.
double t_tot[NDS][NPG]
Temperature (total error) [K].
int np
Number of data points.
double time[NDS][NPG]
Time (seconds since 2000-01-01T00:00Z).
double lon[NDS][NPG]
Longitude [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 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].