41 if (nc_inq_varid(ncid, varname, varid) != NC_NOERR) {
44 NC(nc_def_var(ncid, varname, type, ndims, dimid, varid));
48 (ncid, *varid,
"long_name", strlen(longname), longname));
51 NC(nc_put_att_text(ncid, *varid,
"units", strlen(unit), unit));
63 gsl_multifit_linear_workspace *work;
65 gsl_vector *c, *x, *y;
72 for (i = 0; i < (size_t) n; i++)
73 if (gsl_finite(yy[i])) {
78 if ((
int) n2 < dim || n2 < 0.9 * n) {
79 for (i = 0; i < (size_t) n; i++)
85 work = gsl_multifit_linear_alloc((
size_t) n2, (
size_t) dim);
86 cov = gsl_matrix_alloc((
size_t) dim, (
size_t) dim);
87 X = gsl_matrix_alloc((
size_t) n2, (
size_t) dim);
88 c = gsl_vector_alloc((
size_t) dim);
89 x = gsl_vector_alloc((
size_t) n2);
90 y = gsl_vector_alloc((
size_t) n2);
93 for (i = 0; i < (size_t) n2; i++) {
94 gsl_vector_set(x, i, xx2[i]);
95 gsl_vector_set(y, i, yy2[i]);
96 for (i2 = 0; i2 < (size_t) dim; i2++)
97 gsl_matrix_set(X, i, i2, pow(gsl_vector_get(x, i), (
double) i2));
99 gsl_multifit_linear(X, y, c, cov, &chisq, work);
100 for (i = 0; i < (size_t) n; i++)
101 yy[i] = gsl_poly_eval(c->data, (
int) dim, xx[i]);
104 gsl_multifit_linear_free(work);
105 gsl_matrix_free(cov);
119 double help[
WX], x[
WX], x2[
WY], y[
WX], y2[
WY];
124 for (ix = 0; ix < wave->
nx; ix++)
125 for (iy = 0; iy < wave->
ny; iy++) {
126 wave->
bg[ix][iy] = wave->
temp[ix][iy];
127 wave->
pt[ix][iy] = 0;
131 if (dim_x <= 0 && dim_y <= 0)
136 for (iy = 0; iy < wave->
ny; iy++) {
137 for (ix = 0; ix <= 53; ix++) {
139 y[ix] = wave->
bg[ix][iy];
142 for (ix = 0; ix <= 29; ix++)
145 for (ix = 6; ix <= 59; ix++) {
146 x[ix - 6] = (double) ix;
147 y[ix - 6] = wave->
bg[ix][iy];
150 for (ix = 30; ix <= 59; ix++)
151 help[ix] = y[ix - 6];
153 for (ix = 0; ix < wave->
nx; ix++)
154 wave->
bg[ix][iy] = help[ix];
159 for (ix = 0; ix < wave->
nx; ix++) {
160 for (iy = 0; iy < wave->
ny; iy++) {
162 y2[iy] = wave->
bg[ix][iy];
165 for (iy = 0; iy < wave->
ny; iy++)
166 wave->
bg[ix][iy] = y2[iy];
170 for (ix = 0; ix < wave->
nx; ix++)
171 for (iy = 0; iy < wave->
ny; iy++)
172 wave->
pt[ix][iy] = wave->
temp[ix][iy] - wave->
bg[ix][iy];
182 const double dmax = 2500.0;
184 static double help[
WX][
WY];
187 if (npts_x <= 0 && npts_y <= 0)
191 for (
int ix = 0; ix < wave->
nx; ix++)
192 for (
int iy = 0; iy < wave->
ny; iy++) {
199 const int dx = GSL_MIN(GSL_MIN(npts_x, ix), wave->
nx - 1 - ix);
200 const int dy = GSL_MIN(GSL_MIN(npts_y, iy), wave->
ny - 1 - iy);
203 for (
int i = ix - dx; i <= ix + dx; i++)
204 for (
int j = iy - dy; j <= iy + dy; j++)
205 if (fabs(wave->
x[ix] - wave->
x[i]) < dmax &&
206 fabs(wave->
y[iy] - wave->
y[j]) < dmax) {
207 help[ix][iy] += wave->
bg[i][j];
215 help[ix][iy] = GSL_NAN;
219 for (
int ix = 0; ix < wave->
nx; ix++)
220 for (
int iy = 0; iy < wave->
ny; iy++) {
221 wave->
bg[ix][iy] = help[ix][iy];
222 wave->
pt[ix][iy] = wave->
temp[ix][iy] - wave->
bg[ix][iy];
232 static double help[
WX][
WY];
239 const double sigma2 = gsl_pow_2(fwhm / 2.3548);
242 for (
int ix = 0; ix < wave->
nx; ix++)
243 for (
int iy = 0; iy < wave->
ny; iy++) {
250 for (
int ix2 = 0; ix2 < wave->
nx; ix2++)
251 for (
int iy2 = 0; iy2 < wave->
ny; iy2++) {
252 const double d2 = gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
253 + gsl_pow_2(wave->
y[iy] - wave->
y[iy2]);
254 if (d2 <= 9 * sigma2) {
255 const double w = exp(-d2 / (2 * sigma2));
257 help[ix][iy] += w * wave->
pt[ix2][iy2];
262 wave->
pt[ix][iy] = help[ix][iy] / wsum;
272 static double help[
WX][
WY];
275 for (
int iter = 0; iter < niter; iter++) {
278 for (
int ix = 0; ix < wave->
nx; ix++)
279 for (
int iy = 0; iy < wave->
ny; iy++)
281 = 0.23 * wave->
pt[ix > 0 ? ix - 1 : ix][iy]
282 + 0.54 * wave->
pt[ix][iy]
283 + 0.23 * wave->
pt[ix < wave->nx - 1 ? ix + 1 : ix][iy];
286 for (
int ix = 0; ix < wave->
nx; ix++)
287 for (
int iy = 0; iy < wave->
ny; iy++)
289 = 0.23 * help[ix][iy > 0 ? iy - 1 : iy]
290 + 0.54 * help[ix][iy]
291 + 0.23 * help[ix][iy < wave->ny - 1 ? iy + 1 : iy];
307 else if (format == 2)
312 ERRMSG(
"Unknown IASI Level-1 data format!");
321 const char *product_class;
329 int i, j, w, tr1, tr2, tr1_lpm, tr1_rpm, tr2_lpm, tr2_rpm,
330 ichan, mdr_i, num_dims = 1;
332 long dim[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
334 short int IDefScaleSondNbScale, IDefScaleSondNsfirst[10],
335 IDefScaleSondNslast[10], IDefScaleSondScaleFactor[10];
346 CODA(coda_open(filename, &pf));
347 CODA(coda_get_product_class(pf, &product_class));
348 CODA(coda_cursor_set_product(&cursor, pf));
351 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"GIADR_ScaleFactors"));
353 CODA(coda_cursor_goto_record_field_by_name
354 (&cursor,
"IDefScaleSondNbScale"));
355 CODA(coda_cursor_read_int16(&cursor, &IDefScaleSondNbScale));
356 CODA(coda_cursor_goto_parent(&cursor));
358 CODA(coda_cursor_goto_record_field_by_name
359 (&cursor,
"IDefScaleSondNsfirst"));
360 CODA(coda_cursor_read_int16_array
361 (&cursor, IDefScaleSondNsfirst, coda_array_ordering_c));
362 CODA(coda_cursor_goto_parent(&cursor));
364 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"IDefScaleSondNslast"));
365 CODA(coda_cursor_read_int16_array
366 (&cursor, IDefScaleSondNslast, coda_array_ordering_c));
367 CODA(coda_cursor_goto_parent(&cursor));
369 CODA(coda_cursor_goto_record_field_by_name
370 (&cursor,
"IDefScaleSondScaleFactor"));
371 CODA(coda_cursor_read_int16_array
372 (&cursor, IDefScaleSondScaleFactor, coda_array_ordering_c));
376 scaling[ichan] = GSL_NAN;
377 for (i = 0; i < IDefScaleSondNbScale; i++) {
378 sc = (float) pow(10.0, -IDefScaleSondScaleFactor[i]);
379 for (ichan = IDefScaleSondNsfirst[i] - 1;
380 ichan < IDefScaleSondNslast[i]; ichan++) {
388 CODA(coda_cursor_goto_root(&cursor));
389 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"MDR"));
390 CODA(coda_cursor_get_array_dim(&cursor, &num_dims, dim));
391 iasi_raw->
ntrack = dim[0];
394 for (mdr_i = 0; mdr_i < iasi_raw->
ntrack; mdr_i++) {
397 CODA(coda_cursor_goto_root(&cursor));
400 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"MDR"));
401 CODA(coda_cursor_goto_array_element_by_index(&cursor, mdr_i));
402 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"MDR"));
403 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"GS1cSpect"));
404 CODA(coda_cursor_read_int16_array
405 (&cursor, &iasi_raw->
Radiation[mdr_i][0][0][0],
406 coda_array_ordering_c));
409 CODA(coda_cursor_goto_parent(&cursor));
410 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"OnboardUTC"));
411 CODA(coda_cursor_read_double_array
412 (&cursor, &iasi_raw->
Time[mdr_i][0], coda_array_ordering_c));
415 CODA(coda_cursor_goto_parent(&cursor));
416 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"GGeoSondLoc"));
417 CODA(coda_cursor_read_double_array
418 (&cursor, &iasi_raw->
Loc[mdr_i][0][0][0], coda_array_ordering_c));
421 CODA(coda_cursor_goto_parent(&cursor));
422 CODA(coda_cursor_goto_record_field_by_name(&cursor,
423 "EARTH_SATELLITE_DISTANCE"));
424 CODA(coda_cursor_read_uint32(&cursor, &iasi_raw->
Sat_z[mdr_i]));
429 CODA(coda_cursor_goto_parent(&cursor));
430 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"IDefNsfirst1b"));
433 ERRMSG(
"Unexpected value for IDefNsfirst1b!");
435 CODA(coda_cursor_goto_parent(&cursor));
436 CODA(coda_cursor_goto_record_field_by_name(&cursor,
"IDefNslast1b"));
439 ERRMSG(
"Unexpected value for IDefNslast1b!");
450 CODA(coda_close(pf));
463 for (mdr_i = 0; mdr_i < iasi_raw->
ntrack; mdr_i++) {
473 iasi_rad->
Time[tr1][i * 2] = iasi_raw->
Time[mdr_i][i];
474 iasi_rad->
Time[tr1][i * 2 + 1] = iasi_raw->
Time[mdr_i][i];
475 iasi_rad->
Time[tr2][i * 2] = iasi_raw->
Time[mdr_i][i];
476 iasi_rad->
Time[tr2][i * 2 + 1] = iasi_raw->
Time[mdr_i][i];
481 iasi_rad->
Longitude[tr1][i * 2] = iasi_raw->
Loc[mdr_i][i][tr1_lpm][0];
483 iasi_raw->
Loc[mdr_i][i][tr1_rpm][0];
484 iasi_rad->
Latitude[tr1][i * 2] = iasi_raw->
Loc[mdr_i][i][tr1_lpm][1];
485 iasi_rad->
Latitude[tr1][i * 2 + 1] =
486 iasi_raw->
Loc[mdr_i][i][tr1_rpm][1];
488 iasi_rad->
Longitude[tr2][i * 2] = iasi_raw->
Loc[mdr_i][i][tr2_lpm][0];
490 iasi_raw->
Loc[mdr_i][i][tr2_rpm][0];
491 iasi_rad->
Latitude[tr2][i * 2] = iasi_raw->
Loc[mdr_i][i][tr2_lpm][1];
492 iasi_rad->
Latitude[tr2][i * 2 + 1] =
493 iasi_raw->
Loc[mdr_i][i][tr2_rpm][1];
501 iasi_rad->
Sat_z[tr1] =
503 iasi_rad->
Sat_z[tr2] =
509 sc = scaling[ichan] * 100.0f;
510 iasi_rad->
Rad[tr1][i * 2][ichan] =
511 iasi_raw->
Radiation[mdr_i][i][tr1_lpm][ichan] * sc;
512 iasi_rad->
Rad[tr1][i * 2 + 1][ichan] =
513 iasi_raw->
Radiation[mdr_i][i][tr1_rpm][ichan] * sc;
514 iasi_rad->
Rad[tr2][i * 2][ichan] =
515 iasi_raw->
Radiation[mdr_i][i][tr2_lpm][ichan] * sc;
516 iasi_rad->
Rad[tr2][i * 2 + 1][ichan] =
517 iasi_raw->
Radiation[mdr_i][i][tr2_rpm][ichan] * sc;
523 for (i = 0; i < iasi_rad->
ntrack; i++)
525 if (iasi_rad->
Rad[i][j][6753] > iasi_rad->
Rad[i][j][6757]
526 || iasi_rad->
Rad[i][j][6753] < 0)
528 iasi_rad->
Rad[i][j][ichan] = GSL_NAN;
541static int cmp_orbit_scan(
561 int ncid = -1, dim_point_id = -1, dim_chan_id = -1, var_lat = -1,
562 var_lon = -1, var_date = -1, var_orbit = -1, var_scan = -1,
563 var_pixel = -1, var_fov = -1, var_channame = -1, var_R = -1,
564 *channel_name = NULL;
566 size_t npoint = 0, nchan = 0;
569 int *orbit_all = NULL;
570 int *scan_all = NULL;
571 int *pixel_all = NULL;
573 double *lat_all = NULL;
574 double *lon_all = NULL;
575 double *date_all = NULL;
588 iasi_rad->
freq[ichan] = 644.75 + (
double) (ichan + 1) * 0.25;
591 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
592 WARN(
"Cannot open file %s", filename);
597 NC(nc_inq_dimid(ncid,
"point", &dim_point_id));
598 NC(nc_inq_dimlen(ncid, dim_point_id, &npoint));
599 NC(nc_inq_dimid(ncid,
"channel", &dim_chan_id));
600 NC(nc_inq_dimlen(ncid, dim_chan_id, &nchan));
601 if (npoint == 0 || nchan == 0)
602 ERRMSG(
"Empty file, npoint and/or nchan is zero!");
605 NC(nc_inq_varid(ncid,
"lat", &var_lat));
606 NC(nc_inq_varid(ncid,
"lon", &var_lon));
607 NC(nc_inq_varid(ncid,
"date", &var_date));
608 NC(nc_inq_varid(ncid,
"orbit", &var_orbit));
609 NC(nc_inq_varid(ncid,
"scan", &var_scan));
610 NC(nc_inq_varid(ncid,
"pixel", &var_pixel));
611 NC(nc_inq_varid(ncid,
"fov", &var_fov));
612 NC(nc_inq_varid(ncid,
"channel_name", &var_channame));
613 NC(nc_inq_varid(ncid,
"R", &var_R));
616 ALLOC(channel_name,
int,
618 NC(nc_get_var_int(ncid, var_channame, channel_name));
621 ALLOC(orbit_all,
int,
625 ALLOC(pixel_all,
int,
629 ALLOC(lat_all,
double,
631 ALLOC(lon_all,
double,
633 ALLOC(date_all,
double,
639 NC(nc_get_var_int(ncid, var_orbit, orbit_all));
640 NC(nc_get_var_int(ncid, var_scan, scan_all));
641 NC(nc_get_var_int(ncid, var_pixel, pixel_all));
642 NC(nc_get_var_int(ncid, var_fov, fov_all));
643 NC(nc_get_var_double(ncid, var_lat, lat_all));
644 NC(nc_get_var_double(ncid, var_lon, lon_all));
645 NC(nc_get_var_double(ncid, var_date, date_all));
646 NC(nc_get_var_float(ncid, var_R, R_all));
650 for (
size_t i = 0; i < npoint; i++) {
651 keys_all[i].
orbit = orbit_all[i];
652 keys_all[i].
scan = scan_all[i];
656 qsort(keys_all, npoint,
sizeof(
orbit_scan_t), cmp_orbit_scan);
659 for (
size_t i = 0; i < npoint; i++)
660 if (i == 0 || cmp_orbit_scan(&keys_all[i], &keys_all[i - 1]) != 0)
661 keys_uniq[nuniq++] = keys_all[i];
665 ERRMSG(
"Too many scanlines in file: %zu (max %d). Increase L1_NTRACK!",
669 iasi_rad->
ntrack = (int) (2 * nuniq);
672 for (
int tr = 0; tr < iasi_rad->
ntrack; tr++)
675 iasi_rad->
Rad[tr][ix][g] = GSL_NAN;
678 for (
int tr = 0; tr < iasi_rad->
ntrack; tr++) {
679 iasi_rad->
Sat_z[tr] = GSL_NAN;
680 iasi_rad->
Sat_lon[tr] = GSL_NAN;
681 iasi_rad->
Sat_lat[tr] = GSL_NAN;
685 for (
size_t i = 0; i < npoint; i++) {
689 key.
orbit = orbit_all[i];
690 key.
scan = scan_all[i];
696 size_t scan_idx = (size_t) (found - keys_uniq);
699 if (f < 1 || f > 120)
703 int pos = (f - 1) / 4;
704 int sub = (f - 1) % 4;
708 int track_add, x_add;
730 int tr = 2 * (int) scan_idx + track_add;
731 int ix = 2 * pos + x_add;
733 if (tr < 0 || tr >= iasi_rad->
ntrack)
739 iasi_rad->
Time[tr][ix] = date_all[i];
740 iasi_rad->
Longitude[tr][ix] = lon_all[i];
741 iasi_rad->
Latitude[tr][ix] = lat_all[i];
742 float *row = &R_all[i * nchan];
743 for (
size_t k = 0; k < nchan; k++) {
744 int g = channel_name[k] - 1;
746 iasi_rad->
Rad[tr][ix][g] = 100.0f * row[k];
773 static double data[
WX *
WY], help[
WX][
WY];
780 for (
int ix = 0; ix < wave->
nx; ix++)
781 for (
int iy = 0; iy < wave->
ny; iy++) {
787 for (
int ix2 = GSL_MAX(ix - dx, 0);
788 ix2 < GSL_MIN(ix + dx, wave->
nx - 1); ix2++)
789 for (
int iy2 = GSL_MAX(iy - dx, 0);
790 iy2 < GSL_MIN(iy + dx, wave->
ny - 1); iy2++) {
791 data[n] = wave->
pt[ix2][iy2];
796 gsl_sort(data, 1, n);
797 help[ix][iy] = gsl_stats_median_from_sorted_data(data, 1, n);
801 for (
int ix = 0; ix < wave->
nx; ix++)
802 for (
int iy = 0; iy < wave->
ny; iy++)
803 wave->
pt[ix][iy] = help[ix][iy];
813 int ix, ix2, iy, iy2, n = 0, okay;
820 for (ix = 1; ix < wave->
nx - 1; ix++)
821 for (iy = 1; iy < wave->
ny - 1; iy++) {
825 for (ix2 = ix - 1; ix2 <= ix + 1; ix2++)
826 for (iy2 = iy - 1; iy2 <= iy + 1; iy2++)
827 if (!gsl_finite(wave->
temp[ix2][iy2]))
834 *mu += wave->
temp[ix][iy];
835 *sig += gsl_pow_2(+4. / 6. * wave->
temp[ix][iy]
836 - 2. / 6. * (wave->
temp[ix - 1][iy]
837 + wave->
temp[ix + 1][iy]
838 + wave->
temp[ix][iy - 1]
839 + wave->
temp[ix][iy + 1])
840 + 1. / 6. * (wave->
temp[ix - 1][iy - 1]
841 + wave->
temp[ix + 1][iy - 1]
842 + wave->
temp[ix - 1][iy + 1]
843 + wave->
temp[ix + 1][iy + 1]));
848 *sig = sqrt(*sig / (
double) n);
866 track0 = GSL_MIN(GSL_MAX(track0, 0), pert->
ntrack - 1);
867 track1 = GSL_MIN(GSL_MAX(track1, 0), pert->
ntrack - 1);
868 xtrack0 = GSL_MIN(GSL_MAX(xtrack0, 0), pert->
nxtrack - 1);
869 xtrack1 = GSL_MIN(GSL_MAX(xtrack1, 0), pert->
nxtrack - 1);
872 wave->
nx = xtrack1 - xtrack0 + 1;
874 ERRMSG(
"Too many across-track values!");
875 wave->
ny = track1 - track0 + 1;
877 ERRMSG(
"Too many along-track values!");
880 for (itrack = track0; itrack <= track1; itrack++)
881 for (ixtrack = xtrack0; ixtrack <= xtrack1; ixtrack++) {
884 if (itrack == track0) {
886 if (ixtrack > xtrack0) {
887 geo2cart(0, pert->
lon[itrack][ixtrack - 1],
888 pert->
lat[itrack][ixtrack - 1], x0);
889 geo2cart(0, pert->
lon[itrack][ixtrack],
890 pert->
lat[itrack][ixtrack], x1);
891 wave->
x[ixtrack - xtrack0] =
892 wave->
x[ixtrack - xtrack0 - 1] + DIST(x0, x1);
895 if (ixtrack == xtrack0) {
897 if (itrack > track0) {
898 geo2cart(0, pert->
lon[itrack - 1][ixtrack],
899 pert->
lat[itrack - 1][ixtrack], x0);
900 geo2cart(0, pert->
lon[itrack][ixtrack],
901 pert->
lat[itrack][ixtrack], x1);
902 wave->
y[itrack - track0] =
903 wave->
y[itrack - track0 - 1] + DIST(x0, x1);
908 wave->
time = pert->
time[(track0 + track1) / 2][(xtrack0 + xtrack1) / 2];
910 wave->
lon[ixtrack - xtrack0][itrack - track0] =
911 pert->
lon[itrack][ixtrack];
912 wave->
lat[ixtrack - xtrack0][itrack - track0] =
913 pert->
lat[itrack][ixtrack];
916 wave->
temp[ixtrack - xtrack0][itrack - track0]
917 = pert->
bt[itrack][ixtrack];
918 wave->
bg[ixtrack - xtrack0][itrack - track0]
919 = pert->
bt[itrack][ixtrack] - pert->
pt[itrack][ixtrack];
920 wave->
pt[ixtrack - xtrack0][itrack - track0]
921 = pert->
pt[itrack][ixtrack];
922 wave->
var[ixtrack - xtrack0][itrack - track0]
923 = pert->
var[itrack][ixtrack];
934 static char varname[LEN];
936 static int dimid[2], ncid, varid;
938 static size_t ntrack, nxtrack, start[2] = { 0, 0 }, count[2] = { 1, 1 };
941 printf(
"Read perturbation data: %s\n", filename);
944 NC(nc_open(filename, NC_NOWRITE, &ncid));
947 NC(nc_inq_dimid(ncid,
"NTRACK", &dimid[0]));
948 NC(nc_inq_dimid(ncid,
"NXTRACK", &dimid[1]));
949 NC(nc_inq_dimlen(ncid, dimid[0], &ntrack));
950 NC(nc_inq_dimlen(ncid, dimid[1], &nxtrack));
952 ERRMSG(
"Too many tracks!");
954 ERRMSG(
"Too many scans!");
955 pert->
ntrack = (int) ntrack;
960 NC(nc_inq_varid(ncid,
"time", &varid));
961 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
963 NC(nc_get_vara_double(ncid, varid, start, count, pert->
time[itrack]));
966 NC(nc_inq_varid(ncid,
"lon", &varid));
967 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
969 NC(nc_get_vara_double(ncid, varid, start, count, pert->
lon[itrack]));
972 NC(nc_inq_varid(ncid,
"lat", &varid));
973 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
975 NC(nc_get_vara_double(ncid, varid, start, count, pert->
lat[itrack]));
978 NC(nc_inq_varid(ncid,
"bt_8mu", &varid));
979 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
981 NC(nc_get_vara_double(ncid, varid, start, count, pert->
dc[itrack]));
984 sprintf(varname,
"bt_%s", pertname);
985 NC(nc_inq_varid(ncid, varname, &varid));
986 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
988 NC(nc_get_vara_double(ncid, varid, start, count, pert->
bt[itrack]));
991 sprintf(varname,
"bt_%s_pt", pertname);
992 NC(nc_inq_varid(ncid, varname, &varid));
993 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
995 NC(nc_get_vara_double(ncid, varid, start, count, pert->
pt[itrack]));
998 sprintf(varname,
"bt_%s_var", pertname);
999 NC(nc_inq_varid(ncid, varname, &varid));
1000 for (
size_t itrack = 0; itrack < ntrack; itrack++) {
1002 NC(nc_get_vara_double(ncid, varid, start, count, pert->
var[itrack]));
1015 double dh2, mu, help;
1017 int dx, dy, ix, ix2, iy, iy2, n;
1024 dh2 = gsl_pow_2(dh);
1028 (int) (dh / fabs(wave->
x[wave->
nx - 1] - wave->
x[0]) *
1029 (wave->
nx - 1.0) + 1);
1031 (int) (dh / fabs(wave->
y[wave->
ny - 1] - wave->
y[0]) *
1032 (wave->
ny - 1.0) + 1);
1035 for (ix = 0; ix < wave->
nx; ix++)
1036 for (iy = 0; iy < wave->
ny; iy++) {
1043 for (ix2 = GSL_MAX(ix - dx, 0); ix2 <= GSL_MIN(ix + dx, wave->
nx - 1);
1045 for (iy2 = GSL_MAX(iy - dy, 0);
1046 iy2 <= GSL_MIN(iy + dy, wave->
ny - 1); iy2++)
1047 if ((gsl_pow_2(wave->
x[ix] - wave->
x[ix2])
1048 + gsl_pow_2(wave->
y[iy] - wave->
y[iy2])) <= dh2)
1049 if (gsl_finite(wave->
pt[ix2][iy2])) {
1050 mu += wave->
pt[ix2][iy2];
1051 help += gsl_pow_2(wave->
pt[ix2][iy2]);
1057 wave->
var[ix][iy] = help / n - gsl_pow_2(mu / n);
1059 wave->
var[ix][iy] = GSL_NAN;
1068 const double a = 6378.1370, b = 6356.7523;
1072 cphi = cos(lat * M_PI / 180.);
1073 sphi = sin(lat * M_PI / 180.);
1075 return sqrt((gsl_pow_2(a * a * cphi) + gsl_pow_2(b * b * sphi))
1076 / (gsl_pow_2(a * cphi) + gsl_pow_2(b * sphi)));
1085 int dimid[10], ncid, time_id, lon_id, lat_id,
1086 sat_z_id, sat_lon_id, sat_lat_id, nu_id, rad_id;
1089 printf(
"Write IASI Level-1 file: %s\n", filename);
1090 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
1091 NC(nc_create(filename, NC_CLOBBER, &ncid));
1097 if (nc_inq_dimid(ncid,
"L1_NTRACK", &dimid[0]) != NC_NOERR)
1098 NC(nc_def_dim(ncid,
"L1_NTRACK", l1->
ntrack, &dimid[0]));
1099 if (nc_inq_dimid(ncid,
"L1_NXTRACK", &dimid[1]) != NC_NOERR)
1100 NC(nc_def_dim(ncid,
"L1_NXTRACK",
L1_NXTRACK, &dimid[1]));
1101 if (nc_inq_dimid(ncid,
"L1_NCHAN", &dimid[2]) != NC_NOERR)
1102 NC(nc_def_dim(ncid,
"L1_NCHAN",
L1_NCHAN, &dimid[2]));
1105 add_var(ncid,
"l1_time",
"s",
"time (seconds since 2000-01-01T00:00Z)",
1106 NC_DOUBLE, dimid, &time_id, 2);
1107 add_var(ncid,
"l1_lon",
"deg",
"longitude", NC_DOUBLE, dimid, &lon_id, 2);
1108 add_var(ncid,
"l1_lat",
"deg",
"latitude", NC_DOUBLE, dimid, &lat_id, 2);
1109 add_var(ncid,
"l1_sat_z",
"km",
"satellite altitude",
1110 NC_DOUBLE, dimid, &sat_z_id, 1);
1111 add_var(ncid,
"l1_sat_lon",
"deg",
"(estimated) satellite longitude",
1112 NC_DOUBLE, dimid, &sat_lon_id, 1);
1113 add_var(ncid,
"l1_sat_lat",
"deg",
"(estimated) satellite latitude",
1114 NC_DOUBLE, dimid, &sat_lat_id, 1);
1115 add_var(ncid,
"l1_nu",
"cm^-1",
"channel wavenumber",
1116 NC_DOUBLE, &dimid[2], &nu_id, 1);
1117 add_var(ncid,
"l1_rad",
"W/(m^2 sr cm^-1)",
"channel radiance",
1118 NC_FLOAT, dimid, &rad_id, 3);
1121 NC(nc_enddef(ncid));
1124 NC(nc_put_var_double(ncid, time_id, l1->
time[0]));
1125 NC(nc_put_var_double(ncid, lon_id, l1->
lon[0]));
1126 NC(nc_put_var_double(ncid, lat_id, l1->
lat[0]));
1127 NC(nc_put_var_double(ncid, sat_z_id, l1->
sat_z));
1128 NC(nc_put_var_double(ncid, sat_lon_id, l1->
sat_lon));
1129 NC(nc_put_var_double(ncid, sat_lat_id, l1->
sat_lat));
1130 NC(nc_put_var_double(ncid, nu_id, l1->
nu));
1131 NC(nc_put_var_float(ncid, rad_id, &l1->
rad[0][0][0]));
1143 int dimid[10], ncid, time_id, z_id, lon_id, lat_id, p_id, t_id;
1146 printf(
"Write IASI Level-2 file: %s\n", filename);
1147 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
1148 NC(nc_create(filename, NC_CLOBBER, &ncid));
1154 if (nc_inq_dimid(ncid,
"L2_NTRACK", &dimid[0]) != NC_NOERR)
1155 NC(nc_def_dim(ncid,
"L2_NTRACK", l2->
ntrack, &dimid[0]));
1156 if (nc_inq_dimid(ncid,
"L2_NXTRACK", &dimid[1]) != NC_NOERR)
1157 NC(nc_def_dim(ncid,
"L2_NXTRACK",
L2_NXTRACK, &dimid[1]));
1158 if (nc_inq_dimid(ncid,
"L2_NLAY", &dimid[2]) != NC_NOERR)
1159 NC(nc_def_dim(ncid,
"L2_NLAY",
L2_NLAY, &dimid[2]));
1162 add_var(ncid,
"l2_time",
"s",
"time (seconds since 2000-01-01T00:00Z)",
1163 NC_DOUBLE, dimid, &time_id, 2);
1164 add_var(ncid,
"l2_z",
"km",
"altitude", NC_DOUBLE, dimid, &z_id, 3);
1165 add_var(ncid,
"l2_lon",
"deg",
"longitude", NC_DOUBLE, dimid, &lon_id, 2);
1166 add_var(ncid,
"l2_lat",
"deg",
"latitude", NC_DOUBLE, dimid, &lat_id, 2);
1167 add_var(ncid,
"l2_press",
"hPa",
"pressure",
1168 NC_DOUBLE, &dimid[2], &p_id, 1);
1169 add_var(ncid,
"l2_temp",
"K",
"temperature", NC_DOUBLE, dimid, &t_id, 3);
1172 NC(nc_enddef(ncid));
1175 NC(nc_put_var_double(ncid, time_id, l2->
time[0]));
1176 NC(nc_put_var_double(ncid, z_id, l2->
z[0][0]));
1177 NC(nc_put_var_double(ncid, lon_id, l2->
lon[0]));
1178 NC(nc_put_var_double(ncid, lat_id, l2->
lat[0]));
1179 NC(nc_put_var_double(ncid, p_id, l2->
p));
1180 NC(nc_put_var_double(ncid, t_id, l2->
t[0][0]));
void iasi_read(int format, char *filename, iasi_rad_t *iasi_rad)
Read IASI Level-1 data.
void background_poly_help(double *xx, double *yy, int n, int dim)
Get background based on polynomial fits.
void background_smooth(wave_t *wave, int npts_x, int npts_y)
Smooth background.
void write_l2(char *filename, iasi_l2_t *l2)
Write IASI Level-2 data.
void noise(wave_t *wave, double *mu, double *sig)
Estimate noise.
void write_l1(char *filename, iasi_l1_t *l1)
Write IASI Level-1 data.
void iasi_read_netcdf(char *filename, iasi_rad_t *iasi_rad)
Read IASI Level-1 data from netCDF file.
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 variance(wave_t *wave, double dh)
Compute local variance.
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 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_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 iasi_read_native(char *filename, iasi_rad_t *iasi_rad)
Read IASI Level-1 data from native file.
void median(wave_t *wave, int dx)
Apply median filter to perturbations...
double wgs84(double lat)
Calculate Earth radius according to WGS-84 reference ellipsoid.
IASI Code Collection library declarations.
#define IASI_NXTRACK
Raw data across-track size of IASI radiance granule.
#define IASI_IDefNslast1b
Expected value for the computation of the last wavenumber.
#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 IASI radiance granule (don't change).
#define L1_NTRACK
Maximum along-track size of IASI radiance granule (don't change).
#define IASI_L1_NCHAN
Number of channels of IASI radiance granule.
#define WX
Across-track size of wave analysis data.
#define L2_NXTRACK
Across-track size of IASI retrieval granule (don't change).
#define PERT_NTRACK
Along-track size of perturbation data.
#define IASI_IDefSpectDWn1b
Expected value for the interval of the IASI wavenumbers [m^-1].
#define L2_NLAY
Number of IASI pressure layers (don't change).
#define IASI_IDefNsfirst1b
Expected value for the computation of the first wavenumber.
#define L1_NCHAN
Number of IASI radiance channels (don't change).
#define CODA(cmd)
Execute CODA library command and check result.
#define WY
Along-track size of wave analysis data.
double sat_z[L1_NTRACK]
Satellite altitude [km].
double nu[L1_NCHAN]
Channel frequencies [cm^-1].
double sat_lon[L1_NTRACK]
Satellite longitude [deg].
double sat_lat[L1_NTRACK]
Satellite latitude [deg].
double lon[L1_NTRACK][L1_NXTRACK]
Footprint longitude [deg].
double time[L1_NTRACK][L1_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
double lat[L1_NTRACK][L1_NXTRACK]
Footprint latitude [deg].
float rad[L1_NTRACK][L1_NXTRACK][L1_NCHAN]
Radiance [W/(m^2 sr cm^-1)].
size_t ntrack
Number of along-track values.
double time[L2_NTRACK][L2_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
double lon[L2_NTRACK][L2_NXTRACK]
Longitude [deg].
double p[L2_NLAY]
Pressure [hPa].
double lat[L2_NTRACK][L2_NXTRACK]
Latitude [deg].
double t[L2_NTRACK][L2_NXTRACK][L2_NLAY]
Temperature [K].
double z[L2_NTRACK][L2_NXTRACK][L2_NLAY]
Geopotential height [km].
size_t ntrack
Number of along-track values.
IASI converted Level-1 radiation data.
double Longitude[L1_NTRACK][L1_NXTRACK]
Longitude of the sounder pixel.
double Latitude[L1_NTRACK][L1_NXTRACK]
Latitude of the sounder pixel.
double Time[L1_NTRACK][L1_NXTRACK]
Seconds since 2000-01-01 for each sounder pixel.
double freq[IASI_L1_NCHAN]
channel wavenumber [cm^-1]
int ntrack
Number of along-track samples.
double Sat_lon[L1_NTRACK]
Estimated longitude of the satellite.
double Sat_z[L1_NTRACK]
Altitude of the satellite.
float Rad[L1_NTRACK][L1_NXTRACK][IASI_L1_NCHAN]
Radiance [W/(m^2 sr cm^-1)].
double Sat_lat[L1_NTRACK]
Estimated latitude of the satellite.
float Wavenumber[IASI_L1_NCHAN]
Wavenumbers are computed with the expected values.
float IDefSpectDWn1b[L1_NTRACK]
Constants for radiation spectrum (must be equal to the expected constant).
int32_t IDefNslast1b[L1_NTRACK]
Constants for radiation spectrum (must be equal to the expected constant).
double Time[L1_NTRACK][IASI_NXTRACK]
Time (seconds since 2000-01-01T00:00Z).
long ntrack
Number of along-track samples.
short int Radiation[L1_NTRACK][IASI_NXTRACK][IASI_PM][IASI_L1_NCHAN]
Radiance [W/(m^2 sr m^-1)].
unsigned int Sat_z[L1_NTRACK]
Satellite altitude [m].
int32_t IDefNsfirst1b[L1_NTRACK]
Constants for radiation spectrum (must be equal to the expected constant).
double Loc[L1_NTRACK][IASI_NXTRACK][IASI_PM][2]
Location of the sounder pixel (long,lat).
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].
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 time
Time (seconds since 2000-01-01T00:00Z).
double pt[WX][WY]
Perturbation [K].