18 static int firstCall = 1;
19 static int nx =
NXANC;
20 static int ny =
NYANC;
21 static float dx = 360.0 /
NXANC;
22 static float dy = 180.0 /
NYANC;
24 typedef float map_frac_t[
NXANC + 2];
25 static map_frac_t *map_frac;
42 int32 dims[H4_MAX_VAR_DIMS];
46 char name[H4_MAX_NC_NAME];
47 char sdsname[H4_MAX_NC_NAME];
49 char *no2_frac_fil, no2_frac_file[300];
56 if ((no2_frac_fil = getenv(
"OCDATAROOT")) ==
NULL) {
57 printf(
"-E- %s: Error looking up environmental variable OCDATAROOT\n", __FILE__);
60 strcpy(no2_frac_file, no2_frac_fil);
61 strcat(no2_frac_file,
"/common/trop_f_no2_200m.hdf");
65 printf(
"-E- %s: Error allocating NO2 frac space for %s.\n", __FILE__, no2_frac_file);
69 sd_id = SDstart(no2_frac_file, DFACC_RDONLY);
71 printf(
"-E- %s: Error opening NO2 frac file %s.\n", __FILE__, no2_frac_file);
75 printf(
"\nOpening NO2 frac file %s\n\n", no2_frac_file);
77 strcpy(sdsname,
"f_no2_200m");
78 sds_index = SDnametoindex(sd_id, sdsname);
79 if (sds_index == -1) {
80 printf(
"-E- %s: Error seeking %s SDS from %s.\n", __FILE__, sdsname, no2_frac_file);
83 sds_id = SDselect(sd_id, sds_index);
87 printf(
"-E- %s: Error reading SDS info for %s from %s.\n", __FILE__, sdsname, no2_frac_file);
90 if (dims[0] != ny || dims[1] != nx) {
91 printf(
"-E- %s: Dimension mis-match on %s array from %s.\n", __FILE__, sdsname, no2_frac_file);
92 printf(
" Expecting %d x %d\n", nx, ny);
93 printf(
" Reading %d x %d\n", dims[1], dims[0]);
104 printf(
"-E- %s: Error reading SDS %s from %s.\n", __FILE__, sdsname, no2_frac_file);
108 for (
j = 0;
j < ny;
j++) {
109 for (
i = 0;
i < nx;
i++) {
110 map_frac[
j + 1][
i + 1] = map[ny -
j - 1][
i];
116 for (
j = 0;
j < ny;
j++) {
117 map_frac[
j + 1][0] = map_frac[
j + 1][nx];
118 map_frac[
j + 1][nx + 1] = map_frac[
j + 1][1];
120 for (
i = 0;
i < nx + 2;
i++) {
121 map_frac[0][
i] = map_frac[1][
i];
122 map_frac[ny + 1][
i] = map_frac[ny][
i];
132 i =
MAX(
MIN((
int)((
lon + 180.0 + dx / 2) / dx), nx + 1), 0);
133 j =
MAX(
MIN((
int)((
lat + 90.0 + dy / 2) / dy), ny + 1), 0);
135 xx =
i * dx - 180.0 - dx / 2;
136 yy =
j * dy - 90.0 - dy / 2;
141 frac = (1 -
t) * (1 -
u) * map_frac[
j][
i] +
t * (1 -
u) * map_frac[
j][
i + 1] +
142 t *
u * map_frac[
j + 1][
i + 1] + (1 -
t) *
u * map_frac[
j + 1][
i];
146 *no2_frac_200 =
MAX(frac, 0.0);
152 static int firstCall = 1;
158 static float *mapTropo;
159 static float *mapStrato;
174 hid_t file_id, set_id, space_id;
175 hsize_t dims[2], maxdims[2];
178 hsize_t
start[2] = {(hsize_t)0, (hsize_t)0};
179 hsize_t stride[2] = {(hsize_t)1, (hsize_t)1};
180 hsize_t
count[2] = {(hsize_t)1, (hsize_t)1};
182 if ((file_id = H5Fopen(no2file, H5F_ACC_RDONLY, H5P_DEFAULT)) == -1) {
183 printf(
"error in opening -%s-\n", no2file);
187 set_id = H5Dopen(file_id,
"STRATCOL_NO2", H5P_DEFAULT);
188 space_id = H5Dget_space(set_id);
189 H5Sget_simple_extent_dims(space_id, dims, maxdims);
191 mapTropo=(
float *)malloc(dims[0]*dims[1]*
sizeof(
float));
192 mapStrato=(
float *)malloc(dims[0]*dims[1]*
sizeof(
float));
196 mem_space_id=H5Screate_simple(2,
count,
NULL);
197 H5Sselect_hyperslab(space_id, H5S_SELECT_SET,
start, stride,
count,
NULL);
198 H5Dread(set_id,H5T_NATIVE_FLOAT, mem_space_id, space_id, H5P_DEFAULT, (
void *)mapStrato);
204 set_id = H5Dopen(file_id,
"TROPCOL_NO2", H5P_DEFAULT);
205 space_id = H5Dget_space(set_id);
206 mem_space_id=H5Screate_simple(2,
count,
NULL);
207 H5Sselect_hyperslab(space_id, H5S_SELECT_SET,
start, stride,
count,
NULL);
208 H5Dread(set_id,H5T_NATIVE_FLOAT, mem_space_id, space_id, H5P_DEFAULT, (
void *)mapTropo);
223 i =
MAX(
MIN((
int)((
lon + 180.0 + dx / 2) / dx), nx + 1), 0);
224 j =
MAX(
MIN((
int)((
lat + 90.0 + dy / 2) / dy), ny + 1), 0);
226 xx =
i * dx - 180.0 - dx / 2;
227 yy =
j * dy - 90.0 - dy / 2;
232 strato = (1 -
t) * (1 -
u) * mapStrato[
j*nx+
i] +
t * (1 -
u) * mapStrato[
j*nx+
i + 1] +
233 t *
u * mapStrato[(
j + 1)*nx+
i + 1] + (1 -
t) *
u * mapStrato[(
j + 1)*nx+
i];
235 tropo = (1 -
t) * (1 -
u) * mapTropo[
j*nx+
i] +
t * (1 -
u) * mapTropo[
j*nx+
i + 1] +
236 t *
u * mapTropo[(
j + 1)*nx+
i + 1] + (1 -
t) *
u * mapTropo[(
j + 1)*nx+
i];
240 *no2_strat =
MAX(strato, 0.0);
241 *no2_tropo =
MAX(tropo, 0.0);
246 void no2conc(
char *no2file,
float lon,
float lat, int32_t doy,
float *no2_tropo,
float *no2_strat) {
247 static int firstCall = 1;
248 static int nx =
NXNO2;
249 static int ny =
NYNO2;
250 static float dx = 360.0 /
NXNO2;
251 static float dy = 180.0 /
NYNO2;
253 typedef float map_t[
NXNO2 + 2];
254 static map_t *map_total;
255 static map_t *map_tropo;
267 if (!Hishdf(no2file)) {
279 int32 dims[H4_MAX_VAR_DIMS];
283 char name[H4_MAX_NC_NAME];
284 char sdsname[H4_MAX_NC_NAME];
298 printf(
"-E- %s: Error allocating space for %s.\n", __FILE__, no2file);
302 sd_id = SDstart(no2file, DFACC_RDONLY);
304 printf(
"-E- %s: Error opening NO2 file %s.\n", __FILE__, no2file);
308 printf(
"\nOpening NO2 file %s\n\n", no2file);
310 if (SDreadattr(sd_id, SDfindattr(sd_id,
"Title"), (VOIDP)
title) == 0) {
311 if (strstr(
title,
"NO2 Climatology") !=
NULL) {
312 month = (
int)doy / 31;
313 sprintf(mstr,
"_%2.2i", month + 1);
317 strcpy(sdsname,
"tot_no2");
318 strcat(sdsname, mstr);
319 sds_index = SDnametoindex(sd_id, sdsname);
320 if (sds_index == -1) {
321 printf(
"-E- %s: Error seeking %s SDS from %s.\n", __FILE__, sdsname, no2file);
324 sds_id = SDselect(sd_id, sds_index);
328 printf(
"-E- %s: Error reading SDS info for %s from %s.\n", __FILE__, sdsname, no2file);
331 if (dims[0] != ny || dims[1] != nx) {
332 printf(
"-E- %s: Dimension mis-match on %s array from %s.\n", __FILE__, sdsname, no2file);
333 printf(
" Expecting %d x %d\n", nx, ny);
334 printf(
" Reading %d x %d\n", dims[1], dims[0]);
345 printf(
"-E- %s: Error reading SDS %s from %s.\n", __FILE__, sdsname, no2file);
349 for (
j = 0;
j < ny;
j++) {
350 for (
i = 0;
i < nx;
i++) {
351 map_total[
j + 1][
i + 1] = map[ny -
j - 1][
i];
355 status = SDendaccess(sds_id);
357 printf(
"-E- %s: Error closing SDS %s from %s.\n", __FILE__, sdsname, no2file);
361 strcpy(sdsname,
"trop_no2");
362 strcat(sdsname, mstr);
363 sds_index = SDnametoindex(sd_id, sdsname);
364 if (sds_index == -1) {
365 printf(
"-E- %s: Error seeking %s SDS from %s.\n", __FILE__, sdsname, no2file);
368 sds_id = SDselect(sd_id, sds_index);
372 printf(
"-E- %s: Error reading SDS info for %s from %s.\n", __FILE__, sdsname, no2file);
375 if (dims[0] != ny || dims[1] != nx) {
376 printf(
"-E- %s: Dimension mis-match on %s array from %s.\n", __FILE__, sdsname, no2file);
377 printf(
" Expecting %d x %d\n", nx, ny);
378 printf(
" Reading %d x %d\n", dims[1], dims[0]);
389 printf(
"-E- %s: Error reading SDS %s from %s.\n", __FILE__, sdsname, no2file);
393 status = SDendaccess(sds_id);
395 printf(
"-E- %s: Error closing SDS %s from %s.\n", __FILE__, sdsname, no2file);
399 for (
j = 0;
j < ny;
j++) {
400 for (
i = 0;
i < nx;
i++) {
401 map_tropo[
j + 1][
i + 1] = map[ny -
j - 1][
i];
407 for (
j = 0;
j < ny;
j++) {
408 map_total[
j + 1][0] = map_total[
j + 1][nx];
409 map_total[
j + 1][nx + 1] = map_total[
j + 1][1];
410 map_tropo[
j + 1][0] = map_tropo[
j + 1][nx];
411 map_tropo[
j + 1][nx + 1] = map_tropo[
j + 1][1];
413 for (
i = 0;
i < nx + 2;
i++) {
414 map_total[0][
i] = map_total[1][
i];
415 map_total[ny + 1][
i] = map_total[ny][
i];
416 map_tropo[0][
i] = map_tropo[1][
i];
417 map_tropo[ny + 1][
i] = map_tropo[ny][
i];
426 i =
MAX(
MIN((
int)((
lon + 180.0 + dx / 2) / dx), nx + 1), 0);
427 j =
MAX(
MIN((
int)((
lat + 90.0 + dy / 2) / dy), ny + 1), 0);
429 xx =
i * dx - 180.0 - dx / 2;
430 yy =
j * dy - 90.0 - dy / 2;
435 total = (1 -
t) * (1 -
u) * map_total[
j][
i] +
t * (1 -
u) * map_total[
j][
i + 1] +
436 t *
u * map_total[
j + 1][
i + 1] + (1 -
t) *
u * map_total[
j + 1][
i];
438 tropo = (1 -
t) * (1 -
u) * map_tropo[
j][
i] +
t * (1 -
u) * map_tropo[
j][
i + 1] +
439 t *
u * map_tropo[
j + 1][
i + 1] + (1 -
t) *
u * map_tropo[
j + 1][
i];
443 *no2_strat =
MAX(
total - tropo, 0.0);
444 *no2_tropo =
MAX(tropo, 0.0);
458 static int firstCall = 1;
459 static int nx, ny, mapx;
460 static float dx, dy, *map;
464 float t,
u, val_11, val_12, val_21, val_22;
474 int32 dims[H4_MAX_VAR_DIMS];
478 char name[H4_MAX_NC_NAME];
479 char sdsname[H4_MAX_NC_NAME];
483 if (day < 1 || day > 366) {
484 printf(
"-E- %s: Bogus day number for ozone look-up: %d\n", __FILE__,
day);
499 sd_id = SDstart(
file, DFACC_RDONLY);
501 printf(
"-E- %s: Error openin file %s.\n", __FILE__,
file);
505 printf(
"\nOpening ozone file %s\n\n",
file);
507 sprintf(sdsname,
"ozone_mean_%03d",
day);
508 sds_index = SDnametoindex(sd_id, sdsname);
509 if (sds_index == -1) {
510 printf(
"-E- %s: Error seeking %s SDS from %s.\n", __FILE__, sdsname,
file);
513 sds_id = SDselect(sd_id, sds_index);
517 printf(
"-E- %s: Error reading SDS info for %s from %s.\n", __FILE__, sdsname,
file);
523 if (nx < 0 || ny < 0) {
524 printf(
"-E- %s: grid has bad dimensions, sds %s from %s.\n", __FILE__, sdsname,
file);
525 printf(
" Reading %d x %d\n", nx, ny);
534 if (((
tmp = (
float *)malloc(nx * ny *
sizeof(
float))) ==
NULL) ||
535 ((map = (
float *)malloc(mapx * (ny + 2) *
sizeof(
float))) ==
NULL)) {
536 printf(
"-E- %s, %d: Unable to allocate space for climatology grid storage\n", __FILE__, __LINE__);
547 printf(
"-E- %s: Error reading SDS %s from %s.\n", __FILE__, sdsname,
file);
551 for (
j = 0;
j < ny;
j++) {
552 for (
i = 0;
i < nx;
i++) {
553 *(map +
i + 1 + mapx * (
j + 1)) = *(
tmp +
i + nx *
j);
554 *(map +
i + 1 + mapx * (
j + 1)) = *(
tmp +
i + nx * (ny -
j - 1));
562 for (
j = 0;
j < ny;
j++) {
563 *(map + mapx * (
j + 1)) = *(map + nx + mapx * (
j + 1));
564 *(map + (nx + 1) + mapx * (
j + 1)) = *(map + 1 + mapx * (
j + 1));
566 for (
i = 0;
i < mapx;
i++) {
567 *(map +
i) = *(map + mapx +
i);
568 *(map +
i + mapx * (ny + 1)) = *(map +
i + mapx * ny);
578 i =
MAX(
MIN((
int)((
lon + 180.0 + dx / 2) / dx), nx + 1), 0);
579 j =
MAX(
MIN((
int)((
lat + 90.0 + dy / 2) / dy), ny + 1), 0);
581 xx =
i * dx - 180.0 - dx / 2;
582 yy =
j * dy - 90.0 - dy / 2;
587 val_11 = *(map +
i + mapx *
j);
588 val_12 = *(map +
i + 1 + mapx *
j);
589 val_21 = *(map +
i + mapx * (
j + 1));
590 val_22 = *(map +
i + 1 + mapx * (
j + 1));
592 if ((val_11 < 0) || (val_12 < 0) || (val_21 < 0) || (val_22 < 0)) {
594 printf(
"I %s, %d: Attempt to use missing climatology points\n", __FILE__, __LINE__);
596 ozone = (1 -
t) * (1 -
u) * val_11 +
t * (1 -
u) * val_12 +
t *
u * val_22 + (1 -
t) *
u * val_21;
629 static float r2d = 57.29577951;
630 static int firstCall = 1;
631 static int32_t anc_id[] = {-1, -1};
632 static short *ancqc =
NULL;
633 static char *no2file =
NULL;
636 float u,
v, u_u, v_u, ws_2;
644 int32_t
msec = (int32_t)(dsec * 1.e3);
646 uncertainty_t *uncertainty =
l1rec->uncertainty;
647 static float *dtemp =
NULL;
656 printf(
"\nOpening meteorological files.\n");
657 printf(
" met1 = %s\n",
input->met1);
658 printf(
" met2 = %s\n",
input->met2);
659 printf(
" met3 = %s\n",
input->met3);
660 printf(
" ozone1 = %s\n",
input->ozone1);
661 printf(
" ozone2 = %s\n",
input->ozone2);
662 printf(
" ozone3 = %s\n",
input->ozone3);
663 printf(
" no2 = %s\n",
input->no2file);
666 if ((ancqc = calloc(
npix,
sizeof(
short))) ==
NULL) {
667 fprintf(
stderr,
"-E- %s %d: Unable to allocate buffer space.\n", __FILE__, __LINE__);
671 dtemp = (
float *)malloc(
npix *
sizeof(
float));
673 if (strcmp(
input->no2file,
"") != 0) {
674 no2file =
input->no2file;
685 if ((ancqc = calloc(
npix,
sizeof(
short))) ==
NULL) {
686 fprintf(
stderr,
"-E- %s %d: Unable to allocate buffer space.\n", __FILE__, __LINE__);
691 dtemp = (
float *)malloc(
npix *
sizeof(
float));
698 if (anc_id[0] == 0) {
701 }
else if (anc_id[0] == 2) {
704 }
else if (anc_id[0] == 3) {
712 if (
input->relhumid != -2000) {
714 get_ancillary(
lat,
lon,
npix, year,
jday,
jday,
msec,
input->met1,
input->met2,
input->met3,
717 fprintf(
stderr,
"-E- %s %d: Error loading relative humidity ancillary data. %s\n", __FILE__,
718 __LINE__,
input->anc_cor_file);
724 uncertainty->drh[
i] = dtemp[
i];
730 retval =
get_ancillary(
lat,
lon,
npix, year,
jday,
jday,
msec,
input->met1,
input->met2,
input->met3,
731 input->cld_rad1,
input->anc_cor_file, parmID,
l1rec->zw, dtemp, ancqc);
733 fprintf(
stderr,
"-E- %s %d: Error loading Zonal wind speed ancillary data.\n", __FILE__,
739 uncertainty->dzw[
i] = dtemp[
i];
743 retval =
get_ancillary(
lat,
lon,
npix, year,
jday,
jday,
msec,
input->met1,
input->met2,
input->met3,
744 input->cld_rad1,
input->anc_cor_file, parmID,
l1rec->mw, dtemp, ancqc);
746 fprintf(
stderr,
"-E- %s %d: Error loading Meridional wind speed ancillary data.\n", __FILE__,
752 uncertainty->dmw[
i] = dtemp[
i];
762 u_u =
l1rec->uncertainty->dzw[
i];
763 v_u =
l1rec->uncertainty->dmw[
i];
765 ws_2 =
u *
u +
v *
v;
767 if (
input->windspeed != -2000)
768 l1rec->ws[
i] = sqrt(ws_2);
769 if (
input->windangle != -2000)
778 if ((
u +
v) > 0.05 * (u_u + v_u)) {
779 uncertainty->dws[
i] = sqrt((
u *
u * u_u * u_u +
v *
v * v_u * v_u) / ws_2);
780 uncertainty->dwd[
i] = sqrt(
v *
v * u_u * u_u +
u *
u * v_u * v_u) / ws_2;
781 if (uncertainty->dwd[
i] >
M_PI)
782 uncertainty->dwd[
i] =
M_PI;
784 uncertainty->dws[
i] = sqrt(0.5 * (u_u * u_u + v_u * v_u));
785 uncertainty->dwd[
i] =
M_PI;
787 uncertainty->dwd[
i] *= r2d;
796 if (
input->pressure != -2000) {
798 get_ancillary(
lat,
lon,
npix, year,
jday,
jday,
msec,
input->met1,
input->met2,
input->met3,
799 input->cld_rad1,
input->anc_cor_file, parmID,
l1rec->pr, dtemp, ancqc);
801 fprintf(
stderr,
"-E- %s %d: Error loading surface pressure ancillary data.\n", __FILE__,
809 uncertainty->dpr[
i] = dtemp[
i];
814 else if (
l1rec->pr[
i] < 900.0)
816 else if (
l1rec->pr[
i] > 1100.0)
831 if (
input->watervapor != -2000) {
833 get_ancillary(
lat,
lon,
npix, year,
jday,
jday,
msec,
input->met1,
input->met2,
input->met3,
834 input->cld_rad1,
input->anc_cor_file, parmID,
l1rec->wv, dtemp, ancqc);
836 fprintf(
stderr,
"-E- %s %d: Error loading precipitable water ancillary data.\n", __FILE__,
848 uncertainty->dwv[
i] = dtemp[
i] / 10.;
861 if (strlen(
input->anc_profile1)) {
868 if (strlen(
input->anc_aerosol1)) {
872 if (strlen(
input->cld_rad1)) {
877 if (strlen(
input->sfc_albedo)) {
880 }
else if (
input->proc_cloud) {
881 printf(
"%s, %d: Cloud processing, requires an input surface albedo (sfc_albedo=...)\n", __FILE__,
886 if( strlen(
input->cth_albedo) ){
890 if(
input->proc_cloud ) {
892 "%s, %d: Cloud processing, requires an input TROPOMI albedo (cth_albedo=...)\n",
893 __FILE__, __LINE__ );
898 if (anc_id[1] == 0) {
901 }
else if (anc_id[1] == 2) {
904 }
else if (anc_id[1] == 3) {
907 }
else if (
input->ozone != -2000) {
908 if (strstr(
input->ozone1,
"ozone_climatology") !=
NULL) {
920 dtemp,
l1rec->ancqc);
922 fprintf(
stderr,
"-E- %s %d: Error loading Ozone ancillary data.\n", __FILE__, __LINE__);
934 uncertainty->doz[
i] = dtemp[
i] / 1000.;
951 l1rec->no2_tropo[
i] *= 1e15;
952 l1rec->no2_strat[
i] *= 1e15;
959 fprintf(
stderr,
"-E- %s %d: Error loading ancillary data.\n", __FILE__, __LINE__);