bes Updated for version 3.20.13
HDFCFUtil.h
1
2// 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.
42const int MAX_NON_SCALE_SPECIAL_VALUE=65535;
43
44// This is the minimum number of MODIS special values.
45const 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
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
268inline int32
269INDEX_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.
294static 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
305static 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
325template<typename T>
326int 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