21 #include <gsl/gsl_rng.h>
22 #include <gsl/gsl_randist.h>
33 using namespace netCDF;
34 using namespace netCDF::exceptions;
36 string nodestr [3] = {
"Ascending",
"Descending",
"Unknown"};
39 map<string,float>
F0 = {
40 {
"rhot_410", 167.403},
41 {
"rhot_445", 194.417},
42 {
"rhot_490", 195.211},
43 {
"rhot_550", 187.053},
44 {
"rhot_670", 151.462},
46 {
"rhot_1240", 44.830},
47 {
"rhot_1380", 36.468},
48 {
"rhot_1610", 24.439},
76 map<string, ddata*> omap;
79 omap.insert({
"status", pstat});
83 filepath_geo = (filepath_geo==
"") ? filepath_l1b : filepath_geo;
84 map<string,ddata*> gmap = read_geo( filepath_geo,
start,
count );
85 if (
static_cast<ddval<int>*
>(gmap[
"status"])->
val != DTDB_SUCCESS) {
86 cerr <<
"DDSensor:: Read GEO failure. " << endl;
87 pstat->
val = DTDB_FAIL;
90 delete gmap[
"status"];
92 omap.insert(gmap.begin(), gmap.end());
94 map<string,ddata*> lmap = create_l2( gmap );
95 if (
static_cast<ddval<int>*
>(lmap[
"status"])->
val != DTDB_SUCCESS) {
96 cerr <<
"DDSensor:: Create L2 failure. " << endl;
97 pstat->
val = DTDB_FAIL;
100 delete lmap[
"status"];
101 lmap.erase(
"status");
102 omap.insert(lmap.begin(), lmap.end());
113 map<string, ddata*> omap;
114 int status = DTDB_SUCCESS;
116 omap.insert({
"status", pstat});
120 filepath_geo = (filepath_geo==
"") ? filepath_l1b : filepath_geo;
122 map<string,ddata*> lmap = read_l1b( filepath_l1b,
start,
count );
123 if (
static_cast<ddval<int>*
>(lmap[
"status"])->
val != DTDB_SUCCESS) {
124 cerr <<
"DDSensor::Error: Read L1B Failure. " << endl;
125 pstat->
val = DTDB_FAIL;
128 delete lmap[
"status"];
129 lmap.erase(
"status");
130 omap.insert(lmap.begin(), lmap.end());
132 map<string,ddata*> gmap = read_geo( filepath_geo,
start,
count );
133 if (
static_cast<ddval<int>*
>(gmap[
"status"])->
val != DTDB_SUCCESS) {
134 cerr <<
"DDSensor::Error: Read GEO Failure. " << endl;
135 pstat->
val = DTDB_FAIL;
138 delete gmap[
"status"];
139 gmap.erase(
"status");
140 omap.insert(gmap.begin(), gmap.end());
143 for (
size_t iy=0; iy<
count[0]; iy++) {
144 for (
size_t ix=
start[1]; ix<
count[1]; ix++) {
145 double sza =
static_cast<ddma<float,2>*
>(gmap[
"solar_zenith"])->pts[iy][ix];
146 double cossza = cos(
sza*DEGtoRAD);
168 map<string, ddata*> omap;
169 int status = DTDB_SUCCESS;
171 omap.insert({
"status", pstat});
178 nc_input =
new NcFile(
filepath, NcFile::read );
180 catch( NcException& e) {
182 cerr <<
"DDSensor:: Failure opening Land Mask LUT file: "
184 pstat->
val = DTDB_FAIL;
187 NcVar var = nc_input->getVar (
"lat" );
188 var.getVar( lm_lut->
lat );
189 var = nc_input->getVar (
"lon" );
190 var.getVar( lm_lut->
lon );
191 var = nc_input->getVar (
"watermask" );
196 cerr <<
"DDSensor:: Failure, bad Land Mask file path." << endl;
197 pstat->
val = DTDB_FAIL;
203 for (
size_t iy=
start[0]; iy<
count[0]; iy++) {
204 for (
size_t ix=
start[1]; ix<
count[1]; ix++) {
209 iLat =
max (iLat, 0);
211 iLon =
max (iLon, 0);
213 unsigned char c = (
unsigned char) lm_lut->
watermask[iLat][iLon];
214 dlw->
pts[iy][ix] = (
c < 0.5) ? 1 : 0;
219 omap.insert({
"land_water", dlw});
232 gettimeofday(&tv,
nullptr);
233 return (tv.tv_sec + tv.tv_usec);
246 rng = gsl_rng_alloc(gsl_rng_mt19937);
247 gsl_rng_set(rng, randSeed);
248 noise = gsl_ran_gaussian(rng, sigma);
271 map<string, ddata*> omap;
272 int status = DTDB_SUCCESS;
274 omap.insert({
"status", pstat});
286 map<string, ddata*> omap;
287 int status = DTDB_SUCCESS;
289 omap.insert({
"status", pstat});
301 map<string, ddata*> omap;
302 int status = DTDB_SUCCESS;
304 omap.insert({
"status", pstat});
312 struct tm * timeinfo;
315 timeinfo = localtime(&rawtime);
316 strftime(timebuffer, 80,
"%Y-%m-%dT%H:%M:%SZ", timeinfo);
317 string date_created =
string(timebuffer);
320 NcFile* nc_input =
new NcFile(filepath_l1b, NcFile::read );
321 map<string,ddata*> amap = read_l1b_attributes(nc_input);
323 if (
static_cast<ddval<int>*
>(amap[
"status"])->
val != DTDB_SUCCESS) {
324 cerr <<
"DDSensor::Error: Read L1B attributes failure. " << endl;
325 pstat->
val = DTDB_FAIL;
328 delete amap[
"status"];
329 amap.erase(
"status");
330 size_t numx =
static_cast<ddval<int>*
>(amap[
"num_pixels"])->
val;
331 size_t numy =
static_cast<ddval<int>*
>(amap[
"num_lines"])->
val;
332 vector<size_t>
start = {0,0};
333 vector<size_t>
count = {numy,numx};
334 size_t cpix = numx / 2;
336 size_t epix = (epixl < 1) ?
npix-1 : epixl-1;
337 size_t spix = (spixl < 1) ? 0 : spixl-1;
342 nscan = (eline - 1) -
max(sline - 1, 0);
344 size_t cscan =
nscan / 2;
346 vector<size_t> strt = {0};
347 vector<size_t> cntr = {
nscan};
348 vector<size_t> cntc = {numx};
351 if (
static_cast<ddval<int>*
>(lmap[
"status"])->
val != DTDB_SUCCESS) {
352 cerr <<
"DDSensor::Error: Read landmask failure. " << endl;
353 pstat->
val = DTDB_FAIL;
356 delete lmap[
"status"];
357 lmap.erase(
"status");
358 omap.insert(lmap.begin(), lmap.end());
359 omap.insert(gmap.begin(), gmap.end());
360 omap.insert(amap.begin(), amap.end());
361 omap.insert({
"mside", amap[
"mside"]});
363 omap.insert({
"year", dyear});
365 omap.insert({
"day", dday});
367 omap.insert({
"msec", dmsec});
369 omap.insert({
"cntl_pt_rows", drows});
371 omap.insert({
"cntl_pt_cols", dcols});
373 omap.insert({
"slon", dslon});
375 omap.insert({
"clon", dclon});
377 omap.insert({
"elon", delon});
379 omap.insert({
"slat", dslat});
381 omap.insert({
"clat", dclat});
383 omap.insert({
"elat", delat});
385 omap.insert({
"csol_z", dcsol_z});
387 omap.insert({
"tilt", dtilt});
390 for (
size_t ix=0; ix<numx; ix++) {
391 dcols->
pts[ix] = pix_cnt++;
393 for (
size_t iy=0; iy<
nscan; iy++) {
395 time_t utime = (time_t)
static_cast<ddma<double,1>*
>(amap[
"scan_time"])->
pts[iy];
396 trec = gmtime(&utime);
397 int year = trec->tm_year + 1900;
398 int day = trec->tm_yday + 1;
399 double secs = trec->tm_hour * 3600.0 + trec->tm_min * 60. +
400 trec->tm_sec + fmod(
static_cast<ddma<double,1>*
>(amap[
"scan_time"])->pts[iy], 1.);
401 dyear->
pts[iy] = (int32_t)
year;
402 dday->
pts[iy] = (int32_t)
day;
403 dmsec->
pts[iy] = (int32_t) (secs * 1.e3);
405 dclon->
pts[iy] =
static_cast<ddma<float,2>*
>(gmap[
"longitude"])->pts[iy][cpix];
408 dclat->
pts[iy] =
static_cast<ddma<float,2>*
>(gmap[
"latitude"])->pts[iy][cpix];
410 dcsol_z->
pts[iy] =
static_cast<ddma<float,2>*
>(gmap[
"solar_zenith"])->pts[iy][cpix];
411 drows->
pts[iy] = line_cnt++;
414 double esd =
esdist_(&dyear->
pts[cscan], &dday->
pts[cscan], &dmsec->
pts[cscan]);
415 double esdist_correction = pow(1.0 / esd, 2);
416 float start_center_lon =
static_cast<ddma<float,2>*
>(gmap[
"longitude"])->pts[0][cpix];
417 float start_center_lat =
static_cast<ddma<float,2>*
>(gmap[
"latitude"])->pts[0][cpix];
418 float end_center_lon =
static_cast<ddma<float,2>*
>(gmap[
"longitude"])->pts[
nscan-1][cpix];
419 float end_center_lat =
static_cast<ddma<float,2>*
>(gmap[
"latitude"])->pts[
nscan-1][cpix];
421 auto mm = minmax_element(
static_cast<ddma<float,2>*
>(gmap[
"latitude"])->pts.data(),
424 float geospatial_lat_max = *mm.second;
425 float geospatial_lat_min = *mm.first;
426 mm = minmax_element(
static_cast<ddma<float,2>*
>(gmap[
"longitude"])->pts.data(),
429 float geospatial_lon_max = *mm.second;
430 float geospatial_lon_min = *mm.first;
432 float lastLat = start_center_lat;
434 float northern_lat = -90.0;
435 float southern_lat = +90.0;
436 float eastern_lon = +180.0;
437 float western_lon = -180.0;
439 for (
size_t ip =
spix; ip <=
epix; ip++) {
440 northern_lat =
max(northern_lat, (
static_cast<ddma<float,2>*
>(gmap[
"latitude"]))->pts[
is][ip]);
441 southern_lat =
min(southern_lat, (
static_cast<ddma<float,2>*
>(gmap[
"latitude"]))->pts[
is][ip]);
456 western_lon = (wl > western_lon) ? wl : western_lon;
457 eastern_lon = (
el < eastern_lon) ?
el : eastern_lon;
458 lastLat =
static_cast<ddma<float,2>*
>(gmap[
"latitude"])->pts[
is][cpix];
461 string start_direction = (
static_cast<ddma<float,2>*
>(gmap[
"latitude"])->pts[1][cpix] >
464 string end_direction = (
static_cast<ddma<float,2>*
>(gmap[
"latitude"])->pts[
nscan-1][cpix] >
470 ddstr* dstr =
new ddstr(date_created.c_str());
471 omap.insert({
"date_created", dstr});
472 dstr =
new ddstr(start_direction.c_str());
473 omap.insert({
"start_direction", dstr});
474 dstr =
new ddstr(end_direction.c_str());
475 omap.insert({
"end_direction", dstr});
476 dstr =
new ddstr(day_night_flag.c_str());
477 omap.insert({
"day_night_flag", dstr});
479 omap.insert({
"earth_sun_distance_correction", ddoub});
481 omap.insert({
"start_center_longitude", dflt});
483 omap.insert({
"start_center_latitude", dflt});
485 omap.insert({
"end_center_longitude", dflt});
487 omap.insert({
"end_center_latitude", dflt});
489 omap.insert({
"northernmost_latitude", dflt});
491 omap.insert({
"southernmost_latitude", dflt});
493 omap.insert({
"easternmost_longitude", dflt});
495 omap.insert({
"westernmost_longitude", dflt});
497 omap.insert({
"geospatial_lat_max", dflt});
499 omap.insert({
"geospatial_lat_min", dflt});
501 omap.insert({
"geospatial_lon_max", dflt});
503 omap.insert({
"geospatial_lon_min", dflt});
506 omap.insert({
"GRingPointLatitude", gringlat});
507 gringlat->
pts[0] = dslat->
pts[0];
508 gringlat->
pts[1] = dclat->
pts[0];
509 gringlat->
pts[2] = delat->
pts[0];
510 gringlat->
pts[3] = delat->
pts[cscan];
514 gringlat->
pts[7] = dslat->
pts[cscan];
516 omap.insert({
"GRingPointLongitude", gringlon});
517 gringlon->
pts[0] = dslon->
pts[0];
518 gringlon->
pts[1] = dclon->
pts[0];
519 gringlon->
pts[2] = delon->
pts[0];
520 gringlon->
pts[3] = delon->
pts[cscan];
524 gringlon->
pts[7] = dslon->
pts[cscan];
526 omap.insert({
"GRingPointSequenceNo", gringseq});
527 gringseq->
pts[0] = 0;
528 gringseq->
pts[1] = 1;
529 gringseq->
pts[2] = 2;
530 gringseq->
pts[3] = 3;
531 gringseq->
pts[4] = 4;
532 gringseq->
pts[5] = 5;
533 gringseq->
pts[6] = 6;
534 gringseq->
pts[7] = 7;
539 omap.insert({
"vcal_gain", ddat});
541 omap.insert({
"vcal_offset", ddat});
543 omap.insert({
"F0", ddat});
545 fsol_ = esdist_correction;
548 ddat->
pts[(
size_t)it.second] =
F0[
name]*fsol_;
563 map<string,ddata*> omap;
592 float sigma, noise, snr, scaled_lt;
594 {2.1525676E-4, 1.283166E-5},
595 {2.4496944E-4, 9.037615E-6},
596 {2.3188611E-4, 9.68949E-6},
597 {2.011162E-5, 8.404901E-6},
598 {3.2728847E-5, 2.2284337E-6},
599 {0.07877732, 0.00049940},
601 {0.26743281, 0.01044864},
602 {0.00628912, 0.00021160}
605 noise = coef[iw][0] + coef[iw][1] * scaled_lt;
606 snr = scaled_lt * snr_mult / noise;
623 map<string, ddata*> omap;
624 int status = DTDB_SUCCESS;
626 omap.insert({
"status", pstat});
630 nc_input =
new NcFile(
filepath, NcFile::read );
632 catch( NcException& e) {
634 cerr <<
"POCI:: Failure opening PACE L1B input file: " +
filepath << endl;
635 pstat->
val = DTDB_FAIL;
639 NcGroup nc_group = nc_input->getGroup(
"observation_data");
641 vector<size_t> countp = {1,
count[0],
count[1]};
643 vector<size_t> startp = {bindex(410),
start[0],
start[1]};
646 omap.insert({
"rhot_410", dda});
651 omap.insert({
"rhot_445", dda});
656 omap.insert({
"rhot_490", dda});
661 omap.insert({
"rhot_550", dda});
666 omap.insert({
"rhot_670", dda});
671 omap.insert({
"rhot_865", dda});
676 omap.insert({
"rhot_1240", dda});
681 omap.insert({
"rhot_1380", dda});
686 omap.insert({
"rhot_1610", dda});
691 omap.insert({
"rhot_2250", dda});
694 for (
size_t iy=0; iy<
count[0]; iy++) {
695 for (
size_t ix=
start[1]; ix<
count[1]; ix++) {
711 catch( NcException& e) {
713 cerr <<
"POCI::Failure reading PACE L1B input data." << endl;
714 pstat->
val = DTDB_FAIL;
730 map<string, ddata*> omap;
731 int status = DTDB_SUCCESS;
733 omap.insert({
"status", pstat});
737 attributes = nc_input->getAtts(NcGroup::Current);
739 (
attributes.find(
"time_coverage_start")->second).getValues(tcs);
741 omap.insert({
"time_coverage_start", dstr});
742 (
attributes.find(
"time_coverage_end")->second).getValues(tce);
743 dstr =
new ddstr(tce);
744 omap.insert({
"time_coverage_end", dstr});
745 (
attributes.find(
"instrument")->second).getValues(tstr);
746 dstr =
new ddstr(tstr);
747 omap.insert({
"instrument", dstr});
748 dstr =
new ddstr(
"PACE");
749 omap.insert({
"platform", dstr});
752 (
attributes.find(
"normalizedLt")->second).getValues(&normLt);
753 brad_ = (normLt==0) ?
true :
false;
758 omap.insert({
"start_year", dval});
759 int start_month = atoi(tcs.substr(5,2).c_str());
761 omap.insert({
"start_month", dval});
763 omap.insert({
"start_day", dval});
765 omap.insert({
"start_hour", dval});
767 omap.insert({
"end_hour", dval});
769 omap.insert({
"start_minute", dval});
771 omap.insert({
"end_minute", dval});
773 omap.insert({
"start_second", dval});
775 omap.insert({
"end_second", dval});
776 int season = (start_month == 12) ? 0 : start_month/3;
778 omap.insert({
"season", dval});
781 (
attributes.find(
"orbit_number")->second).getValues(&num);
783 omap.insert({
"orbit_number", dval});
786 omap.insert({
"num_pixels", dval});
788 omap.insert({
"num_lines", dval});
790 NcGroup nc_group = nc_input->getGroup(
"scan_line_attributes");
791 vector<size_t> starts = {0};
792 vector<size_t>
counts = {(size_t)dval->
val};
795 omap.insert({
"mside", ddh});
798 omap.insert({
"scan_time", dde});
800 vector<size_t> startw = {0};
801 vector<size_t> countw = {NTWL};
803 omap.insert({
"wavelength", ddw});
827 map<string, ddata*> omap;
828 int status = DTDB_SUCCESS;
830 omap.insert({
"status", pstat});
834 nc_input =
new NcFile(
filepath, NcFile::read );
836 catch( NcException& e) {
838 cerr <<
"POCI:: Failure opening PACE L1B input file: " +
filepath << endl;
839 pstat->
val = DTDB_FAIL;
846 NcGroup nc_group = nc_input->getGroup(
"geolocation_data");
850 omap.insert({
"latitude", dda});
854 omap.insert({
"longitude", dda});
858 omap.insert({
"elevation", dda});
862 omap.insert({
"sensor_azimuth", ddsen});
866 omap.insert({
"sensor_zenith", dda});
870 omap.insert({
"solar_azimuth", ddsol});
874 omap.insert({
"solar_zenith", dda});
876 catch( NcException& e) {
878 cerr <<
"POCI::Failure reading PACE L1B input data." << endl;
879 pstat->
val = DTDB_FAIL;
885 for (
size_t iy=0; iy<
count[0]; iy++) {
886 for (
size_t ix=
start[1]; ix<
count[1]; ix++) {
887 float raa = ddsen->
pts[iy][ix] - ddsol->
pts[iy][ix] - 180.0;
888 if (raa > 180.0) raa = raa - 360.0;
889 if (raa < -180.0) raa = raa + 360.0;
890 if (raa < 0.0) raa = -raa;
891 ddra->
pts[iy][ix] = raa;
894 omap.insert({
"relative_azimuth", ddra});
923 float sigma, noise, snr, scaled_lt;
925 {0.05499859, 0.00008340},
926 {0.01927545, 0.00009450},
927 {0.08769538, 0.00007000},
928 {0.00496291, 0.00014050},
929 {0.00312263, 0.00018600},
930 {0.07877732, 0.00049940},
932 {0.26743281, 0.01044864},
933 {0.00628912, 0.00021160}
936 noise = coef[iw][0] + coef[iw][1] * scaled_lt;
937 snr = scaled_lt * snr_mult / noise;
953 map<string, ddata*> omap;
954 int status = DTDB_SUCCESS;
956 omap.insert({
"status", pstat});
960 nc_input =
new NcFile(
filepath, NcFile::read );
962 catch( NcException& e) {
964 cerr <<
"VIIRS:: Failure opening VIIRS L1B file: " +
filepath << endl;
965 pstat->
val = DTDB_FAIL;
969 NcGroup nc_group = nc_input->getGroup(
"observation_data");
972 omap.insert({
"rhot_410", dda});
975 omap.insert({
"rhot_445", dda});
978 omap.insert({
"rhot_490", dda});
981 omap.insert({
"rhot_550", dda});
984 omap.insert({
"rhot_670", dda});
987 omap.insert({
"rhot_865", dda});
990 omap.insert({
"rhot_1240", dda});
993 omap.insert({
"rhot_1380", dda});
996 omap.insert({
"rhot_1610", dda});
999 omap.insert({
"rhot_2250", dda});
1001 catch( NcException& e) {
1003 cerr <<
"VIIRS::Failure reading VIIRS L1B data." << endl;
1004 pstat->
val = DTDB_FAIL;
1029 map<string, ddata*> omap;
1030 int status = DTDB_SUCCESS;
1032 omap.insert({
"status", pstat});
1036 attributes = nc_input->getAtts(NcGroup::Current);
1037 string tcs,tce,tstr;
1038 (
attributes.find(
"time_coverage_start")->second).getValues(tcs);
1040 omap.insert({
"time_coverage_start", dstr});
1041 (
attributes.find(
"time_coverage_end")->second).getValues(tce);
1042 dstr =
new ddstr(tce);
1043 omap.insert({
"time_coverage_end", dstr});
1044 (
attributes.find(
"instrument")->second).getValues(tstr);
1045 dstr =
new ddstr(tstr);
1046 omap.insert({
"instrument", dstr});
1047 dstr =
new ddstr(
"VIIRS");
1048 omap.insert({
"platform", dstr});
1053 omap.insert({
"start_year", dval});
1054 int start_month = atoi(tcs.substr(5,2).c_str());
1056 omap.insert({
"start_month", dval});
1058 omap.insert({
"start_day", dval});
1060 omap.insert({
"start_hour", dval});
1062 omap.insert({
"end_hour", dval});
1064 omap.insert({
"start_minute", dval});
1066 omap.insert({
"end_minute", dval});
1068 omap.insert({
"start_second", dval});
1070 omap.insert({
"end_second", dval});
1071 int season = (start_month == 12) ? 0 : start_month/3;
1073 omap.insert({
"season", dval});
1076 (
attributes.find(
"orbit_number")->second).getValues(&num);
1078 omap.insert({
"orbit_number", dval});
1081 omap.insert({
"num_pixels", dval});
1083 omap.insert({
"num_lines", dval});
1085 NcGroup nc_group = nc_input->getGroup(
"scan_line_attributes");
1086 vector<size_t> starts = {0};
1087 vector<size_t> countl = {(size_t)dval->
val};
1090 omap.insert({
"mside", ddh});
1092 omap.insert({
"scan_time", dde});
1094 nc_group.getVar(
"ev_mid_time").getVar( &scantimes[0] );
1095 for (
size_t i=0;
i<countl[0];
i++) {
1100 vector<size_t> startw = {0};
1101 vector<size_t> countw = {NTWL};
1103 omap.insert({
"wavelength", ddw});
1129 map<string, ddata*> omap;
1130 int status = DTDB_SUCCESS;
1132 omap.insert({
"status", pstat});
1136 nc_input =
new NcFile(
filepath, NcFile::read );
1138 catch( NcException& e) {
1140 cerr <<
"VIIRS:: Failure opening VIIRS geo file: " +
filepath << endl;
1141 pstat->
val = DTDB_FAIL;
1146 NcGroup nc_group = nc_input->getGroup(
"geolocation_data");
1150 omap.insert({
"latitude", dda});
1154 omap.insert({
"longitude", dda});
1158 omap.insert({
"elevation", dda});
1162 omap.insert({
"sensor_azimuth", dda});
1166 omap.insert({
"sensor_zenith", dda});
1170 omap.insert({
"solar_azimuth", dda});
1174 omap.insert({
"solar_zenith", dda});
1176 catch( NcException& e) {
1178 cerr <<
"VIIRS::Failure reading VIIRS geo data." << endl;
1179 pstat->
val = DTDB_FAIL;
1185 for (
size_t iy=0; iy<
count[0]; iy++) {
1186 for (
size_t ix=
start[1]; ix<
count[1]; ix++) {
1187 float sen =
static_cast<ddma<float,2>*
>(omap[
"sensor_azimuth"])->pts[iy][ix];
1188 float sol =
static_cast<ddma<float,2>*
>(omap[
"solar_azimuth"])->pts[iy][ix];
1189 float raa = sen - sol - 180.0;
1190 if (raa > 180.0) raa = raa - 360.0;
1191 if (raa < -180.0) raa = raa + 360.0;
1192 if (raa < 0.0) raa = -raa;
1193 ddra->
pts[iy][ix] = raa;
1196 omap.insert({
"relative_azimuth", ddra});