12 #include <pugixml.hpp>
26 "observations",
"geophysical_data",
"statistics" };
98 pancillary_ =
nullptr;
120 if (pancillary_ != 0) {
134 int status = DTDB_SUCCESS;
137 if (salg ==
"darktarget") {
138 std::cerr <<
"DDProcess:: Algorithm Dark Target" << std::endl;
140 }
else if (salg ==
"deepblue") {
141 std::cerr <<
"DDProcess:: Algorithm Deep Blue" << std::endl;
144 std::cerr <<
"DDProcess:: Invalid algorithm, exiting ..." << std::endl;
148 if (
status != DTDB_SUCCESS) {
149 cerr <<
"DDProcess:: Query granule failure" << endl;
152 cerr <<
"DDProcess:: Night granule detected" << endl;
155 switch (instrument_) {
157 psensor_ =
new POCI();
160 psensor_ =
new VIIRS();
164 cerr <<
"DDProcess:: Invalid sensor" << endl;
177 lprw_ = (lprw_<3) ? 3 : lprw_;
179 vector<string>
products = pl_->get_products();
195 int status = DTDB_SUCCESS;
201 nc_input =
new NcFile(
filepath, NcFile::read );
203 catch( NcException& e) {
205 cout <<
"DDProcess:: Failure opening L1B file" << endl;
209 multimap <string, NcGroupAtt>
attributes = nc_input->getAtts(NcGroup::Current);
210 multimap <string, NcGroupAtt>::iterator it;
212 (it->second).getValues(
str);
214 if (
str.find(
"OCI") != string::npos) {
216 }
else if (
str.find(
"VIIRS") != string::npos) {
219 cout <<
"DDProcess:: Instrument not supported" << endl;
222 switch (instrument_) {
225 (it->second).getValues(
str);
227 (it->second).getValues(
str);
229 if (
str !=
"Night") {
234 lines_ = nc_input->getDim(
"number_of_lines").getSize();
235 pixels_ = nc_input->getDim(
"number_of_pixels").getSize();
236 title_ =
"VIIRS Level-2 Data";
240 lines_ = nc_input->getDim(
"number_of_scans").getSize();
241 pixels_ = nc_input->getDim(
"ccd_pixels").getSize();
242 title_ =
"OCI Level-2 Data";
245 cout <<
"DDProcess:: Failure reading dimensions" << endl;
250 cout <<
"Invalid L1B filename ..." << endl;
264 int status = DTDB_SUCCESS;
266 map<string,ddata*> imap = psensor_->create( {0, 0}, {lines_, pixels_} );
267 if (
static_cast<ddval<int>*
>(imap[
"status"])->
val != DTDB_SUCCESS) {
268 cerr <<
"DDProcess:: Create sensor failure at line " << endl;
273 imap.insert({
"title", dstr});
276 dstr =
new ddstr(parfilepath);
277 imap.insert({
"config_file", dstr});
279 imap.insert({
"bgascorrect", bval});
280 bgascorrect_ = bval->
val;
282 imap.insert({
"bglintmask", bval});
283 bglintmask_ = bval->
val;
285 imap.insert({
"bcloudmask", bval});
286 bcloudmask_ = bval->
val;
290 if (
status != DTDB_SUCCESS) {
291 cerr <<
"DDProcess:: Ancillary initialization failure" << endl;
294 cerr <<
"DDProcess:: Initializing Land Process" << endl;
295 status = pl_->initialize(imap);
296 if (
status != DTDB_SUCCESS) {
297 cerr <<
"DDProcess:: Land initialization failure" << endl;
300 cerr <<
"DDProcess:: Initializing Ocean Process" << endl;
301 status = po_->initialize(imap);
302 if (
status != DTDB_SUCCESS) {
303 cerr <<
"DDProcess:: Ocean initialization failure" << endl;
307 cerr <<
"DDProcess:: Processing Granule" << endl;
308 status = create_nc4(imap);
309 if (
status != DTDB_SUCCESS) {
310 cerr <<
"DDProcess:: Output file creation failure" << endl;
314 for (
auto &it : imap) {
316 if (
name !=
"land_water") {
321 map<string, ddma<float, 2>*> flmap;
322 map<string, ddma<unsigned int, 2>*> uimap;
323 map<string, ddma<short, 2>*> shmap;
324 map<string, ddma<unsigned char, 2>*> ubmap;
325 map<string, ddata*> smap;
326 map<string, ddata*> amap;
327 map<string, ddata*> pmap;
329 for (
auto &it : dtdb_names) {
334 flmap.insert({
name, ddfl });
338 uimap.insert({
name, ddin });
342 shmap.insert({
name, ddsh });
346 ubmap.insert({
name, ddub });
351 ubmap.insert({
"cloud_mask", ddcm });
353 for (
auto &it : rhot_band_names) {
357 string oname =
"rhot_" +
name.substr(1);
358 flmap.insert({ oname, ddfl });
360 for (
auto &it : aot_band_names) {
364 flmap.insert({
name, ddfl });
366 for (
auto &it : srf_band_names) {
370 flmap.insert({
name, ddfl });
378 flmap.insert({
"aot_380", ddfl });
381 while ( cline < lines_ ) {
385 size_t left = lines_-cline;
389 for (
auto &it : smap) {
390 delete smap[(
string) it.first];
393 smap = psensor_->read( {sy, 0}, {cy, pixels_} );
394 if (
static_cast<ddval<int>*
>(smap[
"status"])->
val != DTDB_SUCCESS) {
395 cerr <<
"DDProcess:: Read sensor failure at line " << sy << endl;
397 delete smap[
"status"];
398 smap.erase(
"status");
399 imap.insert(smap.begin(), smap.end());
400 for (
auto &it : amap) {
401 delete amap[(
string) it.first];
404 amap = pancillary_->read(imap);
405 if (
static_cast<ddval<int>*
>(amap[
"status"])->
val != DTDB_SUCCESS) {
406 cerr <<
"DDProcess:: Read ancillary failure at line " << sy << endl;
408 delete amap[
"status"];
409 amap.erase(
"status");
410 imap.insert(amap.begin(), amap.end());
411 for (
size_t iy = 0; iy < cy; iy++ ) {
412 for (
size_t ix = 0; ix < pixels_; ix++ ) {
413 if (ix==5 && iy+sy==1714) {
416 if (plw->pts[sy+iy][ix] == 0) {
417 pmap = po_->process({iy,ix}, {cy,pixels_}, imap);
418 ddlw->
pts[iy][ix] = 0;
419 if (
static_cast<ddval<int>*
>(pmap[
"status"])->
val != DTDB_SUCCESS) {
420 cerr <<
"DDProcess:: Ocean process failure at line " << iy+sy <<
" pixel " << ix << endl;
422 }
else if (plw->pts[sy+iy][ix] == 1) {
423 pmap = pl_->process({iy,ix}, {cy,pixels_}, imap);
424 ddlw->
pts[iy][ix] = 1;
425 if (
static_cast<ddval<int>*
>(pmap[
"status"])->
val != DTDB_SUCCESS) {
426 cerr <<
"DDProcess:: Land process failure at line " << iy+sy <<
" pixel " << ix << endl;
429 for (
auto &it : flmap) {
431 if (pmap.find(
name) != pmap.end()) {
432 flmap[
name]->pts[iy][ix] =
436 for (
auto &it : uimap) {
438 if (pmap.find(
name) != pmap.end()) {
439 uimap[
name]->pts[iy][ix] =
443 for (
auto &it : shmap) {
445 if (pmap.find(
name) != pmap.end()) {
446 shmap[
name]->pts[iy][ix] =
450 for (
auto &it : ubmap) {
452 if (pmap.find(
name) != pmap.end()) {
453 ubmap[
name]->pts[iy][ix] =
457 if (pmap.find(
"cloud_mask") != pmap.end()) {
458 ubmap[
"cloud_mask"]->pts[iy][ix] =
461 for (
auto &it : pmap) {
462 delete pmap[(
string) it.first];
467 delete amap[
"cloud_mask"];
468 amap.erase(
"cloud_mask");
469 imap.erase(
"cloud_mask");
470 for (
auto &it : flmap) {
472 flmap[
name]->start = {cline, 0};
473 flmap[
name]->count = {cy,pixels_};
476 for (
auto &it : uimap) {
478 uimap[
name]->start = {cline, 0};
479 uimap[
name]->count = {cy,pixels_};
482 for (
auto &it : shmap) {
484 shmap[
name]->start = {cline, 0};
485 shmap[
name]->count = {cy,pixels_};
488 for (
auto &it : ubmap) {
490 ubmap[
name]->start = {cline, 0};
491 ubmap[
name]->count = {cy,pixels_};
494 ddlw->
start = {cline,0};
495 ddlw->
count = {cy,pixels_};
496 imap.insert({
"land_water", ddlw});
498 status = write_nc4( imap );
501 for (
auto &it : imap) {
502 delete imap[(
string) it.first];
510 cerr <<
" DONE! " << endl;
513 vector<string> dnames = {
"fmf_550",
"angstrom",
"aot_410",
"aot_490",\
514 "aot_550",
"aot_670",
"aot_865",
"aot_1240",
"aot_1610",
"aot_2250"};
517 cerr <<
"DDProcess:: Generating statistics on decimated samples" << endl;
518 status = write_decimated(dnames, window);
519 if (
status != DTDB_SUCCESS) {
520 cerr <<
"DDProcess:: Write decimated statistics failure" << endl;
522 cerr <<
"ALL DONE! " << endl;
536 int status = DTDB_SUCCESS;
537 map<string, ddata*> omap;
541 vector<size_t> sdims, cdims;
547 ddata* odat =
new ddata(it.second, sdims, cdims,
nullptr);
548 omap.insert({
name, odat});
556 ddata* odat =
new ddata(it.second, sdims, cdims,
nullptr);
557 omap.insert({
name, odat});
562 omap.insert({
name, odat});
571 omap.insert({
name, odat});
580 omap.insert({
name, odat});
587 omap.insert({
"aot_380", odat});
592 if (output_filepath.empty()) {
593 cerr <<
"\nDDProcess:: Failure locating output file path.\n" << endl;
598 nc_output =
new NcFile( output_filepath, NcFile::replace );
600 catch( NcException& e) {
602 cerr <<
"\nDDProcess:: Failure creating product file: " + output_filepath +
"\n" << endl;
608 xml_parse_result
result = doc.load_file(xfilepath.c_str());
609 if (
result.status != status_ok ) {
610 cerr <<
"DDProcess:: Failure opening XML product configuration file " +
614 xml_node
products = doc.child(
"products");
616 for (xml_node gatt:
products.children()) {
617 string sname =
string(gatt.name());
618 if (sname ==
"group" || sname ==
"metadata") {
621 nc_output->putAtt(sname, gatt.child_value());
624 for (xml_node meta:
products.children(
"metadata"))
626 string mname = meta.attribute(
"name").value();
627 if (imap.find(mname) != imap.end()) {
628 ddata* dsp = imap[mname];
629 dsp->
putAtt(nc_output, mname);
633 NcDim lines_dim = nc_output->addDim(
"number_of_lines",
lines_ );
634 NcDim pixels_dim = nc_output->addDim(
"pixels_per_line",
pixels_ );
635 NcDim all_bands_dim = nc_output->addDim(
"number_of_bands", NTWL );
636 dmap_.insert({lines_dim.getSize(), lines_dim});
637 dmap_.insert({pixels_dim.getSize(), pixels_dim});
638 dmap_.insert({all_bands_dim.getSize(), all_bands_dim});
643 string gname =
group.attribute(
"name").value();
647 bool boutput =
false;
649 if (
str == gname) boutput =
true;
651 NcGroup grp = nc_output->addGroup(gname);
653 string pname =
product.attribute(
"name").value();
659 if (omap.find(pname) != omap.end()) {
661 }
else if (imap.find(pname) != imap.end()) {
664 cout <<
" --" << pname <<
" not found" << endl;
667 bool bnotshort = (gname ==
"sensor_band_parameters" ||
668 gname ==
"scan_line_attributes" ||
669 gname ==
"navigation_data");
674 for (
size_t i=0;
i<dsp->
count.size();
i++) {
676 pdims.push_back(tdim);
680 dsp->
count.size()==2 && !bnotshort) {
681 var = grp.addVar(pname, NcType(NC_SHORT), pdims);
683 var = grp.addVar(pname, NcType((nc_type)dsp->
type), pdims);
687 var.setChunking(var.nc_CHUNKED, chunksizes);
690 for (xml_node patt:
product.children()) {
691 string attr_name =
string(patt.name());
692 if (attr_name ==
"type") {
695 if (attr_name ==
"_FillValue") {
696 string pval_str =
string(patt.child_value());
698 }
else if (attr_name ==
"valid_min") {
699 vmin = boost::lexical_cast<float> (patt.child_value());
700 dsp->
putAtt(var,
"valid_min", patt.child_value());
701 }
else if (attr_name ==
"valid_max") {
702 vmax = boost::lexical_cast<float> (patt.child_value());
703 dsp->
putAtt(var,
"valid_max", patt.child_value());
704 }
else if (attr_name ==
"valid_logmin" ) {
706 vmin = boost::lexical_cast<float> (patt.child_value());
707 dsp->
putAtt(var,
"valid_min", patt.child_value());
709 }
else if (attr_name ==
"valid_logmax" ) {
711 vmax = boost::lexical_cast<float> (patt.child_value());
712 dsp->
putAtt(var,
"valid_max", patt.child_value());
715 var.putAtt(attr_name, patt.child_value());
719 dsp->
count.size()==2 && !bnotshort) {
721 float offset = (vmax+vmin)/2.0;
722 var.putAtt(
"scale_factor", ncFloat,
scale);
723 var.putAtt(
"add_offset", ncFloat,
offset);
724 var.putAtt(
"valid_min", ncShort, -
MAX_SHORT);
725 var.putAtt(
"valid_max", ncShort,
MAX_SHORT);
733 catch( NcException& e) {
735 cerr <<
"\nDDProcess:: Failure initializing product file: " +
736 output_filepath +
"\n" << endl;
740 for (
auto &it : omap) {
741 delete omap[(
string) it.first];
759 int status = DTDB_SUCCESS;
764 if (output_filepath.empty()) {
765 cerr <<
"\nDDProcess:: Failure locating output file path.\n" << endl;
770 nc_output =
new NcFile( output_filepath, NcFile::write );
772 catch( NcException& e) {
774 cerr <<
"\nDDProcess:: Failure writing to product file: " +
775 output_filepath +
"\n" << endl;
781 xml_parse_result
result = doc.load_file(xfilepath.c_str());
782 if (
result.status != status_ok ) {
783 cerr <<
"DDProcess:: Failure opening XML product configuration file " +
787 xml_node
products = doc.child(
"products");
795 products.find_child_by_attribute(
"group",
"name", gname.c_str());
796 string xname =
group.attribute(
"name").value();
797 NcGroup grp = nc_output->getGroup(gname);
799 string pname =
product.attribute(
"name").value();
804 if (omap.find(pname) != omap.end()) {
805 ddata* dsp = omap[pname];
806 if (!(pname==
"latitude" || pname==
"longitude")) {
809 NcVar var = grp.getVar(pname);
816 catch( NcException& e) {
818 cerr <<
"\nDDProcess:: Failure writing line " + output_filepath +
"\n" << endl;
835 int status = DTDB_SUCCESS;
840 cout <<
"DDAlgorithm:: Missing L2 file name for decimation" << endl;
846 nc_output =
new NcFile(
filepath, NcFile::write);
848 catch( NcException& e) {
850 cout <<
"DDAlgorithm:: Failure opening L2 file for decimation" << endl;
853 size_t lines = nc_output->getDim(
"number_of_lines").getSize();
854 size_t pixels = nc_output->getDim(
"pixels_per_line").getSize();
855 vector<size_t> startp = {0,0};
856 vector<size_t> countp = {
lines, pixels};
857 size_t dlines =
lines/nwin+1;
858 size_t dpixels = pixels/nwin+1;
859 vector<size_t> startd = {0,0,0};
860 vector<size_t> countd = {3, dlines, dpixels};
862 NcGroup dgrp = nc_output->addGroup(
"statistics");
863 NcDim sets_dim = nc_output->addDim(
"number_of_views", countd[0] );
864 NcDim lines_dim = nc_output->addDim(
"number_of_decimated_lines", countd[1] );
865 NcDim samples_dim = nc_output->addDim(
"Decimated_samples_per_line", countd[2] );
866 vector<NcDim> dimsd = {sets_dim, lines_dim, samples_dim};
869 for (
auto &it :
names) {
871 NcGroup pgrp = nc_output->getGroup(
"geophysical_data");
874 if (ddat->
ptr ==
nullptr) {
879 fill(ddec->
pts.origin(), ddec->
pts.origin()+ddec->
pts.num_elements(),0);
880 string strdec =
name +
"_"+ to_string(nwin) +
"x"+ to_string(nwin);
881 NcVar vard = dgrp.addVar(strdec, NcType(NC_FLOAT), dimsd);
883 cout <<
"DDProcess::write_decimated() Failure to create netcdf vars" << endl;
886 string lname = strdec +
" Mean, Standard deviation, and sample counts on grid decimated by " + to_string(nwin);
887 vard.putAtt(
"long_name", lname);
889 vector<size_t> chunksizes = {countd[0], countd[1], countd[2]};
891 vard.setChunking(vard.nc_CHUNKED, chunksizes);
894 for (
size_t i=0;
i<pixels;
i++) {
896 size_t iidx =
i/nwin;
897 size_t jidx =
j/nwin;
898 ddec->
pts[0][jidx][iidx] += ddat->
pts[
j][
i];
899 ddec->
pts[2][jidx][iidx]++;
902 for (
size_t j=0;
j<dlines;
j++) {
903 for (
size_t i=0;
i<dpixels;
i++) {
904 if (ddec->
pts[2][
j][
i] >9) {
912 for (
size_t i=0;
i<pixels;
i++) {
914 size_t iidx =
i/nwin;
915 size_t jidx =
j/nwin;
916 ddec->
pts[1][jidx][iidx] +=
917 pow(ddat->
pts[
j][
i]-ddec->
pts[0][jidx][iidx],2.0);
920 for (
size_t j=0;
j<dlines;
j++) {
921 for (
size_t i=0;
i<dpixels;
i++) {
922 if (ddec->
pts[2][
j][
i] >9) {
924 ddec->
pts[1][
j][
i] = sqrt(ddec->
pts[1][
j][
i]);