bes Updated for version 3.20.10
h5gmcfdap.cc
Go to the documentation of this file.
1// This file is part of hdf5_handler: an HDF5 file handler for the OPeNDAP
2// data server.
3
4// Copyright (c) 2011-2016 The HDF Group, Inc. and OPeNDAP, Inc.
5//
6// This is free software; you can redistribute it and/or modify it under the
7// terms of the GNU Lesser General Public License as published by the Free
8// Software Foundation; either version 2.1 of the License, or (at your
9// option) any later version.
10//
11// This software is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14// License for more details.
15//
16// You should have received a copy of the GNU Lesser General Public
17// License along with this library; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19//
20// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
21// You can contact The HDF Group, Inc. at 1800 South Oak Street,
22// Suite 203, Champaign, IL 61820
23
32
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <fcntl.h>
36#include <unistd.h>
37#include <iostream>
38#include <sstream>
39
40#include <BESDebug.h>
41#include <libdap/InternalErr.h>
42
43#include "HDF5RequestHandler.h"
44#include "h5cfdaputil.h"
45#include "h5gmcfdap.h"
46#include "HDF5CFInt8.h"
47#include "HDF5CFByte.h"
48#include "HDF5CFUInt16.h"
49#include "HDF5CFInt16.h"
50#include "HDF5CFUInt32.h"
51#include "HDF5CFInt32.h"
52#include "HDF5CFInt64.h"
53#include "HDF5CFUInt64.h"
54#include "HDF5CFFloat32.h"
55#include "HDF5CFFloat64.h"
56#include "HDF5CFStr.h"
57#include "HDF5CFArray.h"
58#include "HDF5GMCFMissLLArray.h"
62#include "HDF5GMSPCFArray.h"
63
64using namespace std;
65using namespace libdap;
66using namespace HDF5CF;
67
68// Map general HDF5 products to DAP DDS
69void map_gmh5_cfdds(DDS &dds, hid_t file_id, const string& filename){
70
71 BESDEBUG("h5","Coming to GM products DDS mapping function map_gmh5_cfdds() "<<endl);
72
73 H5GCFProduct product_type = check_product(file_id);
74
75 GMPattern gproduct_pattern = OTHERGMS;
76
77 GMFile * f = NULL;
78
79 try {
80 f = new GMFile(filename.c_str(),file_id,product_type,gproduct_pattern);
81 }
82 catch(...) {
83 throw InternalErr(__FILE__,__LINE__,"Cannot allocate memory for GMFile ");
84 }
85 // Generally don't need to handle attributes when handling DDS.
86 bool include_attr = false;
87 try {
88 // Retrieve all HDF5 info(Not the values)
89 f->Retrieve_H5_Info(filename.c_str(),file_id,include_attr);
90
91 // Update product type
92 // Newer version of a product may have different layout and the
93 // product type needs to be changed to reflect it. We also want
94 // to support the older version in case people still use them.
95 // This routine will check if newer layout can be applied. If yes,
96 // update the product type.
98
100
101 // Need to add dimension names.
102 f->Add_Dim_Name();
103
104 // Handle coordinate variables
105 f->Handle_CVar();
106#if 0
107 // We need to retrieve coordinate variable attributes for memory cache use.
108 //f->Retrieve_H5_CVar_Supported_Attr_Values();
109 //if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
110 // (HDF5RequestHandler::get_srdata_mem_cache() != NULL)){
111 // f->Retrieve_H5_Supported_Attr_Values();
112#endif
113
114
115 // Handle special variables
116 f->Handle_SpVar();
117
118 // When cv memory cache is on, the unit attributes are needed to
119 // distinguish whether this is lat/lon. Generally, memory cache
120 // is not used. This snipnet will not be accessed.
121 if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
122 (HDF5RequestHandler::get_srdata_mem_cache() != NULL)){
123
124 // Handle unsupported datatypes including the attributes
126
127 // Handle unsupported dataspaces including the attributes
129
130 // We need to retrieve coordinate variable attributes for memory cache use.
132
133 }
134 else {
135
136 // Handle unsupported datatypes
137 f->Handle_Unsupported_Dtype(include_attr);
138
139 // Handle unsupported dataspaces
140 f->Handle_Unsupported_Dspace(include_attr);
141
142 }
143
144 // Need to handle the "coordinate" attributes when memory cache is turned on.
145 if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
146 (HDF5RequestHandler::get_srdata_mem_cache() != NULL))
147 f->Add_Supplement_Attrs(HDF5RequestHandler::get_add_path_attrs());
148
149 // Adjust object names(may remove redundant paths)
150 f->Adjust_Obj_Name();
151
152 // Flatten the object names
153 f->Flatten_Obj_Name(include_attr);
154
155 // Handle Object name clashings
156 // Only when the check_nameclashing key is turned on or
157 // general product.
158 if(General_Product == product_type ||
159 true == HDF5RequestHandler::get_check_name_clashing())
160 f->Handle_Obj_NameClashing(include_attr);
161
162 // Adjust Dimension name
163 f->Adjust_Dim_Name();
164 if(General_Product == product_type ||
165 true == HDF5RequestHandler::get_check_name_clashing())
167
168 f->Handle_Hybrid_EOS5();
169 if(true == f->Have_Grid_Mapping_Attrs())
171 // Need to handle the "coordinate" attributes when memory cache is turned on.
172 if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
173 (HDF5RequestHandler::get_srdata_mem_cache() != NULL))
174 f->Handle_Coor_Attr();
175
178 }
179 catch (HDF5CF::Exception &e){
180 if (f != NULL)
181 delete f;
182 throw InternalErr(e.what());
183 }
184
185 // generate DDS.
186 try {
187 gen_gmh5_cfdds(dds,f);
188 }
189 catch(...) {
190 if (f != NULL)
191 delete f;
192 throw;
193 }
194
195 if (f != NULL)
196 delete f;
197}
198
199// Map general HDF5 products to DAP DAS
200void map_gmh5_cfdas(DAS &das, hid_t file_id, const string& filename){
201
202 BESDEBUG("h5","Coming to GM products DAS mapping function map_gmh5_cfdas() "<<endl);
203
204 H5GCFProduct product_type = check_product(file_id);
205 GMPattern gproduct_pattern = OTHERGMS;
206
207 GMFile *f = NULL;
208
209 try {
210 f = new GMFile(filename.c_str(),file_id,product_type,gproduct_pattern);
211 }
212 catch(...) {
213 throw InternalErr(__FILE__,__LINE__,"Cannot allocate memory for GMFile ");
214 }
215
216 bool include_attr = true;
217 try {
218 f->Retrieve_H5_Info(filename.c_str(),file_id,include_attr);
219
220 // Update product type(check comments of map_gmh5_cfdds)
222
224
225 f->Add_Dim_Name();
226 f->Handle_CVar();
227 f->Handle_SpVar();
228 f->Handle_Unsupported_Dtype(include_attr);
229
230 // Remove unsupported dataspace
231 f->Handle_Unsupported_Dspace(include_attr);
232
233 // Need to retrieve the attribute values to feed DAS
235
236 // Handle other unsupported objects,
237 // currently it mainly generates the info. for the
238 // unsupported objects other than datatype, dataspace,links and named datatype
239 // One area is maybe very long string. So we retrieve the attribute
240 // values before calling this function.
241 f->Handle_Unsupported_Others(include_attr);
242
243
244 // Need to add original variable name and path
245 // and other special attributes
246 // Can be turned on/off by using the check_path_attrs keys.
247 f->Add_Supplement_Attrs(HDF5RequestHandler::get_add_path_attrs());
248 f->Adjust_Obj_Name();
249 f->Flatten_Obj_Name(include_attr);
250 if(General_Product == product_type ||
251 true == HDF5RequestHandler::get_check_name_clashing())
252 f->Handle_Obj_NameClashing(include_attr);
253 if(f->HaveUnlimitedDim() == true)
254 f->Adjust_Dim_Name();
255 // Handle the "coordinate" attributes.
256 f->Handle_Coor_Attr();
257
258 f->Handle_Hybrid_EOS5();
259 if(true == f->Have_Grid_Mapping_Attrs())
261
263
265
266 if(true == HDF5RequestHandler::get_enable_coord_attr_add_path())
268 }
269 catch (HDF5CF::Exception &e){
270 if (f!= NULL)
271 delete f;
272 throw InternalErr(e.what());
273 }
274
275 // Generate the DAS attributes.
276 try {
277 gen_gmh5_cfdas(das,f);
278 }
279 catch (...) {
280 if (f!= NULL)
281 delete f;
282 throw;
283
284 }
285
286 if (f != NULL)
287 delete f;
288}
289
290
291void map_gmh5_cfdmr(D4Group *d4_root, hid_t file_id, const string& filename){
292
293 BESDEBUG("h5","Coming to GM products DMR mapping function map_gmh5_cfdmr() "<<endl);
294
295 H5GCFProduct product_type = check_product(file_id);
296
297 GMPattern gproduct_pattern = OTHERGMS;
298
299 GMFile * f = NULL;
300
301 try {
302 f = new GMFile(filename.c_str(),file_id,product_type,gproduct_pattern);
303 }
304 catch(...) {
305 throw InternalErr(__FILE__,__LINE__,"Cannot allocate memory for GMFile ");
306 }
307
308 // Both variables and attributes are in DMR.
309 bool include_attr = true;
310 try {
311
312 // Set the is_dap4 flag be true.
313 f->setDap4(true);
314
315 // Retrieve all HDF5 info(Not the values)
316 f->Retrieve_H5_Info(filename.c_str(),file_id,include_attr);
317
318 // Update product type
319 // Newer version of a product may have different layout and the
320 // product type needs to be changed to reflect it. We also want
321 // to support the older version in case people still use them.
322 // This routine will check if newer layout can be applied. If yes,
323 // update the product type.
325
327
328 // Need to add dimension names.
329 f->Add_Dim_Name();
330
331 // Handle coordinate variables
332 f->Handle_CVar();
333#if 0
334 // We need to retrieve coordinate variable attributes for memory cache use.
335 //f->Retrieve_H5_CVar_Supported_Attr_Values();
336 //if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
337 // (HDF5RequestHandler::get_srdata_mem_cache() != NULL)){
338 // f->Retrieve_H5_Supported_Attr_Values();
339#endif
340
341
342 // Handle special variables
343 f->Handle_SpVar();
344
345 // When cv memory cache is on, the unit attributes are needed to
346 // distinguish whether this is lat/lon. Generally, memory cache
347 // is not used. This snipnet will not be accessed.
348 //if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
349 // (HDF5RequestHandler::get_srdata_mem_cache() != NULL)){
350
351 // Handle unsupported datatypes including the attributes
353
354 // Handle unsupported dataspaces including the attributes
356
357 // We need to retrieve variable attributes.
359
360 // Include handling internal netCDF-4 attributes
361 f->Handle_Unsupported_Others(include_attr);
362
363#if 0
364 else {
365
366 // Handle unsupported datatypes
367 f->Handle_Unsupported_Dtype(include_attr);
368
369 // Handle unsupported dataspaces
370 f->Handle_Unsupported_Dspace(include_attr);
371
372 }
373#endif
374 // Need to handle the "coordinate" attributes
375 f->Add_Supplement_Attrs(HDF5RequestHandler::get_add_path_attrs());
376
377 // Adjust object names(may remove redundant paths)
378 f->Adjust_Obj_Name();
379
380 // Flatten the object names
381 f->Flatten_Obj_Name(include_attr);
382
383 // Handle Object name clashings
384 // Only when the check_nameclashing key is turned on or
385 // general product.
386 if(General_Product == product_type ||
387 true == HDF5RequestHandler::get_check_name_clashing())
388 f->Handle_Obj_NameClashing(include_attr);
389
390 // Adjust Dimension name, CHECK: the das generation has a f->HaveUnlimitedDim() condition
391 f->Adjust_Dim_Name();
392 if(General_Product == product_type ||
393 true == HDF5RequestHandler::get_check_name_clashing())
395
396 // Handle the "coordinate" attributes.
397 f->Handle_Coor_Attr();
398
399 f->Handle_Hybrid_EOS5();
400 if(true == f->Have_Grid_Mapping_Attrs())
402#if 0
403 // Need to handle the "coordinate" attributes when memory cache is turned on.
404 if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
405 (HDF5RequestHandler::get_srdata_mem_cache() != NULL))
406 f->Handle_Coor_Attr();
407#endif
408
411
412 if(true == HDF5RequestHandler::get_enable_coord_attr_add_path())
414
415 }
416 catch (HDF5CF::Exception &e){
417 if (f != NULL)
418 delete f;
419 throw InternalErr(e.what());
420 }
421
422 // generate DMR.
423 try {
424 gen_gmh5_cfdmr(d4_root,f);
425 }
426 catch(...) {
427 if (f != NULL)
428 delete f;
429 throw;
430 }
431
432 if (f != NULL)
433 delete f;
434
435}
436
437// Generate DDS mapped from general HDF5 products
438void gen_gmh5_cfdds( DDS & dds, HDF5CF:: GMFile *f) {
439
440 BESDEBUG("h5","Coming to GM DDS generation function gen_gmh5_cfdds() "<<endl);
441
442 const vector<HDF5CF::Var *>& vars = f->getVars();
443 const vector<HDF5CF::GMCVar *>& cvars = f->getCVars();
444 const vector<HDF5CF::GMSPVar *>& spvars = f->getSPVars();
445 const string filename = f->getPath();
446 const hid_t fileid = f->getFileID();
447
448 // Read Variable info.
449
450 vector<HDF5CF::Var *>::const_iterator it_v;
451 vector<HDF5CF::GMCVar *>::const_iterator it_cv;
452 vector<HDF5CF::GMSPVar *>::const_iterator it_spv;
453
454 // Since we need to use dds to add das for 64-bit dmr,we need to check if
455 // this case includes 64-bit integer variables and this is for dmr response.
456 bool dmr_64bit_support = false;
457 if(HDF5RequestHandler::get_dmr_long_int()==true &&
458 HDF5RequestHandler::get_dmr_64bit_int()!=NULL) {
459 for (it_v = vars.begin(); it_v !=vars.end();++it_v) {
460 if (H5INT64 == (*it_v)->getType() || H5UINT64 == (*it_v)->getType()){
461 dmr_64bit_support = true;
462 break;
463 }
464 }
465 }
466
467 // We need to remove the unsupported attributes.
468 if(true == dmr_64bit_support) {
469 //STOP: add non-support stuff
471
472 // Remove unsupported dataspace
474
475 }
476
477 for (it_v = vars.begin(); it_v !=vars.end();++it_v) {
478 BESDEBUG("h5","variable full path= "<< (*it_v)->getFullPath() <<endl);
479 // Handle 64-integer DAP4 CF mapping
480 if(need_attr_values_for_dap4(*it_v) == true)
482 gen_dap_onevar_dds(dds,*it_v,fileid, filename);
483 }
484 for (it_cv = cvars.begin(); it_cv !=cvars.end();++it_cv) {
485 BESDEBUG("h5","variable full path= "<< (*it_cv)->getFullPath() <<endl);
486 gen_dap_onegmcvar_dds(dds,*it_cv,fileid, filename);
487 }
488
489 for (it_spv = spvars.begin(); it_spv !=spvars.end();it_spv++) {
490 BESDEBUG("h5","variable full path= "<< (*it_spv)->getFullPath() <<endl);
491 gen_dap_onegmspvar_dds(dds,*it_spv,fileid, filename);
492 }
493
494}
495
496// Generate DAS mapped from general HDF5 products
497void gen_gmh5_cfdas( DAS & das, HDF5CF:: GMFile *f) {
498
499 BESDEBUG("h5","Coming to GM DAS generation function gen_gmh5_cfdas() "<<endl);
500
501 // First check if this is for generating the ignored object info.
502 if(true == f->Get_IgnoredInfo_Flag()) {
503 gen_gmh5_cf_ignored_obj_info(das, f);
504 return;
505 }
506
507 const vector<HDF5CF::Var *>& vars = f->getVars();
508 const vector<HDF5CF::GMCVar *>& cvars = f->getCVars();
509 const vector<HDF5CF::GMSPVar *>& spvars = f->getSPVars();
510 const vector<HDF5CF::Group *>& grps = f->getGroups();
511 const vector<HDF5CF::Attribute *>& root_attrs = f->getAttributes();
512
513
514 vector<HDF5CF::Var *>::const_iterator it_v;
515 vector<HDF5CF::GMCVar *>::const_iterator it_cv;
516 vector<HDF5CF::GMSPVar *>::const_iterator it_spv;
517 vector<HDF5CF::Group *>::const_iterator it_g;
518 vector<HDF5CF::Attribute *>::const_iterator it_ra;
519
520 // Handling the file attributes(attributes under the root group)
521 // The table name is "HDF_GLOBAL".
522
523 if (false == root_attrs.empty()) {
524
525 AttrTable *at = das.get_table(FILE_ATTR_TABLE_NAME);
526 if (NULL == at)
527 at = das.add_table(FILE_ATTR_TABLE_NAME, new AttrTable);
528
529 for (it_ra = root_attrs.begin(); it_ra != root_attrs.end(); ++it_ra) {
530 // Check and may update the 64-bit integer attributes in DAP4.
531 check_update_int64_attr("",*it_ra);
532 gen_dap_oneobj_das(at,*it_ra,NULL);
533 }
534 }
535
536 if (false == grps.empty()) {
537 for (it_g = grps.begin();
538 it_g != grps.end(); ++it_g) {
539 AttrTable *at = das.get_table((*it_g)->getNewName());
540 if (NULL == at)
541 at = das.add_table((*it_g)->getNewName(), new AttrTable);
542
543 for (it_ra = (*it_g)->getAttributes().begin();
544 it_ra != (*it_g)->getAttributes().end(); ++it_ra) {
545 check_update_int64_attr((*it_g)->getNewName(),*it_ra);
546 gen_dap_oneobj_das(at,*it_ra,NULL);
547 }
548 }
549 }
550
551 for (it_v = vars.begin();
552 it_v != vars.end(); ++it_v) {
553 if (false == ((*it_v)->getAttributes().empty())) {
554
555 // Skip the 64-bit integer variables. The attribute mapping of
556 // DAP4 CF 64-bit integer variable support
557 // has been taken care at the routine gen_dap_onevar_dds()
558 // defined at h5commoncfdap.cc
559 if(H5INT64 == (*it_v)->getType() || H5UINT64 == (*it_v)->getType()){
560 continue;
561 }
562
563 AttrTable *at = das.get_table((*it_v)->getNewName());
564 if (NULL == at)
565 at = das.add_table((*it_v)->getNewName(), new AttrTable);
566
567 for (it_ra = (*it_v)->getAttributes().begin();
568 it_ra != (*it_v)->getAttributes().end(); ++it_ra) {
569 gen_dap_oneobj_das(at,*it_ra,*it_v);
570 }
571 // TODO: If a var has integer-64 bit datatype attributes, maybe
572 // we can just keep that attributes(not consistent but
573 // easy to implement) or we have to duplicate all
574 // the var in dmr and delete this var from dds.
575
576 }
577
578 // GPM needs to be handled in a special way(mostly _FillValue)
579 if(GPMS_L3 == f->getProductType() || GPMM_L3 == f->getProductType()
580 || GPM_L1 == f->getProductType())
581 update_GPM_special_attrs(das,*it_v,false);
582
583 }
584
585 for (it_cv = cvars.begin();
586 it_cv != cvars.end(); ++it_cv) {
587 if (false == ((*it_cv)->getAttributes().empty())) {
588
589 // TODO: Add 64-bit int support for coordinates, this has not been tackled.
590 if(H5INT64 == (*it_cv)->getType() || H5UINT64 == (*it_cv)->getType()){
591 continue;
592 }
593
594 AttrTable *at = das.get_table((*it_cv)->getNewName());
595 if (NULL == at)
596 at = das.add_table((*it_cv)->getNewName(), new AttrTable);
597
598 for (it_ra = (*it_cv)->getAttributes().begin();
599 it_ra != (*it_cv)->getAttributes().end(); ++it_ra){
600 gen_dap_oneobj_das(at,*it_ra,*it_cv);
601 }
602
603 }
604 // Though CF doesn't allow _FillValue, still keep it to keep the original form.
605 if(GPMS_L3 == f->getProductType() || GPMM_L3 == f->getProductType()
606 || GPM_L1 == f->getProductType())
607 update_GPM_special_attrs(das,*it_cv,true);
608
609 }
610
611 // Currently the special variables are only limited to the ACOS/OCO2 64-bit integer variables
612 for (it_spv = spvars.begin();
613 it_spv != spvars.end(); ++it_spv) {
614 if (false == ((*it_spv)->getAttributes().empty())) {
615
616 AttrTable *at = das.get_table((*it_spv)->getNewName());
617 if (NULL == at)
618 at = das.add_table((*it_spv)->getNewName(), new AttrTable);
619#if 0
620 // cerr<<"spv coordinate variable name "<<(*it_spv)->getNewName() <<endl;
621#endif
622
623 for (it_ra = (*it_spv)->getAttributes().begin();
624 it_ra != (*it_spv)->getAttributes().end(); ++it_ra)
625 gen_dap_oneobj_das(at,*it_ra,*it_spv);
626 }
627 }
628
629 // CHECK ALL UNLIMITED DIMENSIONS from the coordinate variables based on the names.
630 if(f->HaveUnlimitedDim() == true) {
631
632 BESDEBUG("h5","Find unlimited dimension in the GM DAS generation function gen_gmh5_cfdas() "<<endl);
633
634 // Currently there is no way for DAP to present the unlimited dimension info.
635 // when there are no dimension names. So don't create DODS_EXTRA even if
636 // there is an unlimited dimension in the file. KY 2016-02-18
637 if(cvars.empty()==false ){
638
639 // First check if we do have unlimited dimension in the coordinate variables.
640 // Since unsupported fakedims are removed, we may not have unlimited dimensions.
641 bool still_has_unlimited = false;
642 for (it_cv = cvars.begin();
643 it_cv != cvars.end(); ++it_cv) {
644 // Check unlimited dimension names.
645 for (vector<Dimension*>::const_iterator ird = (*it_cv)->getDimensions().begin();
646 ird != (*it_cv)->getDimensions().end(); ++ird) {
647
648 // Currently we only check one unlimited dimension, which is the most
649 // common case. When receiving the conventions from JG, will add
650 // the support of multi-unlimited dimension. KY 2016-02-09
651 if((*ird)->HaveUnlimitedDim() == true) {
652 still_has_unlimited = true;
653 break;
654 }// if((*ird) is HaveUnlimitedDim()
655 }// for (vector<Dimension*>::
656 if(true == still_has_unlimited)
657 break;
658 }// for (it_cv=cvars.begin();
659
660 if(true == still_has_unlimited) {
661 AttrTable* at = das.get_table("DODS_EXTRA");
662 if (NULL == at)
663 at = das.add_table("DODS_EXTRA", new AttrTable);
664
665 string unlimited_names;
666
667 for (it_cv = cvars.begin();
668 it_cv != cvars.end(); ++it_cv) {
669#if 0
670 bool has_unlimited_dim = false;
671#endif
672 // Check unlimited dimension names.
673 for (vector<Dimension*>::const_iterator ird = (*it_cv)->getDimensions().begin();
674 ird != (*it_cv)->getDimensions().end(); ++ird) {
675
676 // Currently we only check one unlimited dimension, which is the most
677 // common case. When receiving the conventions from JG, will add
678 // the support of multi-unlimited dimension. KY 2016-02-09
679 if((*ird)->HaveUnlimitedDim() == true) {
680 if(unlimited_names=="") {
681 unlimited_names = (*ird)->getNewName();
682 if(at !=NULL)
683 at->append_attr("Unlimited_Dimension","String",unlimited_names);
684 }
685 else {
686 if(unlimited_names.rfind((*ird)->getNewName()) == string::npos) {
687 unlimited_names = unlimited_names+" "+(*ird)->getNewName();
688 if(at !=NULL)
689 at->append_attr("Unlimited_Dimension","String",(*ird)->getNewName());
690 }
691 }
692 }// if((*ird)->HaveUnlimitedDim()
693 }// for (vector<Dimension*>::
694 }// for (it_cv=cvars.begin();
695 }// if(true == still_has_unlimited)
696
697 }//if(cvars.size()>0)
698#if 0
699 // The following line will generate the string like "Band1 str1 str2".
700 //if(unlimited_names!="")
701 // // at->append_attr("Unlimited_Dimension","String",unlimited_names);
702#endif
703 }
704}
705
706void gen_gmh5_cfdmr(D4Group* d4_root,HDF5CF::GMFile *f) {
707
708 BESDEBUG("h5","Coming to GM DDS generation function gen_gmh5_cfdmr() "<<endl);
709
710 const vector<HDF5CF::Var *>& vars = f->getVars();
711 const vector<HDF5CF::GMCVar *>& cvars = f->getCVars();
712 const vector<HDF5CF::GMSPVar *>& spvars = f->getSPVars();
713 const string filename = f->getPath();
714 const hid_t fileid = f->getFileID();
715 const vector<HDF5CF::Group *>& grps = f->getGroups();
716 const vector<HDF5CF::Attribute *>& root_attrs = f->getAttributes();
717
718 vector<HDF5CF::Var *>::const_iterator it_v;
719 vector<HDF5CF::GMCVar *>::const_iterator it_cv;
720 vector<HDF5CF::GMSPVar *>::const_iterator it_spv;
721 vector<HDF5CF::Group *>::const_iterator it_g;
722 vector<HDF5CF::Attribute *>::const_iterator it_ra;
723
724 // Root and low-level group attributes.
725 if (false == root_attrs.empty()) {
726 for (it_ra = root_attrs.begin(); it_ra != root_attrs.end(); ++it_ra)
727 map_cfh5_grp_attr_to_dap4(d4_root,*it_ra);
728 }
729
730 // Read Variable info.
731 for (it_v = vars.begin(); it_v !=vars.end();++it_v) {
732 BESDEBUG("h5","variable full path= "<< (*it_v)->getFullPath() <<endl);
733 gen_dap_onevar_dmr(d4_root,*it_v,fileid, filename);
734 }
735
736 for (it_cv = cvars.begin(); it_cv !=cvars.end();++it_cv) {
737 BESDEBUG("h5","variable full path= "<< (*it_cv)->getFullPath() <<endl);
738 gen_dap_onegmcvar_dmr(d4_root,*it_cv,fileid, filename);
739 }
740
741 for (it_spv = spvars.begin(); it_spv !=spvars.end();it_spv++) {
742 BESDEBUG("h5","variable full path= "<< (*it_spv)->getFullPath() <<endl);
743 gen_dap_onegmspvar_dmr(d4_root,*it_spv,fileid, filename);
744 }
745
746 // We use the attribute container to store the group attributes.
747 if (false == grps.empty()) {
748 for (it_g = grps.begin();
749 it_g != grps.end(); ++it_g) {
750
751 D4Attribute *tmp_grp = new D4Attribute;
752 tmp_grp->set_name((*it_g)->getNewName());
753
754 // Make the type as a container
755 tmp_grp->set_type(attr_container_c);
756
757 for (it_ra = (*it_g)->getAttributes().begin();
758 it_ra != (*it_g)->getAttributes().end(); ++it_ra) {
759 map_cfh5_attr_container_to_dap4(tmp_grp,(*it_ra));
760 }
761
762 d4_root->attributes()->add_attribute_nocopy(tmp_grp);
763 }
764 }
765
766 // CHECK ALL UNLIMITED DIMENSIONS from the coordinate variables based on the names.
767 if(f->HaveUnlimitedDim() == true) {
768
769 BESDEBUG("h5","Find unlimited dimension in the GM DMR generation function gen_gmh5_cfdmr() "<<endl);
770
771 // Currently there is no way for DAP to present the unlimited dimension info.
772 // when there are no dimension names. So don't create DODS_EXTRA even if
773 // there is an unlimited dimension in the file. KY 2016-02-18
774 if(cvars.empty()==false ){
775
776 // First check if we do have unlimited dimension in the coordinate variables.
777 // Since unsupported fakedims are removed, we may not have unlimited dimensions.
778 bool still_has_unlimited = false;
779 for (it_cv = cvars.begin();
780 it_cv != cvars.end(); ++it_cv) {
781 // Check unlimited dimension names.
782 for (vector<Dimension*>::const_iterator ird = (*it_cv)->getDimensions().begin();
783 ird != (*it_cv)->getDimensions().end(); ++ird) {
784
785 // Currently we only check one unlimited dimension, which is the most
786 // common case. When receiving the conventions from JG, will add
787 // the support of multi-unlimited dimension. KY 2016-02-09
788 if((*ird)->HaveUnlimitedDim() == true) {
789 still_has_unlimited = true;
790 break;
791 }// if((*ird) is HaveUnlimitedDim()
792 }// for (vector<Dimension*>::
793 if(true == still_has_unlimited)
794 break;
795 }// for (it_cv=cvars.begin();
796
797 if(true == still_has_unlimited) {
798
799 string dods_extra = "DODS_EXTRA";
800
801 // If DODS_EXTRA exists, we will not create the unlimited dimensions.
802 if(d4_root->attributes() != NULL) {
803 // The following lines cause seg. fault in libdap4, needs to investigate
804 //if((d4_root->attributes()->find(dods_extra))==NULL)
805
806 string unlimited_dim_names ="";
807
808 for (it_cv = cvars.begin();
809 it_cv != cvars.end(); it_cv++) {
810
811 // Check unlimited dimension names.
812 for (vector<Dimension*>::const_iterator ird = (*it_cv)->getDimensions().begin();
813 ird != (*it_cv)->getDimensions().end(); ++ird) {
814
815 // Currently we only check one unlimited dimension, which is the most
816 // common case. When receiving the conventions from JG, will add
817 // the support of multi-unlimited dimension. KY 2016-02-09
818 if((*ird)->HaveUnlimitedDim() == true) {
819
820 string unlimited_dim_name = (*ird)->getNewName();
821 if(unlimited_dim_names=="")
822 unlimited_dim_names = unlimited_dim_name;
823 else {
824 if(unlimited_dim_names.rfind(unlimited_dim_name) == string::npos)
825 unlimited_dim_names = unlimited_dim_names+" "+unlimited_dim_name;
826 }
827 }
828 }
829 }
830
831 if(unlimited_dim_names != "") {
832 D4Attribute *dods_extra_attr = new D4Attribute(dods_extra,attr_container_c);
833 D4Attribute *unlimited_dim_attr = new D4Attribute("Unlimited_Dimension",attr_str_c);
834 unlimited_dim_attr->add_value(unlimited_dim_names);
835 dods_extra_attr->attributes()->add_attribute_nocopy(unlimited_dim_attr);
836 d4_root->attributes()->add_attribute_nocopy(dods_extra_attr);
837
838 }
839 else
840 throw InternalErr(__FILE__, __LINE__, "Unlimited dimension should exist.");
841 }
842
843 }
844 }
845 }
846
847
848}
849
850// Generate the ignored object info. for the CF option of the general products
851void gen_gmh5_cf_ignored_obj_info(DAS &das, HDF5CF::GMFile *f) {
852
853 BESDEBUG("h5","Coming to gen_gmh5_cf_ignored_obj_info() "<<endl);
854 AttrTable *at = das.get_table("Ignored_Object_Info");
855 if (NULL == at)
856 at = das.add_table("Ignored_Object_Info", new AttrTable);
857
858 at->append_attr("Message","String",f->Get_Ignored_Msg());
859
860}
861
862// Generate the DDS for a coordinate variable of the General products
863void gen_dap_onegmcvar_dds(DDS &dds,const HDF5CF::GMCVar* cvar, const hid_t file_id, const string & filename) {
864
865 BESDEBUG("h5","Coming to gen_dap_onegmcvar_dds() "<<endl);
866
867 if(cvar->getType() == H5INT64 || cvar->getType() == H5UINT64)
868 return;
869 BaseType *bt = NULL;
870
871 switch(cvar->getType()) {
872#define HANDLE_CASE(tid,type) \
873 case tid: \
874 bt = new (type)(cvar->getNewName(),cvar->getFullPath()); \
875 break;
876
877 HANDLE_CASE(H5FLOAT32, HDF5CFFloat32);
878 HANDLE_CASE(H5FLOAT64, HDF5CFFloat64);
879 HANDLE_CASE(H5CHAR,HDF5CFInt16);
880 HANDLE_CASE(H5UCHAR, HDF5CFByte);
881 HANDLE_CASE(H5INT16, HDF5CFInt16);
882 HANDLE_CASE(H5UINT16, HDF5CFUInt16);
883 HANDLE_CASE(H5INT32, HDF5CFInt32);
884 HANDLE_CASE(H5UINT32, HDF5CFUInt32);
885 HANDLE_CASE(H5FSTRING, Str);
886 HANDLE_CASE(H5VSTRING, Str);
887
888 default:
889 throw InternalErr(__FILE__,__LINE__,"unsupported data type.");
890#undef HANDLE_CASE
891 }
892
893 if (bt) {
894
895 const vector<HDF5CF::Dimension *>& dims = cvar->getDimensions();
896 vector <HDF5CF::Dimension*>:: const_iterator it_d;
897 vector <size_t> dimsizes;
898 dimsizes.resize(cvar->getRank());
899 for(int i = 0; i <cvar->getRank();i++)
900 dimsizes[i] = (dims[i])->getSize();
901
902
903 if(dims.empty())
904 throw InternalErr(__FILE__,__LINE__,"the coordinate variable cannot be a scalar");
905
906 switch(cvar->getCVType()) {
907
908 case CV_EXIST:
909 {
910 HDF5CFArray *ar = NULL;
911
912 // Need to check if this CV is lat/lon. This is necessary when data memory cache is turned on.
913 bool is_latlon = cvar->isLatLon();
914
915 try {
916 ar = new HDF5CFArray (
917 cvar->getRank(),
918 file_id,
919 filename,
920 cvar->getType(),
921 dimsizes,
922 cvar->getFullPath(),
923 cvar->getTotalElems(),
924 CV_EXIST,
925 is_latlon,
926 cvar->getCompRatio(),
927 false,
928 cvar->getNewName(),
929 bt);
930 }
931 catch(...) {
932 delete bt;
933 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5CFArray. ");
934 }
935
936 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
937 if (""==(*it_d)->getNewName())
938 ar->append_dim((*it_d)->getSize());
939 else
940 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
941 }
942
943 dds.add_var(ar);
944 delete bt;
945 delete ar;
946 }
947 break;
948
949 case CV_LAT_MISS:
950 case CV_LON_MISS:
951 {
952 // Using HDF5GMCFMissLLArray
953 HDF5GMCFMissLLArray *ar = NULL;
954 try {
955 ar = new HDF5GMCFMissLLArray (
956 cvar->getRank(),
957 filename,
958 file_id,
959 cvar->getType(),
960 cvar->getFullPath(),
961 cvar->getPtType(),
962 cvar->getCVType(),
963 cvar->getNewName(),
964 bt);
965 }
966 catch(...) {
967 delete bt;
968 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5GMCFMissLLArray. ");
969 }
970
971
972 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
973 if (""==(*it_d)->getNewName())
974 ar->append_dim((*it_d)->getSize());
975 else
976 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
977 }
978
979 dds.add_var(ar);
980 delete bt;
981 delete ar;
982 }
983 break;
984
985 case CV_NONLATLON_MISS:
986 {
987
988 if (cvar->getRank() !=1) {
989 delete bt;
990 throw InternalErr(__FILE__, __LINE__, "The rank of missing Z dimension field must be 1");
991 }
992 int nelem = (cvar->getDimensions()[0])->getSize();
993
994 HDF5GMCFMissNonLLCVArray *ar = NULL;
995
996 try {
998 cvar->getRank(),
999 nelem,
1000 cvar->getNewName(),
1001 bt);
1002 }
1003 catch(...) {
1004 delete bt;
1005 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5GMCFMissNonLLCVArray. ");
1006 }
1007
1008
1009 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1010 if (""==(*it_d)->getNewName())
1011 ar->append_dim((*it_d)->getSize());
1012 else
1013 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1014 }
1015 dds.add_var(ar);
1016 delete bt;
1017 delete ar;
1018 }
1019 break;
1020
1021 case CV_FILLINDEX:
1022 {
1023
1024 if (cvar->getRank() !=1) {
1025 delete bt;
1026 throw InternalErr(__FILE__, __LINE__, "The rank of missing Z dimension field must be 1");
1027 }
1028
1029 HDF5GMCFFillIndexArray *ar = NULL;
1030
1031 try {
1032 ar = new HDF5GMCFFillIndexArray(
1033 cvar->getRank(),
1034 cvar->getType(),
1035 false,
1036 cvar->getNewName(),
1037 bt);
1038 }
1039 catch(...) {
1040 delete bt;
1041 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5GMCFMissNonLLCVArray. ");
1042 }
1043
1044
1045 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1046 if (""==(*it_d)->getNewName())
1047 ar->append_dim((*it_d)->getSize());
1048 else
1049 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1050 }
1051 dds.add_var(ar);
1052 delete bt;
1053 delete ar;
1054 }
1055 break;
1056
1057
1058 case CV_SPECIAL:
1059 {
1060 // Currently only handle 1-D special CV.
1061 if (cvar->getRank() !=1) {
1062 delete bt;
1063 throw InternalErr(__FILE__, __LINE__, "The rank of special coordinate variable must be 1");
1064 }
1065 int nelem = (cvar->getDimensions()[0])->getSize();
1066
1067 HDF5GMCFSpecialCVArray * ar = NULL;
1068 ar = new HDF5GMCFSpecialCVArray(
1069 cvar->getType(),
1070 nelem,
1071 cvar->getFullPath(),
1072 cvar->getPtType(),
1073 cvar->getNewName(),
1074 bt);
1075
1076 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1077 if (""==(*it_d)->getNewName())
1078 ar->append_dim((*it_d)->getSize());
1079 else
1080 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1081 }
1082
1083 dds.add_var(ar);
1084 delete bt;
1085 delete ar;
1086
1087 }
1088 break;
1089 case CV_MODIFY:
1090 default:
1091 delete bt;
1092 throw InternalErr(__FILE__,__LINE__,"Coordinate variable type is not supported.");
1093 }
1094 }
1095}
1096
1097// Generate DDS for special variable in a general product
1098void gen_dap_onegmspvar_dds(DDS &dds,const HDF5CF::GMSPVar* spvar, const hid_t fileid, const string & filename) {
1099
1100 BESDEBUG("h5","Coming to gen_dap_onegmspvar_dds() "<<endl);
1101 BaseType *bt = NULL;
1102
1103 switch(spvar->getType()) {
1104#define HANDLE_CASE(tid,type) \
1105 case tid: \
1106 bt = new (type)(spvar->getNewName(),spvar->getFullPath()); \
1107 break;
1108
1109 HANDLE_CASE(H5FLOAT32, HDF5CFFloat32);
1110 HANDLE_CASE(H5FLOAT64, HDF5CFFloat64);
1111 HANDLE_CASE(H5CHAR,HDF5CFInt16);
1112 HANDLE_CASE(H5UCHAR, HDF5CFByte);
1113 HANDLE_CASE(H5INT16, HDF5CFInt16);
1114 HANDLE_CASE(H5UINT16, HDF5CFUInt16);
1115 HANDLE_CASE(H5INT32, HDF5CFInt32);
1116 HANDLE_CASE(H5UINT32, HDF5CFUInt32);
1117 HANDLE_CASE(H5FSTRING, Str);
1118 HANDLE_CASE(H5VSTRING, Str);
1119 default:
1120 throw InternalErr(__FILE__,__LINE__,"unsupported data type.");
1121#undef HANDLE_CASE
1122 }
1123
1124 if (bt) {
1125
1126 const vector<HDF5CF::Dimension *>& dims = spvar->getDimensions();
1127 vector <HDF5CF::Dimension*>:: const_iterator it_d;
1128
1129 if(dims.empty())
1130 throw InternalErr(__FILE__,__LINE__,"Currently don't support scalar special variables. ");
1131
1132 HDF5GMSPCFArray *ar = NULL;
1133
1134 try {
1135 ar = new HDF5GMSPCFArray (
1136 spvar->getRank(),
1137 filename,
1138 fileid,
1139 spvar->getType(),
1140 spvar->getFullPath(),
1141 spvar->getOriginalType(),
1142 spvar->getStartBit(),
1143 spvar->getBitNum(),
1144 spvar->getNewName(),
1145 bt);
1146 }
1147 catch(...) {
1148 delete bt;
1149 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5GMCFMissNonLLCVArray. ");
1150 }
1151
1152
1153 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1154 if (""==(*it_d)->getNewName())
1155 ar->append_dim((*it_d)->getSize());
1156 else
1157 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1158 }
1159
1160 dds.add_var(ar);
1161 delete bt;
1162 delete ar;
1163 }
1164
1165}
1166
1167// When we add floating point fill value at HDF5CF.cc, the value will be changed
1168// a little bit when it changes to string representation.
1169// For example, -9999.9 becomes -9999.9000123. To reduce the misunderstanding,we
1170// just add fillvalue in the string type here. KY 2014-04-02
1171void update_GPM_special_attrs(DAS& das, const HDF5CF::Var *var,bool is_cvar) {
1172
1173 BESDEBUG("h5","Coming to update_GPM_special_attrs() "<<endl);
1174 if(H5FLOAT64 == var->getType() ||
1175 H5FLOAT32 == var->getType() ||
1176 H5INT16 == var->getType() ||
1177 H5CHAR == var->getType()) {
1178
1179 AttrTable *at = das.get_table(var->getNewName());
1180 if (NULL == at)
1181 at = das.add_table(var->getNewName(), new AttrTable);
1182 bool has_fillvalue = false;
1183 AttrTable::Attr_iter it = at->attr_begin();
1184 while (it!=at->attr_end() && false==has_fillvalue) {
1185 if (at->get_name(it) =="_FillValue")
1186 {
1187 has_fillvalue = true;
1188 string fillvalue ="";
1189 if(H5FLOAT32 == var->getType()) {
1190 const string cor_fill_value = "-9999.9";
1191 fillvalue = (*at->get_attr_vector(it)->begin());
1192 if((fillvalue.find(cor_fill_value) == 0) && (fillvalue!= cor_fill_value)) {
1193 at->del_attr("_FillValue");
1194 at->append_attr("_FillValue","Float32",cor_fill_value);
1195 }
1196 }
1197 else if(H5FLOAT64 == var->getType()) {
1198 const string cor_fill_value = "-9999.9";
1199 const string exist_fill_value_substr = "-9999.8999";
1200 fillvalue = (*at->get_attr_vector(it)->begin());
1201 if((fillvalue.find(exist_fill_value_substr) == 0) && (fillvalue!= cor_fill_value)) {
1202 at->del_attr("_FillValue");
1203 at->append_attr("_FillValue","Float64",cor_fill_value);
1204 }
1205
1206 }
1207 }
1208 it++;
1209 }
1210
1211 // Add the fill value
1212 if(false == is_cvar ) {
1213
1214 // Current versions of GPM don't add fillvalues. We add the fillvalue according to the document.
1215 if (has_fillvalue != true ) {
1216
1217 if(H5FLOAT32 == var->getType())
1218 at->append_attr("_FillValue","Float32","-9999.9");
1219 else if(H5FLOAT64 == var->getType())
1220 at->append_attr("_FillValue","Float64","-9999.9");
1221 else if (H5INT16 == var->getType())
1222 at->append_attr("_FillValue","Int16","-9999");
1223 else if (H5CHAR == var->getType())// H5CHAR maps to DAP int16
1224 at->append_attr("_FillValue","Int16","-99");
1225
1226 }
1227 }
1228 }
1229}
1230
1231void gen_dap_onegmcvar_dmr(D4Group*d4_root,const GMCVar* cvar,const hid_t fileid, const string &filename) {
1232
1233 BESDEBUG("h5","Coming to gen_dap_onegmcvar_dds() "<<endl);
1234
1235 BaseType *bt = NULL;
1236
1237 switch(cvar->getType()) {
1238#define HANDLE_CASE(tid,type) \
1239 case tid: \
1240 bt = new (type)(cvar->getNewName(),cvar->getFullPath()); \
1241 break;
1242
1243 HANDLE_CASE(H5FLOAT32, HDF5CFFloat32);
1244 HANDLE_CASE(H5FLOAT64, HDF5CFFloat64);
1245 HANDLE_CASE(H5CHAR,HDF5CFInt8);
1246 HANDLE_CASE(H5UCHAR, HDF5CFByte);
1247 HANDLE_CASE(H5INT16, HDF5CFInt16);
1248 HANDLE_CASE(H5UINT16, HDF5CFUInt16);
1249 HANDLE_CASE(H5INT32, HDF5CFInt32);
1250 HANDLE_CASE(H5UINT32, HDF5CFUInt32);
1251 HANDLE_CASE(H5INT64, HDF5CFInt64);
1252 HANDLE_CASE(H5UINT64, HDF5CFUInt64);
1253 HANDLE_CASE(H5FSTRING, Str);
1254 HANDLE_CASE(H5VSTRING, Str);
1255
1256 default:
1257 throw InternalErr(__FILE__,__LINE__,"unsupported data type.");
1258#undef HANDLE_CASE
1259 }
1260
1261 if (bt) {
1262
1263 const vector<HDF5CF::Dimension *>& dims = cvar->getDimensions();
1264 vector <HDF5CF::Dimension*>:: const_iterator it_d;
1265 vector <size_t> dimsizes;
1266 dimsizes.resize(cvar->getRank());
1267
1268 for(int i = 0; i <cvar->getRank();i++)
1269 dimsizes[i] = (dims[i])->getSize();
1270
1271 if(dims.empty())
1272 throw InternalErr(__FILE__,__LINE__,"the coordinate variable cannot be a scalar");
1273
1274 switch(cvar->getCVType()) {
1275
1276 case CV_EXIST:
1277 {
1278 HDF5CFArray *ar = NULL;
1279
1280 // Need to check if this CV is lat/lon. This is necessary when data memory cache is turned on.
1281 bool is_latlon = cvar->isLatLon();
1282
1283 try {
1284
1285 bool is_dap4 = true;
1286 ar = new HDF5CFArray (
1287 cvar->getRank(),
1288 fileid,
1289 filename,
1290 cvar->getType(),
1291 dimsizes,
1292 cvar->getFullPath(),
1293 cvar->getTotalElems(),
1294 CV_EXIST,
1295 is_latlon,
1296 cvar->getCompRatio(),
1297 is_dap4,
1298 cvar->getNewName(),
1299 bt);
1300 }
1301 catch(...) {
1302 delete bt;
1303 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5CFArray. ");
1304 }
1305
1306 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1307 if (""==(*it_d)->getNewName())
1308 ar->append_dim((*it_d)->getSize());
1309 else
1310 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1311 }
1312
1313 ar->set_is_dap4(true);
1314 BaseType* d4_var=ar->h5cfdims_transform_to_dap4(d4_root);
1315 map_cfh5_var_attrs_to_dap4(cvar,d4_var);
1316 d4_root->add_var_nocopy(d4_var);
1317 delete bt;
1318 delete ar;
1319 }
1320 break;
1321
1322 case CV_LAT_MISS:
1323 case CV_LON_MISS:
1324 {
1325 // Using HDF5GMCFMissLLArray
1326 HDF5GMCFMissLLArray *ar = NULL;
1327 try {
1328 ar = new HDF5GMCFMissLLArray (
1329 cvar->getRank(),
1330 filename,
1331 fileid,
1332 cvar->getType(),
1333 cvar->getFullPath(),
1334 cvar->getPtType(),
1335 cvar->getCVType(),
1336 cvar->getNewName(),
1337 bt);
1338 }
1339 catch(...) {
1340 delete bt;
1341 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5GMCFMissLLArray. ");
1342 }
1343
1344 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1345 if (""==(*it_d)->getNewName())
1346 ar->append_dim((*it_d)->getSize());
1347 else
1348 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1349 }
1350
1351 ar->set_is_dap4(true);
1352 BaseType* d4_var=ar->h5cfdims_transform_to_dap4(d4_root);
1353 map_cfh5_var_attrs_to_dap4(cvar,d4_var);
1354 d4_root->add_var_nocopy(d4_var);
1355 delete bt;
1356 delete ar;
1357 }
1358 break;
1359
1360 case CV_NONLATLON_MISS:
1361 {
1362
1363 if (cvar->getRank() !=1) {
1364 delete bt;
1365 throw InternalErr(__FILE__, __LINE__, "The rank of missing Z dimension field must be 1");
1366 }
1367 int nelem = (cvar->getDimensions()[0])->getSize();
1368
1369 HDF5GMCFMissNonLLCVArray *ar = NULL;
1370
1371 try {
1372 ar = new HDF5GMCFMissNonLLCVArray(
1373 cvar->getRank(),
1374 nelem,
1375 cvar->getNewName(),
1376 bt);
1377 }
1378 catch(...) {
1379 delete bt;
1380 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5GMCFMissNonLLCVArray. ");
1381 }
1382
1383
1384 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1385 if (""==(*it_d)->getNewName())
1386 ar->append_dim((*it_d)->getSize());
1387 else
1388 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1389 }
1390 ar->set_is_dap4(true);
1391 BaseType* d4_var=ar->h5cfdims_transform_to_dap4(d4_root);
1392 map_cfh5_var_attrs_to_dap4(cvar,d4_var);
1393 d4_root->add_var_nocopy(d4_var);
1394 delete bt;
1395 delete ar;
1396 }
1397 break;
1398
1399 case CV_FILLINDEX:
1400 {
1401
1402 if (cvar->getRank() !=1) {
1403 delete bt;
1404 throw InternalErr(__FILE__, __LINE__, "The rank of missing Z dimension field must be 1");
1405 }
1406
1407 HDF5GMCFFillIndexArray *ar = NULL;
1408
1409 try {
1410 ar = new HDF5GMCFFillIndexArray(
1411 cvar->getRank(),
1412 cvar->getType(),
1413 true,
1414 cvar->getNewName(),
1415 bt);
1416 }
1417 catch(...) {
1418 delete bt;
1419 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5GMCFMissNonLLCVArray. ");
1420 }
1421
1422
1423 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1424 if (""==(*it_d)->getNewName())
1425 ar->append_dim((*it_d)->getSize());
1426 else
1427 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1428 }
1429 ar->set_is_dap4(true);
1430 BaseType* d4_var=ar->h5cfdims_transform_to_dap4(d4_root);
1431 map_cfh5_var_attrs_to_dap4(cvar,d4_var);
1432 d4_root->add_var_nocopy(d4_var);
1433 delete bt;
1434 delete ar;
1435 }
1436 break;
1437
1438
1439 case CV_SPECIAL:
1440 {
1441 // Currently only handle 1-D special CV.
1442 if (cvar->getRank() !=1) {
1443 delete bt;
1444 throw InternalErr(__FILE__, __LINE__, "The rank of special coordinate variable must be 1");
1445 }
1446 int nelem = (cvar->getDimensions()[0])->getSize();
1447
1448 HDF5GMCFSpecialCVArray * ar = NULL;
1449 ar = new HDF5GMCFSpecialCVArray(
1450 cvar->getType(),
1451 nelem,
1452 cvar->getFullPath(),
1453 cvar->getPtType(),
1454 cvar->getNewName(),
1455 bt);
1456
1457 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1458 if (""==(*it_d)->getNewName())
1459 ar->append_dim((*it_d)->getSize());
1460 else
1461 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1462 }
1463
1464 ar->set_is_dap4(true);
1465 BaseType* d4_var=ar->h5cfdims_transform_to_dap4(d4_root);
1466 map_cfh5_var_attrs_to_dap4(cvar,d4_var);
1467 d4_root->add_var_nocopy(d4_var);
1468 delete bt;
1469 delete ar;
1470
1471 }
1472 break;
1473 case CV_MODIFY:
1474 default:
1475 delete bt;
1476 throw InternalErr(__FILE__,__LINE__,"Coordinate variable type is not supported.");
1477 }
1478 }
1479
1480
1481}
1482
1483void gen_dap_onegmspvar_dmr(D4Group*d4_root,const GMSPVar*spvar,const hid_t fileid, const string &filename) {
1484
1485 BESDEBUG("h5","Coming to gen_dap_onegmspvar_dmr() "<<endl);
1486 BaseType *bt = NULL;
1487
1488 // Note: The special variable is actually an ACOS_OCO2 64-bit integer variable.
1489 // We decompose 64-bit to two integer variables according to the specification.
1490 // This product has been served in this way for years. For backward compatibility,
1491 // we will not change this in the CF DMR implementation. So Int64/UInt64 are not added.
1492 // KY 2021-03-09
1493 switch(spvar->getType()) {
1494#define HANDLE_CASE(tid,type) \
1495 case tid: \
1496 bt = new (type)(spvar->getNewName(),spvar->getFullPath()); \
1497 break;
1498
1499 HANDLE_CASE(H5FLOAT32, HDF5CFFloat32);
1500 HANDLE_CASE(H5FLOAT64, HDF5CFFloat64);
1501 HANDLE_CASE(H5CHAR,HDF5CFByte);
1502 HANDLE_CASE(H5UCHAR, HDF5CFByte);
1503 HANDLE_CASE(H5INT16, HDF5CFInt16);
1504 HANDLE_CASE(H5UINT16, HDF5CFUInt16);
1505 HANDLE_CASE(H5INT32, HDF5CFInt32);
1506 HANDLE_CASE(H5UINT32, HDF5CFUInt32);
1507 HANDLE_CASE(H5FSTRING, Str);
1508 HANDLE_CASE(H5VSTRING, Str);
1509 default:
1510 throw InternalErr(__FILE__,__LINE__,"unsupported data type.");
1511#undef HANDLE_CASE
1512 }
1513
1514 if (bt) {
1515
1516 const vector<HDF5CF::Dimension *>& dims = spvar->getDimensions();
1517 vector <HDF5CF::Dimension*>:: const_iterator it_d;
1518
1519 if(dims.empty())
1520 throw InternalErr(__FILE__,__LINE__,"Currently don't support scalar special variables. ");
1521
1522 HDF5GMSPCFArray *ar = NULL;
1523
1524 try {
1525 ar = new HDF5GMSPCFArray (
1526 spvar->getRank(),
1527 filename,
1528 fileid,
1529 spvar->getType(),
1530 spvar->getFullPath(),
1531 spvar->getOriginalType(),
1532 spvar->getStartBit(),
1533 spvar->getBitNum(),
1534 spvar->getNewName(),
1535 bt);
1536 }
1537 catch(...) {
1538 delete bt;
1539 throw InternalErr(__FILE__,__LINE__,"Unable to allocate HDF5GMCFMissNonLLCVArray. ");
1540 }
1541
1542
1543 for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
1544 if (""==(*it_d)->getNewName())
1545 ar->append_dim((*it_d)->getSize());
1546 else
1547 ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
1548 }
1549
1550 ar->set_is_dap4(true);
1551 BaseType* d4_var=ar->h5cfdims_transform_to_dap4(d4_root);
1552 map_cfh5_var_attrs_to_dap4(spvar,d4_var);
1553 d4_root->add_var_nocopy(d4_var);
1554
1555 //dds.add_var(ar);
1556 delete bt;
1557 delete ar;
1558 }
1559
1560}
This class includes the methods to read data array into DAP buffer from an HDF5 dataset for the CF op...
This class provides a way to map HDF5 byte to DAP byte for the CF option.
This class provides a way to map HDF5 float to DAP float for the CF option.
This class provides a way to map HDF5 64-bit floating-point(double) to DAP 64-bit floating-point for ...
This class provides a way to map HDF5 int16 to DAP int16 for the CF option.
This class provides a way to map HDF5 32-bit integer to DAP Int32 for the CF option.
This class provides a way to map HDF5 64-bit integer to DAP4 Int64 for the CF option.
This class provides a way to map HDF5 int8 to DAP int16 for the CF option.
This class provides a way to map HDF5 Str to DAP Str for the CF option.
This class provides a way to map HDF5 unsigned 16-bit integer to DAP uint16 for the CF option.
This class provides a way to map HDF5 unsigned 32-bit integer to DAP uint32 for the CF option.
This class provides a way to map HDF5 64-bit unsigned integer to DAP4 UInt64 for the CF option.
This class includes the methods to read data array into DAP buffer from an HDF5 dataset for the CF op...
This class specifies the retrieval of the missing lat/lon values for general HDF5 products.
This class specifies the retrieval of the values of non-lat/lon coordinate variables for general HDF5...
This class specifies the retrieval of the missing lat/lon values for general HDF5 products.
This class specifies the retrieval of data values for special HDF5 products Currently this only appli...
include the entry functions to execute the handlers
CVType getCVType() const
Get the coordinate variable type of this variable.
Definition: HDF5CF.h:372
bool HaveUnlimitedDim() const
Has unlimited dimensions.
Definition: HDF5CF.h:691
virtual void Retrieve_H5_Var_Attr_Values(Var *var)
Retrieve attribute values for a variable.
Definition: HDF5CF.cc:748
hid_t getFileID() const
Obtain the HDF5 file ID.
Definition: HDF5CF.h:661
const std::vector< Attribute * > & getAttributes() const
Public interface to obtain information of all attributes under the root group.
Definition: HDF5CF.h:679
const std::vector< Group * > & getGroups() const
Public interface to obtain all the group info.
Definition: HDF5CF.h:685
const std::string & getPath() const
Obtain the path of the file.
Definition: HDF5CF.h:667
const std::vector< Var * > & getVars() const
Public interface to obtain information of all variables.
Definition: HDF5CF.h:673
This class is a derived class of CVar. It represents a coordinate variable for general HDF5 files.
Definition: HDF5CF.h:427
H5GCFProduct getPtType() const
Get the data type of this variable.
Definition: HDF5CF.h:439
This class is a derived class of File. It includes methods applied to general HDF5 files only.
Definition: HDF5CF.h:845
virtual void Handle_Unsupported_Dtype(bool)
Handle unsupported HDF5 datatypes for general HDF5 products.
Definition: HDF5GMCF.cc:400
virtual void Adjust_Obj_Name()
Adjust object names based on different general NASA HDF5 products.
Definition: HDF5GMCF.cc:4912
virtual void Retrieve_H5_CVar_Supported_Attr_Values()
Retrieve coordinate variable attributes.
Definition: HDF5GMCF.cc:333
void Add_Path_Coord_Attr()
Update the coordinate attribute to include path and also flatten.
Definition: HDF5GMCF.cc:7026
virtual bool Have_Grid_Mapping_Attrs()
Check if having Grid Mapping Attrs.
Definition: HDF5GMCF.cc:6950
virtual void Adjust_Dim_Name()
Adjust dimension name for general NASA HDF5 products.
Definition: HDF5GMCF.cc:5225
void Handle_Obj_NameClashing(bool)
Handle object name clashing for general NASA HDF5 products.
Definition: HDF5GMCF.cc:5055
void Remove_Unused_FakeDimVars()
Unsupported datatype array may generate FakeDim. Remove them.
Definition: HDF5GMCF.cc:6958
void Update_Product_Type()
Update "product type" attributes for general HDF5 products.
Definition: HDF5GMCF.cc:238
virtual void Retrieve_H5_Info(const char *path, hid_t file_id, bool include_attr)
Retrieve DDS information from the HDF5 file; real implementation for general HDF5 products.
Definition: HDF5GMCF.cc:219
virtual void Handle_SpVar()
Handle special variables for general NASA HDF5 products.
Definition: HDF5GMCF.cc:4822
virtual bool Get_IgnoredInfo_Flag()
Obtain ignored info. flag.
Definition: HDF5CF.h:947
virtual void Handle_Unsupported_Dspace(bool)
Handle unsupported HDF5 dataspaces for general HDF5 products.
Definition: HDF5GMCF.cc:597
virtual void Handle_Unsupported_Others(bool)
Handle other unmapped objects/attributes for general HDF5 products.
Definition: HDF5GMCF.cc:694
void Remove_Unneeded_Objects()
Remove unneeded objects.
Definition: HDF5GMCF.cc:261
virtual const std::string & Get_Ignored_Msg()
Get the message that contains the ignored obj. info.
Definition: HDF5CF.h:953
void Add_Dim_Name()
Add dimension name.
Definition: HDF5GMCF.cc:833
virtual void Flatten_Obj_Name(bool include_attr)
Flatten the object name for general NASA HDF5 products.
Definition: HDF5GMCF.cc:4997
virtual void Handle_Grid_Mapping_Vars()
Handle Grid Mapping Vars.
Definition: HDF5GMCF.cc:6954
virtual void Handle_DimNameClashing()
Definition: HDF5GMCF.cc:5160
virtual void Handle_Coor_Attr()
Handle "coordinates" attributes for general HDF5 products.
Definition: HDF5GMCF.cc:6016
void Rename_NC4_NonCoordVars()
Remove the _nc4_non_coord from the variable new names.
Definition: HDF5GMCF.cc:7006
virtual void Retrieve_H5_Supported_Attr_Values()
Retrieve attribute values for the supported HDF5 datatypes for general HDF5 products.
Definition: HDF5GMCF.cc:348
virtual void Add_Supplement_Attrs(bool)
Add supplemental attributes such as fullpath and original name for general NASA HDF5 products.
Definition: HDF5GMCF.cc:5287
virtual void Handle_CVar()
Handle coordinate variables for general NASA HDF5 products.
Definition: HDF5GMCF.cc:2939
This class is a derived class of Var. It represents a special general HDF5 product(currently ACOS and...
Definition: HDF5CF.h:392
This class represents one HDF5 dataset(CF variable)
Definition: HDF5CF.h:259
int getRank() const
Get the dimension rank of this variable.
Definition: HDF5CF.h:305
const std::string & getFullPath() const
Get the full path of this variable.
Definition: HDF5CF.h:283
H5DataType getType() const
Get the data type of this variable(Not HDF5 datatype id)
Definition: HDF5CF.h:311
const std::vector< Dimension * > & getDimensions() const
Get the list of the dimensions.
Definition: HDF5CF.h:322
int getCompRatio() const
Get the compression ratio of this dataset.
Definition: HDF5CF.h:328
const std::string & getNewName() const
Get the new name of this variable.
Definition: HDF5CF.h:277
Helper functions for generating DAS attributes and a function to check BES Key.
Map and generate DDS and DAS for the CF option for generic HDF5 products.