bes  Updated for version 3.20.13
HDFCFUtil.h
1 // Helper functions for handling dimension maps,clear memories and separating namelist
3 //
4 // Authors: MuQun Yang <myang6@hdfgroup.org> Eunsoo Seo
5 // Copyright (c) 2010-2012 The HDF Group
7 #ifndef HDFCFUTIL_H
8 #define HDFCFUTIL_H
9 
10 #include <stdlib.h>
11 #include <string>
12 #include <iostream>
13 #include <sstream>
14 #include <vector>
15 #include <map>
16 #include <set>
17 #include <assert.h>
18 #include <iomanip>
19 #include <dirent.h>
20 #include <libgen.h>
21 #include <unistd.h>
22 #include <cerrno>
23 
24 #include "mfhdf.h"
25 #include "hdf.h"
26 
27 #ifdef USE_HDFEOS2_LIB
28 #include "HdfEosDef.h"
29 #include "HDFEOS2.h"
30 #endif
31 #include "HDFSP.h"
32 
33 #include <TheBESKeys.h>
34 #include <BESUtil.h>
35 #include <libdap/DDS.h>
36 #include <libdap/DAS.h>
37 #include <libdap/InternalErr.h>
38 
39 #include <libdap/escaping.h> // for escattr
40 
41 // This is the maximum number of MODIS special values.
42 const int MAX_NON_SCALE_SPECIAL_VALUE=65535;
43 
44 // This is the minimum number of MODIS special values.
45 const int MIN_NON_SCALE_SPECIAL_VALUE=65500;
46 
47 
48 
49 // This is used to retrieve dimension map info. when retrieving the data values of HDF-EOS swath that
50 // has swath dimension maps.
52 {
53  // geo dimension name
54  std::string geodim;
55 
56  // data dimension name
57  std::string datadim;
58 
59  // offset and increment of a dimension map
60  int32 offset;
61  int32 inc;
62 };
63 
64 
65 struct HDFCFUtil
66 {
67 
70  static void close_fileid(int32 sdfd,int32 file_id,int32 gridfd,int32 swathfd,bool pass_fileid_key);
71 
72 
79  static std::string escattr(std::string s);
80 
81 
84  static void Split (const char *s, int len, char sep,
85  std::vector < std::string > &names);
86 
88  static void Split (const char *sz, char sep,
89  std::vector < std::string > &names);
90 
94  static bool insert_map(std::map<std::string,std::string>& m, std::string key, std::string val);
95 
97  static std::string get_CF_string(std::string s);
98 
100  static void gen_unique_name(std::string &str,std::set<std::string>& namelist, int&clash_index);
101 
103  static void Handle_NameClashing(std::vector<std::string>&newobjnamelist);
104  static void Handle_NameClashing(std::vector<std::string>&newobjnamelist,std::set<std::string>&objnameset);
105 
107  static std::string print_attr(int32, int, void*);
108 
110  static std::string print_type(int32);
111 
113  static short obtain_type_size(int32);
114 
115 
116  // Subsetting the 2-D fields
117  template <typename T> static void LatLon2DSubset (T* outlatlon, int ydim, int xdim, T* latlon, const int32 * offset, const int32 * count, const int32 * step);
118 
121  static void correct_fvalue_type(libdap::AttrTable *at,int32 dtype);
122 
123 
127  static void correct_scale_offset_type(libdap::AttrTable *at);
128 
129 
130 #ifdef USE_HDFEOS2_LIB
131 
134 
143  static bool change_data_type(libdap::DAS & das, SOType scaletype, const std::string & new_field_name);
144 
149  static bool is_special_value(int32 dtype,float fillvalue, float realvalue);
150 
152  static int check_geofile_dimmap(const std::string & geofilename);
153 
157  static bool is_modis_dimmap_nonll_field(std::string & fieldname);
158 
160  static void obtain_dimmap_info(const std::string& filename, HDFEOS2::Dataset*dataset,std::vector<struct dimmap_entry>& dimmaps, std::string & modis_geofilename,bool &geofile_nas_dimmap);
161 
163  //Scale and offset values with other types will be converted to float and their input values must also be in float.
164  //If the add_offset_found is false, the add_offset attribute will not be added. add_offset information will not be used.
165  static void add_scale_offset_attrs(libdap::AttrTable* at, const std::string& s_type, float svalue_f, double svalue_d, bool add_offset_found,
166  const std::string& o_type, float ovalue_f, double ovalue_d);
167 
168  static void add_scale_str_offset_attrs(libdap::AttrTable* at, const std::string& s_type, const std::string& s_value_str, bool add_offset_found,
169  const std::string& o_type, float ovalue_f, double ovalue_d);
170 
171 
172 
174  static void handle_modis_special_attrs_disable_scale_comp(libdap::AttrTable *at,const string &filename, bool is_grid, const std::string &newfname, SOType scaletype);
175 
179  static void handle_modis_special_attrs(libdap::AttrTable *at,const std::string &filename, bool is_grid, const std::string & newfname, SOType scaletype, bool gridname_change_valid_range, bool changedtype, bool &change_fvtype);
180 
182  static void handle_modis_vip_special_attrs(const std::string& valid_range_value,const std::string& scale_factor_value, float& valid_min, float & valid_max);
183 
185  static void handle_amsr_attrs(libdap::AttrTable *at);
186 
187  // The following four functions is to handle 1-D CF CV variables required by CF projection conventions for grid.
188  // Obtains the latitude and longitude dimension info. of an HDF-EOS2 grid.
189  static void obtain_grid_latlon_dim_info(const HDFEOS2::GridDataset*,string &,int32 &,string &,int32 &);
190 
191  // Adds the 1-D cf grid projection mapping attribute to data variables
192  // It is called by the function add_cf_grid_attrs.
193  static void add_cf_grid_mapping_attr(libdap::DAS &das, const HDFEOS2::GridDataset*gdset,const string& cf_projection,
194  const string & dim0name,int32 dim0size,const string &dim1name,int32 dim1size);
195 
196  // This function adds the 1-D horizontal coordinate variables as well as the dummy projection variable to the grid.
197  static void add_cf_grid_cvs(libdap::DDS & dds, const HDFEOS2::GridDataset *gdset);
198 
199  //Adds 1D grid mapping CF attributes to CV and data variables.
200  static void add_cf_grid_cv_attrs(libdap::DAS &das, const HDFEOS2::GridDataset *gdset);
201 
202 #endif
203 
204  // Check OBPG attributes. Specifically, check if slope and intercept can be obtained from the file level.
205  // If having global slope and intercept, obtain OBPG scaling, slope and intercept values.
206  static void check_obpg_global_attrs(HDFSP::File*f,std::string & scaling, float & slope,bool &global_slope_flag,float & intercept, bool & global_intercept_flag);
207 
208  // For some OBPG files that only provide slope and intercept at the file level,
209  // global slope and intercept are needed to add to all fields and their names are needed to be changed to scale_factor and add_offset.
210  // For OBPG files that provide slope and intercept at the field level, slope and intercept are needed to rename to scale_factor and add_offset.
211  static void add_obpg_special_attrs(const HDFSP::File*f,libdap::DAS &das, const HDFSP::SDField* spsds,const std::string & scaling, float&slope,const bool &global_slope_flag,float& intercept,const bool &global_intercept_flag);
212 
213  // Handle HDF4 OTHERHDF products that follow SDS dimension scale model.
214  // The special handling of AVHRR data is also included.
215  static void handle_otherhdf_special_attrs(const HDFSP::File *f, libdap::DAS &das);
216 
217  // Add missing CF attributes for non-CV varibles
218  static void add_missing_cf_attrs(const HDFSP::File*f,libdap::DAS &das);
219 
220  // Handle Merra and CERES attributes with the BES key EnableCERESMERRAShortName.
221  static void handle_merra_ceres_attrs_with_bes_keys(const HDFSP::File*f, libdap::DAS &das,const std::string& filename);
222 
223  // Handle the attributes with the BES key EnableVdataDescAttr.
224  static void handle_vdata_attrs_with_desc_key(const HDFSP::File*f,libdap::DAS &das);
225 
226  // Map AIRS version 6 or MOD08 HDF-EOS object attributes to DAP2, here we simply call Hopen and just retrieve the vgroup info. for the performance reason.
227  static void map_eos2_objects_attrs(libdap::DAS &das,const string &filename);
228  static void map_eos2_one_object_attrs_wrapper(libdap::DAS &das,int32 file_id,int32 vgroup_id, const string &vgroup_name, bool is_grid);
229  static void map_eos2_one_object_attrs(libdap::DAS &das,int32 file_id,int32 obj_attr_group_id, const string &vgroup_name);
230 
231  // Parse TRMM V7 GridHeaders
232  static void parser_trmm_v7_gridheader(const std:: vector<char>&value, int& latsize, int&lonsize, float& lat_start, float& lon_start, float& lat_res, float& lon_res, bool check_reg_orig);
233 
234  // Use to generate cache file name.
235  // Reverse the char array order
236  static void rev_str(char *str, int len);
237 
238  // Return the index of the char array for the integer part
239  static int int_to_str(int,char str[],int);
240 
241  // Convert a double number to char array
242  static void dtoa(double,char *,int);
243 
244  // Obtain the double number in the string format
245  static std::string get_double_str(double,int,int);
246 
247  // Obtain the integer in the string format
248  static std::string get_int_str(int);
249 
250 
251 #if 0
252  static size_t write_vector_to_file(const std::string &,const vector<double> &,size_t);
253  static ssize_t write_vector_to_file2(const std::string &,const vector<double> &,size_t);
254 #endif
255  // Read double-type data from a file to a vector of double type
256  static ssize_t read_vector_from_file(int fd,vector<double> &,size_t);
257 
258  // wrap function of Unix read to a buffer. Memory for the buffer should be allocated.
259  static ssize_t read_buffer_from_file(int fd,void*buf,size_t);
260  static std::string obtain_cache_fname(const std::string & fprefix, const std::string & fname, const std::string &vname);
261  static size_t obtain_dds_cache_size(const HDFSP::File*);
262  static void write_sp_sds_dds_cache(const HDFSP::File*,FILE*,size_t,const std::string & fname);
263  static void read_sp_sds_dds_cache(FILE*,libdap::DDS * dds_ptr,const std::string &filename, const std::string &hdf_filename);
264 
265 };
266 
268 inline int32
269 INDEX_nD_TO_1D (const std::vector < int32 > &dims,
270  const std::vector < int32 > &pos)
271 {
272 #if 0
273  /*
274  int a[10][20][30]; // & a[1][2][3] == a + (20*30+1 + 30*2 + 1 *3);
275  int b[10][2]; // &b[1][2] == b + (20*1 + 2);
276  */
277 #endif
278  assert (dims.size () == pos.size ());
279  int32 sum = 0;
280  int32 start = 1;
281 
282  for (unsigned int p = 0; p < pos.size (); p++) {
283  int32 m = 1;
284 
285  for (unsigned int j = start; j < dims.size (); j++)
286  m *= dims[j];
287  sum += m * pos[p];
288  start++;
289  }
290  return sum;
291 }
292 
293 // Build a lock of a certain type.
294 static inline struct flock *lock(int type) {
295  static struct flock lock;
296  lock.l_type = (short)type;
297  lock.l_whence = SEEK_SET;
298  lock.l_start = 0;
299  lock.l_len = 0;
300  lock.l_pid = getpid();
301 
302  return &lock;
303 }
304 
305 static inline string get_errno() {
306  const char *s_err = strerror(errno);
307  if (s_err)
308  return s_err;
309  else
310  return "Unknown error.";
311 }
312 
314 //
315 // \param input Input variable
316 // \param dim dimension info of the input
317 // \param start start indexes of each dim
318 // \param stride stride of each dim
319 // \param edge count of each dim
320 // \param poutput output variable
321 // \parrm index dimension index
322 // \return 0 if successful. -1 otherwise.
323 //
324 #if 0
325 template<typename T>
326 int subset(
327  const T input[],
328  int rank,
329  vector<int> & dim,
330  vector<int> & start,
331  vector<int> & stride,
332  vector<int> & edge,
333  std::vector<T> *poutput,
334  vector<int>& pos,
335  int index)
336 {
337  for(int k=0; k<edge[index]; k++)
338  {
339  pos[index] = start[index] + k*stride[index];
340  if(index+1<rank)
341  subset(input, rank, dim, start, stride, edge, poutput,pos,index+1);
342  if(index==rank-1)
343  {
344  poutput->push_back(input[INDEX_nD_TO_1D( dim, pos)]);
345  }
346  } // end of for
347  return 0;
348 } // end of template<typename T> static int subset
349 #endif
350 
351 #endif
One instance of this class represents one SDS object.
Definition: HDFSP.h:337
static short obtain_type_size(int32)
Obtain datatype size.
Definition: HDFCFUtil.cc:450
static bool insert_map(std::map< std::string, std::string > &m, std::string key, std::string val)
Definition: HDFCFUtil.cc:150
static std::string print_attr(int32, int, void *)
Print attribute values in string.
Definition: HDFCFUtil.cc:268
static std::string print_type(int32)
Print datatype in string.
Definition: HDFCFUtil.cc:389
static void gen_unique_name(std::string &str, std::set< std::string > &namelist, int &clash_index)
Obtain the unique name for the clashed names and save it to set namelist.
Definition: HDFCFUtil.cc:196
static void Handle_NameClashing(std::vector< std::string > &newobjnamelist)
General routines to handle name clashings.
Definition: HDFCFUtil.cc:260
static void correct_scale_offset_type(libdap::AttrTable *at)
Definition: HDFCFUtil.cc:616
static std::string get_CF_string(std::string s)
Change special characters to "_".
Definition: HDFCFUtil.cc:166
static void Split(const char *s, int len, char sep, std::vector< std::string > &names)
Definition: HDFCFUtil.cc:82
static std::string escattr(std::string s)
Definition: HDFCFUtil.cc:3309
static void correct_fvalue_type(libdap::AttrTable *at, int32 dtype)
Definition: HDFCFUtil.cc:549
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Definition: HDFCFUtil.cc:3650
Definition: HDFCFUtil.h:52