22#include "HDF4RequestHandler.h"
32const char *HDFEOS2::File::_geodim_x_names[] = {
"XDim",
"LonDim",
"nlon"};
35const char *HDFEOS2::File::_geodim_y_names[] = {
"YDim",
"LatDim",
"nlat"};
38const char *HDFEOS2::File::_latfield_names[] = {
39 "Latitude",
"Lat",
"YDim",
"LatCenter"
43const char *HDFEOS2::File::_lonfield_names[] = {
44 "Longitude",
"Lon",
"XDim",
"LonCenter"
49const char *HDFEOS2::File::_geogrid_names[] = {
"location"};
51using namespace HDFEOS2;
55template<
typename T,
typename U,
typename V,
typename W,
typename X>
56static void _throw5(
const char *fname,
int line,
int numarg,
57 const T &a1,
const U &a2,
const V &a3,
const W &a4,
61 ss << fname <<
":" << line <<
":";
62 for (
int i = 0; i < numarg; ++i) {
65 case 0: ss << a1;
break;
66 case 1: ss << a2;
break;
67 case 2: ss << a3;
break;
68 case 3: ss << a4;
break;
69 case 4: ss << a5;
break;
71 ss<<
" Argument number is beyond 5 ";
74 throw Exception(ss.str());
80#define throw1(a1) _throw5(__FILE__, __LINE__, 1, a1, 0, 0, 0, 0)
81#define throw2(a1, a2) _throw5(__FILE__, __LINE__, 2, a1, a2, 0, 0, 0)
82#define throw3(a1, a2, a3) _throw5(__FILE__, __LINE__, 3, a1, a2, a3, 0, 0)
83#define throw4(a1, a2, a3, a4) _throw5(__FILE__, __LINE__, 4, a1, a2, a3, a4, 0)
84#define throw5(a1, a2, a3, a4, a5) _throw5(__FILE__, __LINE__, 5, a1, a2, a3, a4, a5)
86#define assert_throw0(e) do { if (!(e)) throw1("assertion failure"); } while (false)
87#define assert_range_throw0(e, ge, l) assert_throw0((ge) <= (e) && (e) < (l))
92 template<
typename T>
void operator()(T *ptr)
115File * File::Read(
const char *path, int32 mygridfd, int32 myswathfd)
118 auto file =
new File(path);
120 throw1(
"Memory allocation for file class failed. ");
122 file->gridfd = mygridfd;
123 file->swathfd = myswathfd;
126 if (!Utility::ReadNamelist(file->path.c_str(), GDinqgrid, gridlist)) {
128 throw1(
"Grid ReadNamelist failed.");
132 for (
const auto &grid: gridlist)
133 file->grids.push_back(GridDataset::Read(file->gridfd, grid));
137 throw1(
"GridDataset Read failed");
141 if (!Utility::ReadNamelist(file->path.c_str(), SWinqswath, swathlist)){
143 throw1(
"Swath ReadNamelist failed.");
147 for (
const auto &swath:swathlist)
148 file->swaths.push_back(SwathDataset::Read(file->swathfd, swath));
152 throw1(
"SwathDataset Read failed.");
160 if (!Utility::ReadNamelist(file->path.c_str(), PTinqpoint, pointlist)){
162 throw1(
"Point ReadNamelist failed.");
166 for (
const auto&point: pointlist)
167 file->points.push_back(PointDataset::Read(-1, point));
170 if (file->grids.empty() && file->swaths.empty()
171 && file->points.empty()) {
172 Exception e(
"Not an HDF-EOS2 file");
173 e.setFileType(
false);
184string File::get_geodim_x_name()
186 if (!_geodim_x_name.empty())
187 return _geodim_x_name;
188 _find_geodim_names();
189 return _geodim_x_name;
195string File::get_geodim_y_name()
197 if (!_geodim_y_name.empty())
198 return _geodim_y_name;
199 _find_geodim_names();
200 return _geodim_y_name;
210string File::get_latfield_name()
212 if (!_latfield_name.empty())
213 return _latfield_name;
214 _find_latlonfield_names();
215 return _latfield_name;
218string File::get_lonfield_name()
220 if (!_lonfield_name.empty())
221 return _lonfield_name;
222 _find_latlonfield_names();
223 return _lonfield_name;
230string File::get_geogrid_name()
232 if (!_geogrid_name.empty())
233 return _geogrid_name;
234 _find_geogrid_name();
235 return _geogrid_name;
243void File::_find_geodim_names()
246 for(
size_t i = 0; i<
sizeof(_geodim_x_names) /
sizeof(
const char *); i++)
247 geodim_x_name_set.emplace(_geodim_x_names[i]);
250 for (
size_t i = 0; i<
sizeof(_geodim_y_names) /
sizeof(
const char *); i++)
251 geodim_y_name_set.emplace(_geodim_y_names[i]);
253 const size_t gs = grids.size();
257 const Dataset *dataset=
nullptr;
258 dataset =
static_cast<Dataset*
>(grids[0]);
261 for (
const auto &dim:dims)
269 if (geodim_x_name_set.find(dim->getName()) != geodim_x_name_set.end())
270 _geodim_x_name = dim->getName();
271 else if (geodim_y_name_set.find(dim->getName()) != geodim_y_name_set.end())
272 _geodim_y_name = dim->getName();
275 if (_geodim_x_name.empty())
276 _geodim_x_name = _geodim_x_names[0];
277 if (_geodim_y_name.empty())
278 _geodim_y_name = _geodim_y_names[0];
286void File::_find_latlonfield_names()
289 for(
size_t i = 0; i<
sizeof(_latfield_names) /
sizeof(
const char *); i++)
290 latfield_name_set.emplace(_latfield_names[i]);
293 for(
size_t i = 0; i<
sizeof(_lonfield_names) /
sizeof(
const char *); i++)
294 lonfield_name_set.emplace(_lonfield_names[i]);
296 const size_t gs = grids.size();
297 const size_t ss = swaths.size();
298 for(
size_t i=0;i<1 ;i++)
300 const Dataset *dataset =
nullptr;
301 SwathDataset *sw =
nullptr;
303 dataset =
static_cast<Dataset*
>(grids[i]);
304 else if (i < gs + ss)
307 dataset =
static_cast<Dataset*
>(sw);
313 for (
const auto &field:fields)
315 if (latfield_name_set.find(field->getName()) != latfield_name_set.end())
316 _latfield_name = field->getName();
317 else if (lonfield_name_set.find(field->getName()) != lonfield_name_set.end())
318 _lonfield_name = field->getName();
324 for(
const auto &gfield:geofields)
326 if (latfield_name_set.find(gfield->getName()) != latfield_name_set.end())
327 _latfield_name = gfield->getName();
328 else if (lonfield_name_set.find(gfield->getName()) != lonfield_name_set.end())
329 _lonfield_name = gfield->getName();
333 if (_latfield_name.empty())
334 _latfield_name = _latfield_names[0];
335 if (_lonfield_name.empty())
336 _lonfield_name = _lonfield_names[0];
344void File::_find_geogrid_name()
347 for(
size_t i = 0; i<
sizeof(_geogrid_names) /
sizeof(
const char *); i++)
348 geogrid_name_set.emplace(_geogrid_names[i]);
350 const size_t gs = grids.size();
351 const size_t ss = swaths.size();
352 for(
size_t i=0; ;i++)
354 const Dataset *dataset =
nullptr;
356 dataset =
static_cast<Dataset*
>(grids[i]);
357 else if (i < gs + ss)
358 dataset =
static_cast<Dataset*
>(swaths[i-gs]);
362 if (geogrid_name_set.find(dataset->getName()) != geogrid_name_set.end())
363 _geogrid_name = dataset->getName();
365 if (_geogrid_name.empty())
366 _geogrid_name =
"location";
370void File::check_onelatlon_grids() {
373 string LATFIELDNAME = this->get_latfield_name();
374 string LONFIELDNAME = this->get_lonfield_name();
377 string GEOGRIDNAME =
"location";
386 for (
const auto &grid:grids){
389 for (
const auto &field:grid->getDataFields()) {
390 if (grid->getName()==GEOGRIDNAME){
391 if (field->getName()==LATFIELDNAME){
393 grid->latfield = field;
395 if (field->getName()==LONFIELDNAME){
397 grid->lonfield = field;
403 if ((field->getName()==LATFIELDNAME)||(field->getName()==LONFIELDNAME)){
404 grid->ownllflag =
true;
412 if (morellcount ==0 && onellcount ==2)
413 this->onelatlon =
true;
417void File::handle_one_grid_zdim(GridDataset* gdset) {
420 string DIMXNAME = this->get_geodim_x_name();
421 string DIMYNAME = this->get_geodim_y_name();
423 bool missingfield_unlim_flag =
false;
424 const Field *missingfield_unlim =
nullptr;
434 for (
const auto &field:gdset->getDataFields()) {
437 if (field->getRank()==1){
441 if ((field->getDimensions())[0]->getName()!=DIMXNAME && (field->getDimensions())[0]->getName()!=DIMYNAME){
443 tempdimret = tempdimlist.insert((field->getDimensions())[0]->getName());
448 if (tempdimret.second ==
true) {
452 field->fieldtype = 3;
453 if (field->getName() ==
"Time")
454 field->fieldtype = 5;
469 for (
const auto &gdim:gdset->getDimensions()) {
472 if (gdim->getName()!=DIMXNAME && gdim->getName()!=DIMYNAME){
475 if ((tempdimlist.find(gdim->getName())) == tempdimlist.end()){
478 auto missingfield =
new Field();
479 missingfield->name = gdim->getName();
480 missingfield->rank = 1;
483 missingfield->type = DFNT_INT32;
486 auto dim =
new Dimension(gdim->getName(),gdim->getSize());
489 missingfield->dims.push_back(dim);
491 if (0 == gdim->getSize()) {
492 missingfield_unlim_flag =
true;
493 missingfield_unlim = missingfield;
500 missingfield->fieldtype = 4;
504 gdset->datafields.push_back(missingfield);
513 bool temp_missingfield_unlim_flag = missingfield_unlim_flag;
514 if (
true == temp_missingfield_unlim_flag) {
515 for (
unsigned int i =0; i<gdset->getDataFields().size(); i++) {
517 for (
const auto &gdim:gdset->getDimensions()) {
519 if (gdim->getName() == (missingfield_unlim->getDimensions())[0]->getName()) {
520 if (gdim->getSize()!= 0) {
521 Dimension *dim = missingfield_unlim->getDimensions()[0];
524 dim->dimsize = gdim->getSize();
525 missingfield_unlim_flag =
false;
531 if (
false == missingfield_unlim_flag)
539void File::handle_one_grid_latlon(GridDataset* gdset)
543 string DIMXNAME = this->get_geodim_x_name();
544 string DIMYNAME = this->get_geodim_y_name();
546 string LATFIELDNAME = this->get_latfield_name();
547 string LONFIELDNAME = this->get_lonfield_name();
551 if (gdset->ownllflag) {
554 for (
const auto &field:gdset->getDataFields()) {
556 if (field->getName() == LATFIELDNAME) {
560 field->fieldtype = 1;
567 if (field->getRank() > 2)
568 throw3(
"The rank of latitude is greater than 2",
569 gdset->getName(),field->getName());
571 if (field->getRank() != 1) {
575 field->ydimmajor = gdset->getCalculated().isYDimMajor();
581 int32 projectioncode = gdset->getProjection().getCode();
582 if (projectioncode == GCTP_GEO || projectioncode ==GCTP_CEA) {
583 field->condenseddim =
true;
593 for (
const auto &dim:field->getDimensions()) {
594 if (dim->getName() == DIMYNAME)
604 else if (field->getName() == LONFIELDNAME) {
607 field->fieldtype = 2;
613 if (field->getRank() >2)
614 throw3(
"The rank of Longitude is greater than 2",gdset->getName(),field->getName());
616 if (field->getRank() != 1) {
619 field->ydimmajor = gdset->getCalculated().isYDimMajor();
624 int32 projectioncode = gdset->getProjection().getCode();
625 if (projectioncode == GCTP_GEO || projectioncode ==GCTP_CEA) {
626 field->condenseddim =
true;
636 for (
const auto &dim:field->getDimensions()) {
637 if (dim->getName() == DIMXNAME)
652 auto latfield =
new Field();
653 auto lonfield =
new Field();
655 latfield->name = LATFIELDNAME;
656 lonfield->name = LONFIELDNAME;
663 latfield->type = DFNT_FLOAT64;
664 lonfield->type = DFNT_FLOAT64;
667 latfield->fieldtype = 1;
670 lonfield->fieldtype = 2;
674 latfield->ydimmajor = gdset->getCalculated().isYDimMajor();
675 lonfield->ydimmajor = latfield->ydimmajor;
678 int xdimsize = gdset->getInfo().getX();
679 int ydimsize = gdset->getInfo().getY();
684 bool dmajor=(gdset->getProjection().getCode()==GCTP_LAMAZ)? gdset->getCalculated().DetectFieldMajorDimension()
685 : latfield->ydimmajor;
688 auto dimlaty =
new Dimension(DIMYNAME,ydimsize);
689 latfield->dims.push_back(dimlaty);
690 auto dimlony =
new Dimension(DIMYNAME,ydimsize);
691 lonfield->dims.push_back(dimlony);
692 auto dimlatx =
new Dimension(DIMXNAME,xdimsize);
693 latfield->dims.push_back(dimlatx);
694 auto dimlonx =
new Dimension(DIMXNAME,xdimsize);
695 lonfield->dims.push_back(dimlonx);
698 auto dimlatx =
new Dimension(DIMXNAME,xdimsize);
699 latfield->dims.push_back(dimlatx);
700 auto dimlonx =
new Dimension(DIMXNAME,xdimsize);
701 lonfield->dims.push_back(dimlonx);
702 auto dimlaty =
new Dimension(DIMYNAME,ydimsize);
703 latfield->dims.push_back(dimlaty);
704 auto dimlony =
new Dimension(DIMYNAME,ydimsize);
705 lonfield->dims.push_back(dimlony);
710 const float64* upleft = gdset->getInfo().getUpLeft();
711 const float64* lowright = gdset->getInfo().getLowRight();
714 int32 projectioncode = gdset->getProjection().getCode();
715 if (((
int)lowright[0]>180000000) && ((
int)upleft[0]>-1)) {
718 if (projectioncode == GCTP_GEO) {
719 lonfield->speciallon =
true;
725 if (HDF4RequestHandler::get_enable_eosgeo_cachefile() ==
true)
726 latfield->speciallon =
true;
738 if (((
int)(lowright[0]/1000)==0) &&((
int)(upleft[0]/1000)==0)
739 && ((
int)(upleft[1]/1000)==0) && ((
int)(lowright[1]/1000)==0)) {
740 if (projectioncode == GCTP_GEO){
741 lonfield->specialformat = 1;
742 latfield->specialformat = 1;
751 if (((
int)(lowright[0])==0) &&((
int)(upleft[0])==0)
752 && ((
int)(upleft[1])==0) && ((
int)(lowright[1])==0)) {
753 if (projectioncode == GCTP_GEO){
754 lonfield->specialformat = 2;
755 latfield->specialformat = 2;
756 gdset->addfvalueattr =
true;
767 if (((
int)(lowright[0])==-1) &&((
int)(upleft[0])==-1)
768 && ((
int)(upleft[1])==-1) && ((
int)(lowright[1])==-1)) {
769 lonfield->specialformat = 3;
770 latfield->specialformat = 3;
771 lonfield->condenseddim =
true;
772 latfield->condenseddim =
true;
777 if (GCTP_SOM == projectioncode) {
778 lonfield->specialformat = 4;
779 latfield->specialformat = 4;
785 if (projectioncode == GCTP_GEO || projectioncode ==GCTP_CEA) {
786 lonfield->condenseddim =
true;
787 latfield->condenseddim =
true;
791 gdset->datafields.push_back(latfield);
792 gdset->datafields.push_back(lonfield);
803 for (
const auto &dim:lonfield->getDimensions()) {
804 if (dim->getName() == DIMXNAME)
807 if (dim->getName() == DIMYNAME)
815void File::handle_onelatlon_grids() {
818 string DIMXNAME = this->get_geodim_x_name();
819 string DIMYNAME = this->get_geodim_y_name();
820 string LATFIELDNAME = this->get_latfield_name();
821 string LONFIELDNAME = this->get_lonfield_name();
825 string GEOGRIDNAME =
"location";
831 for (
const auto &grid:this->grids) {
835 grid->setDimxName(DIMXNAME);
836 grid->setDimyName(DIMYNAME);
839 if (grid->getName()==GEOGRIDNAME) {
844 grid->lonfield->fieldtype = 2;
845 grid->latfield->fieldtype = 1;
848 if (grid->lonfield->rank >2 || grid->latfield->rank >2)
849 throw2(
"Either the rank of lat or the lon is greater than 2",grid->getName());
850 if (grid->lonfield->rank !=grid->latfield->rank)
851 throw2(
"The rank of the latitude is not the same as the rank of the longitude",grid->getName());
854 if (grid->lonfield->rank != 1) {
858 grid->lonfield->ydimmajor = grid->getCalculated().isYDimMajor();
859 grid->latfield->ydimmajor = grid->lonfield->ydimmajor;
864 int32 projectioncode = grid->getProjection().getCode();
865 if (projectioncode == GCTP_GEO || projectioncode ==GCTP_CEA) {
866 grid->lonfield->condenseddim =
true;
867 grid->latfield->condenseddim =
true;
880 for (
const auto &dim:grid->lonfield->getDimensions()) {
881 if (dim->getName() == DIMXNAME) {
883 grid->lonfield->getName());
885 if (dim->getName() == DIMYNAME) {
887 grid->latfield->getName());
893 grid->lonfield->getName());
895 grid->latfield->getName());
897 temponelatlondimcvarlist = grid->dimcvarlist;
905 for (
const auto &grid:this->grids) {
907 string templatlonname1;
908 string templatlonname2;
910 if (grid->getName() != GEOGRIDNAME) {
915 tempmapit = temponelatlondimcvarlist.find(DIMXNAME);
916 if (tempmapit != temponelatlondimcvarlist.end())
917 templatlonname1= tempmapit->second;
919 throw2(
"cannot find the dimension field of XDim", grid->getName());
924 tempmapit = temponelatlondimcvarlist.find(DIMYNAME);
925 if (tempmapit != temponelatlondimcvarlist.end())
926 templatlonname2= tempmapit->second;
928 throw2(
"cannot find the dimension field of YDim", grid->getName());
936void File::handle_grid_dim_cvar_maps() {
939 string DIMXNAME = this->get_geodim_x_name();
941 string DIMYNAME = this->get_geodim_y_name();
943 string LATFIELDNAME = this->get_latfield_name();
945 string LONFIELDNAME = this->get_lonfield_name();
950 string GEOGRIDNAME =
"location";
964 vector <string> tempfieldnamelist;
965 for (
const auto &grid:this->grids) {
966 for (
const auto &field:grid->getDataFields())
976 string tempcorrectedlatname;
977 string tempcorrectedlonname;
979 int total_fcounter = 0;
981 for (
const auto &grid:this->grids) {
986 for (
const auto &field:grid->getDataFields())
988 field->newname = tempfieldnamelist[total_fcounter];
992 if (field->fieldtype!=0) {
994 tempncvarnamelist.insert(make_pair(field->getName(), field->newname));
997 if ((this->onelatlon)&&((grid->getName())==GEOGRIDNAME)) {
998 if (field->getName()==LATFIELDNAME)
999 tempcorrectedlatname = field->newname;
1000 if (field->getName()==LONFIELDNAME)
1001 tempcorrectedlonname = field->newname;
1006 grid->ncvarnamelist = tempncvarnamelist;
1007 tempncvarnamelist.clear();
1013 if (this->onelatlon) {
1014 for (
const auto &grid:this->grids) {
1016 if (grid->getName()!=GEOGRIDNAME){
1027 vector <string>tempalldimnamelist;
1028 for (
const auto &grid:this->grids) {
1030 grid->dimcvarlist.begin(); j!= grid->dimcvarlist.end();++j)
1038 int total_dcounter = 0;
1039 for (
const auto &grid:this->grids) {
1042 grid->dimcvarlist.begin(); j!= grid->dimcvarlist.end();++j){
1045 if ((DIMXNAME == (*j).first || DIMYNAME == (*j).first) && (
true==(this->onelatlon)))
1052 grid->ndimnamelist = tempndimnamelist;
1053 tempndimnamelist.clear();
1058void File::handle_grid_coards() {
1061 string DIMXNAME = this->get_geodim_x_name();
1062 string DIMYNAME = this->get_geodim_y_name();
1063 string LATFIELDNAME = this->get_latfield_name();
1064 string LONFIELDNAME = this->get_lonfield_name();
1070 string GEOGRIDNAME =
"location";
1075 string tempcorrecteddimname;
1084 Dimension *correcteddim;
1086 for (
const auto &grid:this->grids) {
1087 for (
const auto &field:grid->getDataFields()) {
1092 if (field->getName()==LATFIELDNAME && field->getRank()==2 &&field->condenseddim) {
1094 string templatdimname;
1098 tempmapit = grid->ncvarnamelist.find(LATFIELDNAME);
1099 if (tempmapit != grid->ncvarnamelist.end())
1100 templatdimname= tempmapit->second;
1102 throw2(
"cannot find the corrected field of Latitude", grid->getName());
1104 for (
const auto &dim:field->getDimensions()) {
1108 if (dim->getName()==DIMYNAME) {
1109 correcteddim =
new Dimension(templatdimname,dim->getSize());
1110 correcteddims.push_back(correcteddim);
1111 field->setCorrectedDimensions(correcteddims);
1115 field->iscoard =
true;
1116 grid->iscoard =
true;
1117 if (this->onelatlon)
1118 this->iscoard =
true;
1121 correcteddims.clear();
1125 else if (field->getName()==LONFIELDNAME && field->getRank()==2 &&field->condenseddim){
1127 string templondimname;
1131 tempmapit = grid->ncvarnamelist.find(LONFIELDNAME);
1132 if (tempmapit != grid->ncvarnamelist.end())
1133 templondimname= tempmapit->second;
1135 throw2(
"cannot find the corrected field of Longitude", grid->getName());
1137 for (
const auto &dim:field->getDimensions()) {
1141 if (dim->getName()==DIMXNAME) {
1142 correcteddim =
new Dimension(templondimname,dim->getSize());
1143 correcteddims.push_back(correcteddim);
1144 field->setCorrectedDimensions(correcteddims);
1149 field->iscoard =
true;
1150 grid->iscoard =
true;
1151 if (this->onelatlon)
1152 this->iscoard =
true;
1153 correcteddims.clear();
1157 else if ((field->getRank()==1) &&(field->getName()==LONFIELDNAME) ) {
1159 string templondimname;
1163 tempmapit = grid->ncvarnamelist.find(LONFIELDNAME);
1164 if (tempmapit != grid->ncvarnamelist.end())
1165 templondimname= tempmapit->second;
1167 throw2(
"cannot find the corrected field of Longitude", grid->getName());
1169 correcteddim =
new Dimension(templondimname,(field->getDimensions())[0]->getSize());
1170 correcteddims.push_back(correcteddim);
1171 field->setCorrectedDimensions(correcteddims);
1172 field->iscoard =
true;
1173 grid->iscoard =
true;
1174 if (this->onelatlon)
1175 this->iscoard =
true;
1176 correcteddims.clear();
1178 if (((field->getDimensions())[0]->getName()!=DIMXNAME)
1179 &&(((field->getDimensions())[0]->getName())!=DIMYNAME)){
1180 throw3(
"the dimension name of longitude should not be ",
1181 (field->getDimensions())[0]->getName(),grid->getName());
1183 if (((field->getDimensions())[0]->getName())==DIMXNAME) {
1192 else if ((field->getRank()==1) &&(field->getName()==LATFIELDNAME) ) {
1194 string templatdimname;
1198 tempmapit = grid->ncvarnamelist.find(LATFIELDNAME);
1199 if (tempmapit != grid->ncvarnamelist.end())
1200 templatdimname= tempmapit->second;
1202 throw2(
"cannot find the corrected field of Latitude", grid->getName());
1204 correcteddim =
new Dimension(templatdimname,(field->getDimensions())[0]->getSize());
1205 correcteddims.push_back(correcteddim);
1206 field->setCorrectedDimensions(correcteddims);
1208 field->iscoard =
true;
1209 grid->iscoard =
true;
1210 if (this->onelatlon)
1211 this->iscoard =
true;
1212 correcteddims.clear();
1214 if ((((field->getDimensions())[0]->getName())!=DIMXNAME)
1215 &&(((field->getDimensions())[0]->getName())!=DIMYNAME))
1216 throw3(
"the dimension name of latitude should not be ",
1217 (field->getDimensions())[0]->getName(),grid->getName());
1218 if (((field->getDimensions())[0]->getName())==DIMXNAME){
1230 if (
true == this->onelatlon){
1233 if (
true == this->iscoard){
1236 string tempcorrectedxdimname;
1237 string tempcorrectedydimname;
1239 if ((
int)(tempnewxdimnamelist.size())!= 1)
1240 throw1(
"the corrected dimension name should have only one pair");
1241 if ((
int)(tempnewydimnamelist.size())!= 1)
1242 throw1(
"the corrected dimension name should have only one pair");
1245 tempcorrectedxdimname = tempdimmapit->second;
1246 tempdimmapit = tempnewydimnamelist.begin();
1247 tempcorrectedydimname = tempdimmapit->second;
1249 for (
const auto &grid:this->grids) {
1253 tempmapit = grid->ndimnamelist.find(DIMXNAME);
1254 if (tempmapit != grid->ndimnamelist.end()) {
1258 throw2(
"cannot find the corrected dimension name", grid->getName());
1259 tempmapit = grid->ndimnamelist.find(DIMYNAME);
1260 if (tempmapit != grid->ndimnamelist.end()) {
1264 throw2(
"cannot find the corrected dimension name", grid->getName());
1269 for (
const auto &grid:this->grids) {
1273 string tempcorrectedxdimname;
1274 string tempcorrectedydimname;
1279 tempdimmapit = tempnewxdimnamelist.find(grid->getName());
1280 if (tempdimmapit != tempnewxdimnamelist.end())
1281 tempcorrectedxdimname = tempdimmapit->second;
1283 throw2(
"cannot find the corrected COARD XDim dimension name", grid->getName());
1284 tempmapit = grid->ndimnamelist.find(DIMXNAME);
1285 if (tempmapit != grid->ndimnamelist.end()) {
1289 throw2(
"cannot find the corrected dimension name", grid->getName());
1291 tempdimmapit = tempnewydimnamelist.find(grid->getName());
1292 if (tempdimmapit != tempnewydimnamelist.end())
1293 tempcorrectedydimname = tempdimmapit->second;
1295 throw2(
"cannot find the corrected COARD YDim dimension name", grid->getName());
1297 tempmapit = grid->ndimnamelist.find(DIMYNAME);
1298 if (tempmapit != grid->ndimnamelist.end()) {
1302 throw2(
"cannot find the corrected dimension name", grid->getName());
1310 for (
const auto &grid:this->grids){
1312 grid->dimcvarlist.begin(); j!= grid->dimcvarlist.end();++j){
1316 if ((this->iscoard||grid->iscoard) && (*j).first !=DIMXNAME && (*j).first !=DIMYNAME) {
1317 string tempnewdimname;
1321 tempmapit = grid->ncvarnamelist.find((*j).second);
1322 if (tempmapit != grid->ncvarnamelist.end())
1323 tempnewdimname= tempmapit->second;
1325 throw3(
"cannot find the corrected field of ", (*j).second,grid->getName());
1328 tempmapit =grid->ndimnamelist.find((*j).first);
1329 if (tempmapit != grid->ndimnamelist.end())
1332 throw3(
"cannot find the corrected dimension name of ", (*j).first,grid->getName());
1340void File::update_grid_field_corrected_dims() {
1344 string tempcorrecteddimname;
1346 Dimension *correcteddim;
1348 for (
const auto &grid:this->grids) {
1350 for (
const auto &field:grid->getDataFields()) {
1353 if (field->iscoard ==
false) {
1356 for (
const auto &dim:field->getDimensions()){
1361 tempmapit = grid->ndimnamelist.find(dim->getName());
1362 if (tempmapit != grid->ndimnamelist.end())
1363 tempcorrecteddimname= tempmapit->second;
1365 throw4(
"cannot find the corrected dimension name", grid->getName(),field->getName(),dim->getName());
1366 correcteddim =
new Dimension(tempcorrecteddimname,dim->getSize());
1367 correcteddims.push_back(correcteddim);
1369 field->setCorrectedDimensions(correcteddims);
1370 correcteddims.clear();
1377void File::handle_grid_cf_attrs() {
1384 for (
const auto &grid:this->grids) {
1385 for (
const auto &field:grid->getDataFields()) {
1388 if (field->fieldtype == 0) {
1389 string tempcoordinates=
"";
1390 string tempfieldname=
"";
1391 string tempcorrectedfieldname=
"";
1393 for (
const auto &dim:field->getDimensions()) {
1400 tempmapit = (grid->dimcvarlist).find(dim->getName());
1401 if (tempmapit != (grid->dimcvarlist).end())
1402 tempfieldname = tempmapit->second;
1404 throw4(
"cannot find the dimension field name",
1405 grid->getName(),field->getName(),dim->getName());
1408 tempmapit2 = (grid->ncvarnamelist).find(tempfieldname);
1409 if (tempmapit2 != (grid->ncvarnamelist).end())
1410 tempcorrectedfieldname = tempmapit2->second;
1412 throw4(
"cannot find the corrected dimension field name",
1413 grid->getName(),field->getName(),dim->getName());
1416 tempcoordinates= tempcorrectedfieldname;
1418 tempcoordinates = tempcoordinates +
" "+tempcorrectedfieldname;
1421 field->setCoordinates(tempcoordinates);
1425 if (field->fieldtype == 1) {
1426 string tempunits =
"degrees_north";
1427 field->setUnits(tempunits);
1429 if (field->fieldtype == 2) {
1430 string tempunits =
"degrees_east";
1431 field->setUnits(tempunits);
1438 if (field->fieldtype == 4) {
1439 string tempunits =
"level";
1440 field->setUnits(tempunits);
1444 if (field->fieldtype == 5) {
1445 string tempunits =
"days since 1900-01-01 00:00:00";
1446 field->setUnits(tempunits);
1454 if (
true == grid->addfvalueattr) {
1455 if (((field->getFillValue()).empty()) && (field->getType()==DFNT_FLOAT32 )) {
1456 float tempfillvalue = FLT_MAX;
1457 field->addFillValue(tempfillvalue);
1458 field->setAddedFillValue(
true);
1466void File::handle_grid_SOM_projection() {
1475 for (
const auto &grid:this->grids) {
1476 if (GCTP_SOM == grid->getProjection().getCode()) {
1482 for (
const auto &dim:grid->getDimensions()) {
1485 if (NBLOCK == dim->getSize()) {
1489 if (dim->getName().compare(0,3,
"SOM") == 0) {
1490 som_dimname = dim->getName();
1496 if (
""== som_dimname)
1497 throw4(
"Wrong number of block: The number of block of MISR SOM Grid ",
1498 grid->getName(),
" is not ",NBLOCK);
1503 string cor_som_dimname;
1504 tempmapit = grid->ndimnamelist.find(som_dimname);
1505 if (tempmapit != grid->ndimnamelist.end())
1506 cor_som_dimname = tempmapit->second;
1508 throw2(
"cannot find the corrected dimension name for ", som_dimname);
1511 string cor_som_cvname;
1516 j != grid->datafields.end(); ) {
1520 if (1 == (*j)->fieldtype || 2 == (*j)->fieldtype) {
1522 auto newdim =
new Dimension(som_dimname,NBLOCK);
1523 auto newcor_dim =
new Dimension(cor_som_dimname,NBLOCK);
1526 it_d = (*j)->dims.begin();
1527 (*j)->dims.insert(it_d,newdim);
1529 it_d = (*j)->correcteddims.begin();
1530 (*j)->correcteddims.insert(it_d,newcor_dim);
1539 if ( 4 == (*j)->fieldtype) {
1540 cor_som_cvname = (*j)->newname;
1542 j = grid->datafields.erase(j);
1556 for (
const auto &field:grid->getDataFields()) {
1558 if ( 0 == field->fieldtype) {
1560 string temp_coordinates = field->coordinates;
1563 found = temp_coordinates.find(cor_som_cvname);
1567 if (temp_coordinates.size() >cor_som_cvname.size())
1568 temp_coordinates.erase(found,cor_som_cvname.size()+1);
1570 temp_coordinates.erase(found,cor_som_cvname.size());
1572 else if (found != string::npos)
1573 temp_coordinates.erase(found-1,cor_som_cvname.size()+1);
1575 throw4(
"cannot find the coordinate variable ",cor_som_cvname,
1576 "from ",temp_coordinates);
1578 field->setCoordinates(temp_coordinates);
1588void File::check_swath_dimmap(
int numswath) {
1590 if (HDF4RequestHandler::get_disable_swath_dim_map() ==
true)
1595 int temp_num_map = 0;
1596 bool odd_num_map =
false;
1597 for (
const auto &swath:this->swaths) {
1598 temp_num_map = swath->get_num_map();
1599 tempnumdm += temp_num_map;
1600 if (temp_num_map%2!=0) {
1607 if (tempnumdm != 0 && odd_num_map ==
false)
1608 handle_swath_dimmap =
true;
1617 bool fakedimmap =
false;
1619 if (numswath == 1) {
1621 if ((this->swaths[0]->getName()).find(
"atml2")!=string::npos){
1627 for (
const auto &gfield:this->swaths[0]->getGeoFields()) {
1628 if (gfield->getName() ==
"Latitude" || gfield->getName() ==
"Longitude") {
1629 if (gfield->getType() == DFNT_UINT16 ||
1630 gfield->getType() == DFNT_INT16)
1631 gfield->type = DFNT_FLOAT32;
1633 if (templlflag == 2)
1640 for (
const auto &dfield:this->swaths[0]->getDataFields()) {
1655 if ((dfield->getName()).find(
"Latitude") != string::npos){
1657 if (dfield->getType() == DFNT_UINT16 ||
1658 dfield->getType() == DFNT_INT16)
1659 dfield->type = DFNT_FLOAT32;
1661 dfield->fieldtype = 1;
1664 if (dfield->getRank() != 2)
1665 throw2(
"The lat/lon rank must be 2 for Java clients to work",
1668 ((dfield->getDimensions())[0])->getName(),dfield->getName());
1672 if ((dfield->getName()).find(
"Longitude")!= string::npos) {
1674 if (dfield->getType() == DFNT_UINT16 ||
1675 dfield->getType() == DFNT_INT16)
1676 dfield->type = DFNT_FLOAT32;
1678 dfield->fieldtype = 2;
1679 if (dfield->getRank() != 2)
1680 throw2(
"The lat/lon rank must be 2 for Java clients to work",
1683 ((dfield->getDimensions())[1])->getName(), dfield->getName());
1687 if (templlflag == 2)
1695 if (
true == fakedimmap)
1696 handle_swath_dimmap =
false;
1703void File::check_swath_dimmap_bk_compat(
int numswath){
1705 if (
true == handle_swath_dimmap) {
1707 if (numswath == 1 && (((this->swaths)[0])->name==
"MODIS_SWATH_Type_L1B"))
1708 backward_handle_swath_dimmap =
true;
1714 bool all_2_dimmaps_no_geodim =
true;
1715 for (
const auto &swath:this->swaths) {
1716 if (swath->get_num_map() !=2 || swath->GeoDim_in_vars ==
true) {
1717 all_2_dimmaps_no_geodim =
false;
1721 if (
true == all_2_dimmaps_no_geodim)
1722 backward_handle_swath_dimmap =
true;
1729void File::create_swath_latlon_dim_cvar_map(){
1733 if (handle_swath_dimmap ==
true && backward_handle_swath_dimmap ==
false) {
1738 multi_dimmap =
true;
1740 for (
const auto &swath:this->swaths) {
1742 bool has_cf_lat =
false;
1743 bool has_cf_lon =
false;
1745 for (
const auto &gfield:swath->getGeoFields()) {
1750 if (gfield->getName()==
"Latitude" && gfield->getRank() == 2){
1752 ori_lats.push_back(gfield);
1754 else if (gfield->getName()==
"Longitude" && gfield->getRank() == 2){
1756 ori_lons.push_back(gfield);
1758 if (has_cf_lat ==
true && has_cf_lon ==
true)
1761 if (has_cf_lat ==
false || has_cf_lon ==
false) {
1762 multi_dimmap =
false;
1771 if (
true == multi_dimmap) {
1774 for (
const auto &swath:this->swaths) {
1775 create_swath_latlon_dim_cvar_map_for_dimmap(swath,ori_lats[ll_count],ori_lons[ll_count]);
1796 bool lat_in_geofields =
false;
1797 bool lon_in_geofields =
false;
1799 for (
const auto &swath:this->swaths) {
1801 int tempgeocount = 0;
1802 for (
const auto &gfield:swath->getGeoFields()) {
1806 if (gfield->getName()==
"Latitude" ){
1807 if (gfield->getRank() > 2)
1808 throw2(
"Currently the lat/lon rank must be 1 or 2 for Java clients to work",
1811 lat_in_geofields =
true;
1822 if (handle_swath_dimmap ==
true) {
1825 if (
true == backward_handle_swath_dimmap) {
1828 for (
const auto &dmap:swath->getDimensionMaps()) {
1832 if ((gfield->getDimensions()[0])->getName() == dmap->getGeoDimension()) {
1840 gfield->fieldtype = 1;
1844 if (gfield->getName()==
"Longitude"){
1845 if (gfield->getRank() > 2)
1846 throw2(
"Currently the lat/lon rank must be 1 or 2 for Java clients to work",
1851 lon_in_geofields =
true;
1852 if (gfield->getRank() == 1) {
1862 ((gfield->getDimensions())[1])->getName(),
"Longitude");
1863 if (handle_swath_dimmap ==
true) {
1864 if (
true == backward_handle_swath_dimmap) {
1867 for (
const auto &dmap:swath->getDimensionMaps()) {
1872 if ((gfield->getDimensions()[1])->getName() ==
1873 dmap->getGeoDimension()) {
1875 dmap->getDataDimension(),
"Longitude");
1881 gfield->fieldtype = 2;
1884 if (tempgeocount == 2)
1890 if (lat_in_geofields!=lon_in_geofields)
1891 throw1(
"Latitude and longitude must be both under Geolocation fields or Data fields");
1894 if (!lat_in_geofields && !lon_in_geofields) {
1896 bool lat_in_datafields =
false;
1897 bool lon_in_datafields =
false;
1899 for (
const auto &swath:this->swaths) {
1901 int tempgeocount = 0;
1902 for (
const auto &dfield:swath->getDataFields()) {
1908 if (dfield->getName()==
"Latitude" ){
1909 if (dfield->getRank() > 2) {
1910 throw2(
"Currently the lat/lon rank must be 1 or 2 for Java clients to work",
1913 lat_in_datafields =
true;
1922 ((dfield->getDimensions())[0])->getName(),
"Latitude");
1924 if (handle_swath_dimmap ==
true) {
1925 if (
true == backward_handle_swath_dimmap) {
1927 for (
const auto &dmap:swath->getDimensionMaps()) {
1930 if ((dfield->getDimensions()[0])->getName() == dmap->getGeoDimension()) {
1937 dfield->fieldtype = 1;
1941 if (dfield->getName()==
"Longitude"){
1943 if (dfield->getRank() > 2) {
1944 throw2(
"Currently the lat/lon rank must be 1 or 2 for Java clients to work",
1950 lon_in_datafields =
true;
1951 if (dfield->getRank() == 1) {
1961 ((dfield->getDimensions())[1])->getName(),
"Longitude");
1962 if (handle_swath_dimmap ==
true) {
1963 if (
true == backward_handle_swath_dimmap) {
1965 for (
const auto &dmap:swath->getDimensionMaps()) {
1968 if ((dfield->getDimensions()[1])->getName() == dmap->getGeoDimension()) {
1970 dmap->getDataDimension(),
"Longitude");
1976 dfield->fieldtype = 2;
1979 if (tempgeocount == 2)
1985 if (lat_in_datafields!=lon_in_datafields)
1986 throw1(
"Latitude and longitude must be both under Geolocation fields or Data fields");
1994void File:: create_swath_nonll_dim_cvar_map()
1997 for (
const auto &swath:this->swaths) {
2016 j!= swath->dimcvarlist.end();++j){
2017 tempdimret = swath->nonmisscvdimlist.insert((*j).first);
2024 for (
const auto &gfield:swath->getGeoFields()) {
2026 if (gfield->getRank()==1) {
2027 if (swath->nonmisscvdimlist.find(((gfield->getDimensions())[0])->getName()) == swath->nonmisscvdimlist.end()){
2028 tempdimret = swath->nonmisscvdimlist.insert(((gfield->getDimensions())[0])->getName());
2029 if (gfield->getName() ==
"Time")
2030 gfield->fieldtype = 5;
2032 HDFCFUtil::insert_map(swath->dimcvarlist, ((gfield->getDimensions())[0])->getName(), gfield->getName());
2033 gfield->fieldtype = 3;
2043 for (
const auto &dfield:swath->getDataFields()) {
2045 if (dfield->getRank()==1) {
2046 if (swath->nonmisscvdimlist.find(((dfield->getDimensions())[0])->getName()) == swath->nonmisscvdimlist.end()){
2047 tempdimret = swath->nonmisscvdimlist.insert(((dfield->getDimensions())[0])->getName());
2048 if (dfield->getName() ==
"Time")
2049 dfield->fieldtype = 5;
2055 HDFCFUtil::insert_map(swath->dimcvarlist, ((dfield->getDimensions())[0])->getName(), dfield->getName());
2056 dfield->fieldtype = 3;
2066 bool missingfield_unlim_flag =
false;
2067 Field *missingfield_unlim =
nullptr;
2069 for (
const auto &sdim:swath->getDimensions()) {
2071 if ((swath->nonmisscvdimlist.find(sdim->getName())) == swath->nonmisscvdimlist.end()){
2074 auto missingfield =
new Field();
2087 if (
true == multi_dimmap && (this->swaths.size() != 1)) {
2088 missingfield->name = sdim->getName()+
"_"+swath->name;
2089 dim =
new Dimension(missingfield->name,sdim->getSize());
2092 missingfield->name = sdim->getName();
2093 dim =
new Dimension(sdim->getName(),sdim->getSize());
2095 missingfield->rank = 1;
2096 missingfield->type = DFNT_INT32;
2099 missingfield->dims.push_back(dim);
2106 if (0 == sdim->getSize()) {
2107 missingfield_unlim_flag =
true;
2108 missingfield_unlim = missingfield;
2112 missingfield->fieldtype = 4;
2114 swath->geofields.push_back(missingfield);
2116 (missingfield->getDimensions())[0]->getName(), missingfield->name);
2126 bool temp_missingfield_unlim_flag = missingfield_unlim_flag;
2127 if (
true == temp_missingfield_unlim_flag) {
2128 for (
const auto &dfield:swath->getDataFields()) {
2130 for (
const auto &fdim:dfield->getDimensions()) {
2132 if (fdim->getName() == (missingfield_unlim->getDimensions())[0]->getName()) {
2133 if (fdim->getSize()!= 0) {
2134 Dimension *dim = missingfield_unlim->getDimensions()[0];
2136 dim->dimsize = fdim->getSize();
2137 missingfield_unlim_flag =
false;
2142 if (
false == missingfield_unlim_flag)
2147 swath->nonmisscvdimlist.clear();
2154void File::handle_swath_dim_cvar_maps() {
2157 vector <string> tempfieldnamelist;
2158 for (
const auto &swath:this->swaths) {
2161 for (
const auto &gfield:swath->getGeoFields()) {
2162 if (gfield->fieldtype == 0 && (this->swaths.size() !=1) &&
2163 (
true == handle_swath_dimmap) &&
2164 (backward_handle_swath_dimmap ==
false)){
2165 string new_field_name = gfield->name+
"_"+swath->name;
2172 for (
const auto &dfield:swath->getDataFields()) {
2173 if (dfield->fieldtype == 0 && (this->swaths.size() !=1) &&
2174 true == multi_dimmap){
2178 string new_field_name = dfield->name+
"_"+swath->name;
2188 int total_fcounter = 0;
2194 for (
const auto &swath:this->swaths) {
2197 for (
const auto &gfield:swath->getGeoFields())
2200 gfield->newname = tempfieldnamelist[total_fcounter];
2204 if (gfield->fieldtype!=0)
2209 for (
const auto &dfield:swath->getDataFields())
2211 dfield->newname = tempfieldnamelist[total_fcounter];
2215 if (dfield->fieldtype!=0) {
2223 vector <string>tempalldimnamelist;
2225 for (
const auto &swath:this->swaths) {
2227 swath->dimcvarlist.begin(); j!= swath->dimcvarlist.end();++j)
2234 int total_dcounter = 0;
2236 for (
const auto &swath:this->swaths) {
2238 swath->dimcvarlist.begin(); j!= swath->dimcvarlist.end();++j){
2246 string tempcorrecteddimname;
2247 Dimension *correcteddim;
2249 for (
const auto &swath:this->swaths) {
2252 for (
const auto &gfield:swath->getGeoFields()) {
2254 for (
const auto &gdim:gfield->getDimensions()) {
2259 if (handle_swath_dimmap ==
false || multi_dimmap ==
true) {
2262 tempmapit = swath->ndimnamelist.find(gdim->getName());
2263 if (tempmapit != swath->ndimnamelist.end())
2264 tempcorrecteddimname= tempmapit->second;
2266 throw4(
"cannot find the corrected dimension name",
2267 swath->getName(),gfield->getName(),gdim->getName());
2269 correcteddim =
new Dimension(tempcorrecteddimname,gdim->getSize());
2273 bool isdimmapname =
false;
2276 for (
const auto &sdmap:swath->getDimensionMaps()) {
2280 if (gdim->getName() == sdmap->getGeoDimension()) {
2282 isdimmapname =
true;
2283 gfield->dmap =
true;
2284 string temprepdimname = sdmap->getDataDimension();
2287 tempmapit = swath->ndimnamelist.find(temprepdimname);
2288 if (tempmapit != swath->ndimnamelist.end())
2289 tempcorrecteddimname= tempmapit->second;
2291 throw4(
"cannot find the corrected dimension name", swath->getName(),
2292 gfield->getName(),gdim->getName());
2296 bool ddimsflag =
false;
2297 for (
const auto &sdim:swath->getDimensions()) {
2298 if (sdim->getName() == temprepdimname) {
2300 correcteddim =
new Dimension(tempcorrecteddimname,sdim->getSize());
2306 throw4(
"cannot find the corrected dimension size", swath->getName(),
2307 gfield->getName(),gdim->getName());
2311 if (
false == isdimmapname) {
2313 tempmapit = swath->ndimnamelist.find(gdim->getName());
2314 if (tempmapit != swath->ndimnamelist.end())
2315 tempcorrecteddimname= tempmapit->second;
2317 throw4(
"cannot find the corrected dimension name",
2318 swath->getName(),gfield->getName(),gdim->getName());
2320 correcteddim =
new Dimension(tempcorrecteddimname,gdim->getSize());
2325 correcteddims.push_back(correcteddim);
2327 gfield->setCorrectedDimensions(correcteddims);
2328 correcteddims.clear();
2332 for (
const auto &dfield:swath->getDataFields()) {
2334 for (
const auto &fdim:dfield->getDimensions()) {
2336 if ((handle_swath_dimmap ==
false) || multi_dimmap ==
true) {
2340 tempmapit = swath->ndimnamelist.find(fdim->getName());
2341 if (tempmapit != swath->ndimnamelist.end())
2342 tempcorrecteddimname= tempmapit->second;
2344 throw4(
"cannot find the corrected dimension name", swath->getName(),
2345 dfield->getName(),fdim->getName());
2347 correcteddim =
new Dimension(tempcorrecteddimname,fdim->getSize());
2351 bool isdimmapname =
false;
2354 for (
const auto &smap:swath->getDimensionMaps()) {
2357 if (fdim->getName() == smap->getGeoDimension()) {
2358 isdimmapname =
true;
2359 dfield->dmap =
true;
2360 string temprepdimname = smap->getDataDimension();
2363 tempmapit = swath->ndimnamelist.find(temprepdimname);
2364 if (tempmapit != swath->ndimnamelist.end())
2365 tempcorrecteddimname= tempmapit->second;
2367 throw4(
"cannot find the corrected dimension name",
2368 swath->getName(),dfield->getName(),fdim->getName());
2372 bool ddimsflag =
false;
2373 for (
const auto &sdim:swath->getDimensions()) {
2376 if (sdim->getName() == temprepdimname) {
2377 correcteddim =
new Dimension(tempcorrecteddimname,sdim->getSize());
2383 throw4(
"cannot find the corrected dimension size",
2384 swath->getName(),dfield->getName(),fdim->getName());
2389 if (!isdimmapname) {
2392 tempmapit = swath->ndimnamelist.find(fdim->getName());
2393 if (tempmapit != swath->ndimnamelist.end())
2394 tempcorrecteddimname= tempmapit->second;
2396 throw4(
"cannot find the corrected dimension name",
2397 swath->getName(),dfield->getName(),fdim->getName());
2399 correcteddim =
new Dimension(tempcorrecteddimname,fdim->getSize());
2403 correcteddims.push_back(correcteddim);
2405 dfield->setCorrectedDimensions(correcteddims);
2406 correcteddims.clear();
2413void File::handle_swath_cf_attrs() {
2423 for (
const auto &swath:this->swaths) {
2426 for (
const auto &gfield:swath->getGeoFields()) {
2429 if (gfield->fieldtype == 0) {
2430 string tempcoordinates=
"";
2431 string tempfieldname=
"";
2432 string tempcorrectedfieldname=
"";
2434 bool has_ll_coord =
false;
2435 if (swath->get_num_map() == 0)
2436 has_ll_coord =
true;
2437 else if (handle_swath_dimmap ==
true) {
2438 if (backward_handle_swath_dimmap ==
true || multi_dimmap ==
true)
2439 has_ll_coord =
true;
2441 for (
const auto &dim:gfield->getDimensions()) {
2448 tempmapit = (swath->dimcvarlist).find(dim->getName());
2449 if (tempmapit != (swath->dimcvarlist).end())
2450 tempfieldname = tempmapit->second;
2452 throw4(
"cannot find the dimension field name",swath->getName(),
2453 gfield->getName(),dim->getName());
2456 tempmapit2 = (swath->ncvarnamelist).find(tempfieldname);
2457 if (tempmapit2 != (swath->ncvarnamelist).end())
2458 tempcorrectedfieldname = tempmapit2->second;
2460 throw4(
"cannot find the corrected dimension field name",
2461 swath->getName(),gfield->getName(),dim->getName());
2463 if (
false == has_ll_coord)
2464 has_ll_coord= check_ll_in_coords(tempcorrectedfieldname);
2467 tempcoordinates= tempcorrectedfieldname;
2469 tempcoordinates = tempcoordinates +
" "+tempcorrectedfieldname;
2472 if (
true == has_ll_coord)
2473 gfield->setCoordinates(tempcoordinates);
2478 if (gfield->fieldtype == 1) {
2479 string tempunits =
"degrees_north";
2480 gfield->setUnits(tempunits);
2484 if (gfield->fieldtype == 2) {
2485 string tempunits =
"degrees_east";
2486 gfield->setUnits(tempunits);
2493 if (gfield->fieldtype == 4) {
2494 string tempunits =
"level";
2495 gfield->setUnits(tempunits);
2500 if (gfield->fieldtype == 5) {
2501 string tempunits =
"days since 1900-01-01 00:00:00";
2502 gfield->setUnits(tempunits);
2508 if (((gfield->getFillValue()).empty()) &&
2509 (gfield->getType()==DFNT_FLOAT32 || gfield->getType()==DFNT_FLOAT64)) {
2510 float tempfillvalue = -9999.0;
2511 gfield->addFillValue(tempfillvalue);
2512 gfield->setAddedFillValue(
true);
2517 for (
const auto &dfield:swath->getDataFields()) {
2520 if (dfield->fieldtype == 0) {
2521 string tempcoordinates=
"";
2522 string tempfieldname=
"";
2523 string tempcorrectedfieldname=
"";
2525 bool has_ll_coord =
false;
2526 if (swath->get_num_map() == 0)
2527 has_ll_coord =
true;
2528 else if (handle_swath_dimmap ==
true) {
2529 if (backward_handle_swath_dimmap ==
true || multi_dimmap ==
true)
2530 has_ll_coord =
true;
2532 for (
const auto &dim:dfield->getDimensions()) {
2539 tempmapit = (swath->dimcvarlist).find(dim->getName());
2540 if (tempmapit != (swath->dimcvarlist).end())
2541 tempfieldname = tempmapit->second;
2543 throw4(
"cannot find the dimension field name",swath->getName(),
2544 dfield->getName(),dim->getName());
2547 tempmapit2 = (swath->ncvarnamelist).find(tempfieldname);
2548 if (tempmapit2 != (swath->ncvarnamelist).end())
2549 tempcorrectedfieldname = tempmapit2->second;
2551 throw4(
"cannot find the corrected dimension field name",
2552 swath->getName(),dfield->getName(),dim->getName());
2554 if (
false == has_ll_coord)
2555 has_ll_coord= check_ll_in_coords(tempcorrectedfieldname);
2558 tempcoordinates= tempcorrectedfieldname;
2560 tempcoordinates = tempcoordinates +
" "+tempcorrectedfieldname;
2563 if (
true == has_ll_coord)
2564 dfield->setCoordinates(tempcoordinates);
2567 if ((dfield->fieldtype == 3)||(dfield->fieldtype == 4)) {
2568 string tempunits =
"level";
2569 dfield->setUnits(tempunits);
2574 if (dfield->fieldtype == 5) {
2575 string tempunits =
"days since 1900-01-01 00:00:00";
2576 dfield->setUnits(tempunits);
2583 if (((dfield->getFillValue()).empty()) &&
2584 (dfield->getType()==DFNT_FLOAT32 || dfield->getType()==DFNT_FLOAT64)) {
2585 float tempfillvalue = -9999.0;
2586 dfield->addFillValue(tempfillvalue);
2587 dfield->setAddedFillValue(
true);
2594bool File::find_dim_in_dims(
const std::vector<Dimension*>&dims,
const std::string &dim_name)
const {
2596 bool ret_value =
false;
2597 for (
const auto &dim:dims) {
2598 if (dim->name == dim_name) {
2607void File::check_dm_geo_dims_in_vars()
const {
2609 if (handle_swath_dimmap ==
false)
2612 for (
const auto &swath:this->swaths) {
2615 if (swath->get_num_map() > 0) {
2617 for (
const auto &dfield:swath->getDataFields()) {
2621 if (dfield->rank >=2) {
2622 for (
const auto &dim:dfield->getDimensions()) {
2626 bool not_match_geo_dim =
true;
2627 for (
const auto &sdmap:swath->getDimensionMaps()) {
2629 if ((dim->getName() == sdmap->getGeoDimension()) && not_match_geo_dim){
2631 not_match_geo_dim =
false;
2637 if (match_dims == 2) {
2638 swath->GeoDim_in_vars =
true;
2643 if (swath->GeoDim_in_vars ==
false) {
2645 for (
const auto &gfield:swath->getGeoFields()) {
2649 if (gfield->rank >=2 && (gfield->name !=
"Latitude" && gfield->name !=
"Longitude")) {
2650 for (
const auto &dim:gfield->getDimensions()) {
2654 bool not_match_geo_dim =
true;
2656 for (
const auto &sdmap:swath->getDimensionMaps()) {
2657 if ((dim->getName() == sdmap->getGeoDimension()) && not_match_geo_dim){
2659 not_match_geo_dim =
false;
2665 if (match_dims == 2){
2666 swath->GeoDim_in_vars =
true;
2679bool SwathDataset::obtain_dmap_offset_inc(
const string& ori_dimname,
const string & mapped_dimname,
int &offset,
int&inc)
const{
2680 bool ret_value =
false;
2681 for (
const auto &sdmap:this->dimmaps) {
2682 if (sdmap->geodim==ori_dimname && sdmap->datadim == mapped_dimname){
2683 offset = sdmap->offset;
2684 inc = sdmap->increment;
2696void File::create_geo_varnames_list(
vector<string> & geo_varnames,
const string & swathname,
2697 const string & fieldname,
int extra_ll_pairs,
bool oneswath)
const{
2699 if (
true == oneswath)
2700 geo_varnames.push_back(fieldname);
2702 string nfieldname = fieldname+
"_"+swathname;
2703 geo_varnames.push_back(nfieldname);
2705 for (
int i = 0; i <extra_ll_pairs;i++) {
2709 if (
true == oneswath)
2710 nfieldname = fieldname+
"_"+si.str();
2712 nfieldname = fieldname+
"_"+swathname+
"_"+si.str();
2713 geo_varnames.push_back(nfieldname);
2720void File::create_geo_dim_var_maps(SwathDataset*sd, Field*fd,
const vector<string>& lat_names,
2723 string field_lat_dim1_name =(fd->dims)[0]->name;
2724 string field_lat_dim2_name =(fd->dims)[1]->name;
2727 if (sd->GeoDim_in_vars ==
true) {
2728 if ((this->swaths).size() >1) {
2729 (fd->dims)[0]->name = field_lat_dim1_name+
"_"+sd->name;
2730 (fd->dims)[1]->name = field_lat_dim2_name+
"_"+sd->name;
2732 geo_var_dim1.push_back((fd->dims)[0]);
2733 geo_var_dim2.push_back((fd->dims)[1]);
2743 short dim1_map_count = 0;
2744 short dim2_map_count = 0;
2745 for (
const auto &sdmap:sd->getDimensionMaps()) {
2746 if (sdmap->getGeoDimension()==field_lat_dim1_name){
2747 string data_dim1_name = sdmap->getDataDimension();
2748 int dim1_size = sd->obtain_dimsize_with_dimname(data_dim1_name);
2749 if ((this->swaths).size() > 1)
2750 data_dim1_name = data_dim1_name+
"_"+sd->name;
2752 if (sd->GeoDim_in_vars ==
false && dim1_map_count == 0) {
2753 (fd->dims)[0]->name = data_dim1_name;
2754 (fd->dims)[0]->dimsize = dim1_size;
2755 geo_var_dim1.push_back((fd->dims)[0]);
2758 auto lat_dim =
new Dimension(data_dim1_name,dim1_size);
2759 geo_var_dim1.push_back(lat_dim);
2763 else if (sdmap->getGeoDimension()==field_lat_dim2_name){
2764 string data_dim2_name = sdmap->getDataDimension();
2765 int dim2_size = sd->obtain_dimsize_with_dimname(data_dim2_name);
2766 if ((this->swaths).size() > 1)
2767 data_dim2_name = data_dim2_name+
"_"+sd->name;
2768 if (sd->GeoDim_in_vars ==
false && dim2_map_count == 0) {
2769 (fd->dims)[1]->name = data_dim2_name;
2770 (fd->dims)[1]->dimsize = dim2_size;
2771 geo_var_dim2.push_back((fd->dims)[1]);
2774 auto lon_dim =
new Dimension(data_dim2_name,dim2_size);
2775 geo_var_dim2.push_back(lon_dim);
2782 for(
int i = 0; i<lat_names.size();i++) {
2792void File::create_geo_vars(SwathDataset* sd,Field *orig_lat,Field*orig_lon,
2797 string ll_ori_dim0_name = (orig_lon->dims)[0]->name;
2798 string ll_ori_dim1_name = (orig_lon->dims)[1]->name;
2799 int dmap_offset = 0;
2801 if (sd->GeoDim_in_vars ==
false) {
2805 (orig_lon->dims)[0]->name = geo_var_dim1[0]->name;
2806 (orig_lon->dims)[0]->dimsize = geo_var_dim1[0]->dimsize;
2807 (orig_lon->dims)[1]->name = geo_var_dim2[0]->name;
2808 (orig_lon->dims)[1]->dimsize = geo_var_dim2[0]->dimsize;
2809 string ll_datadim0_name = geo_var_dim1[0]->name;
2810 string ll_datadim1_name = geo_var_dim2[0]->name;
2811 if (this->swaths.size() >1) {
2812 string prefix_remove =
"_"+sd->name;
2813 ll_datadim0_name = ll_datadim0_name.substr(0,ll_datadim0_name.size()-prefix_remove.size());
2814 ll_datadim1_name = ll_datadim1_name.substr(0,ll_datadim1_name.size()-prefix_remove.size());
2818 if (
false == sd->obtain_dmap_offset_inc(ll_ori_dim0_name,ll_datadim0_name,dmap_offset,dmap_inc)){
2819 throw5(
"Cannot retrieve dimension map offset and inc ",sd->name,
2820 orig_lon->name,ll_ori_dim0_name,ll_datadim0_name);
2822 orig_lon->ll_dim0_inc = dmap_inc;
2823 orig_lon->ll_dim0_offset = dmap_offset;
2824 orig_lat->ll_dim0_inc = dmap_inc;
2825 orig_lat->ll_dim0_offset = dmap_offset;
2827 if (
false == sd->obtain_dmap_offset_inc(ll_ori_dim1_name,ll_datadim1_name,dmap_offset,dmap_inc)){
2828 throw5(
"Cannot retrieve dimension map offset and inc ",sd->name,
2829 orig_lon->name,ll_ori_dim1_name,ll_datadim1_name);
2831 orig_lon->ll_dim1_inc = dmap_inc;
2832 orig_lon->ll_dim1_offset = dmap_offset;
2833 orig_lat->ll_dim1_inc = dmap_inc;
2834 orig_lat->ll_dim1_offset = dmap_offset;
2836cerr<<
"orig_lon "<<orig_lon->name <<endl;
2837cerr<<
"orig_lon dim1 inc "<<orig_lon->ll_dim1_inc<<endl;
2838cerr<<
"orig_lon dim1 offset "<<orig_lon->ll_dim1_offset<<endl;
2839cerr<<
"orig_lon dim0 inc "<<orig_lon->ll_dim0_inc<<endl;
2840cerr<<
"orig_lon dim0 offset "<<orig_lon->ll_dim0_offset<<endl;
2848 if ((this->swaths).size() >1) {
2849 (orig_lon->dims)[0]->name = (orig_lon->dims)[0]->name +
"_" + sd->name;
2850 (orig_lon->dims)[1]->name = (orig_lon->dims)[1]->name +
"_" + sd->name;
2855 if ((this->swaths).size()>1) {
2856 orig_lat->name = lat_names[0];
2857 orig_lon->name = lon_names[0];
2861 orig_lat->fieldtype = 1;
2862 orig_lon->fieldtype = 2;
2865 for (
int i = 1; i <lat_names.size();i++) {
2866 auto newlat =
new Field();
2867 newlat->name = lat_names[i];
2868 (newlat->dims).push_back(geo_var_dim1[i]);
2869 (newlat->dims).push_back(geo_var_dim2[i]);
2870 newlat->fieldtype = 1;
2872 newlat->type = orig_lat->type;
2873 auto newlon =
new Field();
2874 newlon->name = lon_names[i];
2878 new Dimension(geo_var_dim1[i]->name,geo_var_dim1[i]->dimsize);
2880 new Dimension(geo_var_dim2[i]->name,geo_var_dim2[i]->dimsize);
2881 (newlon->dims).push_back(lon_dim1);
2882 (newlon->dims).push_back(lon_dim2);
2883 newlon->fieldtype = 2;
2885 newlon->type = orig_lon->type;
2887 string ll_datadim0_name = geo_var_dim1[i]->name;
2888 string ll_datadim1_name = geo_var_dim2[i]->name;
2889 if (this->swaths.size() >1) {
2890 string prefix_remove =
"_"+sd->name;
2891 ll_datadim0_name = ll_datadim0_name.substr(0,ll_datadim0_name.size()-prefix_remove.size());
2892 ll_datadim1_name = ll_datadim1_name.substr(0,ll_datadim1_name.size()-prefix_remove.size());
2896 if (
false == sd->obtain_dmap_offset_inc(ll_ori_dim0_name,ll_datadim0_name,dmap_offset,dmap_inc)){
2897 throw5(
"Cannot retrieve dimension map offset and inc ",sd->name,
2898 newlon->name,ll_ori_dim0_name,ll_datadim0_name);
2900 newlon->ll_dim0_inc = dmap_inc;
2901 newlon->ll_dim0_offset = dmap_offset;
2902 newlat->ll_dim0_inc = dmap_inc;
2903 newlat->ll_dim0_offset = dmap_offset;
2904 if (
false == sd->obtain_dmap_offset_inc(ll_ori_dim1_name,ll_datadim1_name,dmap_offset,dmap_inc)){
2905 throw5(
"Cannot retrieve dimension map offset and inc ",sd->name,
2906 newlon->name,ll_ori_dim0_name,ll_datadim1_name);
2908 newlon->ll_dim1_inc = dmap_inc;
2909 newlon->ll_dim1_offset = dmap_offset;
2910 newlat->ll_dim1_inc = dmap_inc;
2911 newlat->ll_dim1_offset = dmap_offset;
2913cerr<<
"newlon "<<newlon->name <<endl;
2914cerr<<
"newlon dim1 inc "<<newlon->ll_dim1_inc<<endl;
2915cerr<<
"newlon dim1 offset "<<newlon->ll_dim1_offset<<endl;
2916cerr<<
"newlon dim0 inc "<<newlon->ll_dim0_inc<<endl;
2917cerr<<
"newlon dim0 offset "<<newlon->ll_dim0_offset<<endl;
2919 sd->geofields.push_back(newlat);
2920 sd->geofields.push_back(newlon);
2925 sd->getGeoFields().begin();
2926 j != sd->getGeoFields().end(); ++j) {
2927cerr<<
"Field name: "<<(*j)->name <<endl;
2928cerr<<
"Dimension name and size: "<<endl;
2930 (*j)->getDimensions().begin();k!=(*j)->getDimensions().end();++k)
2931cerr<<(*k)->getName() <<
": "<<(*k)->getSize() <<endl;
2940void File::update_swath_dims_for_dimmap(
const SwathDataset* sd,
const std::vector<Dimension*>&geo_var_dim1,
2941 const std::vector<Dimension*>&geo_var_dim2)
const{
2946 for (
const auto &gfield:sd->getGeoFields()) {
2948 if (gfield->fieldtype == 1 || gfield->fieldtype == 2)
2950 for (
const auto &dim:gfield->getDimensions()) {
2951 string new_dim_name = dim->name +
"_"+sd->name;
2952 if (find_dim_in_dims(geo_var_dim1,new_dim_name) ||
2953 find_dim_in_dims(geo_var_dim2,new_dim_name))
2954 dim->name = new_dim_name;
2958 for (
const auto &dfield:sd->getDataFields()){
2959 for (
const auto &dim:dfield->getDimensions()) {
2960 string new_dim_name = dim->name +
"_"+sd->name;
2961 if (find_dim_in_dims(geo_var_dim1,new_dim_name) ||
2962 find_dim_in_dims(geo_var_dim2,new_dim_name))
2963 dim->name = new_dim_name;
2968 for (
const auto &dim:sd->getDimensions()) {
2969 string new_dim_name = dim->name +
"_"+sd->name;
2970 if (find_dim_in_dims(geo_var_dim1,new_dim_name) ||
2971 find_dim_in_dims(geo_var_dim2,new_dim_name))
2972 dim->name = new_dim_name;
2982void File::create_swath_latlon_dim_cvar_map_for_dimmap(SwathDataset* sd, Field* ori_lat, Field* ori_lon) {
2984 bool one_swath = ((this->swaths).size() == 1);
2986 int num_extra_lat_lon_pairs = 0;
2989if (sd->GeoDim_in_vars ==
true)
2990 cerr<<
" swath name is "<<sd->name <<endl;
2994 if (sd->GeoDim_in_vars ==
false)
2995 num_extra_lat_lon_pairs--;
2997 num_extra_lat_lon_pairs += (sd->num_map)/2;
3000 create_geo_varnames_list(lat_names,sd->name,ori_lat->name,num_extra_lat_lon_pairs,one_swath);
3002 create_geo_varnames_list(lon_names,sd->name,ori_lon->name,num_extra_lat_lon_pairs,one_swath);
3007 create_geo_dim_var_maps(sd, ori_lat,lat_names,lon_names,geo_var_dim1,geo_var_dim2);
3008 create_geo_vars(sd,ori_lat,ori_lon,lat_names,lon_names,geo_var_dim1,geo_var_dim2);
3012 if ((this->swaths).size() >1)
3013 update_swath_dims_for_dimmap(sd,geo_var_dim1,geo_var_dim2);
3020void File::Prepare(
const char *eosfile_path)
3028 auto numgrid = (
int)(this->grids.size());
3029 auto numswath = (
int)(this->swaths.size());
3032 throw2(
"the number of grid is less than 0", eosfile_path);
3038 string DIMXNAME = this->get_geodim_x_name();
3040 string DIMYNAME = this->get_geodim_y_name();
3042 string LATFIELDNAME = this->get_latfield_name();
3044 string LONFIELDNAME = this->get_lonfield_name();
3047 string GEOGRIDNAME =
"location";
3052 check_onelatlon_grids();
3055 for (
const auto &grid:this->grids)
3056 handle_one_grid_zdim(grid);
3060 if (
true == this->onelatlon)
3061 handle_onelatlon_grids();
3063 for (
const auto &grid:this->grids) {
3067 grid->setDimxName(DIMXNAME);
3068 grid->setDimyName(DIMYNAME);
3071 handle_one_grid_latlon(grid);
3076 handle_grid_dim_cvar_maps();
3079 handle_grid_coards();
3082 update_grid_field_corrected_dims();
3085 handle_grid_cf_attrs();
3088 handle_grid_SOM_projection();
3094 for (
const auto& grid:this->grids)
3095 grid->SetScaleType(grid->name);
3103 check_swath_dimmap(numswath);
3106 check_dm_geo_dims_in_vars();
3109 check_swath_dimmap_bk_compat(numswath);
3112 create_swath_latlon_dim_cvar_map();
3115 create_swath_nonll_dim_cvar_map();
3118 handle_swath_dim_cvar_maps();
3122 handle_swath_cf_attrs();
3125 for (
const auto &swath:this->swaths)
3126 swath->SetScaleType(swath->name);
3133bool File::check_special_1d_grid() {
3135 auto numgrid = (
int)(this->grids.size());
3136 auto numswath = (
int)(this->swaths.size());
3138 if (numgrid != 1 || numswath != 0)
3142 string DIMXNAME = this->get_geodim_x_name();
3143 string DIMYNAME = this->get_geodim_y_name();
3145 if (DIMXNAME !=
"XDim" || DIMYNAME !=
"YDim")
3148 int var_dimx_size = 0;
3149 int var_dimy_size = 0;
3151 const GridDataset *mygrid = (this->grids)[0];
3153 int field_xydim_flag = 0;
3154 for (
const auto &dfield:mygrid->getDataFields()) {
3155 if (1==dfield->rank) {
3156 if (dfield->name ==
"XDim"){
3158 var_dimx_size = (dfield->getDimensions())[0]->getSize();
3160 if (dfield->name ==
"YDim"){
3162 var_dimy_size = (dfield->getDimensions())[0]->getSize();
3165 if (2==field_xydim_flag)
3169 if (field_xydim_flag !=2)
3173 int xdimsize = mygrid->getInfo().getX();
3174 int ydimsize = mygrid->getInfo().getY();
3176 if (var_dimx_size != xdimsize || var_dimy_size != ydimsize)
3184bool File::check_ll_in_coords(
const string& vname) {
3186 bool ret_val =
false;
3187 for (
const auto &swath:this->swaths) {
3188 for (
const auto &gfield:swath->getGeoFields()) {
3190 if (gfield->fieldtype == 1 || gfield->fieldtype == 2) {
3191 if (gfield->getNewName() == vname) {
3197 if (
true == ret_val)
3199 for (
const auto &dfield:swath->getDataFields()) {
3202 if (dfield->fieldtype == 1 || dfield->fieldtype == 2) {
3203 if (dfield->getNewName() == vname) {
3209 if (
true == ret_val)
3224void Dataset::SetScaleType(
const string & EOS2ObjName) {
3230 modis_multi_scale_type.emplace_back(
"L1B");
3231 modis_multi_scale_type.emplace_back(
"GEO");
3232 modis_multi_scale_type.emplace_back(
"BRDF");
3233 modis_multi_scale_type.emplace_back(
"0.05Deg");
3234 modis_multi_scale_type.emplace_back(
"Reflectance");
3235 modis_multi_scale_type.emplace_back(
"MOD17A2");
3236 modis_multi_scale_type.emplace_back(
"North");
3237 modis_multi_scale_type.emplace_back(
"South");
3238 modis_multi_scale_type.emplace_back(
"MOD_Swath_Sea_Ice");
3239 modis_multi_scale_type.emplace_back(
"MOD_Grid_MOD15A2");
3240 modis_multi_scale_type.emplace_back(
"MOD_Grid_MOD16A2");
3241 modis_multi_scale_type.emplace_back(
"MOD_Grid_MOD16A3");
3242 modis_multi_scale_type.emplace_back(
"MODIS_NACP_LAI");
3247 modis_div_scale_type.emplace_back(
"VI");
3248 modis_div_scale_type.emplace_back(
"1km_2D");
3249 modis_div_scale_type.emplace_back(
"L2g_2d");
3250 modis_div_scale_type.emplace_back(
"CMG");
3251 modis_div_scale_type.emplace_back(
"MODIS SWATH TYPE L2");
3253 string modis_eq_scale_type =
"LST";
3254 string modis_equ_scale_lst_group1=
"MODIS_Grid_8Day_1km_LST21";
3255 string modis_equ_scale_lst_group2=
"MODIS_Grid_Daily_1km_LST21";
3257 string modis_divequ_scale_group =
"MODIS_Grid";
3258 string modis_div_scale_group =
"MOD_Grid";
3262 string modis_equ_scale_group =
"MODIS_Grid_1km_2D";
3264 if (EOS2ObjName==
"mod05" || EOS2ObjName==
"mod06" || EOS2ObjName==
"mod07"
3265 || EOS2ObjName==
"mod08" || EOS2ObjName==
"atml2")
3267 scaletype = SOType::MODIS_MUL_SCALE;
3281 if (EOS2ObjName.find(
"MOD")==0 || EOS2ObjName.find(
"mod")==0)
3283 size_t pos = EOS2ObjName.rfind(modis_eq_scale_type);
3284 if (pos != string::npos &&
3285 (pos== (EOS2ObjName.size()-modis_eq_scale_type.size())))
3287 scaletype = SOType::MODIS_EQ_SCALE;
3291 for(
unsigned int k=0; k<modis_multi_scale_type.size(); k++)
3293 pos = EOS2ObjName.rfind(modis_multi_scale_type[k]);
3294 if (pos !=string::npos &&
3295 (pos== (EOS2ObjName.size()-modis_multi_scale_type[k].size())))
3297 scaletype = SOType::MODIS_MUL_SCALE;
3302 for(
unsigned int k=0; k<modis_div_scale_type.size(); k++)
3304 pos = EOS2ObjName.rfind(modis_div_scale_type[k]);
3305 if (pos != string::npos &&
3306 (pos==(EOS2ObjName.size()-modis_div_scale_type[k].size()))){
3307 scaletype = SOType::MODIS_DIV_SCALE;
3312 if (EOS2ObjName !=
"MODIS_Grid_1km_2D")
3319 pos = EOS2ObjName.find(modis_divequ_scale_group);
3325 size_t eq_scale_pos = EOS2ObjName.find(modis_equ_scale_group)
3326 *EOS2ObjName.find(modis_equ_scale_lst_group1)
3327 *EOS2ObjName.find(modis_equ_scale_lst_group2);
3328 if (0 == eq_scale_pos)
3329 scaletype = SOType::MODIS_EQ_SCALE;
3331 scaletype = SOType::MODIS_DIV_SCALE;
3334 size_t div_scale_pos = EOS2ObjName.find(modis_div_scale_group);
3337 if ( 0 == div_scale_pos)
3338 scaletype = SOType::MODIS_DIV_SCALE;
3344 if (EOS2ObjName ==
"VIP_CMG_GRID")
3345 scaletype = SOType::MODIS_DIV_SCALE;
3348int Dataset::obtain_dimsize_with_dimname(
const string & dimname)
const{
3352 for (
const auto & dim:this->getDimensions()) {
3353 if (dim->name == dimname){
3354 ret_value = dim->dimsize;
3365 for_each(this->dims.begin(), this->dims.end(), delete_elem());
3366 for_each(this->correcteddims.begin(), this->correcteddims.end(), delete_elem());
3372 for_each(this->dims.begin(), this->dims.end(), delete_elem());
3373 for_each(this->datafields.begin(), this->datafields.end(),
3375 for_each(this->attrs.begin(), this->attrs.end(), delete_elem());
3379void Dataset::ReadDimensions(int32 (*entries)(int32, int32, int32 *),
3380 int32 (*inq)(int32,
char *, int32 *),
3391 if ((numdims = entries(this->datasetid, HDFE_NENTDIM, &bufsize)) == -1)
3392 throw2(
"dimension entry", this->name);
3399 namelist.resize(bufsize + 1);
3400 dimsize.resize(numdims);
3403 if (inq(this->datasetid, namelist.data(), dimsize.data()) == -1)
3404 throw2(
"inquire dimension", this->name);
3413 for (
const auto &dimname:dimnames) {
3414 auto dim =
new Dimension(dimname, dimsize[count]);
3415 d_dims.push_back(dim);
3423void Dataset::ReadFields(int32 (*entries)(int32, int32, int32 *),
3424 int32 (*inq)(int32,
char *, int32 *, int32 *),
3426 (int32,
char *, int32 *, int32 *, int32 *,
char *),
3427 intn (*getfill)(int32,
char *, VOIDP),
3433 int32 numfields = 0;
3440 if ((numfields = entries(this->datasetid, geofield ?
3441 HDFE_NENTGFLD : HDFE_NENTDFLD, &bufsize)) == -1)
3442 throw2(
"field entry", this->name);
3446 if (numfields > 0) {
3449 namelist.resize(bufsize + 1);
3452 if (inq(this->datasetid, namelist.data(),
nullptr,
nullptr) == -1)
3453 throw2(
"inquire field", this->name);
3460 for (
const auto& fdname:fieldnames){
3462 auto field =
new Field();
3463 if (field ==
nullptr)
3464 throw1(
"The field is nullptr");
3465 field->name = fdname;
3467 bool throw_error =
false;
3476 if ((fldinfo(this->datasetid,
3477 const_cast<char *
>(field->name.c_str()),
3478 &field->rank, dimsize, &field->type, dimlist)) == -1){
3479 string fieldname_for_eh = field->name;
3481 err_msg =
"Obtain field info error for field name "+fieldname_for_eh;
3484 if (
false == throw_error) {
3490 if ((
int)dimnames.size() != field->rank) {
3492 err_msg =
"Dimension names size is not consistent with field rank. ";
3493 err_msg +=
"Field name is "+field->name;
3496 for (
int k = 0; k < field->rank; ++k) {
3497 auto dim =
new Dimension(dimnames[k], dimsize[k]);
3498 field->dims.push_back(dim);
3502 field->filler.resize(DFKNTsize(field->type));
3503 if (getfill(this->datasetid,
3504 const_cast<char *
>(field->name.c_str()),
3505 &field->filler[0]) == -1)
3506 field->filler.clear();
3509 fields.push_back(field);
3513 if (
true == throw_error) {
3523void Dataset::ReadAttributes(int32 (*inq)(int32,
char *, int32 *),
3524 intn (*attrinfo)(int32,
char *, int32 *, int32 *),
3525 intn (*readattr)(int32,
char *, VOIDP),
3535 if ((numattrs = inq(this->datasetid,
nullptr, &bufsize)) == -1)
3536 throw2(
"inquire attribute", this->name);
3542 namelist.resize(bufsize + 1);
3545 if (inq(this->datasetid, namelist.data(), &bufsize) == -1)
3546 throw2(
"inquire attribute", this->name);
3553 for (
const auto &attrname:attrnames) {
3554 auto attr =
new Attribute();
3555 attr->name = attrname;
3561 if (attrinfo(this->datasetid,
const_cast<char *
>
3562 (attr->name.c_str()), &attr->type, &count) == -1) {
3564 throw3(
"attribute info", this->name, attr->name);
3567 attr->count = count/DFKNTsize(attr->type);
3568 attr->value.resize(count);
3575 if (readattr(this->datasetid,
3576 const_cast<char *
>(attr->name.c_str()),
3577 &attr->value[0]) == -1) {
3579 throw3(
"read attribute", this->name, attr->name);
3583 obj_attrs.push_back(attr);
3589GridDataset::~GridDataset()
3591 if (this->datasetid != -1){
3592 GDdetach(this->datasetid);
3597GridDataset * GridDataset::Read(int32 fd,
const string &gridname)
3600 bool GD_fun_err =
false;
3601 auto grid =
new GridDataset(gridname);
3604 if ((grid->datasetid = GDattach(fd,
const_cast<char *
>(gridname.c_str())))
3606 err_msg =
"attach grid";
3614 Info &info = grid->info;
3615 if (GDgridinfo(grid->datasetid, &info.xdim, &info.ydim, info.upleft,
3616 info.lowright) == -1) {
3617 err_msg =
"grid info";
3625 Projection &proj = grid->proj;
3626 if (GDprojinfo(grid->datasetid, &proj.code, &proj.zone, &proj.sphere,
3627 proj.param) == -1) {
3628 err_msg =
"projection info";
3632 if (GDpixreginfo(grid->datasetid, &proj.pix) == -1) {
3633 err_msg =
"pixreg info";
3637 if (GDorigininfo(grid->datasetid, &proj.origin) == -1){
3638 err_msg =
"origin info";
3644 if (
true == GD_fun_err){
3646 throw2(err_msg,gridname);
3651 grid->ReadDimensions(GDnentries, GDinqdims, grid->dims);
3654 grid->ReadFields(GDnentries, GDinqfields, GDfieldinfo,
3655 GDgetfillvalue,
false, grid->datafields);
3658 grid->ReadAttributes(GDinqattrs, GDattrinfo, GDreadattr, grid->attrs);
3668GridDataset::Calculated & GridDataset::getCalculated()
const
3670 if (this->calculated.grid !=
this)
3671 this->calculated.grid =
this;
3672 return this->calculated;
3675bool GridDataset::Calculated::isYDimMajor()
3677 this->DetectMajorDimension();
3678 return this->ydimmajor;
3682int GridDataset::Calculated::DetectFieldMajorDimension()
const
3687 for (
const auto& gfd:this->grid->getDataFields()) {
3694 for (
const auto& dim:gfd->getDimensions()) {
3695 if (dim->getName() == this->grid->dimxname)
3697 else if (dim->getName() == this->grid->dimyname)
3701 if (xdimindex == -1 || ydimindex == -1)
3704 int major = ydimindex < xdimindex ? 1 : 0;
3715 else if (ym != major)
3716 throw2(
"inconsistent XDim, YDim order", this->grid->getName());
3722 throw2(
"lack of data fields", this->grid->getName());
3727void GridDataset::Calculated::DetectMajorDimension()
3735 for (
const auto& fd:this->grid->getDataFields()) {
3742 for (
const auto& dim:fd->getDimensions()) {
3743 if (dim->getName() == this->grid->dimxname)
3745 else if (dim->getName() == this->grid->dimyname)
3749 if (xdimindex == -1 || ydimindex == -1)
3754 if (this->grid->getProjection().getCode() == GCTP_LAMAZ)
3757 major = ydimindex < xdimindex ? 1 : 0;
3768 else if (ym != major)
3769 throw2(
"inconsistent XDim, YDim order", this->grid->getName());
3774 throw2(
"lack of data fields", this->grid->getName());
3775 this->ydimmajor = ym != 0;
3789 if (find(r.begin(), r.end(), *i) != r.end())
3800 l.begin(); i != l.end(); ++i) {
3801 if (find(r.begin(), r.end(), i->first) != r.end())
3812 if (find(b.begin(), b.end(), *i) == b.end())
3822 = s.begin(); i != s.end(); ++i) {
3823 if (find(b.begin(), b.end(), i->first) == b.end())
3831SwathDataset::~SwathDataset()
3833 if (this->datasetid != -1) {
3834 SWdetach(this->datasetid);
3837 for_each(this->dimmaps.begin(), this->dimmaps.end(), delete_elem());
3838 for_each(this->indexmaps.begin(), this->indexmaps.end(),
3841 for_each(this->geofields.begin(), this->geofields.end(),
3848SwathDataset * SwathDataset::Read(int32 fd,
const string &swathname)
3851 auto swath =
new SwathDataset(swathname);
3852 if (swath ==
nullptr)
3853 throw1(
"Cannot allocate HDF5 Swath object");
3856 if ((swath->datasetid = SWattach(fd,
3857 const_cast<char *
>(swathname.c_str())))
3860 throw2(
"attach swath", swathname);
3866 swath->ReadDimensions(SWnentries, SWinqdims, swath->dims);
3869 swath->ReadFields(SWnentries, SWinqdatafields, SWfieldinfo,
3870 SWgetfillvalue,
false, swath->datafields);
3873 swath->ReadFields(SWnentries, SWinqgeofields, SWfieldinfo,
3874 SWgetfillvalue,
true, swath->geofields);
3877 swath->ReadAttributes(SWinqattrs, SWattrinfo, SWreadattr, swath->attrs);
3880 swath->set_num_map(swath->ReadDimensionMaps(swath->dimmaps));
3883 swath->ReadIndexMaps(swath->indexmaps);
3902 if ((nummaps = SWnentries(this->datasetid, HDFE_NENTMAP, &bufsize)) == -1)
3903 throw2(
"dimmap entry", this->name);
3918 namelist.resize(bufsize + 1);
3919 offset.resize(nummaps);
3920 increment.resize(nummaps);
3921 if (SWinqmaps(this->datasetid, namelist.data(), offset.data(), increment.data())
3923 throw2(
"inquire dimmap", this->name);
3928 for (
const auto& mapname:mapnames) {
3931 if (parts.size() != 2)
3932 throw3(
"dimmap part", parts.size(),
3935 DimensionMap *dimmap =
new DimensionMap(parts[0], parts[1],
3938 swath_dimmaps.push_back(dimmap);
3952 if ((numindices = SWnentries(this->datasetid, HDFE_NENTIMAP, &bufsize)) ==
3954 throw2(
"indexmap entry", this->name);
3955 if (numindices > 0) {
3959 namelist.resize(bufsize + 1);
3960 if (SWinqidxmaps(this->datasetid, namelist.data(),
nullptr) == -1)
3961 throw2(
"inquire indexmap", this->name);
3965 for (
const auto& mapname: mapnames) {
3966 auto indexmap =
new IndexMap();
3969 if (parts.size() != 2)
3970 throw3(
"indexmap part", parts.size(),
3972 indexmap->geo = parts[0];
3973 indexmap->data = parts[1];
3978 SWdiminfo(this->datasetid,
3979 const_cast<char *
>(indexmap->geo.c_str())))
3981 throw3(
"dimension info", this->name, indexmap->geo);
3982 indexmap->indices.resize(dimsize);
3983 if (SWidxmapinfo(this->datasetid,
3984 const_cast<char *
>(indexmap->geo.c_str()),
3985 const_cast<char *
>(indexmap->data.c_str()),
3986 &indexmap->indices[0]) == -1)
3987 throw4(
"indexmap info", this->name, indexmap->geo,
3991 swath_indexmaps.push_back(indexmap);
3997PointDataset::~PointDataset()
4001PointDataset * PointDataset::Read(int32 ,
const string &pointname)
4007 auto point =
new PointDataset(pointname);
4014bool Utility::ReadNamelist(
const char *path,
4015 int32 (*inq)(
char *,
char *, int32 *),
4018 char *fname =
const_cast<char *
>(path);
4022 if ((numobjs = inq(fname,
nullptr, &bufsize)) == -1)
return false;
4025 buffer.resize(bufsize + 1);
4026 if (inq(fname, buffer.data(), &bufsize) == -1)
return false;
static bool insert_map(std::map< std::string, std::string > &m, std::string key, std::string val)
static void Handle_NameClashing(std::vector< std::string > &newobjnamelist)
General routines to handle name clashings.
static std::string get_CF_string(std::string s)
Change special characters to "_".
static void Split(const char *s, int len, char sep, std::vector< std::string > &names)