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];
291 for (
int ix = 0; ix < wave->
nx; ix++)
292 for (
int iy = 0; iy < wave->
ny; iy++) {
294 = amp * cos(kx * wave->
x[ix] + ky * wave->
y[iy]
295 - phi * M_PI / 180.);
296 *chisq +=
POW2(wave->
fit[ix][iy] - wave->
pt[ix][iy]);
300 *chisq /= (double) (wave->
nx * wave->
ny);
310 double data[2 *
PMAX];
314 ERRMSG(
"Too many data points!");
317 gsl_fft_complex_wavetable *wavetable =
318 gsl_fft_complex_wavetable_alloc((
size_t) n);
319 gsl_fft_complex_workspace *workspace =
320 gsl_fft_complex_workspace_alloc((
size_t) n);
323 for (
int i = 0; i < n; i++) {
324 data[2 * i] = fcReal[i];
325 data[2 * i + 1] = fcImag[i];
329 gsl_fft_complex_forward(data, 1, (
size_t) n, wavetable, workspace);
332 for (
int i = 0; i < n; i++) {
333 fcReal[i] = data[2 * i];
334 fcImag[i] = data[2 * i + 1];
338 gsl_fft_complex_wavetable_free(wavetable);
339 gsl_fft_complex_workspace_free(workspace);
358 int imin, imax, jmin, jmax;
363 for (
int i = 0; i < wave->
nx; i++)
364 for (
int j = 0; j < wave->
ny; j++)
365 if (gsl_finite(wave->
var[i][j])) {
366 imin = GSL_MIN(imin, i);
367 imax = GSL_MAX(imax, i);
368 jmin = GSL_MIN(jmin, j);
369 jmax = GSL_MAX(jmax, j);
371 const int nx = imax - imin + 1;
372 const int ny = jmax - jmin + 1;
375 for (
int i = imin; i <= imax; i++)
376 for (
int j = jmin; j <= jmax; j++) {
377 if (gsl_finite(wave->
pt[i][j]))
378 boxReal[i - imin][j - jmin] = wave->
pt[i][j];
380 boxReal[i - imin][j - jmin] = 0.0;
381 boxImag[i - imin][j - jmin] = 0.0;
385 for (
int i = 0; i < nx; i++) {
386 for (
int j = 0; j < ny; j++) {
387 cutReal[j] = boxReal[i][j];
388 cutImag[j] = boxImag[i][j];
391 for (
int j = 0; j < ny; j++) {
392 boxReal[i][j] = cutReal[j];
393 boxImag[i][j] = cutImag[j];
398 for (
int j = 0; j < ny; j++) {
399 for (
int i = 0; i < nx; i++) {
400 cutReal[i] = boxReal[i][j];
401 cutImag[i] = boxImag[i][j];
404 for (
int i = 0; i < nx; i++) {
405 boxReal[i][j] = cutReal[i];
406 boxImag[i][j] = cutImag[i];
411 for (
int i = 0; i < nx; i++)
412 kx[i] = 2. * M_PI * ((i < nx / 2) ? (
double) i : -(
double) (nx - i))
413 / (nx * fabs(wave->
x[imax] - wave->
x[imin]) / (nx - 1.0));
414 for (
int j = 0; j < ny; j++)
415 ky[j] = 2. * M_PI * ((j < ny / 2) ? (double) j : -(
double) (ny - j))
416 / (ny * fabs(wave->
y[jmax] - wave->
y[jmin]) / (ny - 1.0));
417 for (
int i = 0; i < nx; i++)
418 for (
int j = 0; j < ny; j++) {
420 = (i == 0 && j == 0 ? 1.0 : 2.0) / (nx * ny)
421 * sqrt(gsl_pow_2(boxReal[i][j]) + gsl_pow_2(boxImag[i][j]));
423 = 180. / M_PI * atan2(boxImag[i][j], boxReal[i][j]);
427 for (
int i = 0; i < nx; i++)
428 for (
int j = 0; j < ny; j++)
429 if (kx[i] == 0 || ky[j] == 0) {
436 for (
int i = 0; i < nx; i++)
437 for (
int j = 0; j < ny / 2; j++)
438 if (gsl_finite(A[i][j]) && A[i][j] > *Amax) {
446 *lhmax = 2 * M_PI / sqrt(gsl_pow_2(*kxmax) + gsl_pow_2(*kymax));
449 *alphamax = 90. - 180. / M_PI * atan2(*kxmax, *kymax);
455 atan2(wave->
lat[wave->
nx / 2 >
456 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
457 - wave->
lat[wave->
nx / 2 <
458 wave->
nx - 1 ? wave->
nx / 2 +
459 1 : wave->
nx / 2][wave->
ny / 2],
460 wave->
lon[wave->
nx / 2 >
461 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
462 - wave->
lon[wave->
nx / 2 <
463 wave->
nx - 1 ? wave->
nx / 2 +
464 1 : wave->
nx / 2][wave->
ny / 2]);
467 if (filename != NULL) {
470 LOG(1,
"Write FFT data: %s", filename);
474 if (!(out = fopen(filename,
"w")))
475 ERRMSG(
"Cannot create file!");
479 "# $1 = altitude [km]\n"
480 "# $2 = wavelength in x-direction [km]\n"
481 "# $3 = wavelength in y-direction [km]\n"
482 "# $4 = wavenumber in x-direction [1/km]\n"
483 "# $5 = wavenumber in y-direction [1/km]\n"
484 "# $6 = amplitude [K]\n" "# $7 = phase [rad]\n");
487 for (
int i = nx - 1; i > 0; i--) {
489 for (
int j = ny / 2; j > 0; j--) {
490 int i2 = (i == nx / 2 ? 0 : i);
491 int j2 = (j == ny / 2 ? 0 : j);
492 fprintf(out,
"%g %g %g %g %g %g %g\n", wave->
z,
493 (kx[i2] != 0 ? 2 * M_PI / kx[i2] : 0),
494 (ky[j2] != 0 ? 2 * M_PI / ky[j2] : 0),
495 kx[i2], ky[j2], A[i2][j2], phi[i2][j2]);
510 static double help[
WX][
WY];
517 const double sigma2 = gsl_pow_2(fwhm / 2.3548);
520 for (
int ix = 0; ix < wave->
nx; ix++)
521 for (
int iy = 0; iy < wave->
ny; iy++) {
528 for (
int ix2 = 0; ix2 < wave->
nx; ix2++)
529 for (
int iy2 = 0; iy2 < wave->
ny; iy2++) {
530 double d2 = gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
531 + gsl_pow_2(wave->
y[iy] - wave->
y[iy2]);
532 if (d2 <= 9 * sigma2) {
533 double w = exp(-d2 / (2 * sigma2));
535 help[ix][iy] += w * wave->
pt[ix2][iy2];
540 wave->
pt[ix][iy] = help[ix][iy] / wsum;
550 static double help[
WX][
WY];
553 for (
int iter = 0; iter < niter; iter++) {
556 for (
int ix = 0; ix < wave->
nx; ix++)
557 for (
int iy = 0; iy < wave->
ny; iy++)
559 = 0.23 * wave->
pt[ix > 0 ? ix - 1 : ix][iy]
560 + 0.54 * wave->
pt[ix][iy]
561 + 0.23 * wave->
pt[ix < wave->nx - 1 ? ix + 1 : ix][iy];
564 for (
int ix = 0; ix < wave->
nx; ix++)
565 for (
int iy = 0; iy < wave->
ny; iy++)
567 = 0.23 * help[ix][iy > 0 ? iy - 1 : iy]
568 + 0.54 * help[ix][iy]
569 + 0.23 * help[ix][iy < wave->ny - 1 ? iy + 1 : iy];
579 double dummy, x[
WX], xc[
WX][3], xc2[
WX][3], y[
WX];
585 ERRMSG(
"Too many data points!");
588 for (
int i = 0; i < n; i++)
589 x[i] =
LIN(0.0, wave->
x[0], n - 1.0, wave->
x[wave->
nx - 1], i);
592 gsl_interp_accel *acc = gsl_interp_accel_alloc();
594 gsl_spline_alloc(gsl_interp_cspline, (
size_t) wave->
nx);
597 for (
int iy = 0; iy < wave->
ny; iy++) {
600 for (
int ix = 0; ix < wave->
nx; ix++)
602 for (
int ic = 0; ic < 3; ic++) {
603 for (
int ix = 0; ix < wave->
nx; ix++)
605 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
606 for (
int i = 0; i < n; i++)
607 xc2[i][ic] = gsl_spline_eval(spline, x[i], acc);
609 for (
int i = 0; i < n; i++)
613 for (
int ix = 0; ix < wave->
nx; ix++)
614 y[ix] = wave->
temp[ix][iy];
615 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
616 for (
int i = 0; i < n; i++)
617 wave->
temp[i][iy] = gsl_spline_eval(spline, x[i], acc);
620 for (
int ix = 0; ix < wave->
nx; ix++)
621 y[ix] = wave->
bg[ix][iy];
622 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
623 for (
int i = 0; i < n; i++)
624 wave->
bg[i][iy] = gsl_spline_eval(spline, x[i], acc);
627 for (
int ix = 0; ix < wave->
nx; ix++)
628 y[ix] = wave->
pt[ix][iy];
629 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
630 for (
int i = 0; i < n; i++)
631 wave->
pt[i][iy] = gsl_spline_eval(spline, x[i], acc);
634 for (
int ix = 0; ix < wave->
nx; ix++)
635 y[ix] = wave->
var[ix][iy];
636 gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
637 for (
int i = 0; i < n; i++)
638 wave->
var[i][iy] = gsl_spline_eval(spline, x[i], acc);
642 gsl_spline_free(spline);
643 gsl_interp_accel_free(acc);
646 for (
int i = 0; i < n; i++)
657 static double data[
WX *
WY], help[
WX][
WY];
666 for (
int ix = 0; ix < wave->
nx; ix++)
667 for (
int iy = 0; iy < wave->
ny; iy++) {
673 for (
int ix2 = GSL_MAX(ix - dx, 0);
674 ix2 < GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
675 for (
int iy2 = GSL_MAX(iy - dx, 0);
676 iy2 < GSL_MIN(iy + dx, wave->
ny - 1); iy2++) {
677 data[n] = wave->
pt[ix2][iy2];
682 gsl_sort(data, 1, n);
683 help[ix][iy] = gsl_stats_median_from_sorted_data(data, 1, n);
687 for (
int ix = 0; ix < wave->
nx; ix++)
688 for (
int iy = 0; iy < wave->
ny; iy++)
689 wave->
pt[ix][iy] = help[ix][iy];
699 if (wave1->
nx != wave2->
nx)
700 ERRMSG(
"Across-track sizes do not match!");
701 if (wave1->
ny + wave2->
ny >
WY)
702 ERRMSG(
"Too many data points!");
706 wave1->
y[wave1->
ny - 1] + (wave1->
y[wave1->
ny - 1] -
707 wave1->
y[0]) / (wave1->
ny - 1);
710 for (
int ix = 0; ix < wave2->
nx; ix++)
711 for (
int iy = 0; iy < wave2->
ny; iy++) {
712 wave1->
y[wave1->
ny + iy] = y + wave2->
y[iy];
713 wave1->
lon[ix][wave1->
ny + iy] = wave2->
lon[ix][iy];
714 wave1->
lat[ix][wave1->
ny + iy] = wave2->
lat[ix][iy];
715 wave1->
temp[ix][wave1->
ny + iy] = wave2->
temp[ix][iy];
716 wave1->
bg[ix][wave1->
ny + iy] = wave2->
bg[ix][iy];
717 wave1->
pt[ix][wave1->
ny + iy] = wave2->
pt[ix][iy];
718 wave1->
var[ix][wave1->
ny + iy] = wave2->
var[ix][iy];
722 wave1->
ny += wave2->
ny;
739 for (
int ix = 1; ix < wave->
nx - 1; ix++)
740 for (
int iy = 1; iy < wave->
ny - 1; iy++) {
744 for (
int ix2 = ix - 1; ix2 <= ix + 1; ix2++)
745 for (
int iy2 = iy - 1; iy2 <= iy + 1; iy2++)
746 if (!gsl_finite(wave->
temp[ix2][iy2]))
753 *mu += wave->
temp[ix][iy];
754 *sig += gsl_pow_2(+4. / 6. * wave->
temp[ix][iy]
755 - 2. / 6. * (wave->
temp[ix - 1][iy]
756 + wave->
temp[ix + 1][iy]
757 + wave->
temp[ix][iy - 1]
758 + wave->
temp[ix][iy + 1])
759 + 1. / 6. * (wave->
temp[ix - 1][iy - 1]
760 + wave->
temp[ix + 1][iy - 1]
761 + wave->
temp[ix - 1][iy + 1]
762 + wave->
temp[ix + 1][iy + 1]));
767 *sig = sqrt(*sig / (
double) n);
786 for (
int track = track0; track < track1; track++)
787 for (
int xtrack = 0; xtrack < pert->
nxtrack; xtrack++) {
791 for (
int ifov = 0; ifov < pert->
nfov; ifov++)
792 if (!(gsl_finite(pert->
bt[track][xtrack][ifov])
793 && gsl_finite(pert->
pt[track][xtrack][ifov])))
800 *mu += pert->
bt[track][xtrack][4];
801 *sig += gsl_pow_2(+4. / 6. * pert->
pt[track][xtrack][4]
802 - 2. / 6. * (pert->
pt[track][xtrack][1]
803 + pert->
pt[track][xtrack][3]
804 + pert->
pt[track][xtrack][5]
805 + pert->
pt[track][xtrack][7])
806 + 1. / 6. * (pert->
pt[track][xtrack][0]
807 + pert->
pt[track][xtrack][2]
808 + pert->
pt[track][xtrack][6]
809 + pert->
pt[track][xtrack][8]));
814 *sig = sqrt(*sig / (
double) n);
835 int imin, imax, jmin, jmax, lmax = 0, mmax = 0;
838 for (
double lx = -lxymax; lx <= lxymax; lx += dlxy) {
839 kx[lmax] = (lx != 0 ? 2 * M_PI / lx : 0);
840 for (
int i = 0; i < wave->
nx; i++) {
841 cx[lmax][i] = cos(kx[lmax] * wave->
x[i]);
842 sx[lmax][i] = sin(kx[lmax] * wave->
x[i]);
845 ERRMSG(
"Too many wavenumbers for periodogram!");
847 for (
double ly = 0; ly <= lxymax; ly += dlxy) {
848 ky[mmax] = (ly != 0 ? 2 * M_PI / ly : 0);
849 for (
int j = 0; j < wave->
ny; j++) {
850 cy[mmax][j] = cos(ky[mmax] * wave->
y[j]);
851 sy[mmax][j] = sin(ky[mmax] * wave->
y[j]);
854 ERRMSG(
"Too many wavenumbers for periodogram!");
860 for (
int i = 0; i < wave->
nx; i++)
861 for (
int j = 0; j < wave->
ny; j++)
862 if (gsl_finite(wave->
var[i][j])) {
863 imin = GSL_MIN(imin, i);
864 imax = GSL_MAX(imax, i);
865 jmin = GSL_MIN(jmin, j);
866 jmax = GSL_MAX(jmax, j);
871 M_PI / fabs((wave->
x[imax] - wave->
x[imin]) /
872 ((
double) imax - (
double) imin));
874 M_PI / fabs((wave->
y[jmax] - wave->
y[jmin]) /
875 ((
double) jmax - (
double) jmin));
878 for (
int l = 0; l < lmax; l++)
879 for (
int m = 0; m < mmax; m++) {
882 if (kx[l] == 0 || fabs(kx[l]) > kx_ny ||
883 ky[m] == 0 || fabs(ky[m]) > ky_ny) {
891 for (
int i = imin; i <= imax; i++)
892 for (
int j = jmin; j <= jmax; j++)
893 if (gsl_finite(wave->
var[i][j])) {
894 a += wave->
pt[i][j] * (cx[l][i] * cy[m][j] - sx[l][i] * sy[m][j]);
895 b += wave->
pt[i][j] * (sx[l][i] * cy[m][j] + cx[l][i] * sy[m][j]);
902 A[l][m] = sqrt(gsl_pow_2(a) + gsl_pow_2(b));
903 phi[l][m] = atan2(b, a) * 180. / M_PI;
908 for (
int l = 0; l < lmax; l++)
909 for (
int m = 0; m < mmax; m++)
910 if (gsl_finite(A[l][m]) && A[l][m] > *Amax) {
918 *lhmax = 2 * M_PI / sqrt(gsl_pow_2(*kxmax) + gsl_pow_2(*kymax));
921 *alphamax = 90. - 180. / M_PI * atan2(*kxmax, *kymax);
927 atan2(wave->
lat[wave->
nx / 2 >
928 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
929 - wave->
lat[wave->
nx / 2 <
930 wave->
nx - 1 ? wave->
nx / 2 +
931 1 : wave->
nx / 2][wave->
ny / 2],
932 wave->
lon[wave->
nx / 2 >
933 0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
934 - wave->
lon[wave->
nx / 2 <
935 wave->
nx - 1 ? wave->
nx / 2 +
936 1 : wave->
nx / 2][wave->
ny / 2]);
939 if (filename != NULL) {
942 LOG(1,
"Write periodogram data: %s", filename);
946 if (!(out = fopen(filename,
"w")))
947 ERRMSG(
"Cannot create file!");
951 "# $1 = altitude [km]\n"
952 "# $2 = wavelength in x-direction [km]\n"
953 "# $3 = wavelength in y-direction [km]\n"
954 "# $4 = wavenumber in x-direction [1/km]\n"
955 "# $5 = wavenumber in y-direction [1/km]\n"
956 "# $6 = amplitude [K]\n" "# $7 = phase [rad]\n");
959 for (
int l = 0; l < lmax; l++) {
961 for (
int m = 0; m < mmax; m++)
962 fprintf(out,
"%g %g %g %g %g %g %g\n", wave->
z,
963 (kx[l] != 0 ? 2 * M_PI / kx[l] : 0),
964 (ky[m] != 0 ? 2 * M_PI / ky[m] : 0),
965 kx[l], ky[m], A[l][m], phi[l][m]);
987 track0 = GSL_MIN(GSL_MAX(track0, 0), pert->
ntrack - 1);
988 track1 = GSL_MIN(GSL_MAX(track1, 0), pert->
ntrack - 1);
989 xtrack0 = GSL_MIN(GSL_MAX(xtrack0, 0), pert->
nxtrack - 1);
990 xtrack1 = GSL_MIN(GSL_MAX(xtrack1, 0), pert->
nxtrack - 1);
993 wave->
nx = xtrack1 - xtrack0 + 1;
995 ERRMSG(
"Too many across-track values!");
996 wave->
ny = track1 - track0 + 1;
998 ERRMSG(
"Too many along-track values!");
1001 for (
int itrack = track0; itrack <= track1; itrack++)
1002 for (
int ixtrack = xtrack0; ixtrack <= xtrack1; ixtrack++) {
1005 if (itrack == track0) {
1007 if (ixtrack > xtrack0) {
1009 pert->
lat[itrack][ixtrack - 1], x0);
1011 pert->
lat[itrack][ixtrack], x1);
1012 wave->
x[ixtrack - xtrack0] =
1013 wave->
x[ixtrack - xtrack0 - 1] +
DIST(x0, x1);
1016 if (ixtrack == xtrack0) {
1018 if (itrack > track0) {
1020 pert->
lat[itrack - 1][ixtrack], x0);
1022 pert->
lat[itrack][ixtrack], x1);
1023 wave->
y[itrack - track0] =
1024 wave->
y[itrack - track0 - 1] +
DIST(x0, x1);
1029 wave->
time = pert->
time[(track0 + track1) / 2][(xtrack0 + xtrack1) / 2];
1031 wave->
lon[ixtrack - xtrack0][itrack - track0] =
1032 pert->
lon[itrack][ixtrack];
1033 wave->
lat[ixtrack - xtrack0][itrack - track0] =
1034 pert->
lat[itrack][ixtrack];
1037 wave->
temp[ixtrack - xtrack0][itrack - track0]
1038 = pert->
bt[itrack][ixtrack];
1039 wave->
bg[ixtrack - xtrack0][itrack - track0]
1040 = pert->
bt[itrack][ixtrack] - pert->
pt[itrack][ixtrack];
1041 wave->
pt[ixtrack - xtrack0][itrack - track0]
1042 = pert->
pt[itrack][ixtrack];
1043 wave->
var[ixtrack - xtrack0][itrack - track0]
1044 = pert->
var[itrack][ixtrack];
1056 int ncid, varid, dimid;
1061 LOG(1,
"Read CrIS Level-1B file: %s", filename);
1064 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
1065 WARN(
"Cannot open file!");
1070 NC(nc_inq_dimid(ncid,
"atrack", &dimid));
1071 NC(nc_inq_dimlen(ncid, dimid, &n));
1073 ERRMSG(
"Level-1B file dimension mismatch!");
1075 NC(nc_inq_dimid(ncid,
"xtrack", &dimid));
1076 NC(nc_inq_dimlen(ncid, dimid, &n));
1078 ERRMSG(
"Level-1B file dimension mismatch!");
1080 NC(nc_inq_dimid(ncid,
"fov", &dimid));
1081 NC(nc_inq_dimlen(ncid, dimid, &n));
1083 ERRMSG(
"Level-1B file dimension mismatch!");
1085 NC(nc_inq_dimid(ncid,
"wnum_lw", &dimid));
1086 NC(nc_inq_dimlen(ncid, dimid, &n));
1088 ERRMSG(
"Level-1B file dimension mismatch!");
1090 NC(nc_inq_dimid(ncid,
"wnum_mw", &dimid));
1091 NC(nc_inq_dimlen(ncid, dimid, &n));
1093 ERRMSG(
"Level-1B file dimension mismatch!");
1095 NC(nc_inq_dimid(ncid,
"wnum_sw", &dimid));
1096 NC(nc_inq_dimlen(ncid, dimid, &n));
1098 ERRMSG(
"Level-1B file dimension mismatch!");
1101 NC(nc_inq_varid(ncid,
"obs_time_tai93", &varid));
1102 NC(nc_get_var_double(ncid, varid, l1->
time[0]));
1103 NC(nc_inq_varid(ncid,
"lon", &varid));
1104 NC(nc_get_var_double(ncid, varid, l1->
lon[0][0]));
1105 NC(nc_inq_varid(ncid,
"lat", &varid));
1106 NC(nc_get_var_double(ncid, varid, l1->
lat[0][0]));
1107 NC(nc_inq_varid(ncid,
"sat_alt", &varid));
1108 NC(nc_get_var_double(ncid, varid, l1->
sat_z));
1109 NC(nc_inq_varid(ncid,
"subsat_lon", &varid));
1110 NC(nc_get_var_double(ncid, varid, l1->
sat_lon));
1111 NC(nc_inq_varid(ncid,
"subsat_lat", &varid));
1112 NC(nc_get_var_double(ncid, varid, l1->
sat_lat));
1115 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1116 l1->
sat_z[itrack] /= 1e3;
1119 NC(nc_inq_varid(ncid,
"wnum_lw", &varid));
1120 NC(nc_get_var_double(ncid, varid, l1->
nu_lw));
1121 NC(nc_inq_varid(ncid,
"rad_lw", &varid));
1122 NC(nc_get_var_float(ncid, varid, l1->
rad_lw[0][0][0]));
1123 NC(nc_inq_varid(ncid,
"wnum_mw", &varid));
1124 NC(nc_get_var_double(ncid, varid, l1->
nu_mw));
1125 NC(nc_inq_varid(ncid,
"rad_mw", &varid));
1126 NC(nc_get_var_float(ncid, varid, l1->
rad_mw[0][0][0]));
1127 NC(nc_inq_varid(ncid,
"wnum_sw", &varid));
1128 NC(nc_get_var_double(ncid, varid, l1->
nu_sw));
1129 NC(nc_inq_varid(ncid,
"rad_sw", &varid));
1130 NC(nc_get_var_float(ncid, varid, l1->
rad_sw[0][0][0]));
1133 NC(nc_inq_varid(ncid,
"nedn_lw", &varid));
1134 NC(nc_get_var_float(ncid, varid, l1->
nedn_lw[0]));
1135 NC(nc_inq_varid(ncid,
"nedn_mw", &varid));
1136 NC(nc_get_var_float(ncid, varid, l1->
nedn_mw[0]));
1137 NC(nc_inq_varid(ncid,
"nedn_sw", &varid));
1138 NC(nc_get_var_float(ncid, varid, l1->
nedn_sw[0]));
1141 NC(nc_inq_varid(ncid,
"rad_lw_qc", &varid));
1142 NC(nc_get_var_short(ncid, varid, l1->
qual_lw[0][0]));
1143 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1144 for (
int ixtrack = 0; ixtrack <
L1_NXTRACK; ixtrack++)
1145 for (
int ifov = 0; ifov <
L1_NFOV; ifov++)
1146 if (l1->
qual_lw[itrack][ixtrack][ifov] > 1)
1148 l1->
rad_lw[itrack][ixtrack][ifov][ichan] = GSL_NAN;
1150 NC(nc_inq_varid(ncid,
"rad_mw_qc", &varid));
1151 NC(nc_get_var_short(ncid, varid, l1->
qual_mw[0][0]));
1152 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1153 for (
int ixtrack = 0; ixtrack <
L1_NXTRACK; ixtrack++)
1154 for (
int ifov = 0; ifov <
L1_NFOV; ifov++)
1155 if (l1->
qual_mw[itrack][ixtrack][ifov] > 1)
1157 l1->
rad_mw[itrack][ixtrack][ifov][ichan] = GSL_NAN;
1159 NC(nc_inq_varid(ncid,
"rad_sw_qc", &varid));
1160 NC(nc_get_var_short(ncid, varid, l1->
qual_sw[0][0]));
1161 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1162 for (
int ixtrack = 0; ixtrack <
L1_NXTRACK; ixtrack++)
1163 for (
int ifov = 0; ifov <
L1_NFOV; ifov++)
1164 if (l1->
qual_sw[itrack][ixtrack][ifov] > 1)
1166 l1->
rad_sw[itrack][ixtrack][ifov][ichan] = GSL_NAN;
1170 for (
int itrack = 0; itrack <
L1_NTRACK; itrack++)
1171 for (
int ixtrack = 0; ixtrack <
L1_NXTRACK; ixtrack++)
1172 for (
int ifov = 0; ifov <
L1_NFOV; ifov++) {
1177 for (
int ichan = 1; ichan <
L1_NCHAN_LW - 1; ichan++)
1179 = 0.23 * l1->
rad_lw[itrack][ixtrack][ifov][ichan - 1]
1180 + 0.54 * l1->
rad_lw[itrack][ixtrack][ifov][ichan]
1181 + 0.23 * l1->
rad_lw[itrack][ixtrack][ifov][ichan + 1];
1182 for (
int ichan = 1; ichan <
L1_NCHAN_LW - 1; ichan++)
1183 l1->
rad_lw[itrack][ixtrack][ifov][ichan] = (
float) help[ichan];
1184 l1->
rad_lw[itrack][ixtrack][ifov][0] =
1189 for (
int ichan = 1; ichan <
L1_NCHAN_MW - 1; ichan++)
1191 = 0.23 * l1->
rad_mw[itrack][ixtrack][ifov][ichan - 1]
1192 + 0.54 * l1->
rad_mw[itrack][ixtrack][ifov][ichan]
1193 + 0.23 * l1->
rad_mw[itrack][ixtrack][ifov][ichan + 1];
1194 for (
int ichan = 1; ichan <
L1_NCHAN_MW - 1; ichan++)
1195 l1->
rad_mw[itrack][ixtrack][ifov][ichan] = (
float) help[ichan];
1196 l1->
rad_mw[itrack][ixtrack][ifov][0] =
1201 for (
int ichan = 1; ichan <
L1_NCHAN_SW - 1; ichan++)
1203 = 0.23 * l1->
rad_sw[itrack][ixtrack][ifov][ichan - 1]
1204 + 0.54 * l1->
rad_sw[itrack][ixtrack][ifov][ichan]
1205 + 0.23 * l1->
rad_sw[itrack][ixtrack][ifov][ichan + 1];
1206 for (
int ichan = 1; ichan <
L1_NCHAN_SW - 1; ichan++)
1207 l1->
rad_sw[itrack][ixtrack][ifov][ichan] = (
float) help[ichan];
1208 l1->
rad_sw[itrack][ixtrack][ifov][0] =
1227 static char varname[
LEN];
1231 static int dimid[3], ncid, varid;
1233 static size_t ntrack, nxtrack, nfov, start[3] = { 0, 0, 0 }, count[3] =
1237 LOG(1,
"Read perturbation data: %s", filename);
1240 NC(nc_open(filename, NC_NOWRITE, &ncid));
1243 NC(nc_inq_dimid(ncid,
"NTRACK", &dimid[0]));
1244 NC(nc_inq_dimlen(ncid, dimid[0], &ntrack));
1246 ERRMSG(
"Too many scans!");
1248 NC(nc_inq_dimid(ncid,
"NXTRACK", &dimid[1]));
1249 NC(nc_inq_dimlen(ncid, dimid[1], &nxtrack));
1251 ERRMSG(
"Too many tracks!");
1253 NC(nc_inq_dimid(ncid,
"NFOV", &dimid[2]));
1254 NC(nc_inq_dimlen(ncid, dimid[2], &nfov));
1256 ERRMSG(
"Too many field of views!");
1258 pert->
ntrack = (int) ntrack;
1259 pert->
nxtrack = (int) nxtrack;
1260 pert->
nfov = (int) nfov;
1264 NC(nc_inq_varid(ncid,
"time", &varid));
1265 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1266 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1269 NC(nc_get_vara_double
1270 (ncid, varid, start, count, pert->
time[itrack][ixtrack]));
1273 NC(nc_inq_varid(ncid,
"lon", &varid));
1274 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1275 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1278 NC(nc_get_vara_double
1279 (ncid, varid, start, count, pert->
lon[itrack][ixtrack]));
1282 NC(nc_inq_varid(ncid,
"lat", &varid));
1283 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1284 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1287 NC(nc_get_vara_double
1288 (ncid, varid, start, count, pert->
lat[itrack][ixtrack]));
1291 NC(nc_inq_varid(ncid,
"bt_8mu", &varid));
1292 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1293 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1296 NC(nc_get_vara_double
1297 (ncid, varid, start, count, pert->
dc[itrack][ixtrack]));
1300 NC(nc_inq_varid(ncid,
"bt_10mu", &varid));
1301 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1302 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1305 NC(nc_get_vara_double
1306 (ncid, varid, start, count, help[itrack][ixtrack]));
1309 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1310 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++)
1311 for (
size_t ifov = 0; ifov < nfov; ifov++)
1313 || (dc == 0 && !gsl_finite(pert->
dc[itrack][ixtrack][ifov])))
1314 pert->
dc[itrack][ixtrack][ifov] = help[itrack][ixtrack][ifov];
1316 sprintf(varname,
"bt_%s", pertname);
1317 NC(nc_inq_varid(ncid, varname, &varid));
1318 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1319 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1322 NC(nc_get_vara_double
1323 (ncid, varid, start, count, pert->
bt[itrack][ixtrack]));
1326 sprintf(varname,
"bt_%s_pt", pertname);
1327 NC(nc_inq_varid(ncid, varname, &varid));
1328 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1329 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1332 NC(nc_get_vara_double
1333 (ncid, varid, start, count, pert->
pt[itrack][ixtrack]));
1336 sprintf(varname,
"bt_%s_var", pertname);
1337 NC(nc_inq_varid(ncid, varname, &varid));
1338 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1339 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1342 NC(nc_get_vara_double
1343 (ncid, varid, start, count, pert->
var[itrack][ixtrack]));
1356 static double help[
NDS *
NPG];
1358 int dimid, ids, ncid, varid;
1360 size_t nds, np, ntrack, nxtrack;
1363 LOG(1,
"Read retrieval data: %s", filename);
1366 NC(nc_open(filename, NC_NOWRITE, &ncid));
1369 if (nc_inq_dimid(ncid,
"L1_NTRACK", &dimid) == NC_NOERR) {
1372 NC(nc_inq_dimid(ncid,
"RET_NP", &dimid));
1373 NC(nc_inq_dimlen(ncid, dimid, &np));
1376 ERRMSG(
"Too many data points!");
1378 NC(nc_inq_dimid(ncid,
"L1_NTRACK", &dimid));
1379 NC(nc_inq_dimlen(ncid, dimid, &ntrack));
1380 NC(nc_inq_dimid(ncid,
"L1_NXTRACK", &dimid));
1381 NC(nc_inq_dimlen(ncid, dimid, &nxtrack));
1382 ret->
nds = (int) (ntrack * nxtrack);
1384 ERRMSG(
"Too many data sets!");
1387 NC(nc_inq_varid(ncid,
"l1_time", &varid));
1388 NC(nc_get_var_double(ncid, varid, help));
1390 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1391 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1392 for (
int ip = 0; ip < ret->
np; ip++)
1393 ret->
time[ids][ip] = help[ids];
1398 NC(nc_inq_varid(ncid,
"ret_z", &varid));
1399 NC(nc_get_var_double(ncid, varid, help));
1401 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1402 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1403 for (
int ip = 0; ip < ret->
np; ip++)
1404 ret->
z[ids][ip] = help[ip];
1409 NC(nc_inq_varid(ncid,
"l1_lon", &varid));
1410 NC(nc_get_var_double(ncid, varid, help));
1412 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1413 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1414 for (
int ip = 0; ip < ret->
np; ip++)
1415 ret->
lon[ids][ip] = help[ids];
1420 NC(nc_inq_varid(ncid,
"l1_lat", &varid));
1421 NC(nc_get_var_double(ncid, varid, help));
1423 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1424 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1425 for (
int ip = 0; ip < ret->
np; ip++)
1426 ret->
lat[ids][ip] = help[ids];
1431 NC(nc_inq_varid(ncid,
"ret_temp", &varid));
1432 NC(nc_get_var_double(ncid, varid, help));
1434 for (
size_t itrack = 0; itrack < ntrack; itrack++)
1435 for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
1436 for (
int ip = 0; ip < ret->
np; ip++)
1438 help[(itrack * nxtrack + ixtrack) * (size_t) np + (
size_t) ip];
1444 if (nc_inq_dimid(ncid,
"np", &dimid) == NC_NOERR) {
1447 NC(nc_inq_dimid(ncid,
"np", &dimid));
1448 NC(nc_inq_dimlen(ncid, dimid, &np));
1451 ERRMSG(
"Too many data points!");
1453 NC(nc_inq_dimid(ncid,
"nds", &dimid));
1454 NC(nc_inq_dimlen(ncid, dimid, &nds));
1455 ret->
nds = (int) nds;
1457 ERRMSG(
"Too many data sets!");
1460 NC(nc_inq_varid(ncid,
"time", &varid));
1461 NC(nc_get_var_double(ncid, varid, help));
1464 NC(nc_inq_varid(ncid,
"z", &varid));
1465 NC(nc_get_var_double(ncid, varid, help));
1468 NC(nc_inq_varid(ncid,
"lon", &varid));
1469 NC(nc_get_var_double(ncid, varid, help));
1472 NC(nc_inq_varid(ncid,
"lat", &varid));
1473 NC(nc_get_var_double(ncid, varid, help));
1476 NC(nc_inq_varid(ncid,
"press", &varid));
1477 NC(nc_get_var_double(ncid, varid, help));
1480 NC(nc_inq_varid(ncid,
"temp", &varid));
1481 NC(nc_get_var_double(ncid, varid, help));
1484 NC(nc_inq_varid(ncid,
"temp_apr", &varid));
1485 NC(nc_get_var_double(ncid, varid, help));
1488 NC(nc_inq_varid(ncid,
"temp_total", &varid));
1489 NC(nc_get_var_double(ncid, varid, help));
1492 NC(nc_inq_varid(ncid,
"temp_noise", &varid));
1493 NC(nc_get_var_double(ncid, varid, help));
1496 NC(nc_inq_varid(ncid,
"temp_formod", &varid));
1497 NC(nc_get_var_double(ncid, varid, help));
1500 NC(nc_inq_varid(ncid,
"temp_cont", &varid));
1501 NC(nc_get_var_double(ncid, varid, help));
1504 NC(nc_inq_varid(ncid,
"temp_res", &varid));
1505 NC(nc_get_var_double(ncid, varid, help));
1508 NC(nc_inq_varid(ncid,
"chisq", &varid));
1509 NC(nc_get_var_double(ncid, varid, ret->
chisq));
1526 for (
int ip = 0; ip < np; ip++)
1527 for (
int ids = 0; ids < nds; ids++)
1528 mat[ids][ip] = help[n++];
1541 double rtime, rz, rlon, rlat, rx, ry, ryold = -1e10,
1542 rtemp, rbg, rpt, rvar, rfit;
1549 LOG(1,
"Read wave data: %s", filename);
1552 if (!(in = fopen(filename,
"r")))
1553 ERRMSG(
"Cannot open file!");
1556 while (fgets(line,
LEN, in))
1557 if (sscanf(line,
"%lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg", &rtime,
1558 &rz, &rlon, &rlat, &rx, &ry, &rtemp, &rbg, &rpt,
1559 &rvar, &rfit) == 11) {
1563 if ((++wave->
ny >=
WY))
1564 ERRMSG(
"Too many y-values!");
1566 }
else if ((++wave->
nx) >=
WX)
1567 ERRMSG(
"Too many x-values!");
1573 wave->
lon[wave->
nx][wave->
ny] = rlon;
1574 wave->
lat[wave->
nx][wave->
ny] = rlat;
1575 wave->
x[wave->
nx] = rx;
1576 wave->
y[wave->
ny] = ry;
1577 wave->
temp[wave->
nx][wave->
ny] = rtemp;
1578 wave->
bg[wave->
nx][wave->
ny] = rbg;
1579 wave->
pt[wave->
nx][wave->
ny] = rpt;
1580 wave->
var[wave->
nx][wave->
ny] = rvar;
1581 wave->
var[wave->
nx][wave->
ny] = rfit;
1600 double x0[3], x1[3];
1605 ERRMSG(
"Too many across-track values!");
1608 ERRMSG(
"Too many along-track values!");
1609 if (ip < 0 || ip >= ret->
np)
1610 ERRMSG(
"Altitude index out of range!");
1613 for (
int ids = 0; ids < ret->
nds; ids++) {
1623 wave->
x[ix] =
DIST(x0, x1);
1628 wave->
y[iy] =
DIST(x0, x1);
1633 if (ix == 0 && iy == 0)
1634 wave->
z = ret->
z[ids][ip];
1635 wave->
lon[ix][iy] = ret->
lon[ids][ip];
1636 wave->
lat[ix][iy] = ret->
lat[ids][ip];
1640 wave->
temp[ix][iy] = ret->
t[ids][ip];
1641 else if (dataset == 2)
1642 wave->
temp[ix][iy] = ret->
t_apr[ids][ip];
1657 const double dh2 = gsl_pow_2(dh);
1661 (int) (dh / fabs(wave->
x[wave->
nx - 1] - wave->
x[0]) * (wave->
nx - 1.0) +
1664 (int) (dh / fabs(wave->
y[wave->
ny - 1] - wave->
y[0]) * (wave->
ny - 1.0) +
1668 for (
int ix = 0; ix < wave->
nx; ix++)
1669 for (
int iy = 0; iy < wave->
ny; iy++) {
1672 double mu = 0, help = 0;
1676 for (
int ix2 = GSL_MAX(ix - dx, 0);
1677 ix2 <= GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
1678 for (
int iy2 = GSL_MAX(iy - dy, 0);
1679 iy2 <= GSL_MIN(iy + dy, wave->
ny - 1); iy2++)
1680 if ((gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
1681 + gsl_pow_2(wave->
y[iy] - wave->
y[iy2])) <= dh2)
1682 if (gsl_finite(wave->
pt[ix2][iy2])) {
1683 mu += wave->
pt[ix2][iy2];
1684 help += gsl_pow_2(wave->
pt[ix2][iy2]);
1690 wave->
var[ix][iy] = help / n - gsl_pow_2(mu / n);
1692 wave->
var[ix][iy] = GSL_NAN;
1705 LOG(1,
"Write wave data: %s", filename);
1708 if (!(out = fopen(filename,
"w")))
1709 ERRMSG(
"Cannot create file!");
1713 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
1714 "# $2 = altitude [km]\n"
1715 "# $3 = longitude [deg]\n"
1716 "# $4 = latitude [deg]\n"
1717 "# $5 = across-track distance [km]\n"
1718 "# $6 = along-track distance [km]\n"
1719 "# $7 = temperature [K]\n"
1720 "# $8 = background [K]\n"
1721 "# $9 = perturbation [K]\n"
1722 "# $10 = variance [K^2]\n" "# $11 = fitting model [K]\n");
1725 for (
int j = 0; j < wave->
ny; j++) {
1727 for (
int i = 0; i < wave->
nx; i++)
1728 fprintf(out,
"%.2f %g %g %g %g %g %g %g %g %g %g\n",
1729 wave->
time, wave->
z, wave->
lon[i][j], wave->
lat[i][j],
1730 wave->
x[i], wave->
y[j], wave->
temp[i][j], wave->
bg[i][j],
1731 wave->
pt[i][j], wave->
var[i][j], wave->
fit[i][j]);
void cart2geo(const double *x, double *z, double *lon, double *lat)
Converts Cartesian coordinates to geographic coordinates.
void geo2cart(const double z, const double lon, const double lat, double *x)
Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.
#define LEN
Maximum length of ASCII data lines.
#define POW2(x)
Compute the square of a value.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define WARN(...)
Print a warning message with contextual information.
#define LOG(level,...)
Print a log message with a specified logging level.
#define DIST(a, b)
Compute Cartesian distance between two 3D vectors.
#define LIN(x0, y0, x1, y1, x)
Compute linear interpolation.
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 ret2wave(retr_t *ret, wave_t *wave, int dataset, int ip)
Convert CrIS retrieval results to wave analysis struct.
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 read_retr(char *filename, retr_t *ret)
Read CrIS retrieval data.
void add_att(const int ncid, const int varid, const char *unit, const char *long_name)
Add variable attributes to netCDF file.
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.
#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 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].