27#define LOOP_ALL(ntrack)                                \ 
   28  for (int track = 0; track < ntrack; track++)          \ 
   29    for (int xtrack = 0; xtrack < L1_NXTRACK; xtrack++) \ 
   30      for (int ifov = 0; ifov < L1_NFOV; ifov++) 
   42  static pert_t *pert_4mu, *pert_15mu_low, *pert_15mu_high;
 
   44  const double var_dh2 = 100. * 100.;
 
   49  const int list_4mu[
N4]
 
   50    = { 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283,
 
   51    284, 285, 286, 288, 289, 291, 292, 294, 295, 296, 297, 298, 299, 300,
 
   52    302, 303, 304, 305, 306, 307, 318, 319, 321, 322, 323, 324, 325, 326,
 
   53    328, 330, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341
 
   56  const int list_15mu_low[
N15_LOW]
 
   57  = { 5, 8, 10, 13, 15, 17, 23, 34, 36, 39, 41, 44, 46, 49, 51 };
 
   59  const int list_15mu_high[
N15_HIGH] = { 31 };
 
   61  const int list_8mu[
N8] = { 36 };
 
   63  const int list_10mu[
N10] = { 502 };
 
   65  const int dtrack = 3, dxtrack = 3;
 
   67  static int dimid[3], n, ncid, track0,
 
   68    time_varid, lon_varid, lat_varid, bt_4mu_varid, init,
 
   69    bt_4mu_pt_varid, bt_4mu_var_varid, bt_8mu_varid, bt_10mu_varid,
 
   70    bt_15mu_low_varid, bt_15mu_low_pt_varid, bt_15mu_low_var_varid,
 
   71    bt_15mu_high_varid, bt_15mu_high_pt_varid, bt_15mu_high_var_varid;
 
   75    ERRMSG(
"Give parameters: <ctl> <pert.nc> <l1b_file1> [<l1b_file2> ...]");
 
   78  const int apo = (int) 
scan_ctl(argc, argv, 
"APO", -1, 
"0", NULL);
 
   90  for (
int iarg = 3; iarg < argc; iarg++) {
 
  101      LOG(2, 
"4.3 micron channels:");
 
  104      for (
int i = 0; i < 
N4; i++) {
 
  105        nu += l1.
nu_sw[list_4mu[i]];
 
  107        LOG(2, 
"  count= %2d | channel index= SW_%03d | nu= %.4f cm^-1", n,
 
  108            list_4mu[i], l1.
nu_sw[list_4mu[i]]);
 
  110      LOG(2, 
"  nu_mean= %.4f cm^-1", nu / n);
 
  113      LOG(2, 
"15 micron low channels:");
 
  116      for (
int i = 0; i < 
N15_LOW; i++) {
 
  117        nu += l1.
nu_lw[list_15mu_low[i]];
 
  119        LOG(2, 
"  count= %2d | channel index= LW_%03d | nu= %.4f cm^-1", n,
 
  120            list_15mu_low[i], l1.
nu_lw[list_15mu_low[i]]);
 
  122      LOG(2, 
"  nu_mean= %.4f cm^-1", nu / n);
 
  125      LOG(2, 
"15 micron high channels:");
 
  128      for (
int i = 0; i < 
N15_HIGH; i++) {
 
  129        nu += l1.
nu_lw[list_15mu_high[i]];
 
  131        LOG(2, 
"  count= %2d | channel index= LW_%03d | nu= %.4f cm^-1", n,
 
  132            list_15mu_high[i], l1.
nu_lw[list_15mu_high[i]]);
 
  134      LOG(2, 
"  nu_mean= %.4f cm^-1", nu / n);
 
  137      LOG(2, 
"8.1 micron channels:");
 
  140      for (
int i = 0; i < 
N8; i++) {
 
  141        nu += l1.
nu_mw[list_8mu[i]];
 
  143        LOG(2, 
"  count= %2d | channel index= MW_%03d | nu= %.4f cm^-1", n,
 
  144            list_8mu[i], l1.
nu_mw[list_8mu[i]]);
 
  146      LOG(2, 
"  nu_mean= %.4f cm^-1", nu / n);
 
  149      LOG(2, 
"10.4 micron channels:");
 
  152      for (
int i = 0; i < 
N10; i++) {
 
  153        nu += l1.
nu_lw[list_10mu[i]];
 
  155        LOG(2, 
"  count= %2d | channel index= LW_%03d | nu= %.4f cm^-1", n,
 
  156            list_10mu[i], l1.
nu_lw[list_10mu[i]]);
 
  158      LOG(2, 
"  nu_mean= %.4f cm^-1", nu / n);
 
  164      ERRMSG(
"Too many granules!");
 
  167      ERRMSG(
"Too many tracks!");
 
  170      ERRMSG(
"Too many field of views!");
 
  172      pert_4mu->
time[track0 + track][xtrack][ifov]
 
  173        = l1.
time[track][xtrack] - 220838400.;
 
  174      pert_4mu->
lon[track0 + track][xtrack][ifov]
 
  175        = l1.
lon[track][xtrack][ifov];
 
  176      pert_4mu->
lat[track0 + track][xtrack][ifov]
 
  177        = l1.
lat[track][xtrack][ifov];
 
  182      pert_4mu->
dc[track0 + track][xtrack][ifov]
 
  183      = 
BRIGHT(l1.
rad_mw[track][xtrack][ifov][list_8mu[0]] * 1e-3,
 
  184               l1.
nu_mw[list_8mu[0]]);
 
  188      pert_15mu_high->
dc[track0 + track][xtrack][ifov]
 
  189      = 
BRIGHT(l1.
rad_lw[track][xtrack][ifov][list_10mu[0]] * 1e-3,
 
  190               l1.
nu_lw[list_10mu[0]]);
 
  196      for (
int i = 0; i < 
N4; i++)
 
  197        if (gsl_finite(l1.
rad_sw[track][xtrack][ifov][list_4mu[i]])) {
 
  198          rad += l1.
rad_sw[track][xtrack][ifov][list_4mu[i]] * 1e-3;
 
  199          nu += l1.
nu_sw[list_4mu[i]];
 
  203        pert_4mu->
bt[track0 + track][xtrack][ifov] = 
BRIGHT(rad / n, nu / n);
 
  205        pert_4mu->
bt[track0 + track][xtrack][ifov] = GSL_NAN;
 
  212      for (
int i = 0; i < 
N15_LOW; i++)
 
  213        if (gsl_finite(l1.
rad_lw[track][xtrack][ifov][list_15mu_low[i]])) {
 
  214          rad += l1.
rad_lw[track][xtrack][ifov][list_15mu_low[i]] * 1e-3;
 
  215          nu += l1.
nu_lw[list_15mu_low[i]];
 
  219        pert_15mu_low->
bt[track0 + track][xtrack][ifov] =
 
  222        pert_15mu_low->
bt[track0 + track][xtrack][ifov] = GSL_NAN;
 
  230        if (gsl_finite(l1.
rad_lw[track][xtrack][ifov][list_15mu_high[i]])) {
 
  231          rad += l1.
rad_lw[track][xtrack][ifov][list_15mu_high[i]] * 1e-3;
 
  232          nu += l1.
nu_lw[list_15mu_high[i]];
 
  236        pert_15mu_high->
bt[track0 + track][xtrack][ifov] =
 
  239        pert_15mu_high->
bt[track0 + track][xtrack][ifov] = GSL_NAN;
 
  251  LOG(1, 
"Calculate perturbations...");
 
  254  for (
int track = 0; track < pert_4mu->
ntrack; track++)
 
  255    for (
int ifov = 0; ifov < 
L1_NFOV; ifov++) {
 
  258      pert_4mu->
dc[track][0][ifov] = GSL_NAN;
 
  260      pert_15mu_high->
dc[track][0][ifov] = GSL_NAN;
 
  261      pert_15mu_high->
dc[track][
L1_NXTRACK - 1][ifov] = GSL_NAN;
 
  262      pert_4mu->
bt[track][0][ifov] = GSL_NAN;
 
  264      pert_15mu_low->
bt[track][0][ifov] = GSL_NAN;
 
  265      pert_15mu_low->
bt[track][
L1_NXTRACK - 1][ifov] = GSL_NAN;
 
  266      pert_15mu_high->
bt[track][0][ifov] = GSL_NAN;
 
  267      pert_15mu_high->
bt[track][
L1_NXTRACK - 1][ifov] = GSL_NAN;
 
  270      for (
int xtrack = 0; xtrack < 
L1_NXTRACK; xtrack++) {
 
  271        x[xtrack] = (double) xtrack;
 
  272        y[xtrack] = pert_4mu->
bt[track][xtrack][ifov];
 
  275      for (
int xtrack = 0; xtrack < 
L1_NXTRACK; xtrack++)
 
  276        pert_4mu->
pt[track][xtrack][ifov] =
 
  277          pert_4mu->
bt[track][xtrack][ifov] - y[xtrack];
 
  280      for (
int xtrack = 0; xtrack < 
L1_NXTRACK; xtrack++) {
 
  281        x[xtrack] = (double) xtrack;
 
  282        y[xtrack] = pert_15mu_low->
bt[track][xtrack][ifov];
 
  285      for (
int xtrack = 0; xtrack < 
L1_NXTRACK; xtrack++)
 
  286        pert_15mu_low->
pt[track][xtrack][ifov] =
 
  287          pert_15mu_low->
bt[track][xtrack][ifov] - y[xtrack];
 
  290      for (
int xtrack = 0; xtrack < 
L1_NXTRACK; xtrack++) {
 
  291        x[xtrack] = (double) xtrack;
 
  292        y[xtrack] = pert_15mu_high->
bt[track][xtrack][ifov];
 
  295      for (
int xtrack = 0; xtrack < 
L1_NXTRACK; xtrack++)
 
  296        pert_15mu_high->
pt[track][xtrack][ifov] =
 
  297          pert_15mu_high->
bt[track][xtrack][ifov] - y[xtrack];
 
  305  LOG(1, 
"Calculate variances...");
 
  312             pert_4mu->
lat[track][xtrack][ifov], x0);
 
  315    int n_4mu = 0, n_15mu_low = 0, n_15mu_high = 0;
 
  316    double mean_4mu = 0, mean_15mu_low = 0, mean_15mu_high = 0;
 
  317    double var_4mu = 0, var_15mu_low = 0, var_15mu_high = 0;
 
  320    for (
int track2 = track - dtrack; track2 <= track + dtrack; track2++)
 
  321      for (
int xtrack2 = xtrack - dxtrack; xtrack2 <= xtrack + dxtrack;
 
  323        for (
int ifov2 = 0; ifov2 < 
L1_NFOV; ifov2++)
 
  324          if (track2 >= 0 && track2 < pert_4mu->ntrack
 
  328            geo2cart(0.0, pert_4mu->
lon[track2][xtrack2][ifov2],
 
  329                     pert_4mu->
lat[track2][xtrack2][ifov2], x1);
 
  330            if (
DIST2(x0, x1) > var_dh2)
 
  334            if (gsl_finite(pert_4mu->
pt[track2][xtrack2][ifov2])) {
 
  335              mean_4mu += pert_4mu->
pt[track2][xtrack2][ifov2];
 
  336              var_4mu += gsl_pow_2(pert_4mu->
pt[track2][xtrack2][ifov2]);
 
  340            if (gsl_finite(pert_15mu_low->
pt[track2][xtrack2][ifov2])) {
 
  341              mean_15mu_low += pert_15mu_low->
pt[track2][xtrack2][ifov2];
 
  343                gsl_pow_2(pert_15mu_low->
pt[track2][xtrack2][ifov2]);
 
  347            if (gsl_finite(pert_15mu_high->
pt[track2][xtrack2][ifov2])) {
 
  348              mean_15mu_high += pert_15mu_high->
pt[track2][xtrack2][ifov2];
 
  350                gsl_pow_2(pert_15mu_high->
pt[track2][xtrack2][ifov2]);
 
  356    if (n_4mu > 0 && xtrack > 0 && xtrack < 
L1_NXTRACK - 1)
 
  357      pert_4mu->
var[track][xtrack][ifov] =
 
  358        var_4mu / n_4mu - gsl_pow_2(mean_4mu / n_4mu);
 
  360      pert_4mu->
var[track][xtrack][ifov] = GSL_NAN;
 
  362    if (n_15mu_low > 0 && xtrack > 0 && xtrack < 
L1_NXTRACK - 1)
 
  363      pert_15mu_low->
var[track][xtrack][ifov] =
 
  364        var_15mu_low / n_15mu_low - gsl_pow_2(mean_15mu_low / n_15mu_low);
 
  366      pert_15mu_low->
var[track][xtrack][ifov] = GSL_NAN;
 
  368    if (n_15mu_high > 0 && xtrack > 0 && xtrack < 
L1_NXTRACK - 1)
 
  369      pert_15mu_high->
var[track][xtrack][ifov] =
 
  370        var_15mu_high / n_15mu_high - gsl_pow_2(mean_15mu_high / n_15mu_high);
 
  372      pert_15mu_high->
var[track][xtrack][ifov] = GSL_NAN;
 
  380  LOG(1, 
"Write perturbation data file: %s", argv[2]);
 
  383  NC(nc_create(argv[2], NC_CLOBBER, &ncid));
 
  386  NC(nc_def_dim(ncid, 
"NTRACK", (
size_t) pert_4mu->
ntrack, &dimid[0]));
 
  388  NC(nc_def_dim(ncid, 
"NFOV", 
L1_NFOV, &dimid[2]));
 
  391  NC(nc_def_var(ncid, 
"time", NC_DOUBLE, 3, dimid, &time_varid));
 
  392  add_att(ncid, time_varid, 
"s", 
"time (seconds since 2000-01-01T00:00Z)");
 
  393  NC(nc_def_var(ncid, 
"lon", NC_DOUBLE, 3, dimid, &lon_varid));
 
  394  add_att(ncid, lon_varid, 
"deg", 
"footprint longitude");
 
  395  NC(nc_def_var(ncid, 
"lat", NC_DOUBLE, 3, dimid, &lat_varid));
 
  396  add_att(ncid, lat_varid, 
"deg", 
"footprint latitude");
 
  398  NC(nc_def_var(ncid, 
"bt_8mu", NC_FLOAT, 3, dimid, &bt_8mu_varid));
 
  399  add_att(ncid, bt_8mu_varid, 
"K", 
"brightness temperature at 8.1 micron");
 
  401  NC(nc_def_var(ncid, 
"bt_10mu", NC_FLOAT, 3, dimid, &bt_10mu_varid));
 
  402  add_att(ncid, bt_10mu_varid, 
"K", 
"brightness temperature at 10.4 micron");
 
  404  NC(nc_def_var(ncid, 
"bt_4mu", NC_FLOAT, 3, dimid, &bt_4mu_varid));
 
  405  add_att(ncid, bt_4mu_varid, 
"K", 
"brightness temperature" " at 4.3 micron");
 
  406  NC(nc_def_var(ncid, 
"bt_4mu_pt", NC_FLOAT, 3, dimid, &bt_4mu_pt_varid));
 
  407  add_att(ncid, bt_4mu_pt_varid, 
"K", 
"brightness temperature perturbation" 
  409  NC(nc_def_var(ncid, 
"bt_4mu_var", NC_FLOAT, 3, dimid, &bt_4mu_var_varid));
 
  410  add_att(ncid, bt_4mu_var_varid, 
"K^2", 
"brightness temperature variance" 
  413  NC(nc_def_var(ncid, 
"bt_15mu_low", NC_FLOAT, 3, dimid, &bt_15mu_low_varid));
 
  414  add_att(ncid, bt_15mu_low_varid, 
"K", 
"brightness temperature" 
  415          " at 15 micron (low altitudes)");
 
  416  NC(nc_def_var(ncid, 
"bt_15mu_low_pt", NC_FLOAT, 3, dimid,
 
  417                &bt_15mu_low_pt_varid));
 
  418  add_att(ncid, bt_15mu_low_pt_varid, 
"K",
 
  419          "brightness temperature perturbation" 
  420          " at 15 micron (low altitudes)");
 
  422     (ncid, 
"bt_15mu_low_var", NC_FLOAT, 3, dimid, &bt_15mu_low_var_varid));
 
  423  add_att(ncid, bt_15mu_low_var_varid, 
"K^2",
 
  424          "brightness temperature variance" " at 15 micron (low altitudes)");
 
  426  NC(nc_def_var(ncid, 
"bt_15mu_high", NC_FLOAT, 3, dimid,
 
  427                &bt_15mu_high_varid));
 
  428  add_att(ncid, bt_15mu_high_varid, 
"K", 
"brightness temperature" 
  429          " at 15 micron (high altitudes)");
 
  430  NC(nc_def_var(ncid, 
"bt_15mu_high_pt", NC_FLOAT, 3, dimid,
 
  431                &bt_15mu_high_pt_varid));
 
  432  add_att(ncid, bt_15mu_high_pt_varid, 
"K",
 
  433          "brightness temperature perturbation" 
  434          " at 15 micron (high altitudes)");
 
  436     (ncid, 
"bt_15mu_high_var", NC_FLOAT, 3, dimid, &bt_15mu_high_var_varid));
 
  437  add_att(ncid, bt_15mu_high_var_varid, 
"K^2",
 
  438          "brightness temperature variance" " at 15 micron (high altitudes)");
 
  446    help[n++] = pert_4mu->
time[track][xtrack][ifov];
 
  447  NC(nc_put_var_double(ncid, time_varid, help));
 
  451    help[n++] = pert_4mu->
lon[track][xtrack][ifov];
 
  452  NC(nc_put_var_double(ncid, lon_varid, help));
 
  456    help[n++] = pert_4mu->
lat[track][xtrack][ifov];
 
  457  NC(nc_put_var_double(ncid, lat_varid, help));
 
  461    help[n++] = pert_4mu->
dc[track][xtrack][ifov];
 
  462  NC(nc_put_var_double(ncid, bt_8mu_varid, help));
 
  466    help[n++] = pert_15mu_high->
dc[track][xtrack][ifov];
 
  467  NC(nc_put_var_double(ncid, bt_10mu_varid, help));
 
  471    help[n++] = pert_4mu->
bt[track][xtrack][ifov];
 
  472  NC(nc_put_var_double(ncid, bt_4mu_varid, help));
 
  476    help[n++] = pert_4mu->
pt[track][xtrack][ifov];
 
  477  NC(nc_put_var_double(ncid, bt_4mu_pt_varid, help));
 
  481    help[n++] = pert_4mu->
var[track][xtrack][ifov];
 
  482  NC(nc_put_var_double(ncid, bt_4mu_var_varid, help));
 
  486    help[n++] = pert_15mu_low->
bt[track][xtrack][ifov];
 
  487  NC(nc_put_var_double(ncid, bt_15mu_low_varid, help));
 
  491    help[n++] = pert_15mu_low->
pt[track][xtrack][ifov];
 
  492  NC(nc_put_var_double(ncid, bt_15mu_low_pt_varid, help));
 
  496    help[n++] = pert_15mu_low->
var[track][xtrack][ifov];
 
  497  NC(nc_put_var_double(ncid, bt_15mu_low_var_varid, help));
 
  501    help[n++] = pert_15mu_high->
bt[track][xtrack][ifov];
 
  502  NC(nc_put_var_double(ncid, bt_15mu_high_varid, help));
 
  506    help[n++] = pert_15mu_high->
pt[track][xtrack][ifov];
 
  507  NC(nc_put_var_double(ncid, bt_15mu_high_pt_varid, help));
 
  511    help[n++] = pert_15mu_high->
var[track][xtrack][ifov];
 
  512  NC(nc_put_var_double(ncid, bt_15mu_high_var_varid, help));
 
  520  free(pert_15mu_high);
 
double scan_ctl(int argc, char *argv[], const char *varname, const int arridx, const char *defvalue, char *value)
Search control parameter file for variable entry.
 
void geo2cart(const double z, const double lon, const double lat, double *x)
Convert geolocation to Cartesian coordinates.
 
#define BRIGHT(rad, nu)
Compute brightness temperature.
 
#define ERRMSG(...)
Print error message and quit program.
 
#define ALLOC(ptr, type, n)
Allocate memory.
 
#define LOG(level,...)
Print log message.
 
#define DIST2(a, b)
Compute squared distance between two vectors.
 
void background_poly_help(const double *xx, double *yy, const int n, const int dim)
Get background based on polynomial fits.
 
int read_cris_l1(char *filename, cris_l1_t *l1, int apo)
Read CrIS Level-1 data.
 
void add_att(const int ncid, const int varid, const char *unit, const char *long_name)
Add variable attributes to netCDF file.
 
#define NC(cmd)
Execute netCDF library command and check result.
 
#define PERT_NXTRACK
Across-track size of perturbation data.
 
#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 PERT_NTRACK
Along-track size of perturbation data.
 
#define PERT_NFOV
Number of field of views of perturbation data.
 
int main(int argc, char *argv[])
 
#define N15_LOW
Number of 15 micron low channels:
 
#define N10
Number of 10.4 micron channels:
 
#define N4
Number of 4.3 micron channels:
 
#define N8
Number of 8.1 micron channels:
 
#define N15_HIGH
Number of 15 micron high channels:
 
#define LOOP_ALL(ntrack)
Loop over all footprints.
 
double nu_sw[L1_NCHAN_SW]
Shortwave channel frequencies [cm^-1].
 
float rad_mw[L1_NTRACK][L1_NXTRACK][L1_NFOV][L1_NCHAN_MW]
Midwave radiance [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)].
 
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 time[L1_NTRACK][L1_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
 
double nu_lw[L1_NCHAN_LW]
Longwave channel frequencies [cm^-1].
 
double lat[L1_NTRACK][L1_NXTRACK][L1_NFOV]
Footprint latitude [deg].
 
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].