bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HDFCFUtil.h
1
2// Helper functions for handling dimension maps,clear memories and separating namelist
3//
4// Authors: Kent Yang <myang6@hdfgroup.org> Eunsoo Seo
5// Copyright (c) The HDF Group
7#ifndef HDFCFUTIL_H
8#define HDFCFUTIL_H
9
10#include <stdlib.h>
11#include <sys/file.h>
12#include <cstring>
13#include <string>
14#include <iostream>
15#include <sstream>
16#include <vector>
17#include <map>
18#include <set>
19#include <assert.h>
20#include <iomanip>
21#include <dirent.h>
22#include <libgen.h>
23#include <unistd.h>
24#include <cerrno>
25
26#include "mfhdf.h"
27#include "hdf.h"
28
29#ifdef USE_HDFEOS2_LIB
30#include "HdfEosDef.h"
31#include "HDFEOS2.h"
32#endif
33#include "HDFSP.h"
34
35#include <TheBESKeys.h>
36#include <BESUtil.h>
37#include <libdap/DDS.h>
38#include <libdap/DAS.h>
39#include <libdap/InternalErr.h>
40
41#include <libdap/escaping.h> // for escattr
42
43// This is the maximum number of MODIS special values.
44const int MAX_NON_SCALE_SPECIAL_VALUE=65535;
45
46// This is the minimum number of MODIS special values.
47const int MIN_NON_SCALE_SPECIAL_VALUE=65500;
48
49
50
51// This is used to retrieve dimension map info. when retrieving the data values of HDF-EOS swath that
52// has swath dimension maps.
54{
55 // geo dimension name
56 std::string geodim;
57
58 // data dimension name
59 std::string datadim;
60
61 // offset and increment of a dimension map
62 int32 offset;
63 int32 inc;
64};
65
66
68{
69
72 static void close_fileid(int32 sdfd,int32 file_id,int32 gridfd,int32 swathfd,bool pass_fileid_key);
73
74 static std::string escattr_fvalue(std::string s);
75
78 static void Split (const char *s, int len, char sep,
79 std::vector < std::string > &names);
80
82 static void Split (const char *sz, char sep,
83 std::vector < std::string > &names);
84
88 static bool insert_map(std::map<std::string,std::string>& m, std::string key, std::string val);
89
91 static std::string get_CF_string(std::string s);
92
94 static void gen_unique_name(std::string &str,std::set<std::string>& namelist, int&clash_index);
95
97 static void Handle_NameClashing(std::vector<std::string>&newobjnamelist);
98 static void Handle_NameClashing(std::vector<std::string>&newobjnamelist,std::set<std::string>&objnameset);
99
101 static std::string print_attr(int32, int, void*);
102
104 static std::string print_type(int32);
105
107 static short obtain_type_size(int32);
108
109
110 // Subsetting the 2-D fields
111 template <typename T> static void LatLon2DSubset (T* outlatlon, int ydim, int xdim, T* latlon, const int32 * offset, const int32 * count, const int32 * step);
112
115 static void correct_fvalue_type(libdap::AttrTable *at,int32 dtype);
116
117
121 static void correct_scale_offset_type(libdap::AttrTable *at);
122
123
124#ifdef USE_HDFEOS2_LIB
125
128
137 static bool change_data_type(libdap::DAS & das, SOType scaletype, const std::string & new_field_name);
138
143 static bool is_special_value(int32 dtype,float fillvalue, float realvalue);
144
146 static int check_geofile_dimmap(const std::string & geofilename);
147
151 static bool is_modis_dimmap_nonll_field(std::string & fieldname);
152
154 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);
155
157 //Scale and offset values with other types will be converted to float and their input values must also be in float.
158 //If the add_offset_found is false, the add_offset attribute will not be added. add_offset information will not be used.
159 static void add_scale_offset_attrs(libdap::AttrTable* at, const std::string& s_type, float svalue_f, double svalue_d, bool add_offset_found,
160 const std::string& o_type, float ovalue_f, double ovalue_d);
161
162 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,
163 const std::string& o_type, float ovalue_f, double ovalue_d);
164
165
166
168 static void handle_modis_special_attrs_disable_scale_comp(libdap::AttrTable *at,const string &filename, bool is_grid, const std::string &newfname, SOType scaletype);
169
173 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);
174
176 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);
177
179 static void handle_amsr_attrs(libdap::AttrTable *at);
180
181 // The following four functions is to handle 1-D CF CV variables required by CF projection conventions for grid.
182 // Obtains the latitude and longitude dimension info. of an HDF-EOS2 grid.
183 static void obtain_grid_latlon_dim_info(const HDFEOS2::GridDataset*,string &,int32 &,string &,int32 &);
184
185 // Adds the 1-D cf grid projection mapping attribute to data variables
186 // It is called by the function add_cf_grid_attrs.
187 static void add_cf_grid_mapping_attr(libdap::DAS &das, const HDFEOS2::GridDataset*gdset,const string& cf_projection,
188 const string & dim0name,int32 dim0size,const string &dim1name,int32 dim1size);
189
190 // This function adds the 1-D horizontal coordinate variables as well as the dummy projection variable to the grid.
191 static void add_cf_grid_cvs(libdap::DDS & dds, const HDFEOS2::GridDataset *gdset);
192
193 //Adds 1D grid mapping CF attributes to CV and data variables.
194 static void add_cf_grid_cv_attrs(libdap::DAS &das, const HDFEOS2::GridDataset *gdset);
195
196#endif
197
198 // Check OBPG attributes. Specifically, check if slope and intercept can be obtained from the file level.
199 // If having global slope and intercept, obtain OBPG scaling, slope and intercept values.
200 static void check_obpg_global_attrs(HDFSP::File*f,std::string & scaling, float & slope,bool &global_slope_flag,float & intercept, bool & global_intercept_flag);
201
202 // For some OBPG files that only provide slope and intercept at the file level,
203 // 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.
204 // 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.
205 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);
206
207 // Handle HDF4 OTHERHDF products that follow SDS dimension scale model.
208 // The special handling of AVHRR data is also included.
209 static void handle_otherhdf_special_attrs(const HDFSP::File *f, libdap::DAS &das);
210
211 // Add missing CF attributes for non-CV varibles
212 static void add_missing_cf_attrs(const HDFSP::File*f,libdap::DAS &das);
213
214 // Handle Merra and CERES attributes with the BES key EnableCERESMERRAShortName.
215 static void handle_merra_ceres_attrs_with_bes_keys(const HDFSP::File*f, libdap::DAS &das,const std::string& filename);
216
217 // Handle the attributes with the BES key EnableVdataDescAttr.
218 static void handle_vdata_attrs_with_desc_key(const HDFSP::File*f,libdap::DAS &das);
219
220 // 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.
221 static void map_eos2_objects_attrs(libdap::DAS &das,const string &filename);
222 static void map_eos2_one_object_attrs_wrapper(libdap::DAS &das,int32 file_id,int32 vgroup_id, const string &vgroup_name, bool is_grid);
223 static void map_eos2_one_object_attrs(libdap::DAS &das,int32 file_id,int32 obj_attr_group_id, const string &vgroup_name);
224
225 // Parse TRMM V7 GridHeaders
226 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);
227
228 // Use to generate cache file name.
229 // Reverse the char array order
230 static void rev_str(char *str, int len);
231
232 // Return the index of the char array for the integer part
233 static int int_to_str(int,char str[],int);
234
235 // Convert a double number to char array
236 static void dtoa(double,char *,int);
237
238 // Obtain the double number in the string format
239 static std::string get_double_str(double,int,int);
240
241 // Obtain the integer in the string format
242 static std::string get_int_str(int);
243
244
245 // Read double-type data from a file to a vector of double type
246 static ssize_t read_vector_from_file(int fd,vector<double> &,size_t);
247
248 // wrap function of Unix read to a buffer. Memory for the buffer should be allocated.
249 static ssize_t read_buffer_from_file(int fd,void*buf,size_t);
250 static std::string obtain_cache_fname(const std::string & fprefix, const std::string & fname, const std::string &vname);
251 static size_t obtain_dds_cache_size(const HDFSP::File*);
252 static void write_sp_sds_dds_cache(const HDFSP::File*,FILE*,size_t,const std::string & fname);
253 static void read_sp_sds_dds_cache(FILE*,libdap::DDS * dds_ptr,const std::string &filename, const std::string &hdf_filename);
254
255};
256
258inline int32
259INDEX_nD_TO_1D (const std::vector < int32 > &dims,
260 const std::vector < int32 > &pos)
261{
262// Leave this #if 0 #endif since this illustrates how this function works. KY 2023-10-12
263#if 0
264 /*
265 int a[10][20][30]; // & a[1][2][3] == a + (20*30+1 + 30*2 + 1 *3);
266 int b[10][2]; // &b[1][2] == b + (20*1 + 2);
267 */
268#endif
269 assert (dims.size () == pos.size ());
270 int32 sum = 0;
271 int32 start = 1;
272
273 for (unsigned int p = 0; p < pos.size (); p++) {
274 int32 m = 1;
275
276 for (unsigned int j = start; j < dims.size (); j++)
277 m *= dims[j];
278 sum += m * pos[p];
279 start++;
280 }
281 return sum;
282}
283
284// Build a lock of a certain type.
285static inline struct flock *lock(int type) {
286 static struct flock lock;
287 lock.l_type = (short)type;
288 lock.l_whence = SEEK_SET;
289 lock.l_start = 0;
290 lock.l_len = 0;
291 lock.l_pid = getpid();
292
293 return &lock;
294}
295
296static inline string get_errno() {
297 const char *s_err = strerror(errno);
298 if (s_err)
299 return s_err;
300 else
301 return "Unknown error.";
302}
303
304#endif
One instance of this class represents one SDS object.
Definition HDFSP.h:331
STL class.
static short obtain_type_size(int32)
Obtain datatype size.
Definition HDFCFUtil.cc:384
static bool insert_map(std::map< std::string, std::string > &m, std::string key, std::string val)
Definition HDFCFUtil.cc:84
static std::string print_attr(int32, int, void *)
Print attribute values in string.
Definition HDFCFUtil.cc:202
static std::string print_type(int32)
Print datatype in string.
Definition HDFCFUtil.cc:323
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:130
static void Handle_NameClashing(std::vector< std::string > &newobjnamelist)
General routines to handle name clashings.
Definition HDFCFUtil.cc:194
static void correct_scale_offset_type(libdap::AttrTable *at)
Definition HDFCFUtil.cc:540
static std::string get_CF_string(std::string s)
Change special characters to "_".
Definition HDFCFUtil.cc:100
static void Split(const char *s, int len, char sep, std::vector< std::string > &names)
Definition HDFCFUtil.cc:58
static void correct_fvalue_type(libdap::AttrTable *at, int32 dtype)
Definition HDFCFUtil.cc:477
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Definition HDFCFUtil.h:54