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];
 
  311    { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
 
  313    { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
 
  316  if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
 
  317    *doy = d0l[mon - 1] + day - 1;
 
  319    *doy = d0[mon - 1] + day - 1;
 
  331    { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
 
  333    { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
 
  337  if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
 
  338    for (i = 11; i >= 0; i--)
 
  342    *day = doy - d0l[i] + 1;
 
  344    for (i = 11; i >= 0; i--)
 
  348    *day = doy - d0[i] + 1;
 
  366  for (
int ix = 0; ix < wave->
nx; ix++)
 
  367    for (
int iy = 0; iy < wave->
ny; iy++) {
 
  369        = amp * cos(kx * wave->
x[ix] + ky * wave->
y[iy]
 
  370                    - phi * M_PI / 180.);
 
  371      *chisq += POW2(wave->
fit[ix][iy] - wave->
pt[ix][iy]);
 
  375  *chisq /= (double) (wave->
nx * wave->
ny);
 
  385  double data[2 * 
PMAX];
 
  389    ERRMSG(
"Too many data points!");
 
  392  gsl_fft_complex_wavetable *wavetable
 
  393    = gsl_fft_complex_wavetable_alloc((
size_t) n);
 
  394  gsl_fft_complex_workspace *workspace
 
  395    = gsl_fft_complex_workspace_alloc((
size_t) n);
 
  398  for (
int i = 0; i < n; i++) {
 
  399    data[2 * i] = fcReal[i];
 
  400    data[2 * i + 1] = fcImag[i];
 
  404  gsl_fft_complex_forward(data, 1, (
size_t) n, wavetable, workspace);
 
  407  for (
int i = 0; i < n; i++) {
 
  408    fcReal[i] = data[2 * i];
 
  409    fcImag[i] = data[2 * i + 1];
 
  413  gsl_fft_complex_wavetable_free(wavetable);
 
  414  gsl_fft_complex_workspace_free(workspace);
 
  434  int imin = 9999, jmin = 9999;
 
  435  int imax = -9999, jmax = -9999;
 
  436  for (
int i = 0; i < wave->
nx; i++)
 
  437    for (
int j = 0; j < wave->
ny; j++)
 
  438      if (gsl_finite(wave->
var[i][j])) {
 
  439        imin = GSL_MIN(imin, i);
 
  440        imax = GSL_MAX(imax, i);
 
  441        jmin = GSL_MIN(jmin, j);
 
  442        jmax = GSL_MAX(jmax, j);
 
  444  const int nx = imax - imin + 1;
 
  445  const int ny = jmax - jmin + 1;
 
  448  for (
int i = imin; i <= imax; i++)
 
  449    for (
int j = jmin; j <= jmax; j++) {
 
  450      if (gsl_finite(wave->
pt[i][j]))
 
  451        boxReal[i - imin][j - jmin] = wave->
pt[i][j];
 
  453        boxReal[i - imin][j - jmin] = 0.0;
 
  454      boxImag[i - imin][j - jmin] = 0.0;
 
  458  for (
int i = 0; i < nx; i++) {
 
  459    for (
int j = 0; j < ny; j++) {
 
  460      cutReal[j] = boxReal[i][j];
 
  461      cutImag[j] = boxImag[i][j];
 
  464    for (
int j = 0; j < ny; j++) {
 
  465      boxReal[i][j] = cutReal[j];
 
  466      boxImag[i][j] = cutImag[j];
 
  471  for (
int j = 0; j < ny; j++) {
 
  472    for (
int i = 0; i < nx; i++) {
 
  473      cutReal[i] = boxReal[i][j];
 
  474      cutImag[i] = boxImag[i][j];
 
  477    for (
int i = 0; i < nx; i++) {
 
  478      boxReal[i][j] = cutReal[i];
 
  479      boxImag[i][j] = cutImag[i];
 
  484  for (
int i = 0; i < nx; i++)
 
  485    kx[i] = 2. * M_PI * ((i < nx / 2) ? (
double) i : -(
double) (nx - i))
 
  486      / (nx * fabs(wave->
x[imax] - wave->
x[imin]) / (nx - 1.0));
 
  487  for (
int j = 0; j < ny; j++)
 
  488    ky[j] = 2. * M_PI * ((j < ny / 2) ? (double) j : -(
double) (ny - j))
 
  489      / (ny * fabs(wave->
y[jmax] - wave->
y[jmin]) / (ny - 1.0));
 
  490  for (
int i = 0; i < nx; i++)
 
  491    for (
int j = 0; j < ny; j++) {
 
  493        = (i == 0 && j == 0 ? 1.0 : 2.0) / (nx * ny)
 
  494        * sqrt(gsl_pow_2(boxReal[i][j]) + gsl_pow_2(boxImag[i][j]));
 
  496        = 180. / M_PI * atan2(boxImag[i][j], boxReal[i][j]);
 
  500  for (
int i = 0; i < nx; i++)
 
  501    for (
int j = 0; j < ny; j++)
 
  502      if (kx[i] == 0 || ky[j] == 0) {
 
  509  for (
int i = 0; i < nx; i++)
 
  510    for (
int j = 0; j < ny / 2; j++)
 
  511      if (gsl_finite(A[i][j]) && A[i][j] > *Amax) {
 
  519  *lhmax = 2 * M_PI / sqrt(gsl_pow_2(*kxmax) + gsl_pow_2(*kymax));
 
  522  *alphamax = 90. - 180. / M_PI * atan2(*kxmax, *kymax);
 
  528    atan2(wave->
lat[wave->
nx / 2 >
 
  529                    0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
 
  530          - wave->
lat[wave->
nx / 2 <
 
  531                      wave->
nx - 1 ? wave->
nx / 2 +
 
  532                      1 : wave->
nx / 2][wave->
ny / 2],
 
  533          wave->
lon[wave->
nx / 2 >
 
  534                    0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
 
  535          - wave->
lon[wave->
nx / 2 <
 
  536                      wave->
nx - 1 ? wave->
nx / 2 +
 
  537                      1 : wave->
nx / 2][wave->
ny / 2]);
 
  540  if (filename != NULL) {
 
  543    printf(
"Write FFT data: %s\n", filename);
 
  547    if (!(out = fopen(filename, 
"w")))
 
  548      ERRMSG(
"Cannot create file!");
 
  552            "# $1 = altitude [km]\n" 
  553            "# $2 = wavelength in x-direction [km]\n" 
  554            "# $3 = wavelength in y-direction [km]\n" 
  555            "# $4 = wavenumber in x-direction [1/km]\n" 
  556            "# $5 = wavenumber in y-direction [1/km]\n" 
  557            "# $6 = amplitude [K]\n" "# $7 = phase [rad]\n");
 
  560    for (
int i = nx - 1; i > 0; i--) {
 
  562      for (
int j = ny / 2; j > 0; j--) {
 
  563        int i2 = (i == nx / 2 ? 0 : i);
 
  564        int j2 = (j == ny / 2 ? 0 : j);
 
  565        fprintf(out, 
"%g %g %g %g %g %g %g\n", wave->
z,
 
  566                (kx[i2] != 0 ? 2 * M_PI / kx[i2] : 0),
 
  567                (ky[j2] != 0 ? 2 * M_PI / ky[j2] : 0),
 
  568                kx[i2], ky[j2], A[i2][j2], phi[i2][j2]);
 
  583  static double help[
WX][
WY];
 
  590  const double sigma2 = gsl_pow_2(fwhm / 2.3548);
 
  593  for (
int ix = 0; ix < wave->
nx; ix++)
 
  594    for (
int iy = 0; iy < wave->
ny; iy++) {
 
  601      for (
int ix2 = 0; ix2 < wave->
nx; ix2++)
 
  602        for (
int iy2 = 0; iy2 < wave->
ny; iy2++) {
 
  603          const double d2 = gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
 
  604            + gsl_pow_2(wave->
y[iy] - wave->
y[iy2]);
 
  605          if (d2 <= 9 * sigma2) {
 
  606            const double w = exp(-d2 / (2 * sigma2));
 
  608            help[ix][iy] += w * wave->
pt[ix2][iy2];
 
  613      wave->
pt[ix][iy] = help[ix][iy] / wsum;
 
  623  static double help[
WX][
WY];
 
  626  for (
int iter = 0; iter < niter; iter++) {
 
  629    for (
int ix = 0; ix < wave->
nx; ix++)
 
  630      for (
int iy = 0; iy < wave->
ny; iy++)
 
  632          = 0.23 * wave->
pt[ix > 0 ? ix - 1 : ix][iy]
 
  633          + 0.54 * wave->
pt[ix][iy]
 
  634          + 0.23 * wave->
pt[ix < wave->nx - 1 ? ix + 1 : ix][iy];
 
  637    for (
int ix = 0; ix < wave->
nx; ix++)
 
  638      for (
int iy = 0; iy < wave->
ny; iy++)
 
  640          = 0.23 * help[ix][iy > 0 ? iy - 1 : iy]
 
  641          + 0.54 * help[ix][iy]
 
  642          + 0.23 * help[ix][iy < wave->ny - 1 ? iy + 1 : iy];
 
  652  double dummy, x[
WX], xc[
WX][3], xc2[
WX][3], y[
WX];
 
  658    ERRMSG(
"Too many data points!");
 
  661  for (
int i = 0; i < n; i++)
 
  662    x[i] = LIN(0.0, wave->
x[0], n - 1.0, wave->
x[wave->
nx - 1], i);
 
  665  gsl_interp_accel *acc = gsl_interp_accel_alloc();
 
  667    = gsl_spline_alloc(gsl_interp_cspline, (
size_t) wave->
nx);
 
  670  for (
int iy = 0; iy < wave->
ny; iy++) {
 
  673    for (
int ix = 0; ix < wave->
nx; ix++)
 
  674      geo2cart(0, wave->
lon[ix][iy], wave->
lat[ix][iy], xc[ix]);
 
  675    for (
int ic = 0; ic < 3; ic++) {
 
  676      for (
int ix = 0; ix < wave->
nx; ix++)
 
  678      gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
 
  679      for (
int i = 0; i < n; i++)
 
  680        xc2[i][ic] = gsl_spline_eval(spline, x[i], acc);
 
  682    for (
int i = 0; i < n; i++)
 
  683      cart2geo(xc2[i], &dummy, &wave->
lon[i][iy], &wave->
lat[i][iy]);
 
  686    for (
int ix = 0; ix < wave->
nx; ix++)
 
  687      y[ix] = wave->
temp[ix][iy];
 
  688    gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
 
  689    for (
int i = 0; i < n; i++)
 
  690      wave->
temp[i][iy] = gsl_spline_eval(spline, x[i], acc);
 
  693    for (
int ix = 0; ix < wave->
nx; ix++)
 
  694      y[ix] = wave->
bg[ix][iy];
 
  695    gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
 
  696    for (
int i = 0; i < n; i++)
 
  697      wave->
bg[i][iy] = gsl_spline_eval(spline, x[i], acc);
 
  700    for (
int ix = 0; ix < wave->
nx; ix++)
 
  701      y[ix] = wave->
pt[ix][iy];
 
  702    gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
 
  703    for (
int i = 0; i < n; i++)
 
  704      wave->
pt[i][iy] = gsl_spline_eval(spline, x[i], acc);
 
  707    for (
int ix = 0; ix < wave->
nx; ix++)
 
  708      y[ix] = wave->
var[ix][iy];
 
  709    gsl_spline_init(spline, wave->
x, y, (
size_t) wave->
nx);
 
  710    for (
int i = 0; i < n; i++)
 
  711      wave->
var[i][iy] = gsl_spline_eval(spline, x[i], acc);
 
  715  gsl_spline_free(spline);
 
  716  gsl_interp_accel_free(acc);
 
  719  for (
int i = 0; i < n; i++)
 
  730  static double data[
WX * 
WY], help[
WX][
WY];
 
  737  for (
int ix = 0; ix < wave->
nx; ix++)
 
  738    for (
int iy = 0; iy < wave->
ny; iy++) {
 
  744      for (
int ix2 = GSL_MAX(ix - dx, 0);
 
  745           ix2 < GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
 
  746        for (
int iy2 = GSL_MAX(iy - dx, 0);
 
  747             iy2 < GSL_MIN(iy + dx, wave->
ny - 1); iy2++) {
 
  748          data[n] = wave->
pt[ix2][iy2];
 
  753      gsl_sort(data, 1, n);
 
  754      help[ix][iy] = gsl_stats_median_from_sorted_data(data, 1, n);
 
  758  for (
int ix = 0; ix < wave->
nx; ix++)
 
  759    for (
int iy = 0; iy < wave->
ny; iy++)
 
  760      wave->
pt[ix][iy] = help[ix][iy];
 
  770  if (wave1->
nx != wave2->
nx)
 
  771    ERRMSG(
"Across-track sizes do not match!");
 
  772  if (wave1->
ny + wave2->
ny > 
WY)
 
  773    ERRMSG(
"Too many data points!");
 
  777    wave1->
y[wave1->
ny - 1] + (wave1->
y[wave1->
ny - 1] -
 
  778                               wave1->
y[0]) / (wave1->
ny - 1);
 
  781  for (
int ix = 0; ix < wave2->
nx; ix++)
 
  782    for (
int iy = 0; iy < wave2->
ny; iy++) {
 
  783      wave1->
y[wave1->
ny + iy] = y + wave2->
y[iy];
 
  784      wave1->
lon[ix][wave1->
ny + iy] = wave2->
lon[ix][iy];
 
  785      wave1->
lat[ix][wave1->
ny + iy] = wave2->
lat[ix][iy];
 
  786      wave1->
temp[ix][wave1->
ny + iy] = wave2->
temp[ix][iy];
 
  787      wave1->
bg[ix][wave1->
ny + iy] = wave2->
bg[ix][iy];
 
  788      wave1->
pt[ix][wave1->
ny + iy] = wave2->
pt[ix][iy];
 
  789      wave1->
var[ix][wave1->
ny + iy] = wave2->
var[ix][iy];
 
  793  wave1->
ny += wave2->
ny;
 
  809  for (
int ix = 1; ix < wave->
nx - 1; ix++)
 
  810    for (
int iy = 1; iy < wave->
ny - 1; iy++) {
 
  814      for (
int ix2 = ix - 1; ix2 <= ix + 1; ix2++)
 
  815        for (
int iy2 = iy - 1; iy2 <= iy + 1; iy2++)
 
  816          if (!gsl_finite(wave->
temp[ix2][iy2]))
 
  823      *mu += wave->
temp[ix][iy];
 
  824      *sig += gsl_pow_2(+4. / 6. * wave->
temp[ix][iy]
 
  825                        - 2. / 6. * (wave->
temp[ix - 1][iy]
 
  826                                     + wave->
temp[ix + 1][iy]
 
  827                                     + wave->
temp[ix][iy - 1]
 
  828                                     + wave->
temp[ix][iy + 1])
 
  829                        + 1. / 6. * (wave->
temp[ix - 1][iy - 1]
 
  830                                     + wave->
temp[ix + 1][iy - 1]
 
  831                                     + wave->
temp[ix - 1][iy + 1]
 
  832                                     + wave->
temp[ix + 1][iy + 1]));
 
  837  *sig = sqrt(*sig / (
double) n);
 
  860  int imin, imax, jmin, jmax, lmax = 0, mmax = 0;
 
  863  for (
double lx = -lxymax; lx <= lxymax; lx += dlxy) {
 
  864    kx[lmax] = (lx != 0 ? 2 * M_PI / lx : 0);
 
  865    for (
int i = 0; i < wave->
nx; i++) {
 
  866      cx[lmax][i] = cos(kx[lmax] * wave->
x[i]);
 
  867      sx[lmax][i] = sin(kx[lmax] * wave->
x[i]);
 
  870      ERRMSG(
"Too many wavenumbers for periodogram!");
 
  872  for (
double ly = 0; ly <= lxymax; ly += dlxy) {
 
  873    ky[mmax] = (ly != 0 ? 2 * M_PI / ly : 0);
 
  874    for (
int j = 0; j < wave->
ny; j++) {
 
  875      cy[mmax][j] = cos(ky[mmax] * wave->
y[j]);
 
  876      sy[mmax][j] = sin(ky[mmax] * wave->
y[j]);
 
  879      ERRMSG(
"Too many wavenumbers for periodogram!");
 
  885  for (
int i = 0; i < wave->
nx; i++)
 
  886    for (
int j = 0; j < wave->
ny; j++)
 
  887      if (gsl_finite(wave->
var[i][j])) {
 
  888        imin = GSL_MIN(imin, i);
 
  889        imax = GSL_MAX(imax, i);
 
  890        jmin = GSL_MIN(jmin, j);
 
  891        jmax = GSL_MAX(jmax, j);
 
  896    M_PI / fabs((wave->
x[imax] - wave->
x[imin]) /
 
  897                ((
double) imax - (
double) imin));
 
  899    M_PI / fabs((wave->
y[jmax] - wave->
y[jmin]) /
 
  900                ((
double) jmax - (
double) jmin));
 
  903  for (
int l = 0; l < lmax; l++)
 
  904    for (
int m = 0; m < mmax; m++) {
 
  907      if (kx[l] == 0 || fabs(kx[l]) > kx_ny ||
 
  908          ky[m] == 0 || fabs(ky[m]) > ky_ny) {
 
  915      double a = 0, b = 0, c = 0;
 
  916      for (
int i = imin; i <= imax; i++)
 
  917        for (
int j = jmin; j <= jmax; j++)
 
  918          if (gsl_finite(wave->
var[i][j])) {
 
  919            a += wave->
pt[i][j] * (cx[l][i] * cy[m][j] - sx[l][i] * sy[m][j]);
 
  920            b += wave->
pt[i][j] * (sx[l][i] * cy[m][j] + cx[l][i] * sy[m][j]);
 
  927      A[l][m] = sqrt(gsl_pow_2(a) + gsl_pow_2(b));
 
  928      phi[l][m] = atan2(b, a) * 180. / M_PI;
 
  933  for (
int l = 0; l < lmax; l++)
 
  934    for (
int m = 0; m < mmax; m++)
 
  935      if (gsl_finite(A[l][m]) && A[l][m] > *Amax) {
 
  943  *lhmax = 2 * M_PI / sqrt(gsl_pow_2(*kxmax) + gsl_pow_2(*kymax));
 
  946  *alphamax = 90. - 180. / M_PI * atan2(*kxmax, *kymax);
 
  952    atan2(wave->
lat[wave->
nx / 2 >
 
  953                    0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
 
  954          - wave->
lat[wave->
nx / 2 <
 
  955                      wave->
nx - 1 ? wave->
nx / 2 +
 
  956                      1 : wave->
nx / 2][wave->
ny / 2],
 
  957          wave->
lon[wave->
nx / 2 >
 
  958                    0 ? wave->
nx / 2 - 1 : wave->
nx / 2][wave->
ny / 2]
 
  959          - wave->
lon[wave->
nx / 2 <
 
  960                      wave->
nx - 1 ? wave->
nx / 2 +
 
  961                      1 : wave->
nx / 2][wave->
ny / 2]);
 
  964  if (filename != NULL) {
 
  967    printf(
"Write periodogram data: %s\n", filename);
 
  970    if (!(out = fopen(filename, 
"w")))
 
  971      ERRMSG(
"Cannot create file!");
 
  975            "# $1 = altitude [km]\n" 
  976            "# $2 = wavelength in x-direction [km]\n" 
  977            "# $3 = wavelength in y-direction [km]\n" 
  978            "# $4 = wavenumber in x-direction [1/km]\n" 
  979            "# $5 = wavenumber in y-direction [1/km]\n" 
  980            "# $6 = amplitude [K]\n" "# $7 = phase [rad]\n");
 
  983    for (
int l = 0; l < lmax; l++) {
 
  985      for (
int m = 0; m < mmax; m++)
 
  986        fprintf(out, 
"%g %g %g %g %g %g %g\n", wave->
z,
 
  987                (kx[l] != 0 ? 2 * M_PI / kx[l] : 0),
 
  988                (ky[m] != 0 ? 2 * M_PI / ky[m] : 0),
 
  989                kx[l], ky[m], A[l][m], phi[l][m]);
 
 1007  double x0[3], x1[3];
 
 1010  track0 = GSL_MIN(GSL_MAX(track0, 0), pert->
ntrack - 1);
 
 1011  track1 = GSL_MIN(GSL_MAX(track1, 0), pert->
ntrack - 1);
 
 1012  xtrack0 = GSL_MIN(GSL_MAX(xtrack0, 0), pert->
nxtrack - 1);
 
 1013  xtrack1 = GSL_MIN(GSL_MAX(xtrack1, 0), pert->
nxtrack - 1);
 
 1016  wave->
nx = xtrack1 - xtrack0 + 1;
 
 1018    ERRMSG(
"Too many across-track values!");
 
 1019  wave->
ny = track1 - track0 + 1;
 
 1021    ERRMSG(
"Too many along-track values!");
 
 1024  for (
int itrack = track0; itrack <= track1; itrack++)
 
 1025    for (
int ixtrack = xtrack0; ixtrack <= xtrack1; ixtrack++) {
 
 1028      if (itrack == track0) {
 
 1030        if (ixtrack > xtrack0) {
 
 1031          geo2cart(0, pert->
lon[itrack][ixtrack - 1],
 
 1032                   pert->
lat[itrack][ixtrack - 1], x0);
 
 1033          geo2cart(0, pert->
lon[itrack][ixtrack],
 
 1034                   pert->
lat[itrack][ixtrack], x1);
 
 1035          wave->
x[ixtrack - xtrack0] =
 
 1036            wave->
x[ixtrack - xtrack0 - 1] + DIST(x0, x1);
 
 1039      if (ixtrack == xtrack0) {
 
 1041        if (itrack > track0) {
 
 1042          geo2cart(0, pert->
lon[itrack - 1][ixtrack],
 
 1043                   pert->
lat[itrack - 1][ixtrack], x0);
 
 1044          geo2cart(0, pert->
lon[itrack][ixtrack],
 
 1045                   pert->
lat[itrack][ixtrack], x1);
 
 1046          wave->
y[itrack - track0] =
 
 1047            wave->
y[itrack - track0 - 1] + DIST(x0, x1);
 
 1052      wave->
time = pert->
time[(track0 + track1) / 2][(xtrack0 + xtrack1) / 2];
 
 1054      wave->
lon[ixtrack - xtrack0][itrack - track0] =
 
 1055        pert->
lon[itrack][ixtrack];
 
 1056      wave->
lat[ixtrack - xtrack0][itrack - track0] =
 
 1057        pert->
lat[itrack][ixtrack];
 
 1060      wave->
temp[ixtrack - xtrack0][itrack - track0]
 
 1061        = pert->
bt[itrack][ixtrack];
 
 1062      wave->
bg[ixtrack - xtrack0][itrack - track0]
 
 1063        = pert->
bt[itrack][ixtrack] - pert->
pt[itrack][ixtrack];
 
 1064      wave->
pt[ixtrack - xtrack0][itrack - track0]
 
 1065        = pert->
pt[itrack][ixtrack];
 
 1066      wave->
var[ixtrack - xtrack0][itrack - track0]
 
 1067        = pert->
var[itrack][ixtrack];
 
 1080  printf(
"Read AIRS Level-1 file: %s\n", filename);
 
 1081  NC(nc_open(filename, NC_NOWRITE, &ncid));
 
 1084  NC(nc_inq_varid(ncid, 
"l1_time", &varid));
 
 1085  NC(nc_get_var_double(ncid, varid, l1->
time[0]));
 
 1086  NC(nc_inq_varid(ncid, 
"l1_lon", &varid));
 
 1087  NC(nc_get_var_double(ncid, varid, l1->
lon[0]));
 
 1088  NC(nc_inq_varid(ncid, 
"l1_lat", &varid));
 
 1089  NC(nc_get_var_double(ncid, varid, l1->
lat[0]));
 
 1090  NC(nc_inq_varid(ncid, 
"l1_sat_z", &varid));
 
 1091  NC(nc_get_var_double(ncid, varid, l1->
sat_z));
 
 1092  NC(nc_inq_varid(ncid, 
"l1_sat_lon", &varid));
 
 1093  NC(nc_get_var_double(ncid, varid, l1->
sat_lon));
 
 1094  NC(nc_inq_varid(ncid, 
"l1_sat_lat", &varid));
 
 1095  NC(nc_get_var_double(ncid, varid, l1->
sat_lat));
 
 1096  NC(nc_inq_varid(ncid, 
"l1_nu", &varid));
 
 1097  NC(nc_get_var_double(ncid, varid, l1->
nu));
 
 1098  NC(nc_inq_varid(ncid, 
"l1_rad", &varid));
 
 1099  NC(nc_get_var_float(ncid, varid, l1->
rad[0][0]));
 
 1114  printf(
"Read AIRS Level-2 file: %s\n", filename);
 
 1115  NC(nc_open(filename, NC_NOWRITE, &ncid));
 
 1118  NC(nc_inq_varid(ncid, 
"l2_time", &varid));
 
 1119  NC(nc_get_var_double(ncid, varid, l2->
time[0]));
 
 1120  NC(nc_inq_varid(ncid, 
"l2_z", &varid));
 
 1121  NC(nc_get_var_double(ncid, varid, l2->
z[0][0]));
 
 1122  NC(nc_inq_varid(ncid, 
"l2_lon", &varid));
 
 1123  NC(nc_get_var_double(ncid, varid, l2->
lon[0]));
 
 1124  NC(nc_inq_varid(ncid, 
"l2_lat", &varid));
 
 1125  NC(nc_get_var_double(ncid, varid, l2->
lat[0]));
 
 1126  NC(nc_inq_varid(ncid, 
"l2_press", &varid));
 
 1127  NC(nc_get_var_double(ncid, varid, l2->
p));
 
 1128  NC(nc_inq_varid(ncid, 
"l2_temp", &varid));
 
 1129  NC(nc_get_var_double(ncid, varid, l2->
t[0][0]));
 
 1142  static char varname[LEN];
 
 1144  static int dimid[2], ncid, varid;
 
 1146  static size_t ntrack, nxtrack, start[2] = { 0, 0 }, count[2] = { 1, 1 };
 
 1149  printf(
"Read perturbation data: %s\n", filename);
 
 1152  NC(nc_open(filename, NC_NOWRITE, &ncid));
 
 1155  NC(nc_inq_dimid(ncid, 
"NTRACK", &dimid[0]));
 
 1156  NC(nc_inq_dimid(ncid, 
"NXTRACK", &dimid[1]));
 
 1157  NC(nc_inq_dimlen(ncid, dimid[0], &ntrack));
 
 1158  NC(nc_inq_dimlen(ncid, dimid[1], &nxtrack));
 
 1160    ERRMSG(
"Too many tracks!");
 
 1162    ERRMSG(
"Too many scans!");
 
 1163  pert->
ntrack = (int) ntrack;
 
 1164  pert->
nxtrack = (int) nxtrack;
 
 1168  NC(nc_inq_varid(ncid, 
"time", &varid));
 
 1169  for (
size_t itrack = 0; itrack < ntrack; itrack++) {
 
 1171    NC(nc_get_vara_double(ncid, varid, start, count, pert->
time[itrack]));
 
 1174  NC(nc_inq_varid(ncid, 
"lon", &varid));
 
 1175  for (
size_t itrack = 0; itrack < ntrack; itrack++) {
 
 1177    NC(nc_get_vara_double(ncid, varid, start, count, pert->
lon[itrack]));
 
 1180  NC(nc_inq_varid(ncid, 
"lat", &varid));
 
 1181  for (
size_t itrack = 0; itrack < ntrack; itrack++) {
 
 1183    NC(nc_get_vara_double(ncid, varid, start, count, pert->
lat[itrack]));
 
 1186  NC(nc_inq_varid(ncid, 
"bt_8mu", &varid));
 
 1187  for (
size_t itrack = 0; itrack < ntrack; itrack++) {
 
 1189    NC(nc_get_vara_double(ncid, varid, start, count, pert->
dc[itrack]));
 
 1192  sprintf(varname, 
"bt_%s", pertname);
 
 1193  NC(nc_inq_varid(ncid, varname, &varid));
 
 1194  for (
size_t itrack = 0; itrack < ntrack; itrack++) {
 
 1196    NC(nc_get_vara_double(ncid, varid, start, count, pert->
bt[itrack]));
 
 1199  sprintf(varname, 
"bt_%s_pt", pertname);
 
 1200  NC(nc_inq_varid(ncid, varname, &varid));
 
 1201  for (
size_t itrack = 0; itrack < ntrack; itrack++) {
 
 1203    NC(nc_get_vara_double(ncid, varid, start, count, pert->
pt[itrack]));
 
 1206  sprintf(varname, 
"bt_%s_var", pertname);
 
 1207  NC(nc_inq_varid(ncid, varname, &varid));
 
 1208  for (
size_t itrack = 0; itrack < ntrack; itrack++) {
 
 1210    NC(nc_get_vara_double(ncid, varid, start, count, pert->
var[itrack]));
 
 1223  static double help[
NDS * 
NPG];
 
 1225  int dimid, ids, ncid, varid;
 
 1227  size_t nds, np, ntrack, nxtrack;
 
 1230  printf(
"Read retrieval data: %s\n", filename);
 
 1233  NC(nc_open(filename, NC_NOWRITE, &ncid));
 
 1236  if (nc_inq_dimid(ncid, 
"L1_NTRACK", &dimid) == NC_NOERR) {
 
 1239    NC(nc_inq_dimid(ncid, 
"RET_NP", &dimid));
 
 1240    NC(nc_inq_dimlen(ncid, dimid, &np));
 
 1243      ERRMSG(
"Too many data points!");
 
 1245    NC(nc_inq_dimid(ncid, 
"L1_NTRACK", &dimid));
 
 1246    NC(nc_inq_dimlen(ncid, dimid, &ntrack));
 
 1247    NC(nc_inq_dimid(ncid, 
"L1_NXTRACK", &dimid));
 
 1248    NC(nc_inq_dimlen(ncid, dimid, &nxtrack));
 
 1249    ret->
nds = (int) (ntrack * nxtrack);
 
 1251      ERRMSG(
"Too many data sets!");
 
 1254    NC(nc_inq_varid(ncid, 
"l1_time", &varid));
 
 1255    NC(nc_get_var_double(ncid, varid, help));
 
 1257    for (
size_t itrack = 0; itrack < ntrack; itrack++)
 
 1258      for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
 
 1259        for (
int ip = 0; ip < ret->
np; ip++)
 
 1260          ret->
time[ids][ip] = help[ids];
 
 1265    NC(nc_inq_varid(ncid, 
"ret_z", &varid));
 
 1266    NC(nc_get_var_double(ncid, varid, help));
 
 1268    for (
size_t itrack = 0; itrack < ntrack; itrack++)
 
 1269      for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
 
 1270        for (
int ip = 0; ip < ret->
np; ip++)
 
 1271          ret->
z[ids][ip] = help[ip];
 
 1276    NC(nc_inq_varid(ncid, 
"l1_lon", &varid));
 
 1277    NC(nc_get_var_double(ncid, varid, help));
 
 1279    for (
size_t itrack = 0; itrack < ntrack; itrack++)
 
 1280      for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
 
 1281        for (
int ip = 0; ip < ret->
np; ip++)
 
 1282          ret->
lon[ids][ip] = help[ids];
 
 1287    NC(nc_inq_varid(ncid, 
"l1_lat", &varid));
 
 1288    NC(nc_get_var_double(ncid, varid, help));
 
 1290    for (
size_t itrack = 0; itrack < ntrack; itrack++)
 
 1291      for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
 
 1292        for (
int ip = 0; ip < ret->
np; ip++)
 
 1293          ret->
lat[ids][ip] = help[ids];
 
 1298    NC(nc_inq_varid(ncid, 
"ret_temp", &varid));
 
 1299    NC(nc_get_var_double(ncid, varid, help));
 
 1301    for (
size_t itrack = 0; itrack < ntrack; itrack++)
 
 1302      for (
size_t ixtrack = 0; ixtrack < nxtrack; ixtrack++) {
 
 1303        for (
int ip = 0; ip < ret->
np; ip++)
 
 1305            help[(itrack * nxtrack + ixtrack) * (size_t) np + (
size_t) ip];
 
 1311  if (nc_inq_dimid(ncid, 
"np", &dimid) == NC_NOERR) {
 
 1314    NC(nc_inq_dimid(ncid, 
"np", &dimid));
 
 1315    NC(nc_inq_dimlen(ncid, dimid, &np));
 
 1318      ERRMSG(
"Too many data points!");
 
 1320    NC(nc_inq_dimid(ncid, 
"nds", &dimid));
 
 1321    NC(nc_inq_dimlen(ncid, dimid, &nds));
 
 1322    ret->
nds = (int) nds;
 
 1324      ERRMSG(
"Too many data sets!");
 
 1327    NC(nc_inq_varid(ncid, 
"time", &varid));
 
 1328    NC(nc_get_var_double(ncid, varid, help));
 
 1331    NC(nc_inq_varid(ncid, 
"z", &varid));
 
 1332    NC(nc_get_var_double(ncid, varid, help));
 
 1335    NC(nc_inq_varid(ncid, 
"lon", &varid));
 
 1336    NC(nc_get_var_double(ncid, varid, help));
 
 1339    NC(nc_inq_varid(ncid, 
"lat", &varid));
 
 1340    NC(nc_get_var_double(ncid, varid, help));
 
 1343    NC(nc_inq_varid(ncid, 
"press", &varid));
 
 1344    NC(nc_get_var_double(ncid, varid, help));
 
 1347    NC(nc_inq_varid(ncid, 
"temp", &varid));
 
 1348    NC(nc_get_var_double(ncid, varid, help));
 
 1351    NC(nc_inq_varid(ncid, 
"temp_apr", &varid));
 
 1352    NC(nc_get_var_double(ncid, varid, help));
 
 1355    NC(nc_inq_varid(ncid, 
"temp_total", &varid));
 
 1356    NC(nc_get_var_double(ncid, varid, help));
 
 1359    NC(nc_inq_varid(ncid, 
"temp_noise", &varid));
 
 1360    NC(nc_get_var_double(ncid, varid, help));
 
 1363    NC(nc_inq_varid(ncid, 
"temp_formod", &varid));
 
 1364    NC(nc_get_var_double(ncid, varid, help));
 
 1367    NC(nc_inq_varid(ncid, 
"temp_cont", &varid));
 
 1368    NC(nc_get_var_double(ncid, varid, help));
 
 1371    NC(nc_inq_varid(ncid, 
"temp_res", &varid));
 
 1372    NC(nc_get_var_double(ncid, varid, help));
 
 1375    NC(nc_inq_varid(ncid, 
"chisq", &varid));
 
 1376    NC(nc_get_var_double(ncid, varid, ret->
chisq));
 
 1393  for (
int ip = 0; ip < np; ip++)
 
 1394    for (
int ids = 0; ids < nds; ids++)
 
 1395      mat[ids][ip] = help[n++];
 
 1408  double rtime, rz, rlon, rlat, rx, ry, ryold = -1e10,
 
 1409    rtemp, rbg, rpt, rvar, rfit;
 
 1416  printf(
"Read wave data: %s\n", filename);
 
 1419  if (!(in = fopen(filename, 
"r")))
 
 1420    ERRMSG(
"Cannot open file!");
 
 1423  while (fgets(line, LEN, in))
 
 1424    if (sscanf(line, 
"%lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg", &rtime,
 
 1425               &rz, &rlon, &rlat, &rx, &ry, &rtemp, &rbg, &rpt,
 
 1426               &rvar, &rfit) == 11) {
 
 1430        if ((++wave->
ny >= 
WY))
 
 1431          ERRMSG(
"Too many y-values!");
 
 1433      } 
else if ((++wave->
nx) >= 
WX)
 
 1434        ERRMSG(
"Too many x-values!");
 
 1440      wave->
lon[wave->
nx][wave->
ny] = rlon;
 
 1441      wave->
lat[wave->
nx][wave->
ny] = rlat;
 
 1442      wave->
x[wave->
nx] = rx;
 
 1443      wave->
y[wave->
ny] = ry;
 
 1444      wave->
temp[wave->
nx][wave->
ny] = rtemp;
 
 1445      wave->
bg[wave->
nx][wave->
ny] = rbg;
 
 1446      wave->
pt[wave->
nx][wave->
ny] = rpt;
 
 1447      wave->
var[wave->
nx][wave->
ny] = rvar;
 
 1448      wave->
fit[wave->
nx][wave->
ny] = rfit;
 
 1462  airs_rad_gran_t *gran,
 
 1467  double x0[3], x1[3];
 
 1469  int ichan[AIRS_RAD_CHANNEL];
 
 1472  for (
int id = 0; 
id < nd; 
id++) {
 
 1473    for (ichan[
id] = 0; ichan[id] < AIRS_RAD_CHANNEL; ichan[id]++)
 
 1474      if (fabs(gran->nominal_freq[ichan[
id]] - nu[
id]) < 0.1)
 
 1476    if (ichan[
id] >= AIRS_RAD_CHANNEL)
 
 1477      ERRMSG(
"Could not find channel!");
 
 1481  wave->
nx = AIRS_RAD_GEOXTRACK;
 
 1482  wave->
ny = AIRS_RAD_GEOTRACK;
 
 1483  if (wave->
nx > 
WX || wave->
ny > 
WY)
 
 1484    ERRMSG(
"Wave struct too small!");
 
 1487  geo2cart(0, gran->Longitude[0][0], gran->Latitude[0][0], x0);
 
 1488  for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
 
 1489    geo2cart(0, gran->Longitude[0][xtrack], gran->Latitude[0][xtrack], x1);
 
 1490    wave->
x[xtrack] = DIST(x0, x1);
 
 1492  for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++) {
 
 1493    geo2cart(0, gran->Longitude[track][0], gran->Latitude[track][0], x1);
 
 1494    wave->
y[track] = DIST(x0, x1);
 
 1499    gran->Time[AIRS_RAD_GEOTRACK / 2][AIRS_RAD_GEOXTRACK / 2] - 220838400;
 
 1501  for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++)
 
 1502    for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
 
 1503      wave->
lon[xtrack][track] = gran->Longitude[track][xtrack];
 
 1504      wave->
lat[xtrack][track] = gran->Latitude[track][xtrack];
 
 1508  for (
int track = 0; track < AIRS_RAD_GEOTRACK; track++)
 
 1509    for (
int xtrack = 0; xtrack < AIRS_RAD_GEOXTRACK; xtrack++) {
 
 1510      wave->
temp[xtrack][track] = 0;
 
 1511      wave->
bg[xtrack][track] = 0;
 
 1512      wave->
pt[xtrack][track] = 0;
 
 1513      wave->
var[xtrack][track] = 0;
 
 1514      for (
int id = 0; 
id < nd; 
id++) {
 
 1515        if ((gran->state[track][xtrack] != 0)
 
 1516            || (gran->ExcludedChans[ichan[
id]] > 2)
 
 1517            || (gran->CalChanSummary[ichan[
id]] & 8)
 
 1518            || (gran->CalChanSummary[ichan[
id]] & (32 + 64))
 
 1519            || (gran->CalFlag[track][ichan[
id]] & 16))
 
 1520          wave->
temp[xtrack][track] = GSL_NAN;
 
 1522          wave->
temp[xtrack][track]
 
 1523            += BRIGHT(gran->radiances[track][xtrack][ichan[
id]] * 1e-3,
 
 1524                      gran->nominal_freq[ichan[
id]]) / nd;
 
 1540    ERRMSG(
"Too many across-track values!");
 
 1543    ERRMSG(
"Too many along-track values!");
 
 1544  if (ip < 0 || ip >= ret->
np)
 
 1545    ERRMSG(
"Altitude index out of range!");
 
 1548  for (
int ids = 0; ids < ret->
nds; ids++) {
 
 1551    const int ix = ids % 90;
 
 1552    const int iy = ids / 90;
 
 1555    double x0[3], x1[3];
 
 1557      geo2cart(0.0, ret->
lon[0][0], ret->
lat[0][0], x0);
 
 1558      geo2cart(0.0, ret->
lon[ids][ip], ret->
lat[ids][ip], x1);
 
 1559      wave->
x[ix] = DIST(x0, x1);
 
 1562      geo2cart(0.0, ret->
lon[0][0], ret->
lat[0][0], x0);
 
 1563      geo2cart(0.0, ret->
lon[ids][ip], ret->
lat[ids][ip], x1);
 
 1564      wave->
y[iy] = DIST(x0, x1);
 
 1569    if (ix == 0 && iy == 0)
 
 1570      wave->
z = ret->
z[ids][ip];
 
 1571    wave->
lon[ix][iy] = ret->
lon[ids][ip];
 
 1572    wave->
lat[ix][iy] = ret->
lat[ids][ip];
 
 1576      wave->
temp[ix][iy] = ret->
t[ids][ip];
 
 1577    else if (dataset == 2)
 
 1578      wave->
temp[ix][iy] = ret->
t_apr[ids][ip];
 
 1593  const double dh2 = gsl_pow_2(dh);
 
 1597    (int) (dh / fabs(wave->
x[wave->
nx - 1] - wave->
x[0]) * (wave->
nx - 1.0) +
 
 1600    (int) (dh / fabs(wave->
y[wave->
ny - 1] - wave->
y[0]) * (wave->
ny - 1.0) +
 
 1604  for (
int ix = 0; ix < wave->
nx; ix++)
 
 1605    for (
int iy = 0; iy < wave->
ny; iy++) {
 
 1608      double mu = 0, help = 0;
 
 1612      for (
int ix2 = GSL_MAX(ix - dx, 0);
 
 1613           ix2 <= GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
 
 1614        for (
int iy2 = GSL_MAX(iy - dy, 0);
 
 1615             iy2 <= GSL_MIN(iy + dy, wave->
ny - 1); iy2++)
 
 1616          if ((gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
 
 1617               + gsl_pow_2(wave->
y[iy] - wave->
y[iy2])) <= dh2)
 
 1618            if (gsl_finite(wave->
pt[ix2][iy2])) {
 
 1619              mu += wave->
pt[ix2][iy2];
 
 1620              help += gsl_pow_2(wave->
pt[ix2][iy2]);
 
 1626        wave->
var[ix][iy] = help / n - gsl_pow_2(mu / n);
 
 1628        wave->
var[ix][iy] = GSL_NAN;
 
 1638  int dimid[10], ncid, time_id, lon_id, lat_id,
 
 1639    sat_z_id, sat_lon_id, sat_lat_id, nu_id, rad_id;
 
 1642  printf(
"Write AIRS Level-1 file: %s\n", filename);
 
 1643  if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
 
 1644    NC(nc_create(filename, NC_CLOBBER, &ncid));
 
 1650  if (nc_inq_dimid(ncid, 
"L1_NTRACK", &dimid[0]) != NC_NOERR)
 
 1651    NC(nc_def_dim(ncid, 
"L1_NTRACK", 
L1_NTRACK, &dimid[0]));
 
 1652  if (nc_inq_dimid(ncid, 
"L1_NXTRACK", &dimid[1]) != NC_NOERR)
 
 1653    NC(nc_def_dim(ncid, 
"L1_NXTRACK", 
L1_NXTRACK, &dimid[1]));
 
 1654  if (nc_inq_dimid(ncid, 
"L1_NCHAN", &dimid[2]) != NC_NOERR)
 
 1655    NC(nc_def_dim(ncid, 
"L1_NCHAN", 
L1_NCHAN, &dimid[2]));
 
 1658  add_var(ncid, 
"l1_time", 
"s", 
"time (seconds since 2000-01-01T00:00Z)",
 
 1659          NC_DOUBLE, dimid, &time_id, 2);
 
 1660  add_var(ncid, 
"l1_lon", 
"deg", 
"longitude", NC_DOUBLE, dimid, &lon_id, 2);
 
 1661  add_var(ncid, 
"l1_lat", 
"deg", 
"latitude", NC_DOUBLE, dimid, &lat_id, 2);
 
 1662  add_var(ncid, 
"l1_sat_z", 
"km", 
"satellite altitude",
 
 1663          NC_DOUBLE, dimid, &sat_z_id, 1);
 
 1664  add_var(ncid, 
"l1_sat_lon", 
"deg", 
"satellite longitude",
 
 1665          NC_DOUBLE, dimid, &sat_lon_id, 1);
 
 1666  add_var(ncid, 
"l1_sat_lat", 
"deg", 
"satellite latitude",
 
 1667          NC_DOUBLE, dimid, &sat_lat_id, 1);
 
 1668  add_var(ncid, 
"l1_nu", 
"cm^-1", 
"channel wavenumber",
 
 1669          NC_DOUBLE, &dimid[2], &nu_id, 1);
 
 1670  add_var(ncid, 
"l1_rad", 
"W/(m^2 sr cm^-1)", 
"channel radiance",
 
 1671          NC_FLOAT, dimid, &rad_id, 3);
 
 1674  NC(nc_enddef(ncid));
 
 1677  NC(nc_put_var_double(ncid, time_id, l1->
time[0]));
 
 1678  NC(nc_put_var_double(ncid, lon_id, l1->
lon[0]));
 
 1679  NC(nc_put_var_double(ncid, lat_id, l1->
lat[0]));
 
 1680  NC(nc_put_var_double(ncid, sat_z_id, l1->
sat_z));
 
 1681  NC(nc_put_var_double(ncid, sat_lon_id, l1->
sat_lon));
 
 1682  NC(nc_put_var_double(ncid, sat_lat_id, l1->
sat_lat));
 
 1683  NC(nc_put_var_double(ncid, nu_id, l1->
nu));
 
 1684  NC(nc_put_var_float(ncid, rad_id, l1->
rad[0][0]));
 
 1696  int dimid[10], ncid, time_id, z_id, lon_id, lat_id, p_id, t_id;
 
 1699  printf(
"Write AIRS Level-2 file: %s\n", filename);
 
 1700  if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
 
 1701    NC(nc_create(filename, NC_CLOBBER, &ncid));
 
 1707  if (nc_inq_dimid(ncid, 
"L2_NTRACK", &dimid[0]) != NC_NOERR)
 
 1708    NC(nc_def_dim(ncid, 
"L2_NTRACK", 
L2_NTRACK, &dimid[0]));
 
 1709  if (nc_inq_dimid(ncid, 
"L2_NXTRACK", &dimid[1]) != NC_NOERR)
 
 1710    NC(nc_def_dim(ncid, 
"L2_NXTRACK", 
L2_NXTRACK, &dimid[1]));
 
 1711  if (nc_inq_dimid(ncid, 
"L2_NLAY", &dimid[2]) != NC_NOERR)
 
 1712    NC(nc_def_dim(ncid, 
"L2_NLAY", 
L2_NLAY, &dimid[2]));
 
 1715  add_var(ncid, 
"l2_time", 
"s", 
"time (seconds since 2000-01-01T00:00Z)",
 
 1716          NC_DOUBLE, dimid, &time_id, 2);
 
 1717  add_var(ncid, 
"l2_z", 
"km", 
"altitude", NC_DOUBLE, dimid, &z_id, 3);
 
 1718  add_var(ncid, 
"l2_lon", 
"deg", 
"longitude", NC_DOUBLE, dimid, &lon_id, 2);
 
 1719  add_var(ncid, 
"l2_lat", 
"deg", 
"latitude", NC_DOUBLE, dimid, &lat_id, 2);
 
 1720  add_var(ncid, 
"l2_press", 
"hPa", 
"pressure",
 
 1721          NC_DOUBLE, &dimid[2], &p_id, 1);
 
 1722  add_var(ncid, 
"l2_temp", 
"K", 
"temperature", NC_DOUBLE, dimid, &t_id, 3);
 
 1725  NC(nc_enddef(ncid));
 
 1728  NC(nc_put_var_double(ncid, time_id, l2->
time[0]));
 
 1729  NC(nc_put_var_double(ncid, z_id, l2->
z[0][0]));
 
 1730  NC(nc_put_var_double(ncid, lon_id, l2->
lon[0]));
 
 1731  NC(nc_put_var_double(ncid, lat_id, l2->
lat[0]));
 
 1732  NC(nc_put_var_double(ncid, p_id, l2->
p));
 
 1733  NC(nc_put_var_double(ncid, t_id, l2->
t[0][0]));
 
 1748  printf(
"Write wave data: %s\n", filename);
 
 1751  if (!(out = fopen(filename, 
"w")))
 
 1752    ERRMSG(
"Cannot create file!");
 
 1756          "# $1  = time (seconds since 2000-01-01T00:00Z)\n" 
 1757          "# $2  = altitude [km]\n" 
 1758          "# $3  = longitude [deg]\n" 
 1759          "# $4  = latitude [deg]\n" 
 1760          "# $5  = across-track distance [km]\n" 
 1761          "# $6  = along-track distance [km]\n" 
 1762          "# $7  = temperature [K]\n" 
 1763          "# $8  = background [K]\n" 
 1764          "# $9  = perturbation [K]\n" 
 1765          "# $10 = variance [K^2]\n" "# $11 = fitting model [K]\n");
 
 1768  for (
int j = 0; j < wave->
ny; j++) {
 
 1770    for (
int i = 0; i < wave->
nx; i++)
 
 1771      fprintf(out, 
"%.2f %g %g %g %g %g %g %g %g %g %g\n",
 
 1772              wave->
time, wave->
z, wave->
lon[i][j], wave->
lat[i][j],
 
 1773              wave->
x[i], wave->
y[j], wave->
temp[i][j], wave->
bg[i][j],
 
 1774              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 day2doy(int year, int mon, int day, int *doy)
Get day of year from date.
 
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 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 ret2wave(ret_t *ret, wave_t *wave, int dataset, int ip)
Convert AIRS retrieval results to wave analysis struct.
 
void pert2wave(pert_t *pert, wave_t *wave, int track0, int track1, int xtrack0, int xtrack1)
Convert radiance perturbation data to wave analysis struct.
 
void read_retr(char *filename, ret_t *ret)
Read AIRS retrieval data.
 
void doy2day(int year, int doy, int *mon, int *day)
Get date from day of year.
 
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 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].