39#include "h5apicompatible.h" 
   46using namespace HDF5CF;
 
   49GMCVar::GMCVar(
const Var*var) {
 
   51    BESDEBUG(
"h5", 
"Coming to GMCVar()"<<endl);
 
   52    newname = var->newname;
 
   54    fullpath = var->fullpath;
 
   56    total_elems = var->total_elems;
 
   57    zero_storage_size = var->zero_storage_size;
 
   59    unsupported_attr_dtype = var->unsupported_attr_dtype;
 
   60    unsupported_dspace = var->unsupported_dspace;
 
   61    coord_attr_add_path = 
false;
 
   63    for (
const auto& vattr:var->attrs) {
 
   64        auto attr_unique = make_unique<Attribute>();
 
   65        auto attr = attr_unique.release();
 
   66        attr->name = vattr->name;
 
   67        attr->newname = vattr->newname;
 
   68        attr->dtype =vattr->dtype;
 
   69        attr->count =vattr->count;
 
   70        attr->strsize = vattr->strsize;
 
   71        attr->fstrsize = vattr->fstrsize;
 
   72        attr->value =vattr->value;
 
   73        attrs.push_back(attr);
 
   76    for (
const auto& vdim:var->dims) {
 
   77        auto dim_unique = make_unique<Dimension>(vdim->size);
 
   78        auto dim = dim_unique.release();
 
   79        dim->name = vdim->name;
 
   80        dim->newname = vdim->newname;
 
   81        dim->unlimited_dim = vdim->unlimited_dim;
 
   85    product_type = General_Product;
 
   90GMSPVar::GMSPVar(
const Var*var) {
 
   92    BESDEBUG(
"h5", 
"Coming to GMSPVar()"<<endl);
 
   93    fullpath = var->fullpath;
 
   95    total_elems = var->total_elems;
 
   96    zero_storage_size = var->zero_storage_size;
 
   97    unsupported_attr_dtype = var->unsupported_attr_dtype;
 
   98    unsupported_dspace = var->unsupported_dspace;
 
   99    coord_attr_add_path = var->coord_attr_add_path;
 
  106    for (
const auto &vattr:var->attrs) {
 
  107        auto attr_unique = make_unique<Attribute>();
 
  108        auto attr = attr_unique.release();
 
  109        attr->name = vattr->name;
 
  110        attr->newname = vattr->newname;
 
  111        attr->dtype =vattr->dtype;
 
  112        attr->count =vattr->count;
 
  113        attr->strsize = vattr->strsize;
 
  114        attr->fstrsize = vattr->fstrsize;
 
  115        attr->value =vattr->value;
 
  116        attrs.push_back(attr);
 
  119    for (
const auto &vdim:var->dims) {
 
  120        auto dim_unique = make_unique<Dimension>(vdim->size);
 
  121        auto dim = dim_unique.release();
 
  122        dim->name = vdim->name;
 
  123        dim->newname = vdim->newname;
 
  124        dim->unlimited_dim = vdim->unlimited_dim;
 
  130GMFile::GMFile(
const char*file_fullpath, hid_t file_id, H5GCFProduct product_type, GMPattern gproduct_pattern):
 
  131File(file_fullpath,file_id), product_type(product_type),gproduct_pattern(gproduct_pattern)
 
  140    if (!this->cvars.empty()){
 
  141        for (
auto i= this->cvars.begin(); i!=this->cvars.end(); ++i) {
 
  146    if (!this->spvars.empty()){
 
  147        for (
auto i= this->spvars.begin(); i!=this->spvars.end(); ++i) {
 
  155string GMFile::get_CF_string(
string s) {
 
  162        return File::get_CF_string(s);
 
  163    else if (General_Product == product_type &&  OTHERGMS == gproduct_pattern)  { 
 
  165        if(
true == HDF5RequestHandler::get_keep_var_leading_underscore())
 
  166            return File::get_CF_string(s);
 
  169            return  File::get_CF_string(s);
 
  175        return File::get_CF_string(s);
 
  181                              hid_t file_id, 
bool include_attr) {
 
  183    BESDEBUG(
"h5", 
"Coming to Retrieve_H5_Info()"<<endl);
 
  186    if (product_type == Mea_SeaWiFS_L2 || product_type == Mea_SeaWiFS_L3
 
  187        || GPMS_L3 == product_type  || GPMM_L3 == product_type || GPM_L1 == product_type || OBPG_L3 == product_type
 
  188        || Mea_Ozone == product_type || General_Product == product_type)  
 
 
  201    BESDEBUG(
"h5", 
"Coming to Update_Product_Type()"<<endl);
 
  202    if(GPMS_L3 == this->product_type || GPMM_L3 == this->product_type) {
 
  209        Check_Dimscale_General_Product_Pattern();
 
  210        if(GENERAL_DIMSCALE == this->gproduct_pattern){
 
  211            if(GPMS_L3 == this->product_type) {
 
  212                for (
auto &var:this->
vars) 
 
  213                    var->newname = var->name;
 
  214                special_gpm_l3 = 
true;
 
  216            this->product_type = General_Product;
 
  219    else if(General_Product == this->product_type)
 
  220        Check_General_Product_Pattern();
 
 
  225    BESDEBUG(
"h5", 
"Coming to Remove_Unneeded_Objects()"<<endl);
 
  226    if(General_Product == this->product_type) {
 
  227        string file_path = this->path;
 
  228        if(HDF5CFUtil::obtain_string_after_lastslash(file_path).find(
"OMPS-NPP")==0) 
 
  229            Remove_OMPSNPP_InputPointers();
 
  231    if((General_Product == this->product_type) && (GENERAL_DIMSCALE == this->gproduct_pattern)) {
 
  232        string nc4_non_coord=
"_nc4_non_coord_";
 
  233        size_t nc4_non_coord_size= nc4_non_coord.size();
 
  234        for (
const auto &var:this->
vars) {
 
  235            if(var->name.find(nc4_non_coord)==0) {
 
  237                string temp_vname = HDF5CFUtil::obtain_string_after_lastslash(var->fullpath);
 
  238                string temp_vpath = HDF5CFUtil::obtain_string_before_lastslash(var->fullpath);
 
  239                string temp_vname_removed = temp_vname.substr(nc4_non_coord_size,temp_vname.size()-nc4_non_coord_size);
 
  240                string temp_v_fullpath_removed = temp_vpath + temp_vname_removed;
 
  241                nc4_sdimv_dv_path.insert(temp_v_fullpath_removed);
 
  245        if(nc4_sdimv_dv_path.empty()==
false)
 
  246            this->have_nc4_non_coord = 
true;
 
  249        if (
true == this->have_nc4_non_coord) {
 
  250            for (
auto irv = this->vars.begin(); irv != this->vars.end();) {
 
  251                if(nc4_sdimv_dv_path.find((*irv)->fullpath)!=nc4_sdimv_dv_path.end()){
 
  253                    irv=this->vars.erase(irv);
 
  261    else if(GPM_L3_New == this->product_type) {
 
  262        for (
auto irg = this->
groups.begin();  irg != this->groups.end(); ) {
 
  263            if((*irg)->attrs.empty()) {
 
  265                irg = this->
groups.erase(irg);
 
 
  274void GMFile::Remove_OMPSNPP_InputPointers()  {
 
  278    for (
auto irg = this->
groups.begin(); irg != this->groups.end(); ) {
 
  279        if((*irg)->path.find(
"/InputPointers")==0) {
 
  281            irg = this->
groups.erase(irg);
 
  288    for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ) {
 
  289         if((*irv)->fullpath.find(
"/InputPointers")==0) {
 
  291            irv = this->
vars.erase(irv);
 
  300    for (
const auto &cvar:this->cvars) {
 
  302        if (cvar->cvartype != CV_NONLATLON_MISS){
 
  303            for (
auto & attr:cvar->attrs) {
 
  304                Retrieve_H5_Attr_Value(attr,cvar->fullpath);
 
 
  313    BESDEBUG(
"h5", 
"Coming to Retrieve_H5_Supported_Attr_Values()"<<endl);
 
  322    for (
const auto &spv:this->spvars) {
 
  323        for (
auto &attr:spv->attrs) {
 
  324            Retrieve_H5_Attr_Value(attr,spv->fullpath);
 
 
  335    BESDEBUG(
"h5", 
"Coming to Adjust_H5_Attr_Value()"<<endl);
 
  336    if (product_type == ACOS_L2S_OR_OCO2_L1B) {
 
  337        if ((
"Type" == attr->name) && (H5VSTRING == attr->dtype)) {
 
  338            string orig_attrvalues(attr->value.begin(),attr->value.end());
 
  339            if (orig_attrvalues != 
"Signed64") 
return;
 
  340            string new_attrvalues = 
"Signed32";
 
  344            attr->value.resize(new_attrvalues.size());
 
  345            copy(new_attrvalues.begin(),new_attrvalues.end(),attr->value.begin()); 
 
 
  353    BESDEBUG(
"h5", 
"Coming to Handle_Unsupported_Dtype()"<<endl);
 
  354    if(
true == check_ignored) {
 
  355        Gen_Unsupported_Dtype_Info(include_attr);
 
  358    Handle_GM_Unsupported_Dtype(include_attr);
 
 
  362void GMFile:: Handle_GM_Unsupported_Dtype(
bool include_attr)  {
 
  364    BESDEBUG(
"h5", 
"Coming to Handle_GM_Unsupported_Dtype()"<<endl);
 
  365    for (
auto ircv = this->cvars.begin(); ircv != this->cvars.end(); ) {
 
  366        if (
true == include_attr) {
 
  367            for (
auto ira = (*ircv)->attrs.begin(); ira != (*ircv)->attrs.end(); ) {
 
  368                H5DataType temp_dtype = (*ira)->getType();
 
  369                if (
false == HDF5CFUtil::cf_strict_support_type(temp_dtype,_is_dap4)) {
 
  371                    ira = (*ircv)->attrs.erase(ira);
 
  378        H5DataType temp_dtype = (*ircv)->getType();
 
  379        if (
false == HDF5CFUtil::cf_strict_support_type(temp_dtype,_is_dap4)) {
 
  387            ircv = this->cvars.erase(ircv);
 
  395    for (
auto ircv = this->spvars.begin(); ircv != this->spvars.end(); ) {
 
  396        if (
true == include_attr) {
 
  397            for (
auto ira = (*ircv)->attrs.begin(); ira != (*ircv)->attrs.end(); ) {
 
  398                H5DataType temp_dtype = (*ira)->getType();
 
  399                if (
false == HDF5CFUtil::cf_strict_support_type(temp_dtype,_is_dap4)) {
 
  401                    ira = (*ircv)->attrs.erase(ira);
 
  408        H5DataType temp_dtype = (*ircv)->getType();
 
  409        if (
false == HDF5CFUtil::cf_strict_support_type(temp_dtype,_is_dap4)) {
 
  411            ircv = this->spvars.erase(ircv);
 
  421void GMFile:: Gen_Unsupported_Dtype_Info(
bool include_attr) {
 
  423    BESDEBUG(
"h5", 
"GMFile::Coming to Gen_Unsupported_Dtype_Info()"<<endl);
 
  424    if(
true == include_attr) {
 
  426        File::Gen_Group_Unsupported_Dtype_Info();
 
  427        File::Gen_Var_Unsupported_Dtype_Info();
 
  428        Gen_VarAttr_Unsupported_Dtype_Info();
 
  434void GMFile:: Gen_VarAttr_Unsupported_Dtype_Info() {
 
  436     BESDEBUG(
"h5", 
"GMFile::Coming to Gen_Unsupported_Dtype_Info()"<<endl);
 
  438    if((General_Product == this->product_type && GENERAL_DIMSCALE== this->gproduct_pattern) 
 
  439           || (Mea_Ozone == this->product_type)  || (Mea_SeaWiFS_L2 == this->product_type) || (Mea_SeaWiFS_L3 == this->product_type)
 
  440          || (OBPG_L3 == this->product_type)) {
 
  441        Gen_DimScale_VarAttr_Unsupported_Dtype_Info();
 
  445        File::Gen_VarAttr_Unsupported_Dtype_Info();
 
  448    Gen_GM_VarAttr_Unsupported_Dtype_Info();
 
  453void GMFile:: Gen_GM_VarAttr_Unsupported_Dtype_Info(){
 
  455     BESDEBUG(
"h5", 
"GMFile::Coming to Gen_GM_VarAttr_Unsupported_Dtype_Info()"<<endl);
 
  456    if((General_Product == this->product_type && GENERAL_DIMSCALE== this->gproduct_pattern)
 
  457        || (Mea_Ozone == this->product_type)  || (Mea_SeaWiFS_L2 == this->product_type) || (Mea_SeaWiFS_L3 == this->product_type)
 
  458        || (OBPG_L3 == this->product_type)) {
 
  460        for (
const auto &cvar:this->cvars) {
 
  463            bool is_ignored = ignored_dimscale_ref_list(cvar);
 
  464            if (
false == cvar->attrs.empty()) {
 
  465                for (
const auto &attr:cvar->attrs) {
 
  466                    H5DataType temp_dtype = attr->getType();
 
  468                    if (
false == HDF5CFUtil::cf_strict_support_type(temp_dtype,_is_dap4) || temp_dtype == H5INT64 || temp_dtype == H5UINT64) {
 
  472                        if ((
"DIMENSION_LIST" !=attr->name) &&
 
  473                            (
"REFERENCE_LIST" != attr->name || 
true == is_ignored))
 
  474                            this->add_ignored_info_attrs(
false,cvar->fullpath,attr->name);
 
  480        for (
const auto&spvar:this->spvars) {
 
  483            bool is_ignored = ignored_dimscale_ref_list(spvar);
 
  484            if (
false == spvar->attrs.empty()) {
 
  488                for (
const auto &attr:spvar->attrs) {
 
  489                    H5DataType temp_dtype = attr->getType();
 
  491                    if (
false == HDF5CFUtil::cf_strict_support_type(temp_dtype,_is_dap4) || temp_dtype == H5INT64 || temp_dtype == H5UINT64) {
 
  495                        if ((
"DIMENSION_LIST" !=attr->name) &&
 
  496                            (
"REFERENCE_LIST" != attr->name || 
true == is_ignored))
 
  497                            this->add_ignored_info_attrs(
false,spvar->fullpath,attr->name);
 
  504        for (
const auto &cvar:this->cvars) {
 
  505            if (
false == cvar->attrs.empty()) {
 
  509                for (
const auto &attr:cvar->attrs) {
 
  510                    H5DataType temp_dtype = attr->getType();
 
  512                    if (
false == HDF5CFUtil::cf_strict_support_type(temp_dtype,_is_dap4) || temp_dtype == H5INT64 || temp_dtype == H5UINT64) 
 
  513                          this->add_ignored_info_attrs(
false,cvar->fullpath,attr->name);
 
  518        for (
const auto &spvar:this->spvars) {
 
  519            if (
false == spvar->attrs.empty()) {
 
  523                for (
const auto &attr:spvar->attrs) {
 
  524                    H5DataType temp_dtype = attr->getType();
 
  526                    if (
false == HDF5CFUtil::cf_strict_support_type(temp_dtype,_is_dap4) || temp_dtype == H5INT64 || temp_dtype == H5UINT64) {
 
  527                        this->add_ignored_info_attrs(
false,spvar->fullpath,attr->name);
 
  540    BESDEBUG(
"h5", 
"Coming to GMFile:Handle_Unsupported_Dspace()"<<endl);
 
  541    if(
true == check_ignored)
 
  542        Gen_Unsupported_Dspace_Info();
 
  545    Handle_GM_Unsupported_Dspace(include_attr);
 
 
  550void GMFile:: Handle_GM_Unsupported_Dspace(
bool include_attr)  {
 
  552    BESDEBUG(
"h5", 
"Coming to GMFile:Handle_GM_Unsupported_Dspace()"<<endl);
 
  553    if(
true == this->unsupported_var_dspace) {
 
  554        for (
auto ircv = this->cvars.begin(); ircv != this->cvars.end(); ) {
 
  555            if (
true  == (*ircv)->unsupported_dspace ) {
 
  563                ircv = this->cvars.erase(ircv);
 
  570        for (
auto ircv = this->spvars.begin(); ircv != this->spvars.end(); ) {
 
  571            if (
true == (*ircv)->unsupported_dspace) {
 
  573                ircv = this->spvars.erase(ircv);
 
  582    if(
true == include_attr) {
 
  583        if(
true == this->unsupported_var_attr_dspace) {
 
  584            for (
auto &cvar:this->cvars) {
 
  585                if (
false == cvar->attrs.empty()) {
 
  586                    if (
true == cvar->unsupported_attr_dspace) {
 
  587                        for (
auto ira = cvar->attrs.begin(); ira != cvar->attrs.end(); ) {
 
  588                            if (0 == (*ira)->count) {
 
  590                                ira = cvar->attrs.erase(ira);
 
  600            for (
auto &spvar:this->spvars) {
 
  601                if (
false == spvar->attrs.empty()) {
 
  602                    if (
true == spvar->unsupported_attr_dspace) {
 
  603                        for (
auto ira = spvar->attrs.begin(); ira != spvar->attrs.end(); ) {
 
  604                            if (0 == (*ira)->count) {
 
  606                                ira = spvar->attrs.erase(ira);
 
  621void GMFile:: Gen_Unsupported_Dspace_Info() {
 
  624    File::Gen_Unsupported_Dspace_Info();
 
  631    BESDEBUG(
"h5", 
"Coming to GMFile:Handle_Unsupported_Others()"<<endl);
 
  636    if(General_Product != this->product_type 
 
  637        || (General_Product == this->product_type && OTHERGMS != this->gproduct_pattern)){
 
  640    if((General_Product == this->product_type && GENERAL_DIMSCALE== this->gproduct_pattern)
 
  641        || (Mea_Ozone == this->product_type)  || (Mea_SeaWiFS_L2 == this->product_type) 
 
  642        || (Mea_SeaWiFS_L3 == this->product_type)
 
  643        || (OBPG_L3 == this->product_type)) 
 
  645      remove_netCDF_internal_attributes(include_attr);
 
  646      if(include_attr == 
true) {
 
  648            for (
auto ira = this->
root_attrs.begin(); ira != this->root_attrs.end();)  {
 
  650                if((*ira)->name == 
"_nc3_strict") {
 
  655                else if((*ira)->name == 
"_NCProperties") {
 
  659                else if((*ira)->name == 
"_Netcdf4Coordinates") {
 
  668            for (
const auto &cvar:this->cvars) {
 
  669                for(
auto ira = cvar->attrs.begin(); ira != cvar->attrs.end();) {
 
  670                    if((*ira)->name == 
"CLASS") {
 
  671                        string class_value = Retrieve_Str_Attr_Value(*ira,cvar->fullpath);
 
  675                        if (0 == class_value.compare(0,15,
"DIMENSION_SCALE")) {
 
  677                            ira = cvar->attrs.erase(ira);
 
  684                    else if((*ira)->name == 
"NAME") {
 
  686                        ira =cvar->attrs.erase(ira);
 
  690                        string name_value = Retrieve_Str_Attr_Value(*ira,cvar->fullpath);
 
  691                        if( 0 == name_value.compare(0,cvar->name.size(),cvar->name)) {
 
  693                            ira =cvar->attrs.erase(ira);
 
  696                            string netcdf_dim_mark= 
"This is a netCDF dimension but not a netCDF variable";
 
  697                            if( 0 == name_value.compare(0,netcdf_dim_mark.size(),netcdf_dim_mark)) {
 
  699                                ira =cvar->attrs.erase(ira);
 
  707                    else if((*ira)->name == 
"_Netcdf4Dimid") {
 
  709                        ira =cvar->attrs.erase(ira);
 
  711                    else if((*ira)->name == 
"_Netcdf4Coordinates") {
 
  713                        ira =cvar->attrs.erase(ira);
 
  717                    else if((*ira)->name == 
"_nc3_strict") {
 
  719                        ira =cvar->attrs.erase(ira);
 
  732    if(
true == this->check_ignored && 
true == include_attr) {
 
  733        if(
true == HDF5RequestHandler::get_drop_long_string()){
 
  735                 irv != this->cvars.end(); ++irv) {
 
  737                    ira != (*irv)->attrs.end();++ira) {
 
  738                    if(
true == Check_DropLongStr((*irv),(*ira))) {
 
  739                        this->add_ignored_droplongstr_hdr();
 
  740                        this->add_ignored_var_longstr_info((*irv),(*ira));
 
  746                irv != this->spvars.end(); ++irv) {
 
  748                    ira != (*irv)->attrs.end();++ira) {
 
  749                    if(
true == Check_DropLongStr((*irv),(*ira))) {
 
  750                        this->add_ignored_droplongstr_hdr();
 
  751                        this->add_ignored_var_longstr_info((*irv),(*ira));
 
  760    if(
false == this->have_ignored)
 
  761        this->add_no_ignored_info();
 
 
  768    BESDEBUG(
"h5", 
"Coming to GMFile:Add_Dim_Name()"<<endl);
 
  769    switch(product_type) {
 
  772            Add_Dim_Name_Mea_SeaWiFS();
 
  775            Add_Dim_Name_Aqu_L3();
 
  778            Add_Dim_Name_OSMAPL2S();
 
  780        case ACOS_L2S_OR_OCO2_L1B:
 
  781            Add_Dim_Name_ACOS_L2S_OCO2_L1B();
 
  784            Add_Dim_Name_Mea_Ozonel3z();
 
  793            Add_Dim_Name_OBPG_L3();
 
  795        case General_Product:
 
  796            Add_Dim_Name_General_Product();
 
  799           throw1(
"Cannot generate dim. names for unsupported datatype");
 
  805    irv2 != this->vars.end(); irv2++) {
 
  807         ird !=(*irv2)->dims.end(); ird++) {
 
  808         cerr<<
"Dimension name afet Add_Dim_Name "<<(*ird)->newname <<endl;
 
 
  816void GMFile::Add_Dim_Name_OBPG_L3()  {
 
  818    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_OBPG_L3()"<<endl);
 
  821    Check_General_Product_Pattern();
 
  822    Add_Dim_Name_General_Product();
 
  826void GMFile::Add_Dim_Name_Mea_SeaWiFS() {
 
  828    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_Mea_SeaWiFS()"<<endl);
 
  829    pair<set<string>::iterator,
bool> setret;
 
  830    if (Mea_SeaWiFS_L3 == product_type) 
 
  832    for (
const auto &var:this->
vars) {
 
  833        Handle_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone(var);
 
  834        for (
const auto &dim:var->dims) {
 
  835            setret = dimnamelist.insert(dim->name);
 
  836            if (
true == setret.second) 
 
  837                Insert_One_NameSizeMap_Element(dim->name,dim->size,dim->unlimited_dim);
 
  841    if (
true == dimnamelist.empty()) 
 
  842        throw1(
"This product should have the dimension names, but no dimension names are found");
 
  846void GMFile::Handle_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone(
Var* var)
 
  849    BESDEBUG(
"h5", 
"Coming to Handle_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone()"<<endl);
 
  850    Attribute* dimlistattr = 
nullptr;
 
  851    bool has_dimlist = 
false;
 
  852    bool has_class = 
false;
 
  853    bool has_reflist = 
false;
 
  855    for (
const auto &attr:var->attrs) {
 
  856        if (
"DIMENSION_LIST" == attr->name) {
 
  860        if (
"CLASS" == attr->name) 
 
  862        if (
"REFERENCE_LIST" == attr->name) 
 
  865        if (
true == has_dimlist) 
 
  867        if (
true == has_class && 
true == has_reflist) 
 
  871    if (
true == has_dimlist) 
 
  872        Add_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone(var,dimlistattr);
 
  875    else if(
true == has_class && 
true == has_reflist) {
 
  876        if (var->dims.size() !=1) 
 
  877           throw2(
"dimension scale dataset must be 1 dimension, this is not true for variable ",
 
  882        (var->dims)[0]->name = var->fullpath;
 
  883        (var->dims)[0]->newname = var->fullpath;
 
  884        pair<set<string>::iterator,
bool> setret;
 
  885        setret = dimnamelist.insert((var->dims)[0]->name);
 
  886        if (
true == setret.second) 
 
  887            Insert_One_NameSizeMap_Element((var->dims)[0]->name,(var->dims)[0]->size,(var->dims)[0]->unlimited_dim);
 
  895        set<hsize_t> fakedimsize;
 
  896        pair<set<hsize_t>::iterator,
bool> setsizeret;
 
  897        for (
auto &dim:var->dims) {
 
  898            Add_One_FakeDim_Name(dim);
 
  899            setsizeret = fakedimsize.insert(dim->size);
 
  900            if (
false == setsizeret.second)   
 
  901                Adjust_Duplicate_FakeDim_Name(dim);
 
  905        for (
int i = 0; i < var->dims.size(); ++i) {
 
  906            Add_One_FakeDim_Name((var->dims)[i]);
 
  907            bool gotoMainLoop = 
false;
 
  908                for (
int j =i-1; j>=0 && !gotoMainLoop; --j) {
 
  909                    if (((var->dims)[i])->size == ((var->dims)[j])->size){
 
  910                        Adjust_Duplicate_FakeDim_Name((var->dims)[i]);
 
  921void GMFile::Add_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone(
const Var *var,
const Attribute*dimlistattr) 
 
  924    BESDEBUG(
"h5", 
"Coming to Add_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone()"<<endl);
 
  925    ssize_t objnamelen = -1;
 
  933    hid_t amemtype_id = -1;
 
  934    hid_t aspace_id = -1;
 
  938    if(
nullptr == dimlistattr) 
 
  939        throw2(
"Cannot obtain the dimension list attribute for variable ",var->name);
 
  942        throw2(
"The number of dimension should NOT be 0 for the variable ",var->name);
 
  946        vlbuf.resize(var->rank);
 
  948        dset_id = H5Dopen(this->fileid,(var->fullpath).c_str(),H5P_DEFAULT);
 
  950            throw2(
"Cannot open the dataset ",var->fullpath);
 
  952        attr_id = H5Aopen(dset_id,(dimlistattr->name).c_str(),H5P_DEFAULT);
 
  954            throw4(
"Cannot open the attribute ",dimlistattr->name,
" of HDF5 dataset ",var->fullpath);
 
  956        atype_id = H5Aget_type(attr_id);
 
  958            throw4(
"Cannot obtain the datatype of the attribute ",dimlistattr->name,
" of HDF5 dataset ",var->fullpath);
 
  960        amemtype_id = H5Tget_native_type(atype_id, H5T_DIR_ASCEND);
 
  963            throw2(
"Cannot obtain the memory datatype for the attribute ",dimlistattr->name);
 
  966        if (H5Aread(attr_id,amemtype_id,vlbuf.data()) <0)
 
  967            throw2(
"Cannot obtain the referenced object for the variable ",var->name);
 
  970        vector<char> objname;
 
  974        for (
auto &vdim:var->dims) {
 
  976            if(vlbuf[vlbuf_index].p== 
nullptr) 
 
  977                throw4(
"The dimension doesn't exist. Var name is ",var->name,
"; the dimension index is ",vlbuf_index);
 
  979            rbuf =((hobj_ref_t*)vlbuf[vlbuf_index].p)[0];
 
  980            if ((ref_dset = H5RDEREFERENCE(attr_id, H5R_OBJECT, &rbuf)) < 0) 
 
  981                throw2(
"Cannot dereference from the DIMENSION_LIST attribute  for the variable ",var->name);
 
  987            rbuf =((hobj_ref_t*)vl_ref[0].p)[0];
 
  989                dset1 =  H5Rdereference2(attr_id,H5P_DEFAULT,H5R_OBJECT,&ds_ref_buf);
 
  992            H5R_ref_t new_rbuf =((H5R_ref_t*)vlbuf[vlbuf_index].p)[0];
 
  993            if ((ref_dset = H5Ropen_object((H5R_ref_t *)&new_rbuf, H5P_DEFAULT, H5P_DEFAULT))<0)
 
  994                throw2(
"Cannot dereference from the DIMENSION_LIST attribute  for the variable ",var->name);
 
  995            H5Rdestroy(&new_rbuf);
 
  998            if ((objnamelen= H5Iget_name(ref_dset,
nullptr,0))<=0) 
 
  999                throw2(
"Cannot obtain the dataset name dereferenced from the DIMENSION_LIST attribute  for the variable ",var->name);
 
 1000            objname.resize(objnamelen+1);
 
 1001            if ((objnamelen= H5Iget_name(ref_dset,objname.data(),objnamelen+1))<=0)
 
 1002                throw2(
"Cannot obtain the dataset name dereferenced from the DIMENSION_LIST attribute  for the variable ",var->name);
 
 1004            auto objname_str = string(objname.begin(),objname.end());
 
 1005            string trim_objname = objname_str.substr(0,objnamelen);
 
 1006            vdim->name = string(trim_objname.begin(),trim_objname.end());
 
 1008            pair<set<string>::iterator,
bool> setret;
 
 1009            setret = dimnamelist.insert(vdim->name);
 
 1010            if (
true == setret.second) 
 
 1011               Insert_One_NameSizeMap_Element(vdim->name,vdim->size,vdim->unlimited_dim);
 
 1012            vdim->newname = vdim->name;
 
 1018        if(vlbuf.empty()==
false) {
 
 1020            if ((aspace_id = H5Aget_space(attr_id)) < 0)
 
 1021                throw2(
"Cannot get hdf5 dataspace id for the attribute ",dimlistattr->name);
 
 1023            if (H5Dvlen_reclaim(amemtype_id,aspace_id,H5P_DEFAULT,(
void*)vlbuf.data())<0)
 
 1024                throw2(
"Cannot successfully clean up the variable length memory for the variable ",var->name);
 
 1026            H5Sclose(aspace_id);
 
 1031        H5Tclose(amemtype_id);
 
 1042        if(amemtype_id != -1)
 
 1043            H5Tclose(amemtype_id);
 
 1046            H5Sclose(aspace_id);
 
 1060void GMFile::Add_Dim_Name_Mea_Ozonel3z() {
 
 1062    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_Mea_Ozonel3z()"<<endl);
 
 1064    bool use_dimscale = 
false;
 
 1066    for (
const auto &grp:this->
groups) {
 
 1067        if (
"/Dimensions" == grp->path) {
 
 1068            use_dimscale = 
true;
 
 1073    if (
false == use_dimscale) {
 
 1075        bool has_dimlist = 
false;
 
 1076        bool has_class = 
false;
 
 1077        bool has_reflist = 
false;
 
 1079        for (
const auto &var:this->
vars) {
 
 1080            for(
const auto &attr:var->attrs) {
 
 1081                if (
"DIMENSION_LIST" == attr->name) 
 
 1084            if (
true == has_dimlist) 
 
 1088        if (
true == has_dimlist) {
 
 1090            for (
const auto &var:this->
vars) {
 
 1092                for (
const auto &attr:var->attrs) {
 
 1093                    if (
"CLASS" == attr->name) 
 
 1095                    if (
"REFERENCE_LIST" == attr->name) 
 
 1097                    if (
true == has_class && 
true == has_reflist) 
 
 1100                if (
true == has_class && 
 
 1101                    true == has_reflist) 
 
 1105            if (
true == has_class && 
true == has_reflist) 
 
 1106                use_dimscale = 
true;
 
 1110    if (
true == use_dimscale) {
 
 1112        pair<set<string>::iterator,
bool> setret;
 
 1113        for (
const auto &var:this->
vars) {
 
 1114            Handle_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone(var);
 
 1115            for (
const auto &dim:var->dims) {  
 
 1116                setret = dimnamelist.insert(dim->name);
 
 1117                if(
true == setret.second) 
 
 1118                    Insert_One_NameSizeMap_Element(dim->name,dim->size,dim->unlimited_dim);
 
 1122        if (
true == dimnamelist.empty()) 
 
 1123            throw1(
"This product should have the dimension names, but no dimension names are found");
 
 1129        multimap<hsize_t,string> ozonedimsize_to_dimname;
 
 1130        pair<multimap<hsize_t,string>::iterator,multimap<hsize_t,string>::iterator> mm_er_ret;
 
 1131        multimap<hsize_t,string>::iterator irmm;
 
 1133        for (
const auto &var:this->
vars) {
 
 1134            bool is_cv = check_cv(var->name);
 
 1135            if (
true == is_cv) {
 
 1136                if (var->dims.size() != 1)
 
 1137                    throw3(
"The coordinate variable", var->name,
" must be one dimension for the zonal average product");
 
 1138                ozonedimsize_to_dimname.insert(pair<hsize_t,string>((var->dims)[0]->size,var->fullpath));
 
 1142        set<hsize_t> fakedimsize;
 
 1143        pair<set<hsize_t>::iterator,
bool> setsizeret;
 
 1144        pair<set<string>::iterator,
bool> setret;
 
 1145        pair<set<string>::iterator,
bool> tempsetret;
 
 1146        set<string> tempdimnamelist;
 
 1147        bool fakedimflag = 
false;
 
 1149        for (
const auto &var:this->
vars) {
 
 1151            for (
auto &dim:var->dims) {
 
 1154                mm_er_ret = ozonedimsize_to_dimname.equal_range(dim->size);
 
 1155                for (irmm = mm_er_ret.first; irmm!=mm_er_ret.second;irmm++) {
 
 1156                    setret = tempdimnamelist.insert(irmm->second);
 
 1157                    if (
true == setret.second) {
 
 1158                       dim->name = irmm->second;
 
 1159                       dim->newname = dim->name;
 
 1160                       setret = dimnamelist.insert(dim->name);
 
 1161                       if(setret.second) Insert_One_NameSizeMap_Element(dim->name,dim->size,dim->unlimited_dim);
 
 1162                       fakedimflag = 
false;
 
 1167                if (
true == fakedimflag) {
 
 1168                     Add_One_FakeDim_Name(dim);
 
 1169                     setsizeret = fakedimsize.insert(dim->size);
 
 1170                     if (
false == setsizeret.second)  
 
 1171                        Adjust_Duplicate_FakeDim_Name(dim);
 
 1175            tempdimnamelist.clear();
 
 1176            fakedimsize.clear();
 
 1182bool GMFile::check_cv(
const string & varname)
 const {
 
 1184     BESDEBUG(
"h5", 
"Coming to check_cv()"<<endl);
 
 1185     const string lat_name =
"Latitude";
 
 1186     const string time_name =
"Time";
 
 1187     const string ratio_pressure_name =
"MixingRatioPressureLevels";
 
 1188     const string profile_pressure_name =
"ProfilePressureLevels";
 
 1189     const string wave_length_name =
"Wavelength";
 
 1191     if (lat_name == varname) 
 
 1193     else if (time_name == varname) 
 
 1195     else if (ratio_pressure_name == varname) 
 
 1197     else if (profile_pressure_name == varname) 
 
 1199     else if (wave_length_name == varname)
 
 1206void GMFile::Add_Dim_Name_GPM()
 
 1209    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_GPM()"<<endl);
 
 1211    pair<set<string>::iterator,
bool> setret;
 
 1223    for (
const auto &var:this->
vars) {
 
 1225        for (
auto &attr:var->attrs) {
 
 1227            if(
"DimensionNames" == attr->name) {
 
 1229                Retrieve_H5_Attr_Value(attr,var->fullpath);
 
 1230                string dimname_value(attr->value.begin(),attr->value.end());
 
 1232                vector<string> ind_elems;
 
 1236                if(ind_elems.size() != (
size_t)(var->
getRank())) {
 
 1237                    throw2(
"The number of dims obtained from the <DimensionNames> attribute is not equal to the rank ", 
 
 1241                for(
unsigned int i = 0; i<ind_elems.size(); ++i) {
 
 1243                    (var->dims)[i]->name = ind_elems[i];
 
 1247                    if((var->dims)[i]->name==
""){ 
 
 1248                        Add_One_FakeDim_Name((var->dims)[i]);
 
 1251                        string fakedim = 
"FakeDim";
 
 1252                        stringstream sdim_count;
 
 1253                        sdim_count << dim_count;
 
 1254                        fakedim = fakedim + sdim_count.str();
 
 1256                        (var->dims)[i]->name = fakedim;
 
 1257                        (var->dims)[i]->newname = fakedim;
 
 1258                        ind_elems[i] = fakedim;
 
 1263                        (var->dims)[i]->newname = ind_elems[i];
 
 1264                        setret = dimnamelist.insert((var->dims)[i]->name);
 
 1266                        if (
true == setret.second) {
 
 1267                            Insert_One_NameSizeMap_Element((var->dims)[i]->name,
 
 1268                                                           (var->dims)[i]->size,
 
 1269                                                           (var->dims)[i]->unlimited_dim);
 
 1272                            if(dimname_to_dimsize[(var->dims)[i]->name] !=(var->dims)[i]->size)
 
 1273                                throw5(
"Dimension ",(var->dims)[i]->name, 
"has two sizes",   
 
 1274                                        (var->dims)[i]->size,dimname_to_dimsize[(var->dims)[i]->name]);
 
 1286        if(
false == has_dim_name_attr) {
 
 1288            throw4( 
"The variable ", var->name, 
" doesn't have the DimensionNames attribute.",
 
 1289                    "We currently don't support this case. Please report to the NASA data center.");
 
 1298void GMFile::Add_Dim_Name_Aqu_L3()
 const 
 1300    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_Aqu_L3()"<<endl);
 
 1301    for (
auto &var:this->
vars) {
 
 1302        if (
"l3m_data" == var->name) {
 
 1303           (var->dims)[0]->name = 
"lat";
 
 1304           (var->dims)[0]->newname = 
"lat";
 
 1305           (var->dims)[1]->name = 
"lon";
 
 1306           (var->dims)[1]->newname = 
"lon";
 
 1313        if (
"palette" == (*irv)->name) {
 
 1315          ((*irv)->dims)[0]->name = 
"paldim0";
 
 1316           ((*irv)->dims)[0]->newname = 
"paldim0";
 
 1317           ((*irv)->dims)[1]->name = 
"paldim1";
 
 1318           ((*irv)->dims)[1]->newname = 
"paldim1";
 
 1326void GMFile::Add_Dim_Name_OSMAPL2S(){
 
 1328    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_OSMAPL2S()"<<endl);
 
 1330    string key = 
"_lat";
 
 1331    string osmapl2sdim0 =
"YDim";
 
 1332    string osmapl2sdim1 =
"XDim";
 
 1335    multimap<hsize_t,string> osmapl2sdimsize_to_dimname;
 
 1336    pair<multimap<hsize_t,string>::iterator,multimap<hsize_t,string>::iterator> mm_er_ret;
 
 1337    multimap<hsize_t,string>::iterator irmm; 
 
 1340    for (
const auto &var:this->
vars) {
 
 1341        tempvarname = var->name;
 
 1342        if ((tempvarname.size() > key.size())&& 
 
 1343            (key == tempvarname.substr(tempvarname.size()-key.size(),key.size()))){
 
 1344            if (var->dims.size() !=2) 
 
 1345                throw1(
"Currently only 2D lat/lon is supported for OSMAPL2S");
 
 1346            osmapl2sdimsize_to_dimname.insert(pair<hsize_t,string>((var->dims)[0]->size,osmapl2sdim0));
 
 1347            osmapl2sdimsize_to_dimname.insert(pair<hsize_t,string>((var->dims)[1]->size,osmapl2sdim1));
 
 1352    set<hsize_t> fakedimsize;
 
 1353    pair<set<hsize_t>::iterator,
bool> setsizeret;
 
 1354    pair<set<string>::iterator,
bool> setret;
 
 1355    pair<set<string>::iterator,
bool> tempsetret;
 
 1356    set<string> tempdimnamelist;
 
 1357    bool fakedimflag = 
false;
 
 1360    for (
const auto &var:this->
vars) {
 
 1361        for (
auto &dim:var->dims) {
 
 1364            mm_er_ret = osmapl2sdimsize_to_dimname.equal_range(dim->size);
 
 1365            for (irmm = mm_er_ret.first; irmm!=mm_er_ret.second;irmm++) {
 
 1366                setret = tempdimnamelist.insert(irmm->second);
 
 1367                if (setret.second) {
 
 1368                   dim->name = irmm->second;
 
 1369                   dim->newname = dim->name;
 
 1370                   setret = dimnamelist.insert(dim->name);
 
 1371                   if(setret.second) Insert_One_NameSizeMap_Element(dim->name,dim->size,dim->unlimited_dim);
 
 1372                   fakedimflag = 
false;
 
 1377            if (
true == fakedimflag) {
 
 1378                 Add_One_FakeDim_Name(dim);
 
 1379                 setsizeret = fakedimsize.insert(dim->size);
 
 1380                 if (!setsizeret.second)  
 
 1381                    Adjust_Duplicate_FakeDim_Name(dim);
 
 1384        tempdimnamelist.clear();
 
 1385        fakedimsize.clear();
 
 1390void GMFile::Add_Dim_Name_ACOS_L2S_OCO2_L1B(){
 
 1392    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_ACOS_L2S_OCO2_L1B()"<<endl);
 
 1393    for (
const auto &var:this->
vars) {
 
 1394        set<hsize_t> fakedimsize;
 
 1395        pair<set<hsize_t>::iterator,
bool> setsizeret;
 
 1396        for (
auto dim:var->dims) {
 
 1397                Add_One_FakeDim_Name(dim);
 
 1398                setsizeret = fakedimsize.insert(dim->size);
 
 1399                if (
false == setsizeret.second)   
 
 1400                    Adjust_Duplicate_FakeDim_Name(dim);
 
 1406void GMFile::Add_Dim_Name_General_Product(){
 
 1408    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_General_Product()"<<endl);
 
 1411    if (GENERAL_DIMSCALE == this->gproduct_pattern){
 
 1412        Add_Dim_Name_Dimscale_General_Product();
 
 1415    else if (GENERAL_LATLON2D == this->gproduct_pattern)
 
 1416        Add_Dim_Name_LatLon2D_General_Product();
 
 1418    else if (GENERAL_LATLON1D == this->gproduct_pattern || GENERAL_LATLON_COOR_ATTR == this->gproduct_pattern)
 
 1419        Add_Dim_Name_LatLon1D_Or_CoordAttr_General_Product();
 
 1432void GMFile::Check_General_Product_Pattern()  {
 
 1434    BESDEBUG(
"h5", 
"Coming to Check_General_Product_Pattern()"<<endl);
 
 1435    if (
false == Check_Dimscale_General_Product_Pattern()) {
 
 1437        if (
false == Check_And_Update_New_GPM_L3()) 
 
 1438            if (
false == Check_LatLon2D_General_Product_Pattern()) 
 
 1439                if (
false == Check_LatLon1D_General_Product_Pattern())
 
 1440                    Check_LatLon_With_Coordinate_Attr_General_Product_Pattern();
 
 1447bool GMFile::Check_Dimscale_General_Product_Pattern()  {
 
 1449    BESDEBUG(
"h5", 
"Coming to Check_Dimscale_General_Product_Pattern()"<<endl);
 
 1450    bool ret_value = 
false;
 
 1451    bool has_dimlist = 
false;
 
 1452    bool has_dimscalelist  = 
false;
 
 1455    for (
const auto &var:this->
vars) {
 
 1456        for(
const auto &attr:var->attrs) {
 
 1457            if (
"DIMENSION_LIST" == attr->name) {
 
 1462        if (
true == has_dimlist)
 
 1471    for (
const auto &var:this->
vars) {
 
 1472        for(
const auto &attr:var->attrs) {
 
 1473            if (
"CLASS" == attr->name) {
 
 1475                Retrieve_H5_Attr_Value(attr,var->fullpath);
 
 1477                class_value.resize(attr->value.size());
 
 1478                copy(attr->value.begin(),attr->value.end(),class_value.begin());
 
 1482                if (0 == class_value.compare(0,15,
"DIMENSION_SCALE")) {
 
 1483                    has_dimscalelist = 
true;
 
 1488        if (
true == has_dimscalelist)
 
 1492    if (
true == has_dimscalelist) {
 
 1493        if (
true == has_dimlist ) {
 
 1494            this->gproduct_pattern = GENERAL_DIMSCALE;
 
 1502            bool is_general_dimscale = 
false;
 
 1504            for (
const auto &var:this->
vars) {
 
 1506                bool has_class_dscale = 
false;
 
 1507                bool has_name = 
false;
 
 1508                bool has_netcdf4_id = 
false;
 
 1510                for (
const auto &attr:var->attrs) {
 
 1512                    if (
"CLASS" == attr->name) {
 
 1513                        Retrieve_H5_Attr_Value(attr,var->fullpath);
 
 1515                        class_value.resize(attr->value.size());
 
 1516                        copy(attr->value.begin(),attr->value.end(),class_value.begin());
 
 1520                        if (0 == class_value.compare(0,15,
"DIMENSION_SCALE")) 
 
 1521                            has_class_dscale= 
true;
 
 1523                    else if (
"NAME" == attr->name)
 
 1525                    else if (
"_Netcdf4Dimid" == attr->name)
 
 1526                        has_netcdf4_id = 
true;
 
 1527                    if(
true == has_class_dscale && 
true == has_name && 
true == has_netcdf4_id)
 
 1528                        is_general_dimscale = 
true;
 
 1531                if(
true == is_general_dimscale)
 
 1535            if (
true == is_general_dimscale) {
 
 1536                this->gproduct_pattern = GENERAL_DIMSCALE;
 
 1545bool GMFile::Check_And_Update_New_GPM_L3() {
 
 1547    bool is_new_gpm_l3 = 
false;
 
 1548    unsigned num_vars = this->
vars.size();
 
 1549    unsigned sel_steps = num_vars/5;
 
 1550    string dim_name=
"DimensionNames";
 
 1551    bool has_dim_name = 
false;
 
 1558    vector<Var *>::iterator it_var_end;
 
 1561        it_var_end = this->
vars.end();
 
 1563        it_var_end = this->
vars.begin()+5*sel_steps;
 
 1565    for (
auto irv = this->
vars.begin(); irv != it_var_end; irv+=sel_steps) {
 
 1566        for (
const auto &attr:(*irv)->attrs) {
 
 1568            if(H5FSTRING == attr->getType()) {
 
 1569                if(attr->name == dim_name){
 
 1570                    has_dim_name = 
true;
 
 1575        if(
true == has_dim_name) 
 
 1581    if(
true == has_dim_name) {
 
 1582        string attr_name_subset = 
"GridHeader";
 
 1583        BESDEBUG(
"h5", 
"GMFile::Check_And_Update_New_GPM_L3() has attribute <DimensionNames>. "<<endl);
 
 1584        for (
const auto &grp:this->
groups) {
 
 1585            for (
const auto &attr:grp->attrs) {
 
 1587                string attr_name = attr->name;
 
 1590                if (attr_name.find(attr_name_subset)!=string::npos) {
 
 1591                    this->product_type = GPM_L3_New;
 
 1592                    is_new_gpm_l3 = 
true;
 
 1596            if (
true == is_new_gpm_l3)
 
 1600    return is_new_gpm_l3;
 
 1606bool GMFile::Check_LatLon2D_General_Product_Pattern()  {
 
 1608    BESDEBUG(
"h5", 
"Coming to Check_LatLon2D_General_Product_Pattern()"<<endl);
 
 1609    bool ret_value = 
false;
 
 1611    ret_value =  Check_LatLon2D_General_Product_Pattern_Name_Size(
"latitude",
"longitude");
 
 1612    if(
false == ret_value) {
 
 1613        ret_value =  Check_LatLon2D_General_Product_Pattern_Name_Size(
"Latitude",
"Longitude");
 
 1614        if(
false == ret_value) {
 
 1615            ret_value =  Check_LatLon2D_General_Product_Pattern_Name_Size(
"lat",
"lon");
 
 1616            if(
false == ret_value)
 
 1617                ret_value =  Check_LatLon2D_General_Product_Pattern_Name_Size(
"cell_lat",
"cell_lon");
 
 1622    if(
true == ret_value)
 
 1623        this->gproduct_pattern = GENERAL_LATLON2D;
 
 1630bool GMFile::Check_LatLon2D_General_Product_Pattern_Name_Size(
const string & latname,
const string & lonname)  {
 
 1632    BESDEBUG(
"h5", 
"Coming to Check_LatLon2D_General_Product_Pattern_Name_Size()"<<endl);
 
 1633    bool ret_value = 
false;
 
 1634    bool ll_flag =  
false;
 
 1636    vector<size_t>lat_size(2,0);
 
 1637    vector<size_t>lon_size(2,0);
 
 1639    const string designed_group1 = 
"/";
 
 1640    const string designed_group2 = 
"/Geolocation/";
 
 1642    bool lat_flag_g1 = 
false;
 
 1643    bool lon_flag_g1 = 
false;
 
 1644    bool lat_flag_g2 = 
false;
 
 1645    bool lon_flag_g2 = 
false;
 
 1651    lat_flag_g1 = is_var_under_group(latname,designed_group1,2,lat_size);
 
 1652    lon_flag_g1 = is_var_under_group(lonname,designed_group1,2,lon_size);
 
 1653    if(lat_flag_g1 == 
true && lon_flag_g1 == 
true) {
 
 1656        lat_flag_g2 = is_var_under_group(latname,designed_group2,2,lat_size);
 
 1657        if(lat_flag_g2 == 
false) {
 
 1658            lon_flag_g2 = is_var_under_group(lonname,designed_group2,2,lon_size);
 
 1659            if(lon_flag_g2 == 
false)
 
 1663    else if(lat_flag_g1 == 
false && lon_flag_g1 == 
false) {
 
 1664        lat_flag_g2 = is_var_under_group(latname,designed_group2,2,lat_size);
 
 1665        if(lat_flag_g2 == 
true) {
 
 1666            lon_flag_g2 = is_var_under_group(lonname,designed_group2,2,lon_size);
 
 1667            if(lon_flag_g2 == 
true)
 
 1676    if(
false == ll_flag) {
 
 1678        const string designed_group3 = 
"/GeolocationData/";
 
 1679        if(is_var_under_group(latname,designed_group3,2,lat_size) && 
 
 1680           is_var_under_group(lonname,designed_group3,2,lon_size))
 
 1686    for (vector<Var *>::iterator irv = this->
vars.begin();
 
 1687        irv != this->vars.end(); ++irv) {
 
 1689        if((*irv)->rank == 2) {
 
 1690            if((*irv)->name == latname) {
 
 1693                string lat_path =HDF5CFUtil::obtain_string_before_lastslash((*irv)->fullpath);
 
 1699                bool has_right_lat = 
false;
 
 1700                if(
"/" == lat_path || 
"/Geolocation/" == lat_path) 
 
 1701                if(
"/" == lat_path || 
"/Geolocation/" == lat_path) {
 
 1703                    lat_size[0] = (*irv)->getDimensions()[0]->size; 
 
 1704                    lat_size[1] = (*irv)->getDimensions()[1]->size; 
 
 1708            else if((*irv)->name == lonname) {
 
 1709                string lon_path = HDF5CFUtil::obtain_string_before_lastslash((*irv)->fullpath);
 
 1710                if(
"/" == lon_path || 
"/Geolocation/" == lon_path) {
 
 1712                    lon_size[0] = (*irv)->getDimensions()[0]->size; 
 
 1713                    lon_size[1] = (*irv)->getDimensions()[1]->size; 
 
 1725    if(
true == ll_flag) {
 
 1727        bool latlon_size_match = 
true;
 
 1728        for (
unsigned int size_index = 0; size_index <lat_size.size();size_index++) {
 
 1729            if(lat_size[size_index] != lon_size[size_index]){
 
 1730                latlon_size_match = 
false;
 
 1734        if (
true == latlon_size_match) {
 
 1736            gp_latname = latname;
 
 1737            gp_lonname = lonname;
 
 1750bool GMFile::Check_LatLon1D_General_Product_Pattern()  {
 
 1752    BESDEBUG(
"h5", 
"Coming to Check_LatLon1D_General_Product_Pattern()"<<endl);
 
 1753    bool ret_value = 
false;
 
 1755    ret_value =  Check_LatLon1D_General_Product_Pattern_Name_Size(
"latitude",
"longitude");
 
 1756    if(
false == ret_value) {
 
 1757        ret_value =  Check_LatLon1D_General_Product_Pattern_Name_Size(
"Latitude",
"Longitude");
 
 1758        if(
false == ret_value) {
 
 1759            ret_value =  Check_LatLon1D_General_Product_Pattern_Name_Size(
"lat",
"lon");
 
 1760            if(
false == ret_value)
 
 1761                ret_value =  Check_LatLon1D_General_Product_Pattern_Name_Size(
"cell_lat",
"cell_lon");
 
 1765    if(
true == ret_value)
 
 1766        this->gproduct_pattern = GENERAL_LATLON1D;
 
 1773bool GMFile::Check_LatLon1D_General_Product_Pattern_Name_Size(
const string & latname,
const string & lonname)  {
 
 1775    BESDEBUG(
"h5", 
"Coming to Check_LatLon1D_General_Product_Pattern_Name_Size()"<<endl);
 
 1776    bool ret_value = 
false;
 
 1778    size_t lat_size = 0;
 
 1779    size_t lon_size = 0;
 
 1781    for (
const auto &var:this->
vars) {
 
 1783        if(var->rank == 1) {
 
 1784            if(var->name == latname)  {
 
 1786                string lat_path =HDF5CFUtil::obtain_string_before_lastslash(var->fullpath);
 
 1790                if(
"/" == lat_path || 
"/Geolocation/" == lat_path) {
 
 1795            else if(var->name == lonname) {
 
 1796                string lon_path = HDF5CFUtil::obtain_string_before_lastslash(var->fullpath);
 
 1797                if(
"/" == lon_path || 
"/Geolocation/" == lon_path) {
 
 1809        bool latlon_size_match_grid = 
true;
 
 1815        if(lat_size == lon_size) {
 
 1818            latlon_size_match_grid = 
false;
 
 1822            for (
const auto &var:this->
vars) {
 
 1824                    short ll_size_flag = 0;
 
 1825                    for (
const auto &dim:var->dims) {
 
 1826                        if(lat_size == dim->size) {
 
 1828                            if(2 == ll_size_flag){
 
 1833                    if(2 == ll_size_flag) {
 
 1834                        latlon_size_match_grid = 
true;
 
 1843        if (
true == latlon_size_match_grid) {
 
 1844            gp_latname = latname;
 
 1845            gp_lonname = lonname;
 
 1855bool GMFile::Check_LatLon_With_Coordinate_Attr_General_Product_Pattern()  {
 
 1857    BESDEBUG(
"h5", 
"Coming to Check_LatLon_With_Coordinate_Attr_General_Product_Pattern()"<<endl);
 
 1858    bool ret_value = 
false;
 
 1859    string co_attrname = 
"coordinates";
 
 1860    string co_attrvalue;
 
 1861    string unit_attrname = 
"units";
 
 1862    string lat_unit_attrvalue =
"degrees_north";
 
 1863    string lon_unit_attrvalue =
"degrees_east";
 
 1865    bool coor_has_lat_flag = 
false;
 
 1866    bool coor_has_lon_flag = 
false;
 
 1868    vector<Var*> tempvar_lat;
 
 1869    vector<Var*> tempvar_lon;
 
 1872    for (
const auto &var:this->
vars) {
 
 1875            for (
const auto &attr:var->attrs) {
 
 1879                if(attr->name == co_attrname) {
 
 1880                    Retrieve_H5_Attr_Value(attr,var->fullpath);
 
 1881                    string orig_attr_value(attr->value.begin(),attr->value.end());
 
 1882                    vector<string> coord_values;
 
 1884                    HDF5CFUtil::Split_helper(coord_values,orig_attr_value,sep);
 
 1886                    for (
const auto &coord_value:coord_values) {
 
 1887                        string coord_value_suffix1;
 
 1888                        string coord_value_suffix2;
 
 1889                        string coord_value_suffix3;
 
 1891                        if(coord_value.size() >=3) {
 
 1894                            coord_value_suffix1 = coord_value.substr(coord_value.size()-3,3);
 
 1897                            if(coord_value.size() >=8){
 
 1898                                coord_value_suffix2 = coord_value.substr(coord_value.size()-8,8);
 
 1899                                if(coord_value.size() >=9)
 
 1900                                    coord_value_suffix3 = coord_value.substr(coord_value.size()-9,9);
 
 1905                        if(coord_value_suffix1==
"lat" || coord_value_suffix2 ==
"latitude" || coord_value_suffix2 == 
"Latitude")
 
 1906                            coor_has_lat_flag = 
true;
 
 1907                        else if(coord_value_suffix1==
"lon" || coord_value_suffix3 ==
"longitude" || coord_value_suffix3 == 
"Longitude")
 
 1908                            coor_has_lon_flag = 
true;
 
 1911                    if(
true == coor_has_lat_flag && 
true == coor_has_lon_flag)
 
 1916            if(
true == coor_has_lat_flag && 
true == coor_has_lon_flag) 
 
 1919                coor_has_lat_flag = 
false;
 
 1920                coor_has_lon_flag = 
false;
 
 1926    if(
true == coor_has_lat_flag && 
true == coor_has_lon_flag) {
 
 1928        for (
const auto &var:this->
vars) {
 
 1930            bool var_is_lat = 
false;
 
 1931            bool var_is_lon = 
false;
 
 1933            string varname = var->name;
 
 1937            if(varname.size() >=3) {
 
 1938                ll_ssuffix = varname.substr(varname.size()-3,3);
 
 1939                if(varname.size() >=8) {
 
 1940                    ll_lsuffix1 = varname.substr(varname.size()-8,8);
 
 1941                    if(varname.size() >=9)
 
 1942                        ll_lsuffix2 = varname.substr(varname.size()-9,9);
 
 1945            if(ll_ssuffix==
"lat" || ll_lsuffix1 ==
"latitude" || ll_lsuffix1 == 
"Latitude")
 
 1947            else if(ll_ssuffix==
"lon" || ll_lsuffix2 ==
"longitude" || ll_lsuffix2 == 
"Longitude")
 
 1951            if(
true == var_is_lat) {
 
 1953                    auto lat_unique = make_unique<Var>(var);
 
 1954                    auto lat = lat_unique.release();
 
 1955                    tempvar_lat.push_back(lat);
 
 1958            else if(
true == var_is_lon) {
 
 1960                    auto lon_unique = make_unique<Var>(var);
 
 1961                    auto lon = lon_unique.release();
 
 1962                    tempvar_lon.push_back(lon);
 
 1972        for (
auto &t_lat:tempvar_lat) {
 
 1975            if(t_lat->rank == 1) 
 
 1976                Build_lat1D_latlon_candidate(t_lat,tempvar_lon);
 
 1979            else if(t_lat->rank >1)
 
 1980                Build_latg1D_latlon_candidate(t_lat,tempvar_lon);
 
 1984for(vector<struct Name_Size_2Pairs>::iterator ivs=latloncv_candidate_pairs.begin(); ivs!=latloncv_candidate_pairs.end();++ivs) {
 
 1985cerr<<
"struct lat lon names are " <<(*ivs).name1 <<
" and " << (*ivs).name2 <<endl;
 
 1992        Build_unique_latlon_candidate();
 
 2006        if(latloncv_candidate_pairs.empty() == 
false) {
 
 2007            int num_1d_rank = 0;
 
 2008            int num_2d_rank = 0;
 
 2009            int num_g2d_rank = 0;
 
 2010            vector<struct Name_Size_2Pairs> temp_1d_latlon_pairs;
 
 2011            for(
const auto &llcv_p:latloncv_candidate_pairs) {
 
 2012                if(1 == llcv_p.rank) {
 
 2014                    temp_1d_latlon_pairs.push_back(llcv_p);
 
 2016                else if(2 == llcv_p.rank)
 
 2018                else if(llcv_p.rank >2) 
 
 2023            if (num_2d_rank !=0) 
 
 2025            else if(num_1d_rank!=0) {
 
 2029                for (
const auto &t_1dll_p:temp_1d_latlon_pairs) {
 
 2030                    if(t_1dll_p.size1 != t_1dll_p.size2) {
 
 2041                        for (
const auto &var:this->
vars) {
 
 2044                                for (
const auto &attr:var->attrs) {
 
 2047                                    if(attr->name == co_attrname) {
 
 2048                                        Retrieve_H5_Attr_Value(attr,var->fullpath);
 
 2049                                        string orig_attr_value(attr->value.begin(),attr->value.end());
 
 2050                                        vector<string> coord_values;
 
 2052                                        HDF5CFUtil::Split_helper(coord_values,orig_attr_value,sep);
 
 2053                                        bool has_lat_flag = 
false;
 
 2054                                        bool has_lon_flag = 
false;
 
 2055                                        for (
const auto &c_value:coord_values) {
 
 2056                                            if(t_1dll_p.name1 == c_value) 
 
 2057                                            has_lat_flag = 
true;
 
 2058                                            else if(t_1dll_p.name2 == c_value)
 
 2059                                                has_lon_flag = 
true;
 
 2062                                        if(
true == has_lat_flag && 
true == has_lon_flag) {
 
 2063                                            short has_same_ll_size = 0;
 
 2064                                            for(
const auto &dim:var->dims){
 
 2065                                                if(dim->size == t_1dll_p.size1)
 
 2068                                            if(has_same_ll_size!=2){
 
 2076                                if(
false == ret_value)
 
 2081                        if(
true == ret_value) 
 
 2088        release_standalone_var_vector(tempvar_lat);
 
 2089        release_standalone_var_vector(tempvar_lon);
 
 2093if(
true == ret_value) 
 
 2094cerr<<
"This product is the coordinate type "<<endl;
 
 2097    if(
true == ret_value)
 
 2098        this->gproduct_pattern = GENERAL_LATLON_COOR_ATTR;
 
 2104void GMFile::Build_lat1D_latlon_candidate(
const Var *lat,
const vector<Var*> &lon_vec) {
 
 2106    BESDEBUG(
"h5", 
"Coming to Build_lat1D_latlon_candidate()"<<endl);
 
 2107    set<string> lon_candidate_path;
 
 2108    vector< pair<string,hsize_t> > lon_path_size_vec;
 
 2111    for(
const auto &lon:lon_vec) {
 
 2113        if (lat->rank == lon->rank) {
 
 2114            pair<string,hsize_t>lon_path_size;
 
 2115            lon_path_size.first = lon->fullpath;
 
 2116            lon_path_size.second = lon->getDimensions()[0]->size;
 
 2117            lon_path_size_vec.push_back(lon_path_size);
 
 2122    if(lon_path_size_vec.size() == 1) {
 
 2124        Name_Size_2Pairs latlon_pair;
 
 2125        latlon_pair.name1 = lat->fullpath;
 
 2126        latlon_pair.name2 = lon_path_size_vec[0].first;
 
 2128        latlon_pair.size2 = lon_path_size_vec[0].second;
 
 2129        latlon_pair.rank = lat->rank;
 
 2130        latloncv_candidate_pairs.push_back(latlon_pair);
 
 2133    else if(lon_path_size_vec.size() >1) {
 
 2137        string lat_path = HDF5CFUtil::obtain_string_before_lastslash(lat->fullpath);
 
 2138        pair<string,hsize_t> lon_final_path_size;
 
 2139        short num_lon_match = 0;
 
 2140        for (
const auto &lon_size:lon_path_size_vec) {
 
 2142            if(HDF5CFUtil::obtain_string_before_lastslash(lon_size.first)==lat_path) {
 
 2144                if(1 == num_lon_match)
 
 2145                    lon_final_path_size = lon_size;
 
 2146                else if(num_lon_match > 1) 
 
 2150        if(num_lon_match ==1) {
 
 2151            Name_Size_2Pairs latlon_pair;
 
 2152            latlon_pair.name1 = lat->fullpath;
 
 2153            latlon_pair.name2 = lon_final_path_size.first;
 
 2155            latlon_pair.size2 = lon_final_path_size.second;
 
 2156            latlon_pair.rank = lat->rank;
 
 2157            latloncv_candidate_pairs.push_back(latlon_pair);
 
 2164void GMFile::Build_latg1D_latlon_candidate(
Var *lat,
const vector<Var*> & lon_vec) {
 
 2166    BESDEBUG(
"h5", 
"Coming to Build_latg1D_latlon_candidate()"<<endl);
 
 2167    set<string> lon_candidate_path;
 
 2170    for(
const auto &lon:lon_vec) {
 
 2172        if (lat->rank == lon->rank) {
 
 2175            bool same_dim = 
true;
 
 2176            for(
int dim_index = 0; dim_index <lat->rank; dim_index++) {
 
 2178                   lon->getDimensions()[dim_index]->size){ 
 
 2183            if(
true == same_dim) 
 
 2184                lon_candidate_path.insert(lon->fullpath);
 
 2189    if(lon_candidate_path.size() > 1) {
 
 2191        string lat_path = HDF5CFUtil::obtain_string_before_lastslash(lat->fullpath);
 
 2192        vector <string> lon_final_candidate_path_vec;
 
 2193        for(
auto islon_path =lon_candidate_path.begin();islon_path!=lon_candidate_path.end();++islon_path) {
 
 2196            if(HDF5CFUtil::obtain_string_before_lastslash(*islon_path)==lat_path) 
 
 2197                lon_final_candidate_path_vec.push_back(*islon_path);
 
 2200        if(lon_final_candidate_path_vec.size() == 1) {
 
 2202            Name_Size_2Pairs latlon_pair;
 
 2204            latlon_pair.name1 = lat->fullpath;
 
 2205            latlon_pair.name2 = lon_final_candidate_path_vec[0];
 
 2208            latlon_pair.rank = lat->rank;
 
 2209            latloncv_candidate_pairs.push_back(latlon_pair);
 
 2211        else if(lon_final_candidate_path_vec.size() >1) {
 
 2218            string lat_name = HDF5CFUtil::obtain_string_after_lastslash(lat->fullpath);
 
 2219            string lat_name_prefix1;
 
 2220            string lat_name_prefix2;
 
 2223            if(lat_name.size() >3) {
 
 2224                lat_name_prefix1 = lat_name.substr(0,lat_name.size()-3);
 
 2225                if(lat_name.size() >8)
 
 2226                    lat_name_prefix2 = lat_name.substr(0,lat_name.size()-8);
 
 2228            string lon_name_prefix1;
 
 2229            string lon_name_prefix2;
 
 2231            for(
auto ilon = lon_final_candidate_path_vec.begin(); ilon!=lon_final_candidate_path_vec.end();++ilon) {
 
 2232                string lon_name = HDF5CFUtil::obtain_string_after_lastslash(*ilon);
 
 2233                if(lon_name.size() >3) {
 
 2234                    lon_name_prefix1 = lon_name.substr(0,lon_name.size()-3);
 
 2235                    if(lon_name.size() >9)
 
 2236                        lon_name_prefix2 = lon_name.substr(0,lon_name.size()-9);
 
 2238                if((lat_name_prefix1 !=
"" && lat_name_prefix1 == lon_name_prefix1) ||
 
 2239                   (lat_name_prefix2 !=
"" && lat_name_prefix2 == lon_name_prefix2)) {
 
 2241                    Name_Size_2Pairs latlon_pair;
 
 2242                    latlon_pair.name1 = lat->fullpath;
 
 2243                    latlon_pair.name2 = *ilon;
 
 2246                    latlon_pair.rank = lat->rank;
 
 2247                    latloncv_candidate_pairs.push_back(latlon_pair);
 
 2254    else if(lon_candidate_path.size() == 1) {
 
 2256        Name_Size_2Pairs latlon_pair;
 
 2258        latlon_pair.name1 = lat->fullpath;
 
 2259        latlon_pair.name2 = *(lon_candidate_path.begin());
 
 2262        latlon_pair.rank = lat->rank;
 
 2263        latloncv_candidate_pairs.push_back(latlon_pair);
 
 2271void GMFile::Build_unique_latlon_candidate() {
 
 2273    BESDEBUG(
"h5", 
"Coming to Build_unique_latlon_candidate()"<<endl);
 
 2274    set<int> duplicate_index;
 
 2275    for(
unsigned int i= 0; i<latloncv_candidate_pairs.size();i++) {
 
 2276        for(
unsigned int j=i+1;j<latloncv_candidate_pairs.size();j++) {
 
 2277            if(latloncv_candidate_pairs[i].name2 == latloncv_candidate_pairs[j].name2) {
 
 2278                duplicate_index.insert(i);
 
 2279                duplicate_index.insert(j);
 
 2285    for(
auto its= duplicate_index.rbegin();its!=duplicate_index.rend();++its) {
 
 2286        latloncv_candidate_pairs[*its] = latloncv_candidate_pairs.back();
 
 2287        latloncv_candidate_pairs.pop_back();
 
 2294bool GMFile::Check_LatLonName_General_Product(
int ll_rank)  {
 
 2296    if(ll_rank <1 || ll_rank >2) 
 
 2297        throw2(
"Only support rank = 1 or 2 lat/lon case for the general product. The current rank is ",ll_rank);
 
 2298    bool ret_value = 
false;
 
 2299    size_t lat2D_dimsize0 = 0;
 
 2300    size_t lat2D_dimsize1 = 0;
 
 2301    size_t lon2D_dimsize0 = 0;
 
 2302    size_t lon2D_dimsize1 = 0;
 
 2305    vector<short>ll_flag(3,0);
 
 2307    vector<size_t>lat_size;
 
 2308    vector<size_t>lon_size;
 
 2313        lat_size.assign(6,0);
 
 2314        lon_size.assign(6,0);
 
 2317    for (
const auto &var:this->
vars) {
 
 2319        if(var->rank == ll_rank) {
 
 2320            if(var->name == 
"lat") {
 
 2329            else if(var->name == 
"lon") {
 
 2338            else if(var->name == 
"latitude"){
 
 2346            else if(var->name == 
"longitude"){
 
 2355            else if(var->name == 
"Latitude"){
 
 2364            else if(var->name == 
"Longitude"){
 
 2374    int total_llflag = 0;
 
 2375    for (
int i = 0; i < ll_flag.size();i++)
 
 2380    if(1 == total_llflag) {
 
 2381        bool latlon_size_match = 
true;
 
 2383            for (
int size_index = 0; size_index <lat_size.size();size_index++) {
 
 2384                if(lat_size[size_index] != lon_size[size_index]){
 
 2385                    latlon_size_match = 
false;
 
 2391        if(
true ==  latlon_size_match) {
 
 2393            if(2 == ll_flag[0]) {
 
 2397            else if ( 2 == ll_flag[1]) {
 
 2398                gp_latname = 
"latitude";
 
 2399                gp_lonname = 
"longitude";
 
 2402            else if (2 == ll_flag[2]){
 
 2403                gp_latname = 
"Latitude";
 
 2404                gp_lonname = 
"Longitude";
 
 2414void GMFile::Add_Dim_Name_LatLon2D_General_Product()  {
 
 2416    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_LatLon2D_General_Product()"<<endl);
 
 2419    size_t latdimsize0 = 0;
 
 2420    size_t latdimsize1 = 0;
 
 2423    for (
const auto &var:this->
vars) {
 
 2425        set<hsize_t> fakedimsize;
 
 2426        pair<set<hsize_t>::iterator,
bool> setsizeret;
 
 2427        int num_dup_dim_size = 0;
 
 2428        for (
auto &dim:var->dims) {
 
 2429            Add_One_FakeDim_Name(dim);
 
 2430            setsizeret = fakedimsize.insert(dim->size);
 
 2433            if (
false == setsizeret.second){   
 
 2435                Adjust_Duplicate_FakeDim_Name2(dim,num_dup_dim_size);
 
 2439                if (
false == setsizeret.second)   
 
 2440                    Adjust_Duplicate_FakeDim_Name(dim);
 
 2446        if(var->name == gp_latname) {
 
 2447            if(var->rank != 2) {
 
 2448                throw4(
"coordinate variables ",gp_latname,
 
 2449                " must have rank 2 for the 2-D latlon case , the current rank is ",
 
 2463    for (
auto &var:this->
vars) {
 
 2464        int lat_dim0_index = 0;
 
 2465        int lat_dim1_index = 0;
 
 2466        bool has_lat_dims_size = 
false;
 
 2468        for (
unsigned int dim_index = 0; dim_index <var->dims.size(); dim_index++) {
 
 2471            if((var->dims[dim_index])->size == latdimsize0) {
 
 2474                lat_dim0_index = dim_index;
 
 2475                for(
unsigned int dim_index2 = dim_index+1;dim_index2 < var->dims.size();dim_index2++) {
 
 2476                    if((var->dims[dim_index2])->size == latdimsize1) {
 
 2477                        lat_dim1_index = dim_index2;
 
 2478                        has_lat_dims_size = 
true;
 
 2483            if(
true == has_lat_dims_size) 
 
 2487        if(
true == has_lat_dims_size) {
 
 2489            (var->dims[lat_dim0_index])->name = latdimname0;
 
 2493            (var->dims[lat_dim1_index])->name = latdimname1;
 
 2506    set<string>tempdimnamelist;
 
 2508    for (
const auto &var:this->
vars) {
 
 2509        for (
const auto &dim:var->dims) 
 
 2510            tempdimnamelist.insert(dim->name);
 
 2514    set<string>finaldimnamelist;
 
 2515    string finaldimname_base = 
"FakeDim";
 
 2517    for(
unsigned int i = 0; i<tempdimnamelist.size();i++) {
 
 2518        stringstream sfakedimindex;
 
 2520        string finaldimname = finaldimname_base + sfakedimindex.str();
 
 2521        finaldimnamelist.insert(finaldimname);
 
 2526    if(finaldimnamelist != tempdimnamelist) {
 
 2527        map<string,string> tempdimname_to_finaldimname;
 
 2528        auto tempit = tempdimnamelist.begin();
 
 2529        auto finalit = finaldimnamelist.begin();
 
 2530        while(tempit != tempdimnamelist.end()) {
 
 2531            tempdimname_to_finaldimname[*tempit] = *finalit;
 
 2537        for (
auto &var:this->
vars) {
 
 2538            for (
auto &dim:var->dims) {
 
 2539                if(tempdimname_to_finaldimname.find(dim->name) !=tempdimname_to_finaldimname.end())
 
 2540                    dim->name = tempdimname_to_finaldimname[dim->name];
 
 2542                    throw3(
"The  dimension names ",dim->name, 
"cannot be found in the dim. name list.");
 
 2548    dimnamelist.clear();
 
 2549    dimnamelist = finaldimnamelist;
 
 2552    dimname_to_dimsize.clear();
 
 2553    for (
const auto &var:this->
vars) {
 
 2554        for (
const auto &dim:var->dims) {
 
 2555            if(finaldimnamelist.find(dim->name)!=finaldimnamelist.end()) {
 
 2556                dimname_to_dimsize[dim->name] = dim->size;
 
 2557                dimname_to_unlimited[dim->name] = dim->unlimited_dim;
 
 2558                finaldimnamelist.erase(dim->name);
 
 2562        if(
true == finaldimnamelist.empty())
 
 2567    for (
auto &var:this->
vars) {
 
 2568        for (
auto &dim:var->dims) 
 
 2569            dim->newname = dim->name;    
 
 2576void GMFile::Add_Dim_Name_LatLon1D_Or_CoordAttr_General_Product()  {
 
 2578    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_LatLon1D_Or_CoordAttr_General_Product()"<<endl);
 
 2580    for (
auto &var:this->
vars) {
 
 2581        set<hsize_t> fakedimsize;
 
 2582        pair<set<hsize_t>::iterator,
bool> setsizeret;
 
 2583        int num_dup_dim_size = 0;
 
 2584        for (
auto &dim:var->dims) {
 
 2585            Add_One_FakeDim_Name(dim);
 
 2586            setsizeret = fakedimsize.insert(dim->size);
 
 2593            if (
false == setsizeret.second){   
 
 2595                Adjust_Duplicate_FakeDim_Name2(dim,num_dup_dim_size);
 
 2599                if (
false == setsizeret.second){   
 
 2601                    Adjust_Duplicate_FakeDim_Name(dim,num_dup_dim_size);
 
 2609for (vector<Var *>::iterator irv = this->
vars.begin();
 
 2610        irv != this->vars.end(); ++irv) {
 
 2611cerr<<
"Var name is "<<(*irv)->newname<<endl;
 
 2612         for (vector<Dimension *>::iterator ird= (*irv)->dims.begin();
 
 2613            ird != (*irv)->dims.end(); ++ird) 
 
 2614cerr<<
"Dimension name is "<<(*ird)->newname <<endl;
 
 2621void GMFile::Add_Dim_Name_Dimscale_General_Product()  {
 
 2623    BESDEBUG(
"h5", 
"Coming to Add_Dim_Name_Dimscale_General_Product()"<<endl);
 
 2625    pair<set<string>::iterator,
bool> setret;
 
 2626    this->iscoard = 
true;
 
 2628    for (
const auto &var:this->
vars) {
 
 2631        Handle_UseDimscale_Var_Dim_Names_General_Product(var);
 
 2634        for (
const auto &dim:var->dims) { 
 
 2635            setret = dimnamelist.insert(dim->name);
 
 2636            if (
true == setret.second) 
 
 2637                Insert_One_NameSizeMap_Element(dim->name,dim->size,dim->unlimited_dim);
 
 2641    if (
true == dimnamelist.empty()) 
 
 2642        throw1(
"This product should have the dimension names, but no dimension names are found");
 
 2647void GMFile::Handle_UseDimscale_Var_Dim_Names_General_Product(
Var *var)  {
 
 2649    BESDEBUG(
"h5", 
"Coming to Handle_UseDimscale_Var_Dim_Names_General_Product()"<<endl);
 
 2650    const Attribute* dimlistattr = 
nullptr;
 
 2651    bool has_dimlist = 
false;
 
 2652    bool has_dimclass   = 
false;
 
 2654    for(
const auto &attr:var->attrs) {
 
 2655        if (
"DIMENSION_LIST" == attr->name) {
 
 2659        if (
"CLASS" == attr->name) {
 
 2661            Retrieve_H5_Attr_Value(attr,var->fullpath);
 
 2663            class_value.resize(attr->value.size());
 
 2664            copy(attr->value.begin(),attr->value.end(),class_value.begin());
 
 2668            if (0 == class_value.compare(0,15,
"DIMENSION_SCALE")) {
 
 2669                has_dimclass = 
true;
 
 2677    if (
true == has_dimlist) 
 
 2678        Add_UseDimscale_Var_Dim_Names_General_Product(var,dimlistattr);
 
 2681    else if(
true == has_dimclass) {
 
 2682        if (var->dims.size() !=1) 
 
 2683           throw2(
"Currently dimension scale dataset must be 1 dimension, this is not true for the dataset ",
 
 2688        (var->dims)[0]->name = var->fullpath;
 
 2689        (var->dims)[0]->newname = var->fullpath;
 
 2690        pair<set<string>::iterator,
bool> setret;
 
 2691        setret = dimnamelist.insert((var->dims)[0]->name);
 
 2692        if (
true == setret.second) 
 
 2693            Insert_One_NameSizeMap_Element((var->dims)[0]->name,(var->dims)[0]->size,(var->dims)[0]->unlimited_dim);
 
 2699        set<hsize_t> fakedimsize;
 
 2700        pair<set<hsize_t>::iterator,
bool> setsizeret;
 
 2701        for (
auto &dim:var->dims) {
 
 2702            Add_One_FakeDim_Name(dim);
 
 2703            setsizeret = fakedimsize.insert(dim->size);
 
 2705            if (
false == setsizeret.second)   
 
 2706                Adjust_Duplicate_FakeDim_Name(dim);
 
 2713void GMFile::Add_UseDimscale_Var_Dim_Names_General_Product(
const Var *var,
const Attribute*dimlistattr) 
 
 2716    BESDEBUG(
"h5", 
"Coming to Add_UseDimscale_Var_Dim_Names_General_Product()"<<endl);
 
 2717    ssize_t objnamelen = -1;
 
 2723    vector<hvl_t> vlbuf;
 
 2727    hid_t atype_id = -1;
 
 2728    hid_t amemtype_id = -1;
 
 2729    hid_t aspace_id = -1;
 
 2730    hid_t ref_dset = -1;
 
 2732    if(
nullptr == dimlistattr) 
 
 2733        throw2(
"Cannot obtain the dimension list attribute for variable ",var->name);
 
 2735    else if (0==var->rank) 
 
 2736        throw2(
"The number of dimension should NOT be 0 for the variable ",var->name);
 
 2741        vlbuf.resize(var->rank);
 
 2743        dset_id = H5Dopen(this->fileid,(var->fullpath).c_str(),H5P_DEFAULT);
 
 2745            throw2(
"Cannot open the dataset ",var->fullpath);
 
 2747        attr_id = H5Aopen(dset_id,(dimlistattr->name).c_str(),H5P_DEFAULT);
 
 2749            throw4(
"Cannot open the attribute ",dimlistattr->name,
" of HDF5 dataset ",var->fullpath);
 
 2751        atype_id = H5Aget_type(attr_id);
 
 2753            throw4(
"Cannot obtain the datatype of the attribute ",dimlistattr->name,
" of HDF5 dataset ",var->fullpath);
 
 2755        amemtype_id = H5Tget_native_type(atype_id, H5T_DIR_ASCEND);
 
 2757        if (amemtype_id < 0) 
 
 2758            throw2(
"Cannot obtain the memory datatype for the attribute ",dimlistattr->name);
 
 2761        if (H5Aread(attr_id,amemtype_id,vlbuf.data()) <0)
 
 2762            throw2(
"Cannot obtain the referenced object for the variable ",var->name);
 
 2765        vector<char> objname;
 
 2766        int vlbuf_index = 0;
 
 2769        for (
auto &dim:var->dims) {
 
 2771            if(vlbuf[vlbuf_index].p== 
nullptr) 
 
 2772                throw4(
"The dimension doesn't exist. Var name is ",var->name,
"; the dimension index is ",vlbuf_index);
 
 2773            rbuf =((hobj_ref_t*)vlbuf[vlbuf_index].p)[0];
 
 2774            if ((ref_dset = H5RDEREFERENCE(attr_id, H5R_OBJECT, &rbuf)) < 0) 
 
 2775                throw2(
"Cannot dereference from the DIMENSION_LIST attribute  for the variable ",var->name);
 
 2777            if ((objnamelen= H5Iget_name(ref_dset,
nullptr,0))<=0) 
 
 2778                throw2(
"Cannot obtain the dataset name dereferenced from the DIMENSION_LIST attribute  for the variable ",var->name);
 
 2779            objname.resize(objnamelen+1);
 
 2780            if ((objnamelen= H5Iget_name(ref_dset,objname.data(),objnamelen+1))<=0)
 
 2781                throw2(
"Cannot obtain the dataset name dereferenced from the DIMENSION_LIST attribute  for the variable ",var->name);
 
 2783            auto objname_str = string(objname.begin(),objname.end());
 
 2789            string trim_objname = objname_str.substr(0,objnamelen);
 
 2790            dim->name = string(trim_objname.begin(),trim_objname.end());
 
 2792            pair<set<string>::iterator,
bool> setret;
 
 2793            setret = dimnamelist.insert(dim->name);
 
 2794            if (
true == setret.second) 
 
 2795               Insert_One_NameSizeMap_Element(dim->name,dim->size,dim->unlimited_dim);
 
 2796            dim->newname = dim->name;
 
 2805        if(vlbuf.empty() == 
false) {
 
 2807            if ((aspace_id = H5Aget_space(attr_id)) < 0)
 
 2808                throw2(
"Cannot get hdf5 dataspace id for the attribute ",dimlistattr->name);
 
 2810            if (H5Dvlen_reclaim(amemtype_id,aspace_id,H5P_DEFAULT,(
void*)vlbuf.data())<0)
 
 2811                throw2(
"Cannot successfully clean up the variable length memory for the variable ",var->name);
 
 2813            H5Sclose(aspace_id);
 
 2818        H5Tclose(amemtype_id);
 
 2828        if(amemtype_id != -1)
 
 2829            H5Tclose(amemtype_id);
 
 2832            H5Sclose(aspace_id);
 
 2849    BESDEBUG(
"h5", 
"GMFile:: Coming to Handle_CVar()"<<endl);
 
 2855    if (General_Product == this->product_type ||
 
 2856        ACOS_L2S_OR_OCO2_L1B == this->product_type) {
 
 2857        if (GENERAL_DIMSCALE == this->gproduct_pattern)
 
 2858            Handle_CVar_Dimscale_General_Product();
 
 2859        else if (GENERAL_LATLON1D == this->gproduct_pattern) 
 
 2860            Handle_CVar_LatLon1D_General_Product();
 
 2861        else if (GENERAL_LATLON2D == this->gproduct_pattern)
 
 2862            Handle_CVar_LatLon2D_General_Product();
 
 2866    else if (Mea_SeaWiFS_L2 == this->product_type ||
 
 2867        Mea_SeaWiFS_L3 == this->product_type) 
 
 2868        Handle_CVar_Mea_SeaWiFS();
 
 2869    else if (Aqu_L3 == this->product_type) 
 
 2870        Handle_CVar_Aqu_L3(); 
 
 2871    else if (OBPG_L3 == this->product_type)
 
 2872        Handle_CVar_OBPG_L3();
 
 2873    else if (OSMAPL2S == this->product_type) 
 
 2874        Handle_CVar_OSMAPL2S();
 
 2875    else if (Mea_Ozone == this->product_type) 
 
 2876        Handle_CVar_Mea_Ozone();
 
 2877    else if (GPMS_L3 == this->product_type || GPMM_L3 == this->product_type 
 
 2878            || GPM_L3_New == this->product_type ) 
 
 2879        Handle_CVar_GPM_L3();
 
 2880    else if (GPM_L1 == this->product_type)
 
 2881        Handle_CVar_GPM_L1();
 
 
 2885void GMFile::Handle_CVar_GPM_L1()  {
 
 2887    BESDEBUG(
"h5", 
"Coming to Handle_CVar_GPM_L1()"<<endl);
 
 2891                irv != this->vars.end(); ++irv) {
 
 2892        if((*irv)->name==
"AlgorithmRuntimeInfo") {
 
 2894            this->vars.erase(irv); 
 
 2907    set<string> ll_dim_set;
 
 2908    for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ) {
 
 2909        if((*irv)->rank == 2 && (*irv)->name == 
"Latitude") {
 
 2910            size_t lat_pos = (*irv)->fullpath.rfind(
"Latitude");
 
 2911            string lat_path = (*irv)->fullpath.substr(0,lat_pos);
 
 2912            auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 2913            auto GMcvar = GMcvar_unique.release();
 
 2914            GMcvar->cfdimname = lat_path + ((*irv)->dims)[0]->name;    
 
 2915            ll_dim_set.insert(((*irv)->dims)[0]->name);
 
 2916            GMcvar->cvartype = CV_EXIST;
 
 2917            GMcvar->product_type = product_type;
 
 2918            this->cvars.push_back(GMcvar);
 
 2920            irv = this->
vars.erase(irv);
 
 2923        if((*irv)->rank == 2 && (*irv)->name == 
"Longitude") {
 
 2924            size_t lon_pos = (*irv)->fullpath.rfind(
"Longitude");
 
 2925            string lon_path = (*irv)->fullpath.substr(0,lon_pos);
 
 2926            auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 2927            auto GMcvar = GMcvar_unique.release();
 
 2928            GMcvar->cfdimname = lon_path + ((*irv)->dims)[1]->name;    
 
 2929            ll_dim_set.insert(((*irv)->dims)[1]->name);
 
 2930            GMcvar->cvartype = CV_EXIST;
 
 2931            GMcvar->product_type = product_type;
 
 2932            this->cvars.push_back(GMcvar);
 
 2934            irv = this->
vars.erase(irv);
 
 2945    for (map<string,hsize_t>::const_iterator itd = dimname_to_dimsize.begin();
 
 2946                                            itd!=dimname_to_dimsize.end();++itd) {
 
 2949        if((ll_dim_set.find(itd->first)) == ll_dim_set.end()) {
 
 2950            auto GMcvar_unique = make_unique<GMCVar>();
 
 2951            auto GMcvar = GMcvar_unique.release();
 
 2952            Create_Missing_CV(GMcvar,itd->first);
 
 2953            this->cvars.push_back(GMcvar);
 
 2960void GMFile::Handle_CVar_GPM_L3() {
 
 2962    BESDEBUG(
"h5", 
"Coming to Handle_CVar_GPM_L3()"<<endl);
 
 2967    for (map<string,hsize_t>::const_iterator itd = dimname_to_dimsize.begin();
 
 2968                                            itd!=dimname_to_dimsize.end();++itd) {
 
 2970        auto GMcvar_unique = make_unique<GMCVar>();
 
 2971        auto GMcvar = GMcvar_unique.release();
 
 2972        if(
"nlon" == itd->first || 
"nlat" == itd->first
 
 2973           || 
"lnH" == itd->first || 
"ltH" == itd->first
 
 2974           || 
"lnL" == itd->first || 
"ltL" == itd->first) {
 
 2975            GMcvar->name = itd->first;
 
 2976            GMcvar->newname = GMcvar->name;
 
 2977            GMcvar->fullpath = GMcvar->name;
 
 2979            GMcvar->dtype = H5FLOAT32;
 
 2980            auto gmcvar_dim_unique = make_unique<Dimension>(itd->second);
 
 2981            auto gmcvar_dim = gmcvar_dim_unique.release();
 
 2982            gmcvar_dim->name = GMcvar->name;
 
 2983            gmcvar_dim->newname = gmcvar_dim->name;
 
 2984            GMcvar->dims.push_back(gmcvar_dim); 
 
 2985            GMcvar->cfdimname = gmcvar_dim->name;
 
 2986            if (
"nlat" ==GMcvar->name || 
"ltH" == GMcvar->name 
 
 2987                 || 
"ltL" == GMcvar->name) 
 
 2988                GMcvar->cvartype = CV_LAT_MISS;
 
 2989            else if (
"nlon" == GMcvar->name || 
"lnH" == GMcvar->name
 
 2990                 || 
"lnL" == GMcvar->name) 
 
 2991                GMcvar->cvartype = CV_LON_MISS;
 
 2992            GMcvar->product_type = product_type;
 
 2994        else if ((
"nlayer" == itd->first && (28 == itd->second || 19 == itd->second)) ||
 
 2995                 (
"hgt" == itd->first && 5 == itd->second) ||
 
 2996                 (
"nalt" == itd->first && 5 == itd->second)){
 
 2997            GMcvar->name = itd->first;
 
 2998            GMcvar->newname = GMcvar->name;
 
 2999            GMcvar->fullpath = GMcvar->name;
 
 3001            GMcvar->dtype = H5FLOAT32;
 
 3002            auto gmcvar_dim_unique = make_unique<Dimension>(itd->second);
 
 3003            auto gmcvar_dim = gmcvar_dim_unique.release();
 
 3004            gmcvar_dim->name = GMcvar->name;
 
 3005            gmcvar_dim->newname = gmcvar_dim->name;
 
 3006            GMcvar->dims.push_back(gmcvar_dim);
 
 3007            GMcvar->cfdimname = gmcvar_dim->name;
 
 3008            GMcvar->cvartype  = CV_SPECIAL;
 
 3009            GMcvar->product_type = product_type;
 
 3012            Create_Missing_CV(GMcvar,itd->first);
 
 3013        this->cvars.push_back(GMcvar);
 
 3018void GMFile::Handle_CVar_Mea_SeaWiFS() {
 
 3020    BESDEBUG(
"h5", 
"Coming to Handle_CVar_Mea_SeaWiFS()"<<endl);
 
 3021    pair<set<string>::iterator,
bool> setret;
 
 3022    set<string>tempdimnamelist = dimnamelist;
 
 3024    for (
const auto &dimname:dimnamelist) {
 
 3025        for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ) {
 
 3026            if (dimname== (*irv)->fullpath) {
 
 3028                if (!iscoard && ((
"/natrack" == dimname) 
 
 3029                                 || 
"/nxtrack" == dimname)) {
 
 3034                if((*irv)->dims.size()!=1) 
 
 3035                    throw3(
"Coard coordinate variable ",(*irv)->name, 
"is not 1D");
 
 3038                tempdimnamelist.erase(dimname);
 
 3039                auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 3040                auto GMcvar = GMcvar_unique.release();
 
 3041                GMcvar->cfdimname = dimname;
 
 3042                GMcvar->cvartype = CV_EXIST;
 
 3043                GMcvar->product_type = product_type;
 
 3044                this->cvars.push_back(GMcvar); 
 
 3046                irv = this->
vars.erase(irv);
 
 3048            else if(
false == iscoard) { 
 
 3050                if (((dimname ==
"/natrack") && ((*irv)->fullpath == 
"/latitude"))
 
 3051                  ||((dimname ==
"/nxtrack") && ((*irv)->fullpath == 
"/longitude"))) {
 
 3052                    tempdimnamelist.erase(dimname);
 
 3053                    auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 3054                    auto GMcvar = GMcvar_unique.release();
 
 3055                    GMcvar->cfdimname = dimname;    
 
 3056                    GMcvar->cvartype = CV_EXIST;
 
 3057                    GMcvar->product_type = product_type;
 
 3058                    this->cvars.push_back(GMcvar);
 
 3060                    irv = this->
vars.erase(irv);
 
 3076    for (
auto &dimname:tempdimnamelist) {
 
 3077        auto GMcvar_unique = make_unique<GMCVar>();
 
 3078        auto GMcvar = GMcvar_unique.release();
 
 3079        Create_Missing_CV(GMcvar,dimname);
 
 3080        this->cvars.push_back(GMcvar);
 
 3085void GMFile::Handle_CVar_OSMAPL2S()  {
 
 3087    BESDEBUG(
"h5", 
"Coming to Handle_CVar_OSMAPL2S()"<<endl);
 
 3088    pair<set<string>::iterator,
bool> setret;
 
 3089    set<string>tempdimnamelist = dimnamelist;
 
 3091    string key0 = 
"_lat";
 
 3092    string key1 = 
"_lon";
 
 3093    string osmapl2sdim0 =
"YDim";
 
 3094    string osmapl2sdim1 =
"XDim";
 
 3096    bool foundkey0 = 
false;
 
 3097    bool foundkey1 = 
false;
 
 3101    for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ) {
 
 3103        tempvarname = (*irv)->name;
 
 3105        if ((tempvarname.size() > key0.size())&&
 
 3106                (key0 == tempvarname.substr(tempvarname.size()-key0.size(),key0.size()))){
 
 3110            if (dimnamelist.find(osmapl2sdim0)== dimnamelist.end()) 
 
 3111                throw5(
"variable ",tempvarname,
" must have dimension ",osmapl2sdim0,
" , but not found ");
 
 3113            tempdimnamelist.erase(osmapl2sdim0);
 
 3114            auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 3115            auto GMcvar = GMcvar_unique.release();
 
 3116            GMcvar->newname = GMcvar->name; 
 
 3117            GMcvar->cfdimname = osmapl2sdim0;    
 
 3118            GMcvar->cvartype = CV_EXIST;
 
 3119            GMcvar->product_type = product_type;
 
 3120            this->cvars.push_back(GMcvar);
 
 3122            irv = this->
vars.erase(irv);
 
 3125        else if ((tempvarname.size() > key1.size())&& 
 
 3126                (key1 == tempvarname.substr(tempvarname.size()-key1.size(),key1.size()))){
 
 3130            if (dimnamelist.find(osmapl2sdim1)== dimnamelist.end()) 
 
 3131                throw5(
"variable ",tempvarname,
" must have dimension ",osmapl2sdim1,
" , but not found ");
 
 3133            tempdimnamelist.erase(osmapl2sdim1);
 
 3135            auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 3136            auto GMcvar = GMcvar_unique.release();
 
 3137            GMcvar->newname = GMcvar->name;
 
 3138            GMcvar->cfdimname = osmapl2sdim1;    
 
 3139            GMcvar->cvartype = CV_EXIST;
 
 3140            GMcvar->product_type = product_type;
 
 3141            this->cvars.push_back(GMcvar);
 
 3143            irv = this->
vars.erase(irv);
 
 3148        if (
true == foundkey0 && 
true == foundkey1) 
 
 3152    for (
auto irs = tempdimnamelist.begin(); irs != tempdimnamelist.end();++irs) {
 
 3154        auto GMcvar_unique = make_unique<GMCVar>();
 
 3155        auto GMcvar = GMcvar_unique.release();
 
 3156        Create_Missing_CV(GMcvar,*irs);
 
 3157        this->cvars.push_back(GMcvar);
 
 3163void GMFile::Handle_CVar_Aqu_L3()  {
 
 3165    BESDEBUG(
"h5", 
"Coming to Handle_CVar_Aqu_L3()"<<endl);
 
 3167    for (
const auto &var:this->
vars) {
 
 3169        if ( 
"l3m_data" == var->name) { 
 
 3170            for (
const auto &dim:var->dims) {
 
 3172                auto GMcvar_unique = make_unique<GMCVar>();
 
 3173                auto GMcvar = GMcvar_unique.release();
 
 3174                GMcvar->name = dim->name;
 
 3175                GMcvar->newname = GMcvar->name;
 
 3176                GMcvar->fullpath = GMcvar->name;
 
 3178                GMcvar->dtype = H5FLOAT32;
 
 3179                auto gmcvar_dim_unique = make_unique<Dimension>(dim->size);
 
 3180                auto gmcvar_dim = gmcvar_dim_unique.release();
 
 3181                gmcvar_dim->name = GMcvar->name;
 
 3182                gmcvar_dim->newname = gmcvar_dim->name;
 
 3183                GMcvar->dims.push_back(gmcvar_dim); 
 
 3184                GMcvar->cfdimname = gmcvar_dim->name;
 
 3185                if (
"lat" ==GMcvar->name ) GMcvar->cvartype = CV_LAT_MISS;
 
 3186                if (
"lon" == GMcvar->name ) GMcvar->cvartype = CV_LON_MISS;
 
 3187                GMcvar->product_type = product_type;
 
 3188                this->cvars.push_back(GMcvar);
 
 3196void GMFile::Handle_CVar_Mea_Ozone() {
 
 3198    BESDEBUG(
"h5", 
"Coming to Handle_CVar_Mea_Ozone()"<<endl);
 
 3199    pair<set<string>::iterator,
bool> setret;
 
 3200    set<string>tempdimnamelist = dimnamelist;
 
 3202    if(
false == iscoard) 
 
 3203        throw1(
"Measure Ozone level 3 zonal average product must follow COARDS conventions");
 
 3205    for (
const auto &dimname:dimnamelist) {
 
 3206        for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ) {
 
 3207            if (dimname== (*irv)->fullpath) {
 
 3209                if((*irv)->dims.size()!=1) 
 
 3210                    throw3(
"Coard coordinate variable",(*irv)->name, 
"is not 1D");
 
 3213                tempdimnamelist.erase(dimname);
 
 3214                auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 3215                auto GMcvar = GMcvar_unique.release();
 
 3216                GMcvar->cfdimname = dimname;
 
 3217                GMcvar->cvartype = CV_EXIST;
 
 3218                GMcvar->product_type = product_type;
 
 3219                this->cvars.push_back(GMcvar); 
 
 3221                irv = this->
vars.erase(irv);
 
 3229    for (
auto irs = tempdimnamelist.begin(); irs != tempdimnamelist.end();irs++) {
 
 3231        auto GMcvar_unique = make_unique<GMCVar>();
 
 3232        auto GMcvar = GMcvar_unique.release();
 
 3233        Create_Missing_CV(GMcvar,*irs);
 
 3234        this->cvars.push_back(GMcvar);
 
 3239void GMFile::Handle_CVar_Dimscale_General_Product()  {
 
 3241    BESDEBUG(
"h5", 
"Coming to Handle_CVar_Dimscale_General_Product"<<endl);
 
 3242    pair<set<string>::iterator,
bool> setret;
 
 3243    set<string>tempdimnamelist = dimnamelist;
 
 3245    for (
const auto &dimname:dimnamelist) {
 
 3246        for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ) {
 
 3249            if (dimname== (*irv)->fullpath) {
 
 3250                if((*irv)->dims.size()!=1) 
 
 3251                    throw3(
"COARDS coordinate variable",(*irv)->name, 
"is not 1D");
 
 3254                tempdimnamelist.erase(dimname);
 
 3256                auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 3257                auto GMcvar = GMcvar_unique.release();
 
 3258                GMcvar->cfdimname = dimname;
 
 3261                bool is_netcdf_dimension = Is_netCDF_Dimension(*irv);
 
 3265                if (
true == is_netcdf_dimension)
 
 3266                   GMcvar->cvartype = CV_FILLINDEX;
 
 3268                    GMcvar->cvartype = CV_EXIST;
 
 3269                GMcvar->product_type = product_type;
 
 3270                this->cvars.push_back(GMcvar); 
 
 3272                irv = this->
vars.erase(irv);
 
 3281    Update_M2DLatLon_Dimscale_CVs();
 
 3284    for (
auto &dimname:tempdimnamelist) {
 
 3285        if ((this->have_nc4_non_coord == 
false) ||
 
 3286            (nc4_sdimv_dv_path.find(dimname) == nc4_sdimv_dv_path.end())) { 
 
 3288            auto GMcvar_unique = make_unique<GMCVar>();
 
 3289            auto GMcvar = GMcvar_unique.release();
 
 3290            Create_Missing_CV(GMcvar,dimname);
 
 3291            this->cvars.push_back(GMcvar);
 
 3298for (set<string>::iterator irs = dimnamelist.begin();
 
 3299        irs != dimnamelist.end();irs++) {
 
 3300cerr<<
"dimension name is "<<(*irs)<<endl;
 
 3309void GMFile::Update_M2DLatLon_Dimscale_CVs()  {
 
 3311    BESDEBUG(
"h5", 
"Coming to Update_M2DLatLon_Dimscale_CVs()"<<endl);
 
 3313    if(
false == Check_1DGeolocation_Dimscale()) {
 
 3316        vector<GMCVar*> tempcvar_1dlat;
 
 3317        vector<GMCVar*> tempcvar_1dlon;
 
 3320        Obtain_1DLatLon_CVs(tempcvar_1dlat,tempcvar_1dlon);
 
 3323        vector<Var*> tempcvar_2dlat;
 
 3324        vector<Var*> tempcvar_2dlon;
 
 3330        map<string,int> latlon2d_path_to_index;
 
 3333        Obtain_2DLatLon_Vars(tempcvar_2dlat,tempcvar_2dlon,latlon2d_path_to_index);
 
 3336for(vector<GMCVar *>::iterator irv = tempcvar_1dlat.begin();irv != tempcvar_1dlat.end();++irv)
 
 3337cerr<<
"1-D lat variable full path is "<<(*irv)->fullpath <<endl;
 
 3338for(vector<GMCVar *>::iterator irv = tempcvar_1dlon.begin();irv != tempcvar_1dlon.end();++irv)
 
 3339cerr<<
"1-D lon variable full path is "<<(*irv)->fullpath <<endl;
 
 3341for(vector<Var *>::iterator irv = tempcvar_2dlat.begin();irv != tempcvar_2dlat.end();++irv)
 
 3342cerr<<
"2-D lat variable full path is "<<(*irv)->fullpath <<endl;
 
 3343for(vector<Var *>::iterator irv = tempcvar_2dlon.begin();irv != tempcvar_2dlon.end();++irv)
 
 3344cerr<<
"2-D lon variable full path is "<<(*irv)->fullpath <<endl;
 
 3348        Obtain_2DLLVars_With_Dims_not_1DLLCVars(tempcvar_2dlat,tempcvar_2dlon,tempcvar_1dlat,tempcvar_1dlon,latlon2d_path_to_index);
 
 3351for(vector<Var *>::iterator irv = tempcvar_2dlat.begin();irv != tempcvar_2dlat.end();++irv)
 
 3352cerr<<
"2-D Left lat variable full path is "<<(*irv)->fullpath <<endl;
 
 3353for(vector<Var *>::iterator irv = tempcvar_2dlon.begin();irv != tempcvar_2dlon.end();++irv)
 
 3354cerr<<
"2-D Left lon variable full path is "<<(*irv)->fullpath <<endl;
 
 3359        Obtain_2DLLCVar_Candidate(tempcvar_2dlat,tempcvar_2dlon,latlon2d_path_to_index);
 
 3362for(vector<Var *>::iterator irv = tempcvar_2dlat.begin();irv != tempcvar_2dlat.end();++irv)
 
 3363cerr<<
"Final candidate 2-D Left lat variable full path is "<<(*irv)->fullpath <<endl;
 
 3364for(vector<Var *>::iterator irv = tempcvar_2dlon.begin();irv != tempcvar_2dlon.end();++irv)
 
 3365cerr<<
"Final candidate 2-D Left lon variable full path is "<<(*irv)->fullpath <<endl;
 
 3370        vector<int> var2d_index;
 
 3371        for (map<string,int>::const_iterator it= latlon2d_path_to_index.begin();it!=latlon2d_path_to_index.end();++it)
 
 3372            var2d_index.push_back(it->second);
 
 3374        Remove_2DLLCVar_Final_Candidate_from_Vars(var2d_index);
 
 3377        if(tempcvar_2dlat.empty()==
false)
 
 3382        set<string>dim_names_2d_cvs;
 
 3384        for (
auto &cvar_lat:tempcvar_2dlat){
 
 3386            auto lat_unique = make_unique<GMCVar>(cvar_lat);
 
 3387            auto lat = lat_unique.release();
 
 3390            dim_names_2d_cvs.insert(lat->cfdimname);
 
 3391            lat->cvartype = CV_EXIST;
 
 3392            lat->product_type = product_type;
 
 3393            this->cvars.push_back(lat);
 
 3395        for (
auto &cvar_lon:tempcvar_2dlon) {
 
 3397            auto lon_unique = make_unique<GMCVar>(cvar_lon);
 
 3398            auto lon = lon_unique.release();
 
 3400            lon->cfdimname = cvar_lon->getDimensions()[1]->name;
 
 3401            dim_names_2d_cvs.insert(lon->cfdimname);
 
 3402            lon->cvartype = CV_EXIST;
 
 3403            lon->product_type = product_type;
 
 3404            this->cvars.push_back(lon);
 
 3410        for(
auto ircv= this->cvars.begin();ircv !=this->cvars.end();) {
 
 3411            if(1 == (*ircv)->rank) {
 
 3412                if(dim_names_2d_cvs.find((*ircv)->cfdimname)!=dim_names_2d_cvs.end()) {
 
 3413                    if(CV_FILLINDEX == (*ircv)->cvartype) {
 
 3415                        ircv = this->cvars.erase(ircv);
 
 3417                    else if(CV_EXIST == (*ircv)->cvartype) {
 
 3420                        auto var_unique = make_unique<Var>(*ircv);
 
 3421                        auto var = var_unique.release();
 
 3422                        this->
vars.push_back(var);
 
 3426                        ircv = this->cvars.erase(ircv);
 
 3430                        if(CV_LAT_MISS == (*ircv)->cvartype) 
 
 3431                            throw3(
"For the 2-D lat/lon case, the latitude dimension name ",(*ircv)->cfdimname, 
"is a coordinate variable of type CV_LAT_MISS");
 
 3432                        else if(CV_LON_MISS == (*ircv)->cvartype)
 
 3433                            throw3(
"For the 2-D lat/lon case, the latitude dimension name ",(*ircv)->cfdimname, 
"is a coordinate variable of type CV_LON_MISS");
 
 3434                        else if(CV_NONLATLON_MISS == (*ircv)->cvartype)
 
 3435                            throw3(
"For the 2-D lat/lon case, the latitude dimension name ",(*ircv)->cfdimname, 
"is a coordinate variable of type CV_NONLATLON_MISS");
 
 3436                        else if(CV_MODIFY == (*ircv)->cvartype)
 
 3437                            throw3(
"For the 2-D lat/lon case, the latitude dimension name ",(*ircv)->cfdimname, 
"is a coordinate variable of type CV_MODIFY");
 
 3438                        else if(CV_SPECIAL == (*ircv)->cvartype)
 
 3439                            throw3(
"For the 2-D lat/lon case, the latitude dimension name ",(*ircv)->cfdimname, 
"is a coordinate variable of type CV_SPECIAL");
 
 3441                            throw3(
"For the 2-D lat/lon case, the latitude dimension name ",(*ircv)->cfdimname, 
"is a coordinate variable of type CV_UNSUPPORTED");
 
 3458for(set<string>::iterator irs = grp_cv_paths.begin();irs != grp_cv_paths.end();++irs) {
 
 3459cerr<<
"group path is "<< (*irs)<<endl;
 
 3466cerr<<
"File name is "<< this->path <<endl;
 
 3467cerr<<
"CV names are the following "<<endl;
 
 3468for (vector<GMCVar *>:: iterator i= this->cvars.begin(); i!=this->cvars.end(); ++i) 
 
 3469cerr<<(*i)->fullpath <<endl;
 
 3474        release_standalone_GMCVar_vector(tempcvar_1dlat);
 
 3475        release_standalone_GMCVar_vector(tempcvar_1dlon);
 
 3476        release_standalone_var_vector(tempcvar_2dlat);
 
 3477        release_standalone_var_vector(tempcvar_2dlon);
 
 3480for (vector<GMCVar *>:: iterator i= this->cvars.begin(); i!=this->cvars.end(); ++i) 
 
 3481cerr<<(*i)->fullpath <<endl;
 
 3488bool GMFile::Check_1DGeolocation_Dimscale()  {
 
 3490    BESDEBUG(
"h5", 
"Coming to Check_1DGeolocation_Dimscale()"<<endl);
 
 3491    bool has_only_1d_geolocation_cv = 
false;
 
 3492    bool has_1d_lat_cv_flag = 
false;
 
 3493    bool has_1d_lon_cv_flag = 
false;
 
 3496    hsize_t lat_size = 0;
 
 3499    hsize_t lon_size = 0;
 
 3502    for (
const auto &cvar:this->cvars) {
 
 3504        if(cvar->cvartype == CV_EXIST) {
 
 3506            string attr_name =
"units";
 
 3507            string lat_unit_value = 
"degrees_north";
 
 3508            string lon_unit_value = 
"degrees_east";
 
 3510           for (
const auto &attr:cvar->attrs) {
 
 3512                if(
true == Is_Str_Attr(attr,cvar->fullpath,attr_name,lat_unit_value)) {
 
 3513                    lat_size = cvar->getDimensions()[0]->size;
 
 3514                    lat_dimname = cvar->getDimensions()[0]->name;
 
 3515                    has_1d_lat_cv_flag = 
true;
 
 3518                else if(
true == Is_Str_Attr(attr,cvar->fullpath,attr_name,lon_unit_value)){ 
 
 3519                    lon_size = cvar->getDimensions()[0]->size;
 
 3520                    lon_dimname = cvar->getDimensions()[0]->name;
 
 3521                    has_1d_lon_cv_flag = 
true;
 
 3530    if(
true == has_1d_lat_cv_flag ) {           
 
 3532        if(
true == has_1d_lon_cv_flag) {
 
 3535            if(
true == this->
groups.empty()) {
 
 3539                if(lat_size == lon_size) { 
 
 3540                    bool var_has_latdim = 
false;
 
 3541                    bool var_has_londim = 
false;
 
 3542                    for (
const auto &var:this->
vars) {
 
 3543                        if(var->rank >= 2) {
 
 3544                            for (
const auto &dim:var->dims) {
 
 3545                                if(dim->name == lat_dimname)
 
 3546                                    var_has_latdim = 
true;
 
 3547                                else if(dim->name == lon_dimname)
 
 3548                                    var_has_londim = 
true;
 
 3550                            if(
true == var_has_latdim && 
true == var_has_londim) {
 
 3551                                has_only_1d_geolocation_cv = 
true;
 
 3555                                var_has_latdim = 
false;
 
 3556                                var_has_londim = 
false;
 
 3562                    has_only_1d_geolocation_cv = 
true;
 
 3566                bool has_2d_latname_flag = 
false;
 
 3567                bool has_2d_lonname_flag = 
false;
 
 3568                for (
const auto &var:this->
vars) {
 
 3569                    if(var->rank == 2) { 
 
 3572                        if(
true == Is_geolatlon(var->name,
true))
 
 3573                            has_2d_latname_flag = 
true;
 
 3576                        else if(
true == Is_geolatlon(var->name,
false))
 
 3577                            has_2d_lonname_flag = 
true;
 
 3579                        if((
true == has_2d_latname_flag) && (
true == has_2d_lonname_flag))
 
 3584                if(has_2d_latname_flag != 
true || has_2d_lonname_flag != 
true) {
 
 3587                    has_2d_latname_flag = 
false;
 
 3588                    has_2d_lonname_flag = 
false;
 
 3590                    for (
const auto &var:this->
vars) { 
 
 3591                        if(var->rank == 2) {
 
 3592                            for (
const auto &attr:var->attrs) {
 
 3594                                if (
false == has_2d_latname_flag) {
 
 3597                                    has_2d_latname_flag = has_latlon_cf_units(attr,var->fullpath,
true);
 
 3598                                    if(
true == has_2d_latname_flag)
 
 3600                                    else if(
false == has_2d_lonname_flag) {
 
 3603                                        has_2d_lonname_flag = has_latlon_cf_units(attr,var->fullpath,
false);
 
 3604                                        if(
true == has_2d_lonname_flag)
 
 3608                                else if(
false == has_2d_lonname_flag) {
 
 3612                                    has_2d_lonname_flag = has_latlon_cf_units(attr,var->fullpath,
false);
 
 3613                                    if(
true == has_2d_lonname_flag)
 
 3617                            if(
true == has_2d_latname_flag && 
true == has_2d_lonname_flag)
 
 3624                if(has_2d_latname_flag != 
true  || has_2d_lonname_flag != 
true)
 
 3625                    has_only_1d_geolocation_cv = 
true;
 
 3630            has_only_1d_geolocation_cv = 
true;
 
 3636if(has_only_1d_geolocation_cv == 
true) 
 
 3637cerr <<
"has only 1D lat/lon CVs. "<<endl;
 
 3639cerr<<
"Possibly has 2D lat/lon CVs. "<<endl;
 
 3642    return has_only_1d_geolocation_cv;
 
 3648void GMFile::Obtain_1DLatLon_CVs(vector<GMCVar*> &cvar_1dlat,vector<GMCVar*> &cvar_1dlon) {
 
 3650    BESDEBUG(
"h5", 
"Coming to Obtain_1DLatLon_CVs()"<<endl);
 
 3651    for (
const auto &cvar:this->cvars) {
 
 3653        if (cvar->cvartype == CV_EXIST) {
 
 3655            string attr_name =
"units";
 
 3656            string lat_unit_value = 
"degrees_north";
 
 3657            string lon_unit_value = 
"degrees_east";
 
 3659           for (
const auto &attr:cvar->attrs) {
 
 3662                if(
true == Is_Str_Attr(attr,cvar->fullpath,attr_name,lat_unit_value)) {
 
 3663                    auto lat_unique = make_unique<GMCVar>(cvar);
 
 3664                    auto lat = lat_unique.release();
 
 3666                    lat->cvartype = cvar->cvartype;
 
 3667                    lat->product_type = cvar->product_type;
 
 3668                    cvar_1dlat.push_back(lat);
 
 3671                else if(
true == Is_Str_Attr(attr,cvar->fullpath,attr_name,lon_unit_value)){ 
 
 3672                    auto lon_unique = make_unique<GMCVar>(cvar);
 
 3673                    auto lon = lon_unique.release();
 
 3674                    lon->cfdimname = cvar->getDimensions()[0]->name;
 
 3675                    lon->cvartype = cvar->cvartype;
 
 3676                    lon->product_type = cvar->product_type;
 
 3677                    cvar_1dlon.push_back(lon);
 
 3688void GMFile::Obtain_2DLatLon_Vars(vector<Var*> &var_2dlat,vector<Var*> &var_2dlon,map<string,int> & latlon2d_path_to_index) {
 
 3690    BESDEBUG(
"h5", 
"Coming to Obtain_2DLatLon_Vars()"<<endl);
 
 3691    for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ++irv) {
 
 3692        if((*irv)->rank == 2) { 
 
 3695            if(
true == Is_geolatlon((*irv)->name,
true)) {
 
 3696                auto lat_unique = make_unique<Var>(*irv);
 
 3697                auto lat = lat_unique.release();
 
 3698                var_2dlat.push_back(lat);
 
 3699                latlon2d_path_to_index[(*irv)->fullpath]= distance(this->
vars.begin(),irv);
 
 3704                bool has_2dlat = 
false;
 
 3705                for (
const auto &attr:(*irv)->attrs) {
 
 3708                    if(
true == has_latlon_cf_units(attr,(*irv)->fullpath,
true)) {
 
 3709                        auto lat_unique = make_unique<Var>(*irv);
 
 3710                        auto lat = lat_unique.release();
 
 3711                        var_2dlat.push_back(lat);
 
 3712                        latlon2d_path_to_index[(*irv)->fullpath] = distance(this->
vars.begin(),irv);
 
 3718                if(
true == has_2dlat)
 
 3723            if (
true == Is_geolatlon((*irv)->name,
false)) {
 
 3724                latlon2d_path_to_index[(*irv)->fullpath] = distance(this->
vars.begin(),irv);
 
 3725                auto lon_unique = make_unique<Var>(*irv);
 
 3726                auto lon = lon_unique.release();
 
 3727                var_2dlon.push_back(lon);
 
 3730                for (
const auto &attr:(*irv)->attrs) {
 
 3733                    if(
true == has_latlon_cf_units(attr,(*irv)->fullpath,
false)) {
 
 3734                        latlon2d_path_to_index[(*irv)->fullpath] = distance(this->
vars.begin(),irv);
 
 3735                        auto lon_unique = make_unique<Var>(*irv);
 
 3736                        auto lon = lon_unique.release();
 
 3737                        var_2dlon.push_back(lon);
 
 3748void GMFile::Obtain_2DLLVars_With_Dims_not_1DLLCVars(vector<Var*> &var_2dlat,
 
 3749                                                     vector<Var*> &var_2dlon, 
 
 3750                                                     const vector<GMCVar*> &cvar_1dlat,
 
 3751                                                     const vector<GMCVar*> &cvar_1dlon,
 
 3752                                                     map<string,int> &latlon2d_path_to_index) {
 
 3754    BESDEBUG(
"h5", 
"Coming to Obtain_2DLLVars_With_Dims_not_1DLLCVars()"<<endl);
 
 3756    for(
auto irv = var_2dlat.begin();irv != var_2dlat.end();) {
 
 3757        bool remove_2dlat = 
false;
 
 3758        for(
const auto &lat:cvar_1dlat) {
 
 3759            for (
auto &dim:(*irv)->dims) {
 
 3762                    latlon2d_path_to_index.erase((*irv)->fullpath);
 
 3764                    irv = var_2dlat.erase(irv);
 
 3765                    remove_2dlat = 
true;
 
 3769            if(
true == remove_2dlat)
 
 3773        if(
false == remove_2dlat)
 
 3778    for(
auto irv = var_2dlon.begin();irv != var_2dlon.end();) {
 
 3779        bool remove_2dlon = 
false;
 
 3780        for(
const auto &lon:cvar_1dlon) {
 
 3781            for (
auto &dim:(*irv)->dims) {
 
 3782                if(dim->name == lon->getDimensions()[0]->name &&
 
 3783                   dim->size == lon->getDimensions()[0]->size) {
 
 3784                    latlon2d_path_to_index.erase((*irv)->fullpath);
 
 3786                    irv = var_2dlon.erase(irv);
 
 3787                    remove_2dlon = 
true;
 
 3791            if(
true == remove_2dlon)
 
 3795        if(
false == remove_2dlon)
 
 3802void GMFile::Obtain_2DLLCVar_Candidate(vector<Var*> &var_2dlat,
 
 3803                                       vector<Var*> &var_2dlon,
 
 3804                                       map<string,int>& latlon2d_path_to_index) {
 
 3805    BESDEBUG(
"h5", 
"Coming to Obtain_2DLLCVar_Candidate()"<<endl);
 
 3808    vector<string> lon2d_group_paths;
 
 3810    for (
auto irv_2dlat = var_2dlat.begin();irv_2dlat !=var_2dlat.end();) {
 
 3811        for (
const auto &lon:var_2dlon) {
 
 3812            if(((*irv_2dlat)->getDimensions()[0]->name == lon->getDimensions()[0]->name) &&
 
 3813               ((*irv_2dlat)->getDimensions()[0]->size == lon->getDimensions()[0]->size) &&
 
 3814               ((*irv_2dlat)->getDimensions()[1]->name == lon->getDimensions()[1]->name) &&
 
 3815               ((*irv_2dlat)->getDimensions()[1]->size == lon->getDimensions()[1]->size)) 
 
 3816                lon2d_group_paths.push_back(HDF5CFUtil::obtain_string_before_lastslash(lon->fullpath));
 
 3820        if (
true == lon2d_group_paths.empty()) {
 
 3821            latlon2d_path_to_index.erase((*irv_2dlat)->fullpath);         
 
 3823            irv_2dlat = var_2dlat.erase(irv_2dlat);
 
 3829            string lat2d_group_path = HDF5CFUtil::obtain_string_before_lastslash((*irv_2dlat)->fullpath);
 
 3832            short lon2d_has_lat2d_group_path_flag = 0;
 
 3833            for(
const auto &lon2d_group_path:lon2d_group_paths) {
 
 3834                if(lon2d_group_path==lat2d_group_path) 
 
 3835                    lon2d_has_lat2d_group_path_flag++;
 
 3839            if(0 == lon2d_has_lat2d_group_path_flag) {
 
 3840                latlon2d_path_to_index.erase((*irv_2dlat)->fullpath);
 
 3842                irv_2dlat = var_2dlat.erase(irv_2dlat);
 
 3845            else if (1== lon2d_has_lat2d_group_path_flag) {
 
 3852                grp_cv_paths.insert(lat2d_group_path);
 
 3853                latlon2d_path_to_index.erase((*irv_2dlat)->fullpath);
 
 3855                irv_2dlat = var_2dlat.erase(irv_2dlat);
 
 3860        lon2d_group_paths.clear();
 
 3864for(
auto irv_2dlat = var_2dlat.begin();irv_2dlat !=var_2dlat.end();++irv_2dlat) 
 
 3865cerr<<
"2 left 2-D lat variable full path is: "<<(*irv_2dlat)->fullpath <<endl;
 
 3871    vector<string> lat2d_group_paths;
 
 3874    for(
auto irv_2dlon = var_2dlon.begin();irv_2dlon !=var_2dlon.end();) {
 
 3875        for(
const auto &lat:var_2dlat) {
 
 3876            if((lat->
getDimensions()[0]->name == (*irv_2dlon)->getDimensions()[0]->name) &&
 
 3877               (lat->
getDimensions()[0]->size == (*irv_2dlon)->getDimensions()[0]->size) &&
 
 3878               (lat->
getDimensions()[1]->name == (*irv_2dlon)->getDimensions()[1]->name) &&
 
 3879               (lat->
getDimensions()[1]->size == (*irv_2dlon)->getDimensions()[1]->size)) 
 
 3880               lat2d_group_paths.push_back(HDF5CFUtil::obtain_string_before_lastslash(lat->fullpath)); 
 
 3886        if(lat2d_group_paths.empty()) {
 
 3887            latlon2d_path_to_index.erase((*irv_2dlon)->fullpath);
 
 3889            irv_2dlon = var_2dlon.erase(irv_2dlon);
 
 3892            string lon2d_group_path = HDF5CFUtil::obtain_string_before_lastslash((*irv_2dlon)->fullpath);
 
 3895            short lat2d_has_lon2d_group_path_flag = 0;
 
 3896            for(
const auto &lat2d_group_path:lat2d_group_paths) {
 
 3897                if(lat2d_group_path == lon2d_group_path) 
 
 3898                    lat2d_has_lon2d_group_path_flag++;
 
 3902            if(0 == lat2d_has_lon2d_group_path_flag) {
 
 3903                latlon2d_path_to_index.erase((*irv_2dlon)->fullpath);
 
 3905                irv_2dlon = var_2dlon.erase(irv_2dlon);
 
 3908            else if (1== lat2d_has_lon2d_group_path_flag) {
 
 3915                grp_cv_paths.insert(lon2d_group_path);
 
 3916                latlon2d_path_to_index.erase((*irv_2dlon)->fullpath);
 
 3918                irv_2dlon = var_2dlon.erase(irv_2dlon);
 
 3922        lat2d_group_paths.clear();
 
 3925for(vector<Var*>::iterator itv = var_2dlat.begin(); itv!= var_2dlat.end();++itv) {
 
 3926cerr<<
"Before unique, 2-D CV latitude name is "<<(*itv)->fullpath <<endl;
 
 3928for(vector<Var*>::iterator itv = var_2dlon.begin(); itv!= var_2dlon.end();++itv) {
 
 3929cerr<<
"Before unique, 2-D CV longitude name is "<<(*itv)->fullpath <<endl;
 
 3934    Obtain_unique_2dCV(var_2dlat,latlon2d_path_to_index);
 
 3935    Obtain_unique_2dCV(var_2dlon,latlon2d_path_to_index);
 
 3937for(vector<Var*>::iterator itv = var_2dlat.begin(); itv!= var_2dlat.end();++itv) {
 
 3938cerr<<
"2-D CV latitude name is "<<(*itv)->fullpath <<endl;
 
 3940for(vector<Var*>::iterator itv = var_2dlon.begin(); itv!= var_2dlon.end();++itv) {
 
 3941cerr<<
"2-D CV longitude name is "<<(*itv)->fullpath <<endl;
 
 3946    if(var_2dlat.size() != var_2dlon.size()) {
 
 3947        throw1(
"Error in generating 2-D lat/lon CVs. The size of 2d-lat should be the same as that of 2d-lon.");
 
 3954void GMFile::Obtain_unique_2dCV(vector<Var*> &var_ll,map<string,int>&latlon2d_path_to_index){
 
 3956    BESDEBUG(
"h5", 
"Coming to Obtain_unique_2dCV()"<<endl);
 
 3957    vector<bool> var_share_dims(var_ll.size(),
false);
 
 3959    for(
unsigned int i = 0; i <var_ll.size();i++) {
 
 3962        string var_ll_i_path = HDF5CFUtil::obtain_string_before_lastslash(var_ll[i]->fullpath);
 
 3965    for(
unsigned int j = i+1; j<var_ll.size();j++)   {
 
 3966            if((var_ll[i]->getDimensions()[0]->name == var_ll[j]->getDimensions()[0]->name)
 
 3967              ||(var_ll[i]->getDimensions()[0]->name == var_ll[j]->getDimensions()[1]->name)
 
 3968              ||(var_ll[i]->getDimensions()[1]->name == var_ll[j]->getDimensions()[0]->name)
 
 3969              ||(var_ll[i]->getDimensions()[1]->name == var_ll[j]->getDimensions()[1]->name)){
 
 3970                string var_ll_j_path = HDF5CFUtil::obtain_string_before_lastslash(var_ll[j]->fullpath);
 
 3977                if(var_ll_i_path.size() > var_ll_j_path.size()) {
 
 3981                    if(var_ll_i_path.compare(0,var_ll_j_path.size(),var_ll_j_path)==0) {
 
 3982                        var_share_dims[i] = 
true;
 
 3983                        grp_cv_paths.insert(var_ll_i_path);
 
 3986                        var_share_dims[i] = 
true;
 
 3987                        var_share_dims[j] = 
true;
 
 3989                        grp_cv_paths.insert(var_ll_i_path);
 
 3990                        grp_cv_paths.insert(var_ll_j_path);
 
 3993                else if (var_ll_i_path.size() == var_ll_j_path.size()) {
 
 3994                    var_share_dims[i] = 
true;      
 
 3995                    var_share_dims[j] = 
true;
 
 3996                   if(var_ll_i_path == var_ll_j_path) 
 
 3997                      grp_cv_paths.insert(var_ll_i_path);
 
 3999                      grp_cv_paths.insert(var_ll_i_path);
 
 4000                      grp_cv_paths.insert(var_ll_j_path);
 
 4006                    if(var_ll_j_path.compare(0,var_ll_i_path.size(),var_ll_i_path)==0) {
 
 4007                        var_share_dims[j] = 
true;
 
 4008                        grp_cv_paths.insert(var_ll_j_path);
 
 4011                        var_share_dims[i] = 
true;
 
 4012                        var_share_dims[j] = 
true;
 
 4014                        grp_cv_paths.insert(var_ll_i_path);
 
 4015                        grp_cv_paths.insert(var_ll_j_path);
 
 4025    for(
auto itv = var_ll.begin(); itv!= var_ll.end();) {
 
 4026        if(
true == var_share_dims[var_index]) {
 
 4027            latlon2d_path_to_index.erase((*itv)->fullpath);        
 
 4029            itv = var_ll.erase(itv);
 
 4040void GMFile::Remove_2DLLCVar_Final_Candidate_from_Vars(vector<int> &var2d_index)  {
 
 4042    BESDEBUG(
"h5", 
"Coming to Remove_2DLLCVar_Final_Candidate_from_Vars()"<<endl);
 
 4044    sort(var2d_index.begin(),var2d_index.end());
 
 4045    auto it = this->
vars.begin();
 
 4051    for (
unsigned int i = 0; i <var2d_index.size();i++) {
 
 4053           advance(it,var2d_index[i]);
 
 4055           advance(it,var2d_index[i]-var2d_index[i-1]-1);
 
 4057       if(it == this->
vars.end())
 
 4058          throw1(
"Out of range to obtain 2D lat/lon variables");
 
 4061          it = this->
vars.erase(it);
 
 4069bool GMFile::Check_Var_2D_CVars(
Var *var)
  const {
 
 4071    BESDEBUG(
"h5", 
"Coming to Check_Var_2D_CVars()"<<endl);
 
 4072    bool ret_value = 
true;
 
 4073    for (
const auto &cvar:this->cvars) {
 
 4075            short first_dim_index = 0;
 
 4076            short first_dim_times = 0;
 
 4077            short second_dim_index = 0;
 
 4078            short second_dim_times = 0;
 
 4079            for (
auto ird = var->dims.begin(); ird != var->dims.end(); ++ird) {
 
 4080                if((*ird)->name == (cvar->getDimensions()[0])->name) {
 
 4081                    first_dim_index = distance(var->dims.begin(),ird);  
 
 4084                else if((*ird)->name == (cvar->getDimensions()[1])->name) {
 
 4085                    second_dim_index = distance(var->dims.begin(),ird);
 
 4091            if(first_dim_times == 1 &&  second_dim_times == 1) { 
 
 4092                if(first_dim_index < second_dim_index) {
 
 4105bool GMFile::Flatten_VarPath_In_Coordinates_Attr(
Var *var)  {
 
 4107    BESDEBUG(
"h5", 
"Coming to Flatten_VarPath_In_Coordinates_Attr()"<<endl);
 
 4108    string co_attrname = 
"coordinates";
 
 4109    bool need_flatten_coor_attr = 
false;
 
 4110    string orig_coor_value;
 
 4111    string flatten_coor_value;
 
 4114    char backslash = 
'/';
 
 4116    for (
auto ira =var->attrs.begin(); ira !=var->attrs.end();) {
 
 4126        if((*ira)->name == co_attrname) {
 
 4127            Retrieve_H5_Attr_Value((*ira),var->fullpath);
 
 4128            string orig_attr_value((*ira)->value.begin(),(*ira)->value.end());
 
 4129            if(orig_attr_value.find_first_of(backslash)!=string::npos){ 
 
 4130                orig_coor_value = orig_attr_value;
 
 4131                need_flatten_coor_attr = 
true;
 
 4133                ira = var->attrs.erase(ira);
 
 4141    if(
true == need_flatten_coor_attr) {
 
 4144        size_t ele_start_pos = 0;
 
 4145        size_t cur_pos = orig_coor_value.find_first_of(sc);
 
 4146        while(cur_pos !=string::npos) {
 
 4147            string tempstr = orig_coor_value.substr(ele_start_pos,cur_pos-ele_start_pos);
 
 4148            tempstr = get_CF_string(tempstr);
 
 4149            flatten_coor_value += tempstr + sc;
 
 4150            ele_start_pos = cur_pos+1;
 
 4151            cur_pos = orig_coor_value.find_first_of(sc,cur_pos+1);
 
 4154        if(ele_start_pos == 0)
 
 4155            flatten_coor_value = get_CF_string(orig_coor_value);
 
 4157            flatten_coor_value += get_CF_string(orig_coor_value.substr(ele_start_pos));
 
 4160        auto attr_unique = make_unique<Attribute>();
 
 4161        auto attr = attr_unique.release();
 
 4162        Add_Str_Attr(attr,co_attrname,flatten_coor_value);
 
 4163        var->attrs.push_back(attr);
 
 4164        var->coord_attr_add_path = 
false;
 
 4175bool GMFile::Flatten_VarPath_In_Coordinates_Attr_EOS5(
Var *var)  {
 
 4177    BESDEBUG(
"h5", 
"Coming to Flatten_VarPath_In_Coordinates_Attr_EOS5()"<<endl);
 
 4178    string co_attrname = 
"coordinates";
 
 4179    bool has_coor_attr = 
false;
 
 4180    string orig_coor_value;
 
 4181    string flatten_coor_value;
 
 4185    for (
auto ira =var->attrs.begin(); ira !=var->attrs.end();) {
 
 4189        if((*ira)->name == co_attrname) {
 
 4190            Retrieve_H5_Attr_Value((*ira),var->fullpath);
 
 4192            string orig_attr_value((*ira)->value.begin(),(*ira)->value.end());
 
 4193            orig_coor_value = orig_attr_value;
 
 4194            has_coor_attr = 
true;
 
 4196            ira = var->attrs.erase(ira);
 
 4203    if(
true == has_coor_attr) {
 
 4207        size_t ele_start_pos = 0;
 
 4209        size_t cur_pos = orig_coor_value.find_first_of(sc);
 
 4210        while(cur_pos !=string::npos) {
 
 4211            string tempstr = orig_coor_value.substr(ele_start_pos,cur_pos-ele_start_pos);
 
 4214            tempstr = get_CF_string(tempstr);
 
 4215            flatten_coor_value += tempstr + sc;
 
 4216            ele_start_pos = cur_pos+1;
 
 4217            cur_pos = orig_coor_value.find_first_of(sc,cur_pos+1);
 
 4220        if(ele_start_pos == 0) {
 
 4223            flatten_coor_value = get_CF_string(tempstr);
 
 4226            flatten_coor_value += get_CF_string(orig_coor_value.substr(ele_start_pos));
 
 4229        Attribute *attr = 
new Attribute();
 
 4230        Add_Str_Attr(attr,co_attrname,flatten_coor_value);
 
 4231        var->attrs.push_back(attr);
 
 4243bool  GMFile::Check_2DLatLon_Dimscale(
string & latname, 
string &lonname)  {
 
 4261    bool latlon_2d_cv_check1 = 
false;
 
 4264    latlon_2d_cv_check1 = 
true;
 
 4267    for (
auto ircv = this->cvars.begin();
 
 4268        ircv != this->cvars.end(); ++ircv) {
 
 4269        if((*ircv)->cvartype == CV_FILLINDEX){ 
 
 4270            latlon_2d_cv_check1 = 
true;
 
 4276    bool latlon_2d_cv_check2 = 
true;
 
 4279    if(
true == latlon_2d_cv_check1) {
 
 4280        BESDEBUG(
"h5",
"Coming to check if having 2d latlon coordinates for a netCDF-4 like product. "<<endl);
 
 4283        for (
auto ircv = this->cvars.begin();
 
 4284            ircv != this->cvars.end(); ++ircv) {       
 
 4285            if((*ircv)->cvartype == CV_EXIST) {
 
 4286                for(
auto ira = (*ircv)->attrs.begin();
 
 4287                     ira != (*ircv)->attrs.end();ira++) {
 
 4288                    string attr_name =
"units";
 
 4289                    string lat_unit_value = 
"degrees_north";
 
 4290                    string lon_unit_value = 
"degrees_east";
 
 4293                    if((
true == Is_Str_Attr(*ira,(*ircv)->fullpath,attr_name,lat_unit_value)) ||
 
 4294                       (
true == Is_Str_Attr(*ira,(*ircv)->fullpath,attr_name,lon_unit_value))) {
 
 4295                        latlon_2d_cv_check2= 
false;
 
 4301            if(
false == latlon_2d_cv_check2) 
 
 4306    bool latlon_2d_cv_check3 = 
true;
 
 4309    if(
true == latlon_2d_cv_check1 && 
true == latlon_2d_cv_check2) {
 
 4311        short latlon_flag   = 0;
 
 4312        short LatLon_flag   = 0;
 
 4313        short latilong_flag = 0;
 
 4315        for (
auto ircv = this->cvars.begin();
 
 4316            ircv != this->cvars.end(); ++ircv) {       
 
 4317            if((*ircv)->cvartype == CV_EXIST) {
 
 4318                if((*ircv)->name == 
"lat")
 
 4320                else if((*ircv)->name == 
"lon")
 
 4322                else if((*ircv)->name == 
"latitude")
 
 4324                else if((*ircv)->name == 
"longitude")
 
 4326                else if((*ircv)->name == 
"Latitude")
 
 4328                else if((*ircv)->name == 
"Longitude")
 
 4333        if((2== latlon_flag) || (2 == latilong_flag) || (2 == LatLon_flag ))
 
 4334            latlon_2d_cv_check3 = 
false;
 
 4337    bool latlon_2d = 
false;
 
 4338    short latlon_flag   = 0;
 
 4339    string latdim1,latdim2,londim1,londim2;
 
 4341    short LatLon_flag   = 0;
 
 4342    string Latdim1,Latdim2,Londim1,Londim2;
 
 4344    short latilong_flag = 0;
 
 4345    string latidim1,latidim2,longdim1,longdim2;
 
 4352    if(
true == latlon_2d_cv_check1 && 
true == latlon_2d_cv_check2 && 
true == latlon_2d_cv_check3) {
 
 4354        for (
auto irv = this->
vars.begin();
 
 4355            irv != this->vars.end(); ++irv) {
 
 4358            if((*irv)->rank == 2) {
 
 4359                if((*irv)->name == 
"lat") {
 
 4361                    latdim1 = (*irv)->getDimensions()[0]->name;
 
 4362                    latdim2 = (*irv)->getDimensions()[1]->name;
 
 4365                else if((*irv)->name == 
"lon") {
 
 4367                    londim1 = (*irv)->getDimensions()[0]->name;
 
 4368                    londim2 = (*irv)->getDimensions()[1]->name;
 
 4370                else if((*irv)->name == 
"latitude"){
 
 4372                    latidim1 = (*irv)->getDimensions()[0]->name;
 
 4373                    latidim2 = (*irv)->getDimensions()[1]->name;
 
 4375                else if((*irv)->name == 
"longitude"){
 
 4377                    longdim1 = (*irv)->getDimensions()[0]->name;
 
 4378                    longdim2 = (*irv)->getDimensions()[1]->name;
 
 4381                else if((*irv)->name == 
"Latitude"){
 
 4383                    Latdim1 = (*irv)->getDimensions()[0]->name;
 
 4384                    Latdim2 = (*irv)->getDimensions()[1]->name;
 
 4387                else if((*irv)->name == 
"Longitude"){
 
 4389                    Londim1 = (*irv)->getDimensions()[0]->name;
 
 4390                    Londim2 = (*irv)->getDimensions()[1]->name;
 
 4400        if(2 == latlon_flag) {
 
 4401            if((2 == latilong_flag) || ( 2 == LatLon_flag))
 
 4403            else if((latdim1 == londim1) && (latdim2 == londim2)) {
 
 4409        else if ( 2 == latilong_flag) {
 
 4410            if( 2 == LatLon_flag)
 
 4412            else if ((latidim1 == longdim1) ||(latidim2 == longdim2)) {
 
 4413                latname = 
"latitude";
 
 4414                lonname = 
"longitude";
 
 4418        else if (2 == LatLon_flag){
 
 4419            if ((Latdim1 == Londim1) ||(Latdim2 == Londim2)) {
 
 4420                latname = 
"Latitude";
 
 4421                lonname = 
"Longitude";
 
 4432void GMFile::Update_2DLatLon_Dimscale_CV(
const string &latname,
const string &lonname)  {
 
 4437    for (
auto irv = this->
vars.begin();
 
 4438        irv != this->vars.end(); ++irv) {
 
 4440        if((*irv)->rank == 2) {
 
 4443            if((*irv)->name == latname) {
 
 4446                string latdim0 = (*irv)->getDimensions()[0]->name;
 
 4450                for (vector<GMCVar *>:: iterator i= this->cvars.begin(); i!=this->cvars.end(); ) {
 
 4451                    if((*i)->cfdimname == latdim0)  {
 
 4452                        if(CV_FILLINDEX == (*i)->cvartype) {
 
 4454                            i = this->cvars.erase(i);
 
 4456                        else if(CV_EXIST == (*i)->cvartype) { 
 
 4458                            Var *var = 
new Var(*i);
 
 4459                            this->
vars.push_back(var);
 
 4462                            i = this->cvars.erase(i);
 
 4466                            if(CV_LAT_MISS == (*i)->cvartype) 
 
 4467                                throw3(
"For the 2-D lat/lon case, the latitude dimension name ",latdim0, 
"is a coordinate variable of type CV_LAT_MISS");
 
 4468                            else if(CV_LON_MISS == (*i)->cvartype)
 
 4469                                throw3(
"For the 2-D lat/lon case, the latitude dimension name ",latdim0, 
"is a coordinate variable of type CV_LON_MISS");
 
 4470                            else if(CV_NONLATLON_MISS == (*i)->cvartype)
 
 4471                                throw3(
"For the 2-D lat/lon case, the latitude dimension name ",latdim0, 
"is a coordinate variable of type CV_NONLATLON_MISS");
 
 4472                            else if(CV_MODIFY == (*i)->cvartype)
 
 4473                                throw3(
"For the 2-D lat/lon case, the latitude dimension name ",latdim0, 
"is a coordinate variable of type CV_MODIFY");
 
 4474                            else if(CV_SPECIAL == (*i)->cvartype)
 
 4475                                throw3(
"For the 2-D lat/lon case, the latitude dimension name ",latdim0, 
"is a coordinate variable of type CV_SPECIAL");
 
 4477                                throw3(
"For the 2-D lat/lon case, the latitude dimension name ",latdim0, 
"is a coordinate variable of type CV_UNSUPPORTED");
 
 4485                GMCVar* GMcvar = 
new GMCVar(*irv);
 
 4486                GMcvar->cfdimname = latdim0;
 
 4487                GMcvar->cvartype = CV_EXIST;
 
 4488                GMcvar->product_type = product_type;
 
 4489                this->cvars.push_back(GMcvar);
 
 4491                this->
vars.erase(irv);
 
 4498    for (
auto irv = this->
vars.begin();
 
 4499        irv != this->vars.end(); ++irv) {
 
 4501        if((*irv)->rank == 2) {
 
 4504            if((*irv)->name == lonname) {
 
 4507                string londim0 = (*irv)->getDimensions()[1]->name;
 
 4510                for (vector<GMCVar *>:: iterator i= this->cvars.begin(); i!=this->cvars.end(); ) {
 
 4512                    if((*i)->cfdimname == londim0) {
 
 4513                        if(CV_FILLINDEX == (*i)->cvartype) {
 
 4515                            i= this->cvars.erase(i);
 
 4517                        else if(CV_EXIST == (*i)->cvartype) { 
 
 4519                            Var *var = 
new Var(*i);
 
 4520                            this->
vars.push_back(var);
 
 4523                            i = this->cvars.erase(i);
 
 4526                            if(CV_LAT_MISS == (*i)->cvartype) 
 
 4527                                throw3(
"For the 2-D lat/lon case, the longitude dimension name ",londim0, 
"is a coordinate variable of type CV_LAT_MISS");
 
 4528                            else if(CV_LON_MISS == (*i)->cvartype)
 
 4529                                throw3(
"For the 2-D lat/lon case, the longitude dimension name ",londim0, 
"is a coordinate variable of type CV_LON_MISS");
 
 4530                            else if(CV_NONLATLON_MISS == (*i)->cvartype)
 
 4531                                throw3(
"For the 2-D lat/lon case, the longitude dimension name ",londim0, 
"is a coordinate variable of type CV_NONLATLON_MISS");
 
 4532                            else if(CV_MODIFY == (*i)->cvartype)
 
 4533                                throw3(
"For the 2-D lat/lon case, the longitude dimension name ",londim0, 
"is a coordinate variable of type CV_MODIFY");
 
 4534                            else if(CV_SPECIAL == (*i)->cvartype)
 
 4535                                throw3(
"For the 2-D lat/lon case, the longitude dimension name ",londim0, 
"is a coordinate variable of type CV_SPECIAL");
 
 4537                                throw3(
"For the 2-D lat/lon case, the longitude dimension name ",londim0, 
"is a coordinate variable of type CV_UNSUPPORTED");
 
 4545                GMCVar* GMcvar = 
new GMCVar(*irv);
 
 4546                GMcvar->cfdimname = londim0;
 
 4547                GMcvar->cvartype = CV_EXIST;
 
 4548                GMcvar->product_type = product_type;
 
 4549                this->cvars.push_back(GMcvar);
 
 4551                this->
vars.erase(irv);
 
 4560void GMFile::Handle_CVar_LatLon1D_General_Product()  {
 
 4562    BESDEBUG(
"h5", 
"Coming to Handle_CVar_LatLon1D_General_Product()"<<endl);
 
 4563    this->iscoard = 
true;
 
 4564    Handle_CVar_LatLon_General_Product();
 
 4569void GMFile::Handle_CVar_LatLon2D_General_Product()  {
 
 4571    BESDEBUG(
"h5", 
"Coming to Handle_CVar_LatLon2D_General_Product()"<<endl);
 
 4572    Handle_CVar_LatLon_General_Product();
 
 4578void GMFile::Handle_CVar_LatLon_General_Product()  {
 
 4580    BESDEBUG(
"h5", 
"Coming to Handle_CVar_LatLon_General_Product()"<<endl);
 
 4581    if((GENERAL_LATLON2D != this->gproduct_pattern) 
 
 4582       && GENERAL_LATLON1D != this->gproduct_pattern)
 
 4583        throw1(
"This function only supports latlon 1D or latlon 2D general products");
 
 4585    pair<set<string>::iterator,
bool> setret;
 
 4586    set<string>tempdimnamelist = dimnamelist;
 
 4588    for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ++irv) {
 
 4591        if (gp_latname== (*irv)->name) {
 
 4595            tempdimnamelist.erase(((*irv)->dims[0])->name);
 
 4596            auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 4597            auto GMcvar = GMcvar_unique.release();
 
 4598            GMcvar->cfdimname = ((*irv)->dims[0])->name;
 
 4599            GMcvar->cvartype = CV_EXIST;
 
 4600            GMcvar->product_type = product_type;
 
 4601            this->cvars.push_back(GMcvar); 
 
 4603            this->
vars.erase(irv);
 
 4608    for (
auto irv = this->
vars.begin(); irv != this->vars.end(); ++irv) {
 
 4611        if (gp_lonname== (*irv)->name) {
 
 4617            if(GENERAL_LATLON2D == this->gproduct_pattern)
 
 4618                londimname = ((*irv)->dims[1])->name;
 
 4620                londimname = ((*irv)->dims[0])->name;
 
 4622            tempdimnamelist.erase(londimname);
 
 4623            auto GMcvar_unique = make_unique<GMCVar>(*irv);
 
 4624            auto GMcvar = GMcvar_unique.release();
 
 4625            GMcvar->cfdimname = londimname;
 
 4626            GMcvar->cvartype = CV_EXIST;
 
 4627            GMcvar->product_type = product_type;
 
 4628            this->cvars.push_back(GMcvar); 
 
 4630            this->
vars.erase(irv);
 
 4637    for (
const auto &dimname:tempdimnamelist) {
 
 4638        auto GMcvar_unique = make_unique<GMCVar>();
 
 4639        auto GMcvar = GMcvar_unique.release();
 
 4640        Create_Missing_CV(GMcvar,dimname);
 
 4641        this->cvars.push_back(GMcvar);
 
 4647void GMFile::Handle_CVar_OBPG_L3()  {
 
 4649    BESDEBUG(
"h5", 
"Coming to Handle_CVar_OBPG_L3()"<<endl);
 
 4650    if (GENERAL_DIMSCALE == this->gproduct_pattern)
 
 4651            Handle_CVar_Dimscale_General_Product();
 
 4654    for (
const auto &var:this->
vars) {
 
 4661        if(var->rank == 2) {
 
 4663            if((var->fullpath.find(
"/geophysical_data") == 0) || (var->dtype == H5FLOAT32)) {
 
 4669                size_t temp_size = 0;
 
 4671                H5DataType ll_dtype = var->dtype;
 
 4674                if(lat_size >lon_size) {
 
 4675                    temp_size = lon_size;
 
 4676                    temp_name = lon_name;
 
 4677                    lon_size = lat_size;
 
 4678                    lon_name = lat_name;
 
 4679                    lat_size = temp_size;
 
 4680                    lat_name = temp_name;
 
 4682                for (
auto &cvar:this->cvars) {
 
 4683                    if(cvar->cvartype == CV_FILLINDEX) {
 
 4684                        if(cvar->getDimensions()[0]->size == lat_size &&
 
 4685                           cvar->getDimensions()[0]->name == lat_name) {
 
 4686                            cvar->cvartype = CV_LAT_MISS;
 
 4687                            cvar->dtype = ll_dtype;
 
 4688                            for (
auto ira = cvar->attrs.begin(); ira != cvar->attrs.end(); ++ira) {
 
 4689                                if ((*ira)->name == 
"NAME") {
 
 4691                                    cvar->attrs.erase(ira);
 
 4696                        else if(cvar->getDimensions()[0]->size == lon_size &&
 
 4697                           cvar->getDimensions()[0]->name == lon_name) {
 
 4698                            cvar->cvartype = CV_LON_MISS;
 
 4699                            cvar->dtype = ll_dtype;
 
 4700                            for (
auto ira = cvar->attrs.begin(); ira != cvar->attrs.end(); ++ira) {
 
 4701                                if ((*ira)->name == 
"NAME") {
 
 4703                                    cvar->attrs.erase(ira);
 
 4721    BESDEBUG(
"h5", 
"Coming to Handle_SpVar()"<<endl);
 
 4722    if (ACOS_L2S_OR_OCO2_L1B == product_type) 
 
 4723        Handle_SpVar_ACOS_OCO2();
 
 4724    else if(GPM_L1 == product_type) {
 
 4727        for (
auto irv = this->vars.begin(); irv != this->vars.end(); ++irv) {
 
 4728            if((*irv)->name==
"AlgorithmRuntimeInfo") {
 
 4730                this->vars.erase(irv); 
 
 4737    else if(GPMM_L3 == product_type || GPMS_L3 == product_type || GPM_L3_New==product_type) {
 
 4739        for (
auto irv = this->vars.begin(); irv != this->vars.end(); ) {
 
 4740            if((*irv)->name==
"InputFileNames") {
 
 4742                irv = this->vars.erase(irv);
 
 4744            else if((*irv)->name==
"InputAlgorithmVersions") {
 
 4746                irv = this->vars.erase(irv);
 
 4748            else if((*irv)->name==
"InputGenerationDateTimes") {
 
 4750                irv = this->vars.erase(irv);
 
 
 4761void GMFile::Handle_SpVar_ACOS_OCO2()  {
 
 4763    BESDEBUG(
"h5", 
"Coming to Handle_SpVar_ACOS_OCO2()"<<endl);
 
 4766    for (
auto irv = this->vars.begin(); irv != this->vars.end(); ) {
 
 4768        if (H5INT64 == (*irv)->getType()) {
 
 4771            auto spvar_unique = make_unique<GMSPVar>(*irv);
 
 4772            auto spvar = spvar_unique.release();
 
 4773            spvar->name = (*irv)->name +
"_Time";
 
 4774            spvar->newname = (*irv)->newname+
"_Time";
 
 4775            spvar->dtype = H5INT32;
 
 4776            spvar->otype = (*irv)->getType();
 
 4780            spvar->numofdbits = 6;
 
 4781            this->spvars.push_back(spvar);
 
 4784            auto spvar2_unique = make_unique<GMSPVar>(*irv);
 
 4785            auto spvar2 = spvar2_unique.release();
 
 4786            spvar2->name = (*irv)->name +
"_Date";
 
 4787            spvar2->newname = (*irv)->newname+
"_Date";
 
 4788            spvar2->dtype = H5INT32;
 
 4789            spvar2->otype = (*irv)->getType();
 
 4793            spvar2->numofdbits = 8;
 
 4794            this->spvars.push_back(spvar2);
 
 4797            irv = this->vars.erase(irv);
 
 4809    BESDEBUG(
"h5", 
"Coming to Adjust_Obj_Name()"<<endl);
 
 4810    if(Mea_Ozone == product_type) 
 
 4811        Adjust_Mea_Ozone_Obj_Name();
 
 4813    if(GPMS_L3 == product_type || GPMM_L3 == product_type)
 
 4814        Adjust_GPM_L3_Obj_Name();
 
 4818for (
auto irv2 = this->vars.begin();
 
 4819    irv2 != this->vars.end(); irv2++) {
 
 4820    for (
auto ird = (*irv2)->dims.begin();
 
 4821         ird !=(*irv2)->dims.end(); ird++) {
 
 4822         cerr<<
"Dimension name afet Adjust_Obj_Name "<<(*ird)->newname <<endl;
 
 
 4830void GMFile:: Adjust_GPM_L3_Obj_Name()
  const {
 
 4832    BESDEBUG(
"h5", 
"Coming to Adjust_GPM_L3_Obj_Name()"<<endl);
 
 4835    if(this->groups.size() <= 1) {
 
 4836        for (
auto &var:this->vars) {
 
 4837            objnewname =  HDF5CFUtil::obtain_string_after_lastslash(var->newname);
 
 4838            if (objnewname !=
"") 
 
 4839                var->newname = objnewname;
 
 4843        for (
auto &var:this->
vars) {
 
 4844            size_t grid_group_path_pos = (var->newname.substr(1)).find_first_of(
"/");
 
 4845            objnewname =  (var->newname).substr(grid_group_path_pos+2);
 
 4846            var->newname = objnewname;
 
 4852void GMFile:: Adjust_Mea_Ozone_Obj_Name()
  const {
 
 4854    BESDEBUG(
"h5", 
"Coming to Adjust_Mea_Ozone_Obj_Name()"<<endl);
 
 4856    for (
auto &var:this->
vars) {
 
 4857        objnewname =  HDF5CFUtil::obtain_string_after_lastslash(var->newname);
 
 4858        if (objnewname !=
"") 
 
 4859           var->newname = objnewname;
 
 4863for (
auto ird = (*irv)->dims.begin();
 
 4864                ird !=(*irv)->dims.end();++ird) {
 
 4865 cerr<<
"Ozone dim. name "<<(*ird)->name <<endl;
 
 4866 cerr<<
"Ozone dim. new name "<<(*ird)->newname <<endl;
 
 4872    for (
auto &cvar:this->cvars) {
 
 4873        objnewname =  HDF5CFUtil::obtain_string_after_lastslash(cvar->newname);
 
 4874        if (objnewname !=
"")
 
 4875           cvar->newname = objnewname;
 
 4878for (
auto ird = (*irv)->dims.begin();
 
 4879                ird !=(*irv)->dims.end();++ird) {
 
 4880 cerr<<
"Ozone CV dim. name "<<(*ird)->name <<endl;
 
 4881 cerr<<
"Ozone CV dim. new name "<<(*ird)->newname <<endl;
 
 4890    BESDEBUG(
"h5", 
"GMFile::Coming to Flatten_Obj_Name()"<<endl);
 
 4895    for (
auto &cvar:this->cvars) {
 
 4896        cvar->newname = get_CF_string(cvar->newname);
 
 4898        for (
auto &dim:cvar->dims) 
 
 4899            dim->newname = get_CF_string(dim->newname);
 
 4901        if (
true == include_attr) {
 
 4902            for (
auto &attr: cvar->attrs)
 
 4903                attr->newname = File::get_CF_string(attr->newname);
 
 4909    for (
auto &spvar:this->spvars) {
 
 4911        spvar->newname = get_CF_string(spvar->newname);
 
 4912        for (
auto &dim:spvar->dims)
 
 4913            dim->newname = get_CF_string(dim->newname);
 
 4915        if (
true == include_attr) {
 
 4916            for (
auto &attr:spvar->attrs)
 
 4917                  attr->newname = File::get_CF_string(attr->newname);
 
 4923for (
auto irv2 = this->vars.begin();
 
 4924    irv2 != this->vars.end(); irv2++) {
 
 4925    for (
auto ird = (*irv2)->dims.begin();
 
 4926         ird !=(*irv2)->dims.end(); ird++) {
 
 4927         cerr<<
"Dimension name afet Flatten_Obj_Name "<<(*ird)->newname <<endl;
 
 
 4939    BESDEBUG(
"h5", 
"GMFile::Coming to Handle_Obj_NameClashing()"<<endl);
 
 4943    set<string>objnameset;
 
 4944    Handle_GMCVar_NameClashing(objnameset);
 
 4945    Handle_GMSPVar_NameClashing(objnameset);
 
 4946    File::Handle_GeneralObj_NameClashing(include_attr,objnameset);
 
 4947    if (
true == include_attr) {
 
 4948        Handle_GMCVar_AttrNameClashing();
 
 4949        Handle_GMSPVar_AttrNameClashing();
 
 
 4956void GMFile::Handle_GMCVar_NameClashing(set<string> &objnameset )  {
 
 4958    GMHandle_General_NameClashing(objnameset,this->cvars);
 
 4962void GMFile::Handle_GMSPVar_NameClashing(set<string> &objnameset )  {
 
 4964    GMHandle_General_NameClashing(objnameset,this->spvars);
 
 4968void GMFile::Handle_GMCVar_AttrNameClashing()  {
 
 4970    BESDEBUG(
"h5", 
"Coming to Handle_GMCVar_AttrNameClashing()"<<endl);
 
 4971    set<string> objnameset;
 
 4973    for (
auto &cvar:this->cvars) {
 
 4974        Handle_General_NameClashing(objnameset,cvar->attrs);
 
 4980void GMFile::Handle_GMSPVar_AttrNameClashing()  {
 
 4982    BESDEBUG(
"h5", 
"Coming to Handle_GMSPVar_AttrNameClashing()"<<endl);
 
 4983    set<string> objnameset;
 
 4985    for (
auto &spvar:this->spvars) {
 
 4986        Handle_General_NameClashing(objnameset,spvar->attrs);
 
 4994template<
class T> 
void 
 4995GMFile::GMHandle_General_NameClashing(set <string>&objnameset, vector<T*>& objvec) {
 
 4997    BESDEBUG(
"h5", 
"Coming to GMHandle_General_NameClashing()"<<endl);
 
 4998    pair<set<string>::iterator,
bool> setret;
 
 4999    set<string>::iterator iss;
 
 5001    vector<string> clashnamelist;
 
 5003    map<int,int> cl_to_ol;
 
 5007    typename vector<T*>::iterator irv;
 
 5009    for (irv = objvec.begin(); irv != objvec.end(); ++irv) {
 
 5011        setret = objnameset.insert((*irv)->newname);
 
 5012        if (
false == setret.second ) {
 
 5013            clashnamelist.insert(clashnamelist.end(),(*irv)->newname);
 
 5014            cl_to_ol[cl_index] = ol_index;
 
 5023    for (
auto &clashname:clashnamelist) {
 
 5024        int clash_index = 1;
 
 5025        string temp_clashname = clashname +
'_';
 
 5026        HDF5CFUtil::gen_unique_name(temp_clashname,objnameset,clash_index);
 
 5027        clashname = temp_clashname;
 
 5032    for (
unsigned int i =0; i <clashnamelist.size(); i++)
 
 5033        objvec[cl_to_ol[i]]->newname = clashnamelist[i];
 
 5041    BESDEBUG(
"h5", 
"GMFile: Coming to Handle_DimNameClashing()"<<endl);
 
 5043    if (ACOS_L2S_OR_OCO2_L1B == product_type) 
 
 5046    map<string,string>dimname_to_dimnewname;
 
 5047    pair<map<string,string>::iterator,
bool>mapret;
 
 5048    set<string> dimnameset;
 
 5049    vector<Dimension*>vdims;
 
 5050    set<string> dimnewnameset;
 
 5051    pair<set<string>::iterator,
bool> setret;
 
 5054    for (
const auto &cvar:this->cvars) {
 
 5055        for (
const auto &dim:cvar->dims) {
 
 5056            setret = dimnameset.insert(dim->name);
 
 5057            if (
true == setret.second) 
 
 5058                vdims.push_back(dim); 
 
 5065    for (
const auto &var:this->vars) {
 
 5066        for (
const auto &dim:var->dims) {
 
 5070            setret = dimnameset.insert(dim->name);
 
 5071            if (setret.second) vdims.push_back(dim);
 
 5075    GMHandle_General_NameClashing(dimnewnameset,vdims);
 
 5078    for (
const auto& dim:vdims) {
 
 5079        mapret = dimname_to_dimnewname.insert(pair<string,string>(dim->name,dim->newname));
 
 5080        if (
false == mapret.second) 
 
 5081            throw4(
"The dimension name ",dim->name,
" should map to ",
 
 5086    for (
auto &cvar:this->cvars)
 
 5087        for (
auto &dim:cvar->dims)
 
 5088            dim->newname = dimname_to_dimnewname[dim->name];
 
 5090    for (
auto &var:this->vars)
 
 5091        for (
auto &dim:var->dims)
 
 5092            dim->newname = dimname_to_dimnewname[dim->name];
 
 
 5099    BESDEBUG(
"h5", 
"GMFile:Coming to Adjust_Dim_Name()"<<endl);
 
 5102for (
auto irv2 = this->vars.begin();
 
 5103       irv2 != this->vars.end(); irv2++) {
 
 5104    for (
auto ird = (*irv2)->dims.begin();
 
 5105           ird !=(*irv2)->dims.end(); ird++) {
 
 5106         cerr<<
"Dimension new name "<<(*ird)->newname <<endl;
 
 5112    if( 
true == iscoard) {
 
 5113        for (
const auto &cvar:this->cvars) {
 
 5115cerr<<
"1D Cvariable name is "<<cvar->name <<endl;
 
 5116cerr<<
"1D Cvariable new name is "<<cvar->newname <<endl;
 
 5117cerr<<
"1D Cvariable dim name is "<<(cvar->dims)[0]->name <<endl;
 
 5118cerr<<
"1D Cvariable dim new name is "<<(cvar->dims)[0]->newname <<endl;
 
 5120            if (cvar->dims.size()!=1) 
 
 5121                throw3(
"Coard coordinate variable ",cvar->name, 
"is not 1D");
 
 5122            if (cvar->newname != ((cvar->dims)[0]->newname)) {
 
 5123                (cvar->dims)[0]->newname = cvar->newname;
 
 5126                for (
auto &var:this->vars) {
 
 5127                    for (
auto &dim:var->dims) {
 
 5132                        if (dim->name == (cvar->dims)[0]->name) 
 
 5133                            dim->newname = (cvar->dims)[0]->newname;
 
 5142for (
auto irv2 = this->vars.begin();
 
 5143    irv2 != this->vars.end(); irv2++) {
 
 5144    for (
auto ird = (*irv2)->dims.begin();
 
 5145         ird !=(*irv2)->dims.end(); ird++) {
 
 5146         cerr<<
"Dimension name afet Adjust_Dim_Name "<<(*ird)->newname <<endl;
 
 
 5158    BESDEBUG(
"h5", 
"GMFile::Coming to Add_Supplement_Attrs()"<<endl);
 
 5159    if (General_Product == product_type || 
true == add_path) {
 
 5162       if (
true == add_path) {
 
 5164            for (
auto &cvar:this->cvars) {
 
 5165                if ((cvar->cvartype == CV_EXIST) || (cvar->cvartype == CV_MODIFY)) {
 
 5166                    const string varname = cvar->name;
 
 5167                    const string attrname = 
"origname";
 
 5168                    auto attr_unique = make_unique<Attribute>();
 
 5169                    auto attr = attr_unique.release();
 
 5170                    Add_Str_Attr(attr,attrname,varname);
 
 5171                    cvar->attrs.push_back(attr);
 
 5175            for (
auto &cvar:this->cvars) {
 
 5179                if(cvar->zero_storage_size == 
false 
 5180                   || HDF5RequestHandler::get_no_zero_size_fullnameattr() == 
false) {
 
 5181                    if ((cvar->cvartype == CV_EXIST) || (cvar->cvartype == CV_MODIFY)) {
 
 5182                        const string varname = cvar->fullpath;
 
 5183                        const string attrname = 
"fullnamepath";
 
 5184                        auto attr_unique = make_unique<Attribute>();
 
 5185                        auto attr = attr_unique.release();
 
 5186                        Add_Str_Attr(attr,attrname,varname);
 
 5187                        cvar->attrs.push_back(attr);
 
 5192            for (
auto &spvar:this->spvars) {
 
 5193                const string varname = spvar->name;
 
 5194                const string attrname = 
"origname";
 
 5195                auto attr_unique = make_unique<Attribute>();
 
 5196                auto attr = attr_unique.release();
 
 5197                Add_Str_Attr(attr,attrname,varname);
 
 5198                spvar->attrs.push_back(attr);
 
 5201            for (
auto &spvar:this->spvars) {
 
 5205                if(spvar->zero_storage_size == 
false 
 5206                   || HDF5RequestHandler::get_no_zero_size_fullnameattr() == 
false) {
 
 5207                    const string varname = spvar->fullpath;
 
 5208                    const string attrname = 
"fullnamepath";
 
 5209                    auto attr_unique = make_unique<Attribute>();
 
 5210                    auto attr = attr_unique.release();
 
 5211                    Add_Str_Attr(attr,attrname,varname);
 
 5212                    spvar->attrs.push_back(attr);
 
 5218    if(GPM_L1 == product_type || GPMS_L3 == product_type || GPMM_L3 == product_type)
 
 5220    else if (Aqu_L3 == product_type) 
 
 5222    else if (Mea_SeaWiFS_L2 == product_type || Mea_SeaWiFS_L3 == product_type) 
 
 5223        Add_SeaWiFS_Attrs();
 
 
 5229GMFile:: Add_GPM_Attrs()  {
 
 5231    BESDEBUG(
"h5", 
"Coming to Add_GPM_Attrs()"<<endl);
 
 5232    const string attr_name_be_replaced = 
"CodeMissingValue";
 
 5233    const string attr_new_name = 
"_FillValue";
 
 5234    const string attr2_name_be_replaced = 
"Units";
 
 5235    const string attr2_new_name =
"units";
 
 5240    for (
const auto &var:this->vars) {
 
 5241        bool has_fvalue_attr = 
false;
 
 5242        for (
const auto &attr:var->attrs) {
 
 5243            if(attr_new_name == attr->name) { 
 
 5244                has_fvalue_attr = 
true;
 
 5249        if(
false == has_fvalue_attr) {
 
 5250            for(
auto &attr:var->attrs) {
 
 5251                if(attr_name_be_replaced == attr->name) { 
 
 5252                    if(attr->dtype == H5FSTRING) 
 
 5253                        Change_Attr_One_Str_to_Others(attr,var);
 
 5254                    attr->name = attr_new_name;
 
 5255                    attr->newname = attr_new_name;
 
 5263    for (
auto &cvar: this->cvars) {
 
 5265        bool has_fvalue_attr = 
false;
 
 5267        for(
const auto &attr:cvar->attrs) {
 
 5269            if(attr_new_name == attr->name) {
 
 5270                has_fvalue_attr = 
true;
 
 5275        if(
false == has_fvalue_attr) {
 
 5277            for(
auto &attr:cvar->attrs) {
 
 5279                if(attr_name_be_replaced == attr->name) {
 
 5280                    if(attr->dtype == H5FSTRING) 
 
 5281                        Change_Attr_One_Str_to_Others(attr,cvar);
 
 5282                    attr->name = attr_new_name;
 
 5283                    attr->newname = attr_new_name;
 
 5290        if(product_type == GPM_L1) {
 
 5292            if (cvar->cvartype == CV_EXIST) {
 
 5293                if(cvar->name.find(
"Latitude") !=string::npos) {
 
 5294                    string unit_value = 
"degrees_north";
 
 5295                    Correct_GPM_L1_LatLon_units(cvar,unit_value);
 
 5298                else if(cvar->name.find(
"Longitude") !=string::npos) {
 
 5299                    string unit_value = 
"degrees_east";
 
 5300                    Correct_GPM_L1_LatLon_units(cvar,unit_value);
 
 5305            else if (cvar->cvartype == CV_NONLATLON_MISS) {
 
 5308            const string attrname = 
"comment";
 
 5311            if(cvar->name == 
"nchannel1") 
 
 5312                comment = 
"Number of Swath S1 channels (10V 10H 19V 19H 23V 37V 37H 89V 89H).";
 
 5313            else if(cvar->name == 
"nchannel2") 
 
 5314                comment = 
"Number of Swath S2 channels (166V 166H 183+/-3V 183+/-8V).";
 
 5315            else if(cvar->name == 
"nchan1")
 
 5316                comment = 
"Number of channels in Swath 1.";
 
 5317            else if(cvar->name == 
"nchan2")
 
 5318                comment = 
"Number of channels in Swath 2.";
 
 5319            else if(cvar->name == 
"VH") 
 
 5320                comment = 
"Number of polarizations.";
 
 5321            else if(cvar->name == 
"GMIxyz") 
 
 5322                comment = 
"x, y, z components in GMI instrument coordinate system.";
 
 5323            else if(cvar->name == 
"LNL")
 
 5324                comment = 
"Linear and non-linear.";
 
 5325            else if(cvar->name == 
"nscan")
 
 5326                comment = 
"Number of scans in the granule.";
 
 5327            else if(cvar->name == 
"nscan1")
 
 5328                comment = 
"Typical number of Swath S1 scans in the granule.";
 
 5329            else if(cvar->name == 
"nscan2")
 
 5330                comment = 
"Typical number of Swath S2 scans in the granule.";
 
 5331            else if(cvar->name == 
"npixelev")
 
 5332                comment = 
"Number of earth view pixels in one scan.";
 
 5333            else if(cvar->name == 
"npixelht")
 
 5334                comment = 
"Number of hot load pixels in one scan.";
 
 5335            else if(cvar->name == 
"npixelcs")
 
 5336                comment = 
"Number of cold sky pixels in one scan.";
 
 5337            else if(cvar->name == 
"npixelfr")
 
 5338                comment = 
"Number of full rotation earth view pixels in one scan.";
 
 5339            else if(cvar->name == 
"nfreq1")
 
 5340                comment = 
"Number of frequencies in Swath 1.";
 
 5341            else if(cvar->name == 
"nfreq2")
 
 5342                comment = 
"Number of frequencies in Swath 2.";
 
 5343            else if(cvar->name == 
"npix1")
 
 5344                comment = 
"Number of pixels in Swath 1.";
 
 5345            else if(cvar->name == 
"npix2")
 
 5346                comment = 
"Number of pixels in Swath 2.";
 
 5347            else if(cvar->name == 
"npix3")
 
 5348                comment = 
"Number of pixels in Swath 3.";
 
 5349            else if(cvar->name == 
"npix4")
 
 5350                comment = 
"Number of pixels in Swath 4.";
 
 5351            else if(cvar->name == 
"ncolds1")
 
 5352                comment = 
"Maximum number of cold samples in Swath 1.";
 
 5353            else if(cvar->name == 
"ncolds2")
 
 5354                comment = 
"Maximum number of cold samples in Swath 2.";
 
 5355            else if(cvar->name == 
"nhots1")
 
 5356                comment = 
"Maximum number of hot samples in Swath 1.";
 
 5357            else if(cvar->name == 
"nhots2")
 
 5358                comment = 
"Maximum number of hot samples in Swath 2.";
 
 5359            else if(cvar->name == 
"ntherm")
 
 5360                comment = 
"Number of hot load thermisters.";
 
 5361            else if(cvar->name == 
"ntach")
 
 5362                comment = 
"Number of tachometer readings.";
 
 5363            else if(cvar->name == 
"nsamt"){
 
 5364                comment = 
"Number of sample types. ";
 
 5365                comment = +
"The types are: total science GSDR, earthview,hot load, cold sky.";
 
 5367            else if(cvar->name == 
"nndiode")
 
 5368                comment = 
"Number of noise diodes.";
 
 5369            else if(cvar->name == 
"n7")
 
 5370                comment = 
"Number seven.";
 
 5371            else if(cvar->name == 
"nray")
 
 5372                comment = 
"Number of angle bins in each NS scan."; 
 
 5373            else if(cvar->name == 
"nrayMS")
 
 5374                comment = 
"Number of angle bins in each MS scan."; 
 
 5375            else if(cvar->name == 
"nrayHS")
 
 5376                comment = 
"Number of angle bins in each HS scan."; 
 
 5377            else if(cvar->name == 
"nbin")
 
 5378                comment = 
"Number of range bins in each NS and MS ray. Bin interval is 125m."; 
 
 5379            else if(cvar->name == 
"nbinHS")
 
 5380                comment = 
"Number of range bins in each HS ray. Bin interval is 250m."; 
 
 5381            else if(cvar->name == 
"nbinSZP")
 
 5382                comment = 
"Number of range bins for sigmaZeroProfile."; 
 
 5383            else if(cvar->name == 
"nbinSZPHS")
 
 5384                comment = 
"Number of range bins for sigmaZeroProfile in each HS scan."; 
 
 5385            else if(cvar->name == 
"nNP")
 
 5386                comment = 
"Number of NP kinds."; 
 
 5387            else if(cvar->name == 
"nearFar")
 
 5388                comment = 
"Near reference, Far reference."; 
 
 5389            else if(cvar->name == 
"foreBack")
 
 5390                comment = 
"Forward, Backward."; 
 
 5391            else if(cvar->name == 
"method")
 
 5392                comment = 
"Number of SRT methods."; 
 
 5393            else if(cvar->name == 
"nNode")
 
 5394                comment = 
"Number of binNode."; 
 
 5395            else if(cvar->name == 
"nDSD")
 
 5396                comment = 
"Number of DSD parameters. Parameters are N0 and D0"; 
 
 5397            else if(cvar->name == 
"LS")
 
 5398                comment = 
"Liquid, solid."; 
 
 5401            if (!comment.empty()) { 
 
 5402                auto attr_unique = make_unique<Attribute>();
 
 5403                auto attr = attr_unique.release();
 
 5404                Add_Str_Attr(attr,attrname,comment);
 
 5405                cvar->attrs.push_back(attr);
 
 5410      if(product_type == GPMS_L3 || product_type == GPMM_L3) {
 
 5411        if (cvar->cvartype == CV_NONLATLON_MISS) {
 
 5414            const string attrname = 
"comment";
 
 5416            if(cvar->name == 
"chn") 
 
 5417                comment = 
"Number of channels:Ku,Ka,KaHS,DPR.";
 
 5418            else if(cvar->name == 
"inst") 
 
 5419                comment = 
"Number of instruments:Ku,Ka,KaHS.";
 
 5420            else if(cvar->name == 
"tim")
 
 5421                comment = 
"Number of hours(local time).";
 
 5422            else if(cvar->name == 
"ang"){
 
 5423                comment = 
"Number of angles.The meaning of ang is different for each channel.";
 
 5425                "For Ku channel all indices are used with the meaning 0,1,2,..6 =angle bins 24,";
 
 5427                "(20,28),(16,32),(12,36),(8,40),(3,44),and (0,48).";
 
 5429                "For Ka channel 4 indices are used with the meaning 0,1,2,3 = angle bins 12,(8,16),";
 
 5431                "(4,20),and (0,24). For KaHS channel 4 indices are used with the meaning 0,1,2,3 =";
 
 5432                comment += 
"angle bins(11,2),(7,16),(3,20),and (0.23).";
 
 5435            else if(cvar->name == 
"rt") 
 
 5436                comment = 
"Number of rain types: stratiform, convective,all.";
 
 5437            else if(cvar->name == 
"st") 
 
 5438                comment = 
"Number of surface types:ocean,land,all.";
 
 5439            else if(cvar->name == 
"bin"){
 
 5440                comment = 
"Number of bins in histogram. The thresholds are different for different";
 
 5441                comment +=
" variables. see the file specification for this algorithm.";
 
 5443            else if(cvar->name == 
"nvar") {
 
 5444                comment = 
"Number of phase bins. Bins are counts of phase less than 100, ";
 
 5445                comment +=
"counts of phase greater than or equal to 100 and less than 200, ";
 
 5446                comment +=
"counts of phase greater than or equal to 200.";
 
 5448            else if(cvar->name == 
"AD")
 
 5449                comment = 
"Ascending or descending half of the orbit.";
 
 5452            if (comment.empty() == 
false) {
 
 5453                auto attr_unique = make_unique<Attribute>();
 
 5454                auto attr = attr_unique.release();
 
 5455                Add_Str_Attr(attr,attrname,comment);
 
 5456                cvar->attrs.push_back(attr);
 
 5461      if (cvar->cvartype == CV_SPECIAL) {
 
 5462            if(cvar->name == 
"nlayer" || cvar->name == 
"hgt" 
 5463               || cvar->name == 
"nalt") {
 
 5464                string unit_value = 
"km";
 
 5465                auto attr_unique = make_unique<Attribute>();
 
 5466                auto attr = attr_unique.release();
 
 5467                Add_Str_Attr(attr,attr2_new_name,unit_value);
 
 5468                cvar->attrs.push_back(attr);
 
 5470                string attr1_axis=
"axis";
 
 5471                string attr1_value = 
"Z";
 
 5472                auto attr1_unique = make_unique<Attribute>();
 
 5473                auto attr1 = attr1_unique.release();
 
 5474                Add_Str_Attr(attr1,attr1_axis,attr1_value);
 
 5475                cvar->attrs.push_back(attr1);
 
 5477                string attr2_positive=
"positive";
 
 5478                string attr2_value = 
"up";
 
 5479                auto attr2_unique = make_unique<Attribute>();
 
 5480                auto attr2 = attr2_unique.release();
 
 5481                Add_Str_Attr(attr2,attr2_positive,attr2_value);
 
 5482                cvar->attrs.push_back(attr2);
 
 5485            if(cvar->name == 
"hgt" || cvar->name == 
"nalt"){
 
 5486                string comment =
"Number of heights above the earth ellipsoid";
 
 5487                auto attr1_unique = make_unique<Attribute>();
 
 5488                auto attr1 = attr1_unique.release();
 
 5489                Add_Str_Attr(attr1,
"comment",comment);
 
 5490                cvar->attrs.push_back(attr1);
 
 5500    const string fill_value_attr_name = 
"_FillValue";
 
 5501    vector<HDF5CF::Var *>::const_iterator it_v;
 
 5502    vector<HDF5CF::Attribute *>::const_iterator ira;
 
 5504    for (it_v = 
vars.begin();
 
 5505                it_v != 
vars.end(); ++it_v) {
 
 5507        bool has_fillvalue = 
false;
 
 5508        for(ira = (*it_v)->attrs.begin(); ira!= (*it_v)->attrs.end();ira++) {
 
 5509            if (fill_value_attr_name == (*ira)->name){
 
 5510                has_fillvalue = 
true;
 
 5517        if (has_fillvalue != 
true ) {
 
 5519            if(H5FLOAT32 == (*it_v)->dtype) {
 
 5520                Attribute* attr = 
new Attribute();
 
 5521                    float _FV = -9999.9;
 
 5522                    Add_One_Float_Attr(attr,fill_value_attr_name,_FV);
 
 5523               (*it_v)->attrs.push_back(attr);
 
 5533GMFile:: Correct_GPM_L1_LatLon_units(
Var *var, 
const string & unit_value)  {
 
 5535    BESDEBUG(
"h5", 
"Coming to Correct_GPM_L1_LatLon_units()"<<endl);
 
 5536    const string Unit_name = 
"Units";
 
 5537    const string unit_name = 
"units";
 
 5540    for(
auto ira = var->attrs.begin(); ira!= var->attrs.end();) {
 
 5541        if(unit_name == (*ira)->name) {
 
 5543            ira = var->attrs.erase(ira); 
 
 5545        else if(Unit_name == (*ira)->name) {
 
 5547            ira = var->attrs.erase(ira);
 
 5555    auto attr_unique = make_unique<Attribute>();
 
 5556    auto attr = attr_unique.release();
 
 5557    Add_Str_Attr(attr,unit_name,unit_value);
 
 5558    var->attrs.push_back(attr);
 
 5565GMFile:: Add_Aqu_Attrs()  {
 
 5567    BESDEBUG(
"h5", 
"Coming to Add_Aqu_Attrs()"<<endl);
 
 5568    vector<HDF5CF::Var *>::const_iterator it_v;
 
 5569    vector<HDF5CF::Attribute *>::const_iterator ira;
 
 5571    const string orig_longname_attr_name = 
"Parameter";
 
 5572    const string longname_attr_name =
"long_name";
 
 5573    bool has_orig_longname = 
false;
 
 5574    string longname_value;
 
 5577    const string orig_units_attr_name = 
"Units";
 
 5578    const string units_attr_name = 
"units";
 
 5579    bool has_orig_units = 
false;
 
 5582    const string orig_valid_min_attr_name = 
"Data Minimum";
 
 5583    const string orig_valid_min_attr_name2 = 
"data_minimum";
 
 5584    const string valid_min_attr_name = 
"valid_min";
 
 5585    bool has_orig_valid_min = 
false;
 
 5586    float valid_min_value = 0;
 
 5588    const string orig_valid_max_attr_name = 
"Data Maximum";
 
 5589    const string orig_valid_max_attr_name2 = 
"data_maximum";
 
 5590    const string valid_max_attr_name = 
"valid_max";
 
 5591    bool has_orig_valid_max = 
false;
 
 5592    float valid_max_value = 0;
 
 5597    const string fill_value_attr_name = 
"_FillValue";
 
 5598    float _FV = -32767.0;
 
 5600    for (ira = this->
root_attrs.begin(); ira != this->root_attrs.end(); ++ira) {
 
 5601        if (orig_longname_attr_name == (*ira)->name) {
 
 5602            Retrieve_H5_Attr_Value(*ira,
"/");
 
 5603            longname_value.resize((*ira)->value.size());
 
 5604            copy((*ira)->value.begin(),(*ira)->value.end(),longname_value.begin());
 
 5605            has_orig_longname = 
true;
 
 5607        else if (orig_units_attr_name == (*ira)->name) {
 
 5608            Retrieve_H5_Attr_Value(*ira,
"/");
 
 5609            units_value.resize((*ira)->value.size());
 
 5610            copy((*ira)->value.begin(),(*ira)->value.end(),units_value.begin());
 
 5611            has_orig_units = 
true;
 
 5613        else if (orig_valid_min_attr_name == (*ira)->name || orig_valid_min_attr_name2 == (*ira)->name) {
 
 5614            Retrieve_H5_Attr_Value(*ira,
"/");
 
 5615            memcpy(&valid_min_value,(
void*)(&((*ira)->value[0])),(*ira)->value.size());
 
 5616            has_orig_valid_min = 
true;
 
 5619        else if (orig_valid_max_attr_name == (*ira)->name || orig_valid_max_attr_name2 == (*ira)->name) {
 
 5620            Retrieve_H5_Attr_Value(*ira,
"/");
 
 5621            memcpy(&valid_max_value,(
void*)(&((*ira)->value[0])),(*ira)->value.size());
 
 5622            has_orig_valid_max = 
true;
 
 5629    bool has_long_name = 
false;
 
 5630    bool has_units = 
false;
 
 5631    bool has_valid_min = 
false;
 
 5632    bool has_valid_max = 
false;
 
 5633    bool has_fillvalue = 
false;
 
 5635    for (it_v = 
vars.begin(); it_v != 
vars.end(); ++it_v) {
 
 5636        if (
"l3m_data" == (*it_v)->name) {
 
 5637            for (ira = (*it_v)->attrs.begin(); ira != (*it_v)->attrs.end(); ++ira) {
 
 5638                if (longname_attr_name == (*ira)->name) 
 
 5639                    has_long_name = 
true;
 
 5640                else if(units_attr_name == (*ira)->name)
 
 5642                else if(valid_min_attr_name == (*ira)->name)
 
 5643                    has_valid_min = 
true;
 
 5644                else if(valid_max_attr_name == (*ira)->name)
 
 5645                    has_valid_max = 
true;
 
 5646                else if(fill_value_attr_name == (*ira)->name)
 
 5647                    has_fillvalue = 
true;
 
 5655    for (it_v = 
vars.begin(); it_v != 
vars.end(); ++it_v) {
 
 5656        if (
"l3m_data" == (*it_v)->name) {
 
 5659            if(
false == has_long_name && 
true == has_orig_longname) {
 
 5660                auto attr_unique = make_unique<Attribute>();
 
 5661                auto attr = attr_unique.release();
 
 5662                Add_Str_Attr(attr,longname_attr_name,longname_value);
 
 5663                (*it_v)->attrs.push_back(attr);
 
 5667            if(
false == has_units && 
true == has_orig_units) {
 
 5668                auto attr_unique = make_unique<Attribute>();
 
 5669                auto attr = attr_unique.release();
 
 5670                Add_Str_Attr(attr,units_attr_name,units_value);
 
 5671                (*it_v)->attrs.push_back(attr);
 
 5675            if (
false == has_valid_min && has_orig_valid_min == 
true) {
 
 5676                auto attr_unique = make_unique<Attribute>();
 
 5677                auto attr = attr_unique.release();
 
 5678                Add_One_Float_Attr(attr,valid_min_attr_name,valid_min_value);
 
 5679                (*it_v)->attrs.push_back(attr);
 
 5683            if(
false == has_valid_max && has_orig_valid_max == 
true) {
 
 5684                auto attr_unique = make_unique<Attribute>();
 
 5685                auto attr = attr_unique.release();
 
 5686                Add_One_Float_Attr(attr,valid_max_attr_name,valid_max_value);
 
 5687                (*it_v)->attrs.push_back(attr);
 
 5691            if(
false == has_fillvalue) {
 
 5692               auto attr_unique = make_unique<Attribute>();
 
 5693               auto attr = attr_unique.release();
 
 5694               Add_One_Float_Attr(attr,fill_value_attr_name,_FV);
 
 5695               (*it_v)->attrs.push_back(attr);
 
 5705GMFile:: Add_SeaWiFS_Attrs()
 const {
 
 5707    BESDEBUG(
"h5", 
"Coming to Add_SeaWiFS_Attrs()"<<endl);
 
 5710    const string fill_value_attr_name = 
"_FillValue";
 
 5712    const string valid_range_attr_name = 
"valid_range";
 
 5714    for (
auto &var:this->
vars) {
 
 5715        if (H5FLOAT32 == var->dtype) {
 
 5716            bool has_fillvalue = 
false;
 
 5717            bool has_validrange = 
false;
 
 5718            for(
const auto &attr:var->attrs) {
 
 5719                if (fill_value_attr_name == attr->name){
 
 5720                    has_fillvalue = 
true;
 
 5723                else if(valid_range_attr_name == attr->name) {
 
 5724                    has_validrange = 
true;
 
 5729            if (has_fillvalue != 
true && has_validrange != 
true ) {
 
 5730                auto attr_unique = make_unique<Attribute>();
 
 5731                auto attr = attr_unique.release();
 
 5732                Add_One_Float_Attr(attr,fill_value_attr_name,_FV);
 
 5733                var->attrs.push_back(attr);
 
 5744    string co_attrname = 
"coordinates";
 
 5745    string co_attrvalue=
"";
 
 5746    string unit_attrname = 
"units";
 
 5747    string nonll_unit_attrvalue =
"level";
 
 5748    string lat_unit_attrvalue =
"degrees_north";
 
 5749    string lon_unit_attrvalue =
"degrees_east";
 
 5751    for (
auto ircv = this->cvars.begin();
 
 5752        ircv != this->cvars.end(); ++ircv) {
 
 5755        if ((*ircv)->cvartype == CV_NONLATLON_MISS) {
 
 5756           Attribute * attr = 
new Attribute();
 
 5757           Add_Str_Attr(attr,unit_attrname,nonll_unit_attrvalue);
 
 5758           (*ircv)->attrs.push_back(attr);
 
 5761        else if ((*ircv)->cvartype == CV_LAT_MISS) {
 
 5763           Attribute * attr = 
new Attribute();
 
 5766           Add_Str_Attr(attr,unit_attrname,lat_unit_attrvalue);
 
 5767           (*ircv)->attrs.push_back(attr);
 
 5771        else if ((*ircv)->cvartype == CV_LON_MISS) {
 
 5772           Attribute * attr = 
new Attribute();
 
 5773           Add_Str_Attr(attr,unit_attrname,lon_unit_attrvalue);
 
 5774           (*ircv)->attrs.push_back(attr);
 
 5779    if(product_type == Mea_SeaWiFS_L2) 
 
 5783    else if(product_type == GPM_L1) {
 
 5784        Handle_GPM_l1_Coor_Attr();
 
 5788    else if (
true == iscoard) {
 
 5795    for (
auto ircv = this->cvars.begin();
 
 5796        ircv != this->cvars.end(); ++ircv) {
 
 5797        if((*ircv)->rank == 2) {
 
 5800            if(gp_latname == (*ircv)->name) 
 
 5801                Replace_Var_Str_Attr((*ircv),unit_attrname,lat_unit_attrvalue);
 
 5802            else if(gp_lonname ==(*ircv)->name) 
 
 5803                Replace_Var_Str_Attr((*ircv),unit_attrname,lon_unit_attrvalue);
 
 5808    string ll2d_dimname0,ll2d_dimname1;
 
 5809    bool has_ll2d_coords = 
false;
 
 5810    for (
auto ircv = this->cvars.begin();
 
 5811        ircv != this->cvars.end(); ++ircv) {
 
 5812        if((*ircv)->rank == 2) {
 
 5814            ll2d_dimname0 = (*ircv)->getDimensions()[0]->name;
 
 5815            ll2d_dimname1 = (*ircv)->getDimensions()[1]->name;
 
 5816            if(ll2d_dimname0 !=
"" && ll2d_dimname1 !=
"")
 
 5817                has_ll2d_coords = 
true;
 
 5822    if(
true == has_ll2d_coords) {
 
 5824        for (
auto irv = this->
vars.begin();
 
 5825                irv != this->vars.end(); ++irv) {
 
 5827            bool coor_attr_keep_exist = 
false;
 
 5830            if(((*irv)->rank >=2)) { 
 
 5832                short ll2dim_flag = 0;
 
 5833                for (
auto ird = (*irv)->dims.begin();
 
 5834                    ird != (*irv)->dims.end(); ++ ird) {
 
 5835                    if((*ird)->name == ll2d_dimname0)
 
 5837                    else if((*ird)->name == ll2d_dimname1)
 
 5841                if(ll2dim_flag != 2) 
 
 5842                    coor_attr_keep_exist = 
true;
 
 5845                if(product_type == OSMAPL2S)
 
 5846                    coor_attr_keep_exist = 
true;
 
 5848                if (
false == coor_attr_keep_exist) {
 
 5849                    for (
auto ira =(*irv)->attrs.begin();
 
 5850                        ira !=(*irv)->attrs.end();) {
 
 5851                        if ((*ira)->newname == co_attrname) {
 
 5853                            ira = (*irv)->attrs.erase(ira);
 
 5861                    for (
auto ird = (*irv)->dims.begin();
 
 5862                        ird != (*irv)->dims.end(); ++ ird) {
 
 5863                        for (
auto ircv = this->cvars.begin();
 
 5864                            ircv != this->cvars.end(); ++ircv) {
 
 5865                            if ((*ird)->name == (*ircv)->cfdimname) 
 
 5866                                co_attrvalue = (co_attrvalue.empty())
 
 5867                                    ?(*ircv)->newname:co_attrvalue + 
" "+(*ircv)->newname;
 
 5871                    if (
false == co_attrvalue.empty()) {
 
 5872                        Attribute * attr = 
new Attribute();
 
 5873                        Add_Str_Attr(attr,co_attrname,co_attrvalue);
 
 5874                       (*irv)->attrs.push_back(attr);
 
 5877                    co_attrvalue.clear();
 
 5889    BESDEBUG(
"h5", 
"GMFile::Coming to Handle_Coor_Attr()"<<endl);
 
 5890    string co_attrname = 
"coordinates";
 
 5891    string co_attrvalue;
 
 5892    string unit_attrname = 
"units";
 
 5893    string nonll_unit_attrvalue =
"level";
 
 5894    string lat_unit_attrvalue =
"degrees_north";
 
 5895    string lon_unit_attrvalue =
"degrees_east";
 
 5899    for (
auto &cvar:this->cvars) {
 
 5901        if (cvar->cvartype == CV_NONLATLON_MISS) {
 
 5902           auto attr_unique = make_unique<Attribute>();
 
 5903           auto attr = attr_unique.release();
 
 5904           Add_Str_Attr(attr,unit_attrname,nonll_unit_attrvalue);
 
 5905           cvar->attrs.push_back(attr);
 
 5907        else if (cvar->cvartype == CV_LAT_MISS) {
 
 5908           auto attr_unique = make_unique<Attribute>();
 
 5909           auto attr = attr_unique.release();
 
 5910           Add_Str_Attr(attr,unit_attrname,lat_unit_attrvalue);
 
 5911           cvar->attrs.push_back(attr);
 
 5913        else if (cvar->cvartype == CV_LON_MISS) {
 
 5914           auto attr_unique = make_unique<Attribute>();
 
 5915           auto attr = attr_unique.release();
 
 5916           Add_Str_Attr(attr,unit_attrname,lon_unit_attrvalue);
 
 5917           cvar->attrs.push_back(attr);
 
 5922    if(product_type == Mea_SeaWiFS_L2) 
 
 5926    else if(product_type == GPM_L1) {
 
 5927        Handle_GPM_l1_Coor_Attr();
 
 5932    else if(product_type == General_Product && gproduct_pattern == GENERAL_LATLON_COOR_ATTR){
 
 5933        Handle_LatLon_With_CoordinateAttr_Coor_Attr();
 
 5937    else if (
true == iscoard) {
 
 5941        if(grp_cv_paths.empty() == 
false) {
 
 5942            for (
auto &var:this->vars) {
 
 5943                if(grp_cv_paths.find(HDF5CFUtil::obtain_string_before_lastslash(var->fullpath)) != grp_cv_paths.end()){ 
 
 5945                    Flatten_VarPath_In_Coordinates_Attr(var);
 
 5953    for (
auto &cvar:this->cvars) {
 
 5955        if(cvar->rank == 2 && cvar->cvartype == CV_EXIST) {
 
 5963            if(gp_latname == cvar->name) { 
 
 5965                if(
false == Is_geolatlon(gp_latname,
true)) 
 
 5966                    Replace_Var_Str_Attr(cvar,unit_attrname,lat_unit_attrvalue);
 
 5968            else if(gp_lonname ==cvar->name) { 
 
 5970                if(
false == Is_geolatlon(gp_lonname,
false))
 
 5971                    Replace_Var_Str_Attr(cvar,unit_attrname,lon_unit_attrvalue);
 
 5979            if(
true == Is_geolatlon(cvar->name,
true))
 
 5980                Replace_Var_Str_Attr(cvar,unit_attrname,lat_unit_attrvalue);
 
 5981            else if(
true == Is_geolatlon(cvar->name,
false))
 
 5982                Replace_Var_Str_Attr(cvar,unit_attrname,lon_unit_attrvalue);
 
 5988    if (grp_cv_paths.empty() == 
false) {
 
 5989        for (
auto &var:this->vars) {
 
 5990            if(grp_cv_paths.find(HDF5CFUtil::obtain_string_before_lastslash(var->fullpath)) != grp_cv_paths.end()){ 
 
 5992                Flatten_VarPath_In_Coordinates_Attr(var);
 
 5998    bool has_ll2d_coords = 
false;
 
 6001    if(General_Product == this->product_type && GENERAL_DIMSCALE == this->gproduct_pattern) 
 
 6002        has_ll2d_coords = 
true; 
 
 6004        string ll2d_dimname0;
 
 6005        string ll2d_dimname1;
 
 6006        for (
const auto &cvar:this->cvars) {
 
 6007            if(cvar->rank == 2) {
 
 6009                ll2d_dimname0 = cvar->getDimensions()[0]->name;
 
 6010                ll2d_dimname1 = cvar->getDimensions()[1]->name;
 
 6011                if(ll2d_dimname0 !=
"" && ll2d_dimname1 !=
"")
 
 6012                    has_ll2d_coords = 
true;
 
 6019    if(
true == has_ll2d_coords) {
 
 6027        bool force_flatten_coor_attr = HDF5RequestHandler::get_force_flatten_coor_attr();
 
 6031        bool has_coor_attr_ge_2d_vars = 
false;
 
 6032        for (
const auto &var:this->vars) {
 
 6034                for (
const auto &attr:var->attrs) {
 
 6036                    if(attr->name == co_attrname) {
 
 6037                        has_coor_attr_ge_2d_vars = 
true;
 
 6041                if(has_coor_attr_ge_2d_vars == 
true)
 
 6048        bool is_hybrid_eos5= 
false;
 
 6049        if(force_flatten_coor_attr == 
true && has_coor_attr_ge_2d_vars == 
true)
 
 6050            is_hybrid_eos5 = Is_Hybrid_EOS5();
 
 6052        for (
auto &var:this->vars) {
 
 6054            bool has_coor = 
false;
 
 6055            for (
const auto &attr:var->attrs) {
 
 6057                if(attr->name == co_attrname) {
 
 6064            if(
true == force_flatten_coor_attr && 
true == has_coor) { 
 
 6066                if(is_hybrid_eos5 == 
true) {
 
 6067                    Flatten_VarPath_In_Coordinates_Attr_EOS5(var);
 
 6071                    Flatten_VarPath_In_Coordinates_Attr(var);
 
 6074            else if((var->rank >=2) && (has_coor_attr_ge_2d_vars == 
false || 
false == force_flatten_coor_attr)) { 
 
 6076                bool coor_attr_keep_exist = 
false;
 
 6079                if(grp_cv_paths.find(HDF5CFUtil::obtain_string_before_lastslash(var->fullpath)) == grp_cv_paths.end()) 
 
 6082                    coor_attr_keep_exist = Check_Var_2D_CVars(var);
 
 6084                    coor_attr_keep_exist = 
true;
 
 6088                if(product_type == OSMAPL2S)
 
 6089                    coor_attr_keep_exist = 
true;
 
 6092                if (
false == coor_attr_keep_exist) {
 
 6093                    for (
auto ira =var->attrs.begin(); ira !=var->attrs.end();) {
 
 6094                        if ((*ira)->newname == co_attrname) {
 
 6096                            ira = var->attrs.erase(ira);
 
 6104                    for (
const auto &dim:var->dims) {
 
 6105                        for (
const auto &cvar:this->cvars) {
 
 6106                            if (dim->name == cvar->cfdimname) 
 
 6107                                co_attrvalue = (co_attrvalue.empty())
 
 6108                                    ?cvar->newname:co_attrvalue + 
" "+cvar->newname;
 
 6112                    if (
false == co_attrvalue.empty()) {
 
 6113                        auto attr_unique = make_unique<Attribute>();
 
 6114                        auto attr = attr_unique.release();
 
 6115                        Add_Str_Attr(attr,co_attrname,co_attrvalue);
 
 6116                        var->attrs.push_back(attr);
 
 6119                    co_attrvalue.clear();
 
 6120                    var->coord_attr_add_path = 
false;
 
 
 6128void GMFile:: Handle_GPM_l1_Coor_Attr()
 const {
 
 6130    BESDEBUG(
"h5", 
"Coming to Handle_GPM_l1_Coor_Attr()"<<endl);
 
 6144    string co_attrname = 
"coordinates";
 
 6145    string co_attrvalue;
 
 6148    set<string> cvar_2d_dimset;
 
 6150    pair<map<string,string>::iterator,
bool>mapret;
 
 6153    map<string,string>cfdimname_to_cvar2dname;
 
 6156    for (
const auto &cvar:this->cvars) {
 
 6159        if(cvar->rank == 2) { 
 
 6167            for (
const auto &dim:cvar->dims) 
 
 6168                cvar_2d_dimset.insert(dim->name);
 
 6171            mapret = cfdimname_to_cvar2dname.insert(pair<string,string>(cvar->cfdimname,cvar->newname));      
 
 6172            if (
false == mapret.second)
 
 6173                throw4(
"The cf dimension name ",cvar->cfdimname,
" should map to 2-D coordinate variable",
 
 6179    for (
auto &var:this->
vars) {
 
 6186            short have_2d_dimnames_flag = 0;
 
 6187            for (
const auto &dim:var->dims) {
 
 6188                if (cvar_2d_dimset.find(dim->name)!=cvar_2d_dimset.end())    
 
 6189                    have_2d_dimnames_flag++;
 
 6193            if(have_2d_dimnames_flag >=2) {
 
 6197                if(var->fullpath.size() > var->name.size()) 
 
 6198                    var_path=var->fullpath.substr(0,var->fullpath.size()-var->name.size());
 
 6200                    throw4(
"The variable full path ",var->fullpath,
" doesn't contain the variable name ",
 
 6204                short cv_2d_flag = 0;
 
 6207                vector<string> cv_2d_names;
 
 6210                set<string> cv_2d_dimnames;
 
 6213                for(map<string,string>::const_iterator itm = cfdimname_to_cvar2dname.begin();
 
 6214                    itm != cfdimname_to_cvar2dname.end();++itm) {
 
 6217                    string reduced_dimname = HDF5CFUtil::obtain_string_after_lastslash(itm->first);
 
 6219                    if(itm->first.size() <= reduced_dimname.size()) 
 
 6220                        throw2(
"The cf dim. name of this dimension is not right.",itm->first);
 
 6222                        cfdim_path= itm->first.substr(0,itm->first.size() - reduced_dimname.size());
 
 6231                    if(var_path == cfdim_path) {
 
 6232                        for (
const auto &dim:var->dims) {
 
 6233                            if(reduced_dimname == dim->name) {
 
 6235                               cv_2d_names.push_back(itm->second);
 
 6236                               cv_2d_dimnames.insert(dim->name);
 
 6248                if(cv_2d_flag != 2) {
 
 6251                    for(map<string,string>::const_iterator itm = cfdimname_to_cvar2dname.begin();
 
 6252                        itm != cfdimname_to_cvar2dname.end();++itm) {
 
 6254                        string reduced_dimname = HDF5CFUtil::obtain_string_after_lastslash(itm->first);
 
 6256                        if(itm->first.size() <= reduced_dimname.size()) 
 
 6257                            throw2(
"The cf dim. name of this dimension is not right.",itm->first);
 
 6259                            cfdim_path= itm->first.substr(0,itm->first.size() - reduced_dimname.size());
 
 6268                        if(var_path.find(cfdim_path)!=string::npos) {
 
 6269                            for (
const auto &dim:var->dims) {
 
 6270                                if(reduced_dimname == dim->name) {
 
 6272                                   cv_2d_names.push_back(itm->second);
 
 6273                                   cv_2d_dimnames.insert(dim->name);
 
 6282                if(2 == cv_2d_flag) {
 
 6285                    co_attrvalue = cv_2d_names[0] + 
" " + cv_2d_names[1];
 
 6287                        for (
const auto &dim:var->dims) {
 
 6290                            if(cv_2d_dimnames.find(dim->name) == cv_2d_dimnames.end())
 
 6291                                co_attrvalue = co_attrvalue + 
" " +dim->newname;
 
 6294                    auto attr_unique = make_unique<Attribute>();
 
 6295                    auto attr = attr_unique.release();
 
 6296                    Add_Str_Attr(attr,co_attrname,co_attrvalue);
 
 6297                    var->attrs.push_back(attr);
 
 6298                    var->coord_attr_add_path = 
false;
 
 6306void GMFile::Handle_LatLon_With_CoordinateAttr_Coor_Attr()  {
 
 6308    BESDEBUG(
"h5", 
"Coming to Handle_LatLon_With_CoordinateAttr_Coor_Attr()"<<endl);
 
 6309    string co_attrname = 
"coordinates";
 
 6312    for (
auto &var:this->
vars) {
 
 6313        if(var->rank >= 2) {
 
 6314            for (
auto &attr:var->attrs) { 
 
 6315                if(attr->name == co_attrname) {
 
 6318                    string coor_value = Retrieve_Str_Attr_Value(attr,var->fullpath);
 
 6319                    if(Coord_Match_LatLon_NameSize(coor_value) == 
true) 
 
 6320                        Flatten_VarPath_In_Coordinates_Attr(var);
 
 6324                    else if(Coord_Match_LatLon_NameSize_Same_Group(coor_value,HDF5CFUtil::obtain_string_before_lastslash(var->fullpath)) == 
true) 
 
 6325                        Add_VarPath_In_Coordinates_Attr(var,coor_value);
 
 6337bool GMFile::Coord_Match_LatLon_NameSize(
const string & coord_values)  {
 
 6339    BESDEBUG(
"h5", 
"Coming to Coord_Match_LatLon_NameSize()"<<endl);
 
 6340    bool ret_value =
false;
 
 6341    vector<string> coord_values_vec;
 
 6343    int match_lat_name_pair_index = -1;
 
 6344    int match_lon_name_pair_index = -2;
 
 6345    int num_match_lat = 0;
 
 6346    int num_match_lon = 0;
 
 6350    HDF5CFUtil::Split_helper(coord_values_vec,coord_values,sep);
 
 6353    if((coord_values_vec[0])[0] !=
'/') {
 
 6354        for(
auto &coor_value:coord_values_vec){
 
 6355            if((coor_value.find_first_of(
'/'))!=string::npos) {
 
 6356                coor_value = 
'/' + coor_value;
 
 6362    for (
const auto &coor_value:coord_values_vec){
 
 6366        for(
auto ivs=latloncv_candidate_pairs.begin(); ivs!=latloncv_candidate_pairs.end();++ivs) {
 
 6367            if(coor_value == (*ivs).name1){
 
 6368                match_lat_name_pair_index = distance(latloncv_candidate_pairs.begin(),ivs);
 
 6371            else if (coor_value == (*ivs).name2) {
 
 6372                match_lon_name_pair_index = distance(latloncv_candidate_pairs.begin(),ivs);
 
 6378    if((match_lat_name_pair_index == match_lon_name_pair_index) && (num_match_lat ==1) && (num_match_lon ==1))
 
 6387bool GMFile::Coord_Match_LatLon_NameSize_Same_Group(
const string &coord_values,
const string &var_path) {
 
 6389    BESDEBUG(
"h5", 
"Coming to Coord_Match_LatLon_NameSize_Same_Group()"<<endl);
 
 6390    bool ret_value =
false;
 
 6391    vector<string> coord_values_vec;
 
 6393    int match_lat_name_pair_index = -1;
 
 6394    int match_lon_name_pair_index = -2;
 
 6395    int num_match_lat = 0;
 
 6396    int num_match_lon = 0;
 
 6398    HDF5CFUtil::Split_helper(coord_values_vec,coord_values,sep);
 
 6401    for (
const auto &coord_value:coord_values_vec){
 
 6405        for(
auto ivs=latloncv_candidate_pairs.begin(); ivs!=latloncv_candidate_pairs.end();++ivs) {
 
 6406            string lat_name = HDF5CFUtil::obtain_string_after_lastslash((*ivs).name1);
 
 6407            string lat_path = HDF5CFUtil::obtain_string_before_lastslash((*ivs).name1);
 
 6408            string lon_name = HDF5CFUtil::obtain_string_after_lastslash((*ivs).name2);
 
 6409            string lon_path = HDF5CFUtil::obtain_string_before_lastslash((*ivs).name2);
 
 6410            if(coord_value == lat_name && lat_path == var_path){
 
 6411                match_lat_name_pair_index = distance(latloncv_candidate_pairs.begin(),ivs);
 
 6414            else if (coord_value == lon_name && lon_path == var_path) {
 
 6415                match_lon_name_pair_index = distance(latloncv_candidate_pairs.begin(),ivs);
 
 6421    if((match_lat_name_pair_index == match_lon_name_pair_index) && (num_match_lat ==1) && (num_match_lon ==1))
 
 6428void GMFile::Add_VarPath_In_Coordinates_Attr(
Var *var, 
const string &coor_value) {
 
 6430    BESDEBUG(
"h5", 
"Coming to Add_VarPath_In_Coordinates_Attr()"<<endl);
 
 6431    string new_coor_value;
 
 6433    string var_path = HDF5CFUtil::obtain_string_before_lastslash(var->fullpath) ;
 
 6434    string var_flatten_path = get_CF_string(var_path);
 
 6437    size_t ele_start_pos = 0;
 
 6438    size_t cur_pos = coor_value.find_first_of(sep);
 
 6439    while(cur_pos !=string::npos) {
 
 6440        string tempstr = coor_value.substr(ele_start_pos,cur_pos-ele_start_pos);
 
 6441        tempstr = var_flatten_path + tempstr;
 
 6442        new_coor_value += tempstr + sep;
 
 6443        ele_start_pos = cur_pos+1;
 
 6444        cur_pos = coor_value.find_first_of(sep,cur_pos+1);
 
 6447    if(ele_start_pos == 0)
 
 6448        new_coor_value = var_flatten_path + coor_value;
 
 6450        new_coor_value += var_flatten_path + coor_value.substr(ele_start_pos);
 
 6452    string coor_attr_name = 
"coordinates";
 
 6453    Replace_Var_Str_Attr(var,coor_attr_name,new_coor_value);
 
 6454    var->coord_attr_add_path = 
false;
 
 6459void GMFile:: Create_Missing_CV(
GMCVar *GMcvar, 
const string& dimname)  {
 
 6461    BESDEBUG(
"h5", 
"GMFile::Coming to Create_Missing_CV()"<<endl);
 
 6463    GMcvar->name = dimname;
 
 6464    GMcvar->newname = GMcvar->name;
 
 6465    GMcvar->fullpath = GMcvar->name;
 
 6467    GMcvar->dtype = H5INT32;
 
 6468    hsize_t gmcvar_dimsize = dimname_to_dimsize[dimname];
 
 6469    bool unlimited_flag = dimname_to_unlimited[dimname];
 
 6471    auto gmcvar_dim_unique = make_unique<Dimension>(gmcvar_dimsize);
 
 6472    auto gmcvar_dim = gmcvar_dim_unique.release();
 
 6474    gmcvar_dim->unlimited_dim = unlimited_flag;
 
 6475    gmcvar_dim->name = dimname;
 
 6476    gmcvar_dim->newname = dimname;
 
 6477    GMcvar->dims.push_back(gmcvar_dim);
 
 6478    GMcvar->cfdimname = dimname;
 
 6479    GMcvar->cvartype = CV_NONLATLON_MISS;
 
 6480    GMcvar->product_type = product_type;
 
 6485bool GMFile::Is_netCDF_Dimension(
const Var *var)
 const {
 
 6487    string netcdf_dim_mark = 
"This is a netCDF dimension but not a netCDF variable";
 
 6489    bool is_only_dimension = 
false;
 
 6491    for(
const auto &attr:var->attrs) {
 
 6493        if (
"NAME" == attr->name) {
 
 6495             Retrieve_H5_Attr_Value(attr,var->fullpath);
 
 6497             name_value.resize(attr->value.size());
 
 6498             copy(attr->value.begin(),attr->value.end(),name_value.begin());
 
 6501             if (0 == name_value.compare(0,netcdf_dim_mark.size(),netcdf_dim_mark))
 
 6502                is_only_dimension = 
true;
 
 6508    return is_only_dimension;
 
 6518GMFile::Is_Hybrid_EOS5()
 const {
 
 6520    bool has_group_hdfeos  = 
false;
 
 6521    bool has_group_hdfeos_info = 
false;
 
 6527    for (
const auto &grp:this->groups) {
 
 6528        if (
"/HDFEOS" == grp->path) 
 
 6529            has_group_hdfeos = 
true;
 
 6530        else if(
"/HDFEOS INFORMATION" == grp->path) {
 
 6531            for(
const auto &attr:grp->attrs) {
 
 6532                if(
"HDFEOSVersion" == attr->name)
 
 6533                    has_group_hdfeos_info = 
true;
 
 6536        if(
true == has_group_hdfeos && 
true == has_group_hdfeos_info)
 
 6541    if(
true == has_group_hdfeos && 
true == has_group_hdfeos_info) 
 
 6547void GMFile::Handle_Hybrid_EOS5() {
 
 6549    string eos_str=
"HDFEOS_";
 
 6550    string eos_info_str=
"HDFEOS_INFORMATION_";
 
 6551    string grid_str=
"GRIDS_";
 
 6552    string swath_str=
"SWATHS_";
 
 6553    string zas_str=
"ZAS_";
 
 6554    string df_str=
"Data_Fields_";
 
 6555    string gf_str=
"Geolocation_Fields_";
 
 6556    for (
auto &var:this->
vars) {
 
 6557        string temp_var_name = var->newname;
 
 6559        bool remove_eos = Remove_EOS5_Strings(temp_var_name);
 
 6561        if(
true == remove_eos)
 
 6562            var->newname = get_CF_string(temp_var_name);
 
 6564            string::size_type eos_info_pos = temp_var_name.find(eos_info_str);
 
 6565            if(eos_info_pos !=string::npos) 
 
 6566                var->newname = temp_var_name.erase(eos_info_pos,eos_info_str.size());
 
 6568                if(Remove_EOS5_Strings_NonEOS_Fields(temp_var_name)==
true)
 
 6569                    var->newname = get_CF_string(temp_var_name);
 
 6575    for (
auto &var:this->
vars) {
 
 6576        for (
auto &dim:var->dims) {
 
 6577            string temp_dim_name = dim->newname;
 
 6578            bool remove_eos = Remove_EOS5_Strings(temp_dim_name);
 
 6580            if(
true == remove_eos)
 
 6581                dim->newname = get_CF_string(temp_dim_name);
 
 6583                string::size_type eos_info_pos = temp_dim_name.find(eos_info_str);
 
 6584                if(eos_info_pos !=string::npos) 
 
 6585                    dim->newname = temp_dim_name.erase(eos_info_pos,eos_info_str.size());
 
 6587                    if(Remove_EOS5_Strings_NonEOS_Fields(temp_dim_name)==
true)
 
 6588                        dim->newname = get_CF_string(temp_dim_name);
 
 6595    for (
auto &cvar:this->cvars) {
 
 6596        string temp_var_name = cvar->newname;
 
 6598        bool remove_eos = Remove_EOS5_Strings(temp_var_name);
 
 6600        if(
true == remove_eos)
 
 6601            cvar->newname = get_CF_string(temp_var_name);
 
 6603            string::size_type eos_info_pos = temp_var_name.find(eos_info_str);
 
 6604            if(eos_info_pos !=string::npos) 
 
 6605                cvar->newname = temp_var_name.erase(eos_info_pos,eos_info_str.size());
 
 6607                if(Remove_EOS5_Strings_NonEOS_Fields(temp_var_name)==
true)
 
 6608                    cvar->newname = get_CF_string(temp_var_name);
 
 6613    for (
const auto &cvar:this->cvars) {
 
 6614        for (
const auto &dim:cvar->dims) {
 
 6615            string temp_dim_name = dim->newname;
 
 6616            bool remove_eos = Remove_EOS5_Strings(temp_dim_name);
 
 6618            if(
true == remove_eos)
 
 6619                dim->newname = get_CF_string(temp_dim_name);
 
 6621                string::size_type eos_info_pos = temp_dim_name.find(eos_info_str);
 
 6622                if(eos_info_pos !=string::npos) 
 
 6623                    dim->newname = temp_dim_name.erase(eos_info_pos,eos_info_str.size());
 
 6625                    if(Remove_EOS5_Strings_NonEOS_Fields(temp_dim_name)==
true)
 
 6626                        dim->newname = get_CF_string(temp_dim_name);
 
 6635    for (
const auto &var:this->
vars) {
 
 6636        for (
const auto &attr:var->attrs) {
 
 6639            if(attr->name == 
"coordinates") {
 
 6640                string cor_values(attr->value.begin(),attr->value.end()) ;
 
 6641                bool change_cor_values = 
false;
 
 6643                if(cor_values.find(eos_str)==0) {
 
 6644                    if(cor_values.find(grid_str)!=string::npos) {
 
 6645                        cor_values = HDF5CFUtil::remove_substrings(cor_values,eos_str);
 
 6646                        cor_values = HDF5CFUtil::remove_substrings(cor_values,grid_str);
 
 6647                        string new_cor_values = HDF5CFUtil::remove_substrings(cor_values,df_str);
 
 6648                        if(new_cor_values.size() < cor_values.size()){
 
 6649                            change_cor_values = 
true;
 
 6650                            cor_values = new_cor_values;
 
 6653                    else if(cor_values.find(zas_str)!=string::npos) {
 
 6654                        cor_values = HDF5CFUtil::remove_substrings(cor_values,eos_str);
 
 6655                        cor_values = HDF5CFUtil::remove_substrings(cor_values,zas_str);
 
 6656                        string new_cor_values = HDF5CFUtil::remove_substrings(cor_values,df_str);
 
 6657                        if(new_cor_values.size() < cor_values.size()){
 
 6658                            change_cor_values = 
true;
 
 6659                            cor_values = new_cor_values;
 
 6662                    else if(cor_values.find(swath_str)!=string::npos) {
 
 6663                        cor_values = HDF5CFUtil::remove_substrings(cor_values,eos_str);
 
 6664                        cor_values = HDF5CFUtil::remove_substrings(cor_values,swath_str);
 
 6665                        string new_cor_values = HDF5CFUtil::remove_substrings(cor_values,df_str);
 
 6666                        if(new_cor_values.size() < cor_values.size()){
 
 6667                            change_cor_values = 
true;
 
 6668                            cor_values = new_cor_values;
 
 6671                            new_cor_values = HDF5CFUtil::remove_substrings(cor_values,gf_str);
 
 6672                            if(new_cor_values.size() < cor_values.size()){
 
 6673                                change_cor_values = 
true;
 
 6674                                cor_values = new_cor_values;
 
 6679                if(
true == change_cor_values) {
 
 6680                    attr->value.resize(cor_values.size());
 
 6681                    attr->fstrsize=cor_values.size();
 
 6682                    attr->strsize[0] = cor_values.size();
 
 6683                    copy(cor_values.begin(), cor_values.end(), attr->value.begin());
 
 6684                    var->coord_attr_add_path = 
false;
 
 6694bool GMFile:: Remove_EOS5_Strings(
string &var_name)
 const {
 
 6696    string eos_str=
"HDFEOS_";
 
 6697    string grid_str=
"GRIDS_";
 
 6698    string swath_str=
"SWATHS_";
 
 6699    string zas_str=
"ZAS_";
 
 6700    string df_str=
"Data_Fields_";
 
 6701    string gf_str=
"Geolocation_Fields_";
 
 6702    string temp_var_name = var_name;
 
 6704    bool remove_eos = 
false;
 
 6706    string::size_type eos_pos = temp_var_name.find(eos_str);
 
 6707    if(eos_pos!=string::npos) {
 
 6708        temp_var_name.erase(eos_pos,eos_str.size());
 
 6710        string::size_type grid_pos=temp_var_name.find(grid_str);
 
 6711        string::size_type grid_df_pos=string::npos;
 
 6712        if(grid_pos!=string::npos)
 
 6713            grid_df_pos = temp_var_name.find(df_str,grid_pos);
 
 6714        string::size_type zas_pos = string::npos;
 
 6715        string::size_type zas_df_pos=string::npos;
 
 6716        if(grid_pos==string::npos || grid_df_pos ==string::npos) 
 
 6717            zas_pos=temp_var_name.find(zas_str);
 
 6718        if(zas_pos!=string::npos)
 
 6719            zas_df_pos=temp_var_name.find(df_str,zas_pos);
 
 6721        if(grid_pos !=string::npos && grid_df_pos!=string::npos) {
 
 6722            temp_var_name.erase(grid_pos,grid_str.size());
 
 6723            grid_df_pos = temp_var_name.find(df_str);              
 
 6724            temp_var_name.erase(grid_df_pos,df_str.size());
 
 6727        else if(zas_pos!=string::npos && zas_df_pos!=string::npos){
 
 6728            temp_var_name.erase(zas_pos,zas_str.size());
 
 6729            zas_df_pos = temp_var_name.find(df_str);              
 
 6730            temp_var_name.erase(zas_df_pos,df_str.size());
 
 6735            string::size_type swath_pos=temp_var_name.find(swath_str);
 
 6736            string::size_type swath_df_pos=string::npos;
 
 6737            if(swath_pos!=string::npos)
 
 6738                swath_df_pos=temp_var_name.find(df_str,swath_pos);
 
 6740            string::size_type swath_gf_pos=string::npos;
 
 6741            if(swath_pos!=string::npos && swath_df_pos == string::npos)
 
 6742                swath_gf_pos=temp_var_name.find(gf_str,swath_pos);
 
 6744            if(swath_pos !=string::npos) {
 
 6746                if(swath_df_pos!=string::npos) {
 
 6747                    temp_var_name.erase(swath_pos,swath_str.size());
 
 6748                    swath_df_pos = temp_var_name.find(df_str);              
 
 6749                    temp_var_name.erase(swath_df_pos,df_str.size());
 
 6752                else if(swath_gf_pos!=string::npos) {
 
 6753                    temp_var_name.erase(swath_pos,swath_str.size());
 
 6754                    swath_gf_pos = temp_var_name.find(gf_str);              
 
 6755                    temp_var_name.erase(swath_gf_pos,gf_str.size());
 
 6761    if(
true == remove_eos)
 
 6762        var_name = temp_var_name;
 
 6767bool GMFile:: Remove_EOS5_Strings_NonEOS_Fields(
string &var_name)
 const{
 
 6769    string eos_str=
"HDFEOS_";
 
 6770    string grid_str=
"GRIDS_";
 
 6771    string swath_str=
"SWATHS_";
 
 6772    string zas_str=
"ZAS_";
 
 6773    string temp_var_name = var_name;
 
 6775    bool remove_eos = 
false;
 
 6777    string::size_type eos_pos = temp_var_name.find(eos_str);
 
 6778    if(eos_pos!=string::npos) {
 
 6779        temp_var_name.erase(eos_pos,eos_str.size());
 
 6783        if(temp_var_name.find(grid_str)==0)
 
 6784            temp_var_name.erase(0,grid_str.size());
 
 6785        else if(temp_var_name.find(swath_str)==0)
 
 6786            temp_var_name.erase(0,swath_str.size());
 
 6787        else if(temp_var_name.find(zas_str)==0)
 
 6788            temp_var_name.erase(0,zas_str.size());
 
 6790    if(
true == remove_eos)
 
 6791        var_name = temp_var_name;
 
 6812    if(this->unsupported_var_dtype == 
true) {
 
 6815        for (
auto ircv = this->cvars.begin(); ircv != this->cvars.end();) {
 
 6816            if((*ircv)->newname.find(
"FakeDim")==0) {
 
 6817                bool var_has_fakedim = 
false;
 
 6818                for (
const auto &var:this->vars) {
 
 6819                    for (
const auto &dim:var->dims) {
 
 6820                        if(dim->newname == (*ircv)->newname){
 
 6821                            var_has_fakedim = 
true;
 
 6825                    if(var_has_fakedim == 
true) 
 
 6828                if(var_has_fakedim == 
false) {
 
 6831                    ircv = this->cvars.erase(ircv);
 
 
 6853    if(
true == this->have_nc4_non_coord) {
 
 6854        string nc4_non_coord=
"_nc4_non_coord_";
 
 6855        size_t nc4_non_coord_size= nc4_non_coord.size();
 
 6856        for (
const auto &var:this->vars) {
 
 6857            if(var->name.find(nc4_non_coord)==0) {
 
 6858                size_t rm_str_pos = var->newname.find(nc4_non_coord);
 
 6859                if (rm_str_pos == string::npos) 
 
 6860                    throw4(var->name,
" variable's new name ",var->newname, 
"doesn't contain nc4_non_coord");
 
 6862                    string var_new_first_part;
 
 6864                        var_new_first_part = var->newname.substr(0,rm_str_pos);
 
 6865                    string var_new_second_part = var->newname.substr(rm_str_pos+nc4_non_coord_size);
 
 6866                    var->newname = var_new_first_part + var_new_second_part;
 
 6873        for (
auto ircv = this->cvars.begin(); ircv != this->cvars.end();++ircv) {
 
 6874            if((*ircv)->name.find(nc4_non_coord)==0)
 
 6875                (*ircv)->newname = (*ircv)->newname.substr(nc4_non_coord_size,(*ircv)->newname.size()-nc4_non_coord_size);
 
 
 6884    BESDEBUG(
"h5", 
"GMFile::Coming to Add_Path_Coor_Attr()"<<endl);
 
 6885    string co_attrname = 
"coordinates";
 
 6886    for (
const auto &var:this->vars) {
 
 6887        if(var->coord_attr_add_path == 
true) {
 
 6888            for (
const auto &attr:var->attrs) {
 
 6890                if(attr->name == co_attrname) {
 
 6891                    string coor_value = Retrieve_Str_Attr_Value(attr,var->fullpath);
 
 6893                    vector<string>cvalue_vec;
 
 6894                    HDF5CFUtil::Split_helper(cvalue_vec,coor_value,sep);
 
 6895                    string new_coor_value;
 
 6896                    for (
int i = 0; i<cvalue_vec.size();i++) {
 
 6897                        HDF5CFUtil::cha_co(cvalue_vec[i],var->fullpath);
 
 6898                        cvalue_vec[i] = get_CF_string(cvalue_vec[i]);
 
 6900                            new_coor_value = cvalue_vec[i];
 
 6902                            new_coor_value += sep+cvalue_vec[i];
 
 6911                        Replace_Var_Str_Attr(var,co_attrname,new_coor_value);
 
 
 6921    BESDEBUG(
"h5", 
"GMFile::Coming to Add_Path_Coor_Attr()"<<endl);
 
 6922    if (product_type == GPMS_L3 || product_type == GPMM_L3 || product_type == GPM_L3_New || special_gpm_l3)
 
 6924    for (
auto &var:this->vars) {
 
 6925        for (
auto &attr:var->attrs) {
 
 6926            if (attr->name == 
"bounds") {
 
 6927                string bnd_values = Retrieve_Str_Attr_Value(attr,var->fullpath);
 
 6928                HDF5CFUtil::cha_co(bnd_values,var->fullpath);
 
 6929                bnd_values = get_CF_string(bnd_values);
 
 6930                Replace_Var_Str_Attr(var,
"bounds",bnd_values);
 
 6936    for (
auto &var:this->cvars) {
 
 6937        for (
auto &attr:var->attrs) {
 
 6938            if (attr->name == 
"bounds") {
 
 6939                string bnd_values = Retrieve_Str_Attr_Value(attr,var->fullpath);
 
 6940                HDF5CFUtil::cha_co(bnd_values,var->fullpath);
 
 6941                bnd_values = get_CF_string(bnd_values);
 
 6942                Replace_Var_Str_Attr(var,
"bounds",bnd_values);
 
 
 6952    for (
auto &cvar:this->cvars) {
 
 6953        if (cvar->getRank() == 1) {
 
 6956                bool correct_dim_size = 
false;
 
 6957                for (
const auto &var:this->vars) {
 
 6958                    for (
auto & vdim:var->dims) {
 
 6959                        if (vdim->unlimited_dim && vdim->newname == dim->newname) {
 
 6960                            dim->size = vdim->size;
 
 6961                            correct_dim_size = 
true;
 
 6965                    if (correct_dim_size)
 
 
 6977GMFile::release_standalone_GMCVar_vector(vector<GMCVar*>&tempgc_vars){
 
 6979    for (
auto i = tempgc_vars.begin(); i != tempgc_vars.end(); ) {
 
 6981        i = tempgc_vars.erase(i);
 
 6988GMFile::add_ignored_info_attrs(
bool is_grp,
bool is_first){
 
 6992GMFile::add_ignored_info_objs(
bool is_dim_related, 
bool is_first) {
 
 6999GMFile::ignored_dimscale_ref_list(
Var *var) {
 
 7001    bool ignored_dimscale = 
true;
 
 7002    if(General_Product == this->product_type && GENERAL_DIMSCALE== this->gproduct_pattern) {
 
 7004        bool has_dimscale = 
false;
 
 7005        bool has_reference_list = 
false;
 
 7007        for(
auto ira = var->attrs.begin(); ira != var->attrs.end();ira++) {
 
 7009             if((*ira)->name == 
"REFERENCE_LIST" && 
 
 7010                false == HDF5CFUtil::cf_strict_support_type((*ira)->getType()))
 
 7011                has_reference_list = 
true;
 
 7012             if((*ira)->name == 
"CLASS") {
 
 7013                Retrieve_H5_Attr_Value(*ira,var->fullpath);
 
 7015                class_value.resize((*ira)->value.size());
 
 7016                copy((*ira)->value.begin(),(*ira)->value.end(),class_value.begin());
 
 7020                if (0 == class_value.compare(0,15,
"DIMENSION_SCALE")) {
 
 7021                    has_dimscale = 
true;
 
 7025            if(
true == has_dimscale && 
true == has_reference_list) {
 
 7026                ignored_dimscale= 
false;
 
 7032    return ignored_dimscale;
 
This class specifies the core engineering of mapping HDF5 to DAP by following CF.
include the entry functions to execute the handlers
This class represents one attribute.
This class repersents one dimension of an HDF5 dataset(variable).
bool HaveUnlimitedDim() const
Has unlimited dimensions.
This class retrieves all information from an HDF5 file.
std::vector< Group * > groups
Non-root group vectors.
virtual void Handle_Unsupported_Dspace(bool)
Handle unsupported HDF5 dataspaces for datasets.
virtual void Handle_Grid_Mapping_Vars()
Handle Grid Mapping Vars.
virtual void Handle_Unsupported_Others(bool)
Handle other unmapped objects/attributes.
virtual void Retrieve_H5_Supported_Attr_Values()
Retrieve attribute values for the supported HDF5 datatypes.
std::vector< Var * > vars
Var vectors.
virtual void Add_Supplement_Attrs(bool)
Add supplemental attributes such as fullpath and original name.
virtual void Retrieve_H5_Info(const char *path, hid_t file_id, bool)
std::vector< Attribute * > root_attrs
Root attribute vectors.
virtual void Handle_Unsupported_Dtype(bool)
Handle unsupported HDF5 datatypes.
virtual void Flatten_Obj_Name(bool)
Flatten the object name.
virtual bool Have_Grid_Mapping_Attrs()
Check if having Grid Mapping Attrs.
This class is a derived class of CVar. It represents a coordinate variable for general HDF5 files.
void Add_Supplement_Attrs(bool) override
Add supplemental attributes such as fullpath and original name for general NASA HDF5 products.
void Add_Path_Coord_Attr()
Update the coordinate attribute to include path and also flatten.
void Rename_NC4_NonCoordVars() const
Remove the _nc4_non_coord from the variable new names.
void Handle_Obj_NameClashing(bool)
Handle object name clashing for general NASA HDF5 products.
void Remove_Unused_FakeDimVars()
Unsupported datatype array may generate FakeDim. Remove them.
void Update_Product_Type()
Update "product type" attributes for general HDF5 products.
bool Have_Grid_Mapping_Attrs() override
Check if having Grid Mapping Attrs.
void Handle_SpVar_Attr() override
Handle special variable attributes for general NASA HDF5 products.
void Handle_DimNameClashing() override
void Handle_Grid_Mapping_Vars() override
Handle Grid Mapping Vars.
void Retrieve_H5_CVar_Supported_Attr_Values() override
Retrieve coordinate variable attributes.
void Update_Bounds_Attr()
Update the Bounds attribute to follow the CF conventions.
void Retrieve_H5_Info(const char *path, hid_t file_id, bool include_attr) override
Retrieve DDS information from the HDF5 file; real implementation for general HDF5 products.
void Handle_SpVar() override
Handle special variables for general NASA HDF5 products.
void Remove_Unneeded_Objects()
Remove unneeded objects.
void Update_NC4_PureDimSize()
Update the netCDF-4 pure dimension size when the pure dimension is an unlimited dimension.
void Handle_CVar() override
Handle coordinate variables for general NASA HDF5 products.
void Add_Dim_Name()
Add dimension name.
void Retrieve_H5_Supported_Attr_Values() override
Retrieve attribute values for the supported HDF5 datatypes for general HDF5 products.
void Handle_Coor_Attr() override
Handle "coordinates" attributes for general HDF5 products.
void Handle_Unsupported_Dspace(bool) override
Handle unsupported HDF5 dataspaces for general HDF5 products.
void Handle_Unsupported_Others(bool) override
Handle other unmapped objects/attributes for general HDF5 products.
void Handle_Unsupported_Dtype(bool) override
Handle unsupported HDF5 datatypes for general HDF5 products.
void Flatten_Obj_Name(bool include_attr) override
Flatten the object name for general NASA HDF5 products.
void Adjust_H5_Attr_Value(Attribute *attr) const
Adjust attribute values for general HDF5 products.
void Adjust_Dim_Name() override
Adjust dimension name for general NASA HDF5 products.
void Adjust_Obj_Name() override
Adjust object names based on different general NASA HDF5 products.
This class represents one HDF5 dataset(CF variable)
int getRank() const
Get the dimension rank of this variable.
const std::vector< Dimension * > & getDimensions() const
Get the list of the dimensions.
static void Split(const char *s, int len, char sep, std::vector< std::string > &names)