OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDFEOS5CFSpecialCVArray.cc
Go to the documentation of this file.
1 // This file is part of the hdf5_handler implementing for the CF-compliant
2 // Copyright (c) 2011-2013 The HDF Group, Inc. and OPeNDAP, Inc.
3 //
4 // This is free software; you can redistribute it and/or modify it under the
5 // terms of the GNU Lesser General Public License as published by the Free
6 // Software Foundation; either version 2.1 of the License, or (at your
7 // option) any later version.
8 //
9 // This software is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 // License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 //
18 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
19 // You can contact The HDF Group, Inc. at 1800 South Oak Street,
20 // Suite 203, Champaign, IL 61820
21 
31 
32 #include "config_hdf5.h"
33 #include <iostream>
34 #include <sstream>
35 #include <cassert>
36 #include <debug.h>
37 #include "InternalErr.h"
38 #include <BESDebug.h>
39 
41 
43 {
44  return new HDFEOS5CFSpecialCVArray(*this);
45 }
46 
48 
49  BESDEBUG("h5","Coming to HDFEOS5CFSpecialCVArray read "<<endl);
50  string check_pass_fileid_key_str="H5.EnablePassFileID";
51  bool check_pass_fileid_key = false;
52  check_pass_fileid_key = HDF5CFDAPUtil::check_beskeys(check_pass_fileid_key_str);
53 
54  vector<int> offset;
55  vector<int> count;
56  vector<int>step;
57  int nelms = 0;
58 
59  if (rank < 0)
60  throw InternalErr (__FILE__, __LINE__,
61  "The number of dimension of the variable is negative.");
62 
63  else if (rank == 0)
64  nelms = 1;
65  else {
66  offset.resize(rank);
67  count.resize(rank);
68  step.resize(rank);
69 
70  nelms = format_constraint (&offset[0], &step[0], &count[0]);
71 
72  }
73 
74  // hid_t fileid = -1;
75  if(false == check_pass_fileid_key) {
76  if ((fileid = H5Fopen(filename.c_str(),H5F_ACC_RDONLY,H5P_DEFAULT))<0) {
77 
78  ostringstream eherr;
79  eherr << "HDF5 File " << filename
80  << " cannot be opened. "<<endl;
81  throw InternalErr (__FILE__, __LINE__, eherr.str ());
82  }
83  }
84  string cv_name = HDF5CFUtil::obtain_string_after_lastslash(varname);
85  if ("" == cv_name) {
86  // H5Fclose(fileid);
87  throw InternalErr (__FILE__, __LINE__, "Cannot obtain TES CV attribute");
88  }
89 
90  string group_name = varname.substr(0,varname.size()-cv_name.size());
91 
92  size_t cv_name_sep_pos = cv_name.find_first_of('_',0);
93 
94  if (string::npos == cv_name_sep_pos) {
95  // H5Fclose(fileid);
96  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
97  throw InternalErr (__FILE__, __LINE__, "Cannot obtain TES CV attribute");
98  }
99  string cv_attr_name = cv_name.substr(0,cv_name_sep_pos);
100 
101  htri_t swath_link_exist = H5Lexists(fileid,group_name.c_str(),H5P_DEFAULT);
102 
103  if (swath_link_exist <= 0) {
104  // H5Fclose(fileid);
105  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
106  throw InternalErr (__FILE__, __LINE__, "The TES swath link doesn't exist");
107  }
108 
109  htri_t swath_exist = H5Oexists_by_name(fileid,group_name.c_str(),H5P_DEFAULT);
110  if (swath_exist <= 0) {
111  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
112  //H5Fclose(fileid);
113  throw InternalErr (__FILE__, __LINE__, "The TES swath doesn't exist");
114  }
115 
116  htri_t cv_attr_exist = H5Aexists_by_name(fileid,group_name.c_str(),cv_attr_name.c_str(),H5P_DEFAULT);
117  if (cv_attr_exist <= 0) {
118  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
119  //H5Fclose(fileid);
120  throw InternalErr (__FILE__, __LINE__, "The TES swath CV attribute doesn't exist");
121  }
122 
123  hid_t cv_attr_id = H5Aopen_by_name(fileid,group_name.c_str(),cv_attr_name.c_str(),H5P_DEFAULT,H5P_DEFAULT);
124  if (cv_attr_id <0) {
125  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
126  //H5Fclose(fileid);
127  throw InternalErr (__FILE__, __LINE__, "Cannot obtain the TES CV attribute id");
128  }
129 
130  hid_t attr_type = -1;
131  if ((attr_type = H5Aget_type(cv_attr_id)) < 0) {
132  string msg = "cannot get the attribute datatype for the attribute ";
133  msg += cv_attr_name;
134  H5Aclose(cv_attr_id);
135  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
136  //H5Fclose(fileid);
137  throw InternalErr(__FILE__, __LINE__, msg);
138  }
139 
140  hid_t attr_space = -1;
141  if ((attr_space = H5Aget_space(cv_attr_id)) < 0) {
142  string msg = "cannot get the hdf5 dataspace id for the attribute ";
143  msg += cv_attr_name;
144  H5Tclose(attr_type);
145  H5Aclose(cv_attr_id);
146  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
147  //H5Fclose(fileid);
148  throw InternalErr(__FILE__, __LINE__, msg);
149  }
150 
151  int attr_num_elm = H5Sget_simple_extent_npoints(attr_space);
152  if (0 == attr_num_elm ) {
153  string msg = "cannot get the number for the attribute ";
154  msg += cv_attr_name;
155  H5Tclose(attr_type);
156  H5Aclose(cv_attr_id);
157  H5Sclose(attr_space);
158  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
159  //H5Fclose(fileid);
160  throw InternalErr(__FILE__, __LINE__, msg);
161  }
162 
163  if (attr_num_elm != (total_num_elm -1)) {
164  string msg = "cannot get the number for the attribute ";
165  msg += cv_attr_name;
166  H5Tclose(attr_type);
167  H5Aclose(cv_attr_id);
168  H5Sclose(attr_space);
169  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
170  //H5Fclose(fileid);
171  throw InternalErr(__FILE__, __LINE__, msg);
172  }
173 
174  if (dtype != H5FLOAT32 || dtype != HDF5CFUtil::H5type_to_H5DAPtype(attr_type)) {
175  string msg = "cannot get the number for the attribute ";
176  msg += cv_attr_name;
177  H5Tclose(attr_type);
178  H5Aclose(cv_attr_id);
179  H5Sclose(attr_space);
180  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
181  //H5Fclose(fileid);
182  throw InternalErr(__FILE__, __LINE__, msg);
183  }
184 
185  hid_t attr_mem_type = -1;
186  if ((attr_mem_type = H5Tget_native_type(attr_type,H5T_DIR_ASCEND)) < 0) {
187  string msg = "cannot get the attribute datatype for the attribute ";
188  msg += cv_attr_name;
189  H5Tclose(attr_type);
190  H5Aclose(cv_attr_id);
191  H5Sclose(attr_space);
192  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
193  //H5Fclose(fileid);
194  throw InternalErr(__FILE__, __LINE__, msg);
195  }
196 
197  if (nelms <= 0 || (total_num_elm -1) <=0 ||total_num_elm < 0) {
198  H5Tclose(attr_mem_type);
199  H5Tclose(attr_type);
200  H5Aclose(cv_attr_id);
201  H5Sclose(attr_space);
202  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
203  //H5Fclose(fileid);
204  throw InternalErr(__FILE__,__LINE__,
205  "Number of elements must be greater than 0");
206  }
207 
208  vector<float> val;
209  val.resize(nelms);
210 
211  vector<float>orig_val;
212  orig_val.resize(total_num_elm-1);
213 
214  vector<float>total_val;
215  total_val.resize(total_num_elm);
216 
217 
218  if (H5Aread(cv_attr_id,attr_mem_type, (void*)&orig_val[0])<0){
219  string msg = "cannot retrieve the value of the attribute ";
220  msg += cv_attr_name;
221  H5Tclose(attr_mem_type);
222  H5Tclose(attr_type);
223  H5Aclose(cv_attr_id);
224  H5Sclose(attr_space);
225  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
226  //H5Fclose(fileid);
227  //throw InternalErr(__FILE__, __LINE__, msg);
228  }
229 
230 
231  // Panoply cannot accept the same value for the coordinate variable.
232  // So I have to create a unique value for the added value.
233  // Since the first data value is 1211.53 hpa, which is below the main sea level
234  // already(1013.25 hpa), so I will just use more weight(0.9) for the first data
235  // value and less weight(0.1) for the second data value to calculate.
236  // As far as I know, no real data at the added level(fill value -999.0 for data value),
237  // it will not affect any visualization results.
238  // The position is position of added_value, position of the first_value, position of the second_value.
239  // So the equal weight equation is first_value = 0.5*(added_value+second_value);
240  // Add the weight, first_value = 0.95*added_value + 0.05*second_value;
241  // The approximate formula for the added_value is
242  // add_value = first_value*1.1 - 0.1*second_value;
243  // KY 2012-2-20
244 
245  total_val[0] = 1.1*orig_val[0] - 0.1*orig_val[1];
246  for (int i = 1; i < total_num_elm; i++)
247  total_val[i] = orig_val[i-1];
248 
249 
250  // Note: offset and step in this case will never be NULL since the total number of elements will be
251  // greater than 1. This is enforced in line 180. KY 2014-02-27
252  for (int i = 0; i <nelms; i++)
253  val[i] = total_val[offset[0]+i*step[0]];
254 
255  set_value((dods_float32*)&val[0], nelms);
256  H5Tclose(attr_type);
257  H5Tclose(attr_mem_type);
258  H5Aclose(cv_attr_id);
259  H5Sclose(attr_space);
260  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
261  //H5Fclose(fileid);
262 
263  return true;
264 }
265 
static void close_fileid(hid_t, bool)
Definition: HDF5CFUtil.cc:395
This class specifies the retrieval of special coordinate variable values for HDF-EOS5 products...
HDFEOS5CFSpecialCVArray(int rank, const string &filename, const hid_t fileid, H5DataType dtype, int num_elm, const string &varfullpath, const string &n="", BaseType *v=0)
static bool check_beskeys(const string key)
Definition: h5cfdaputil.cc:39
int format_constraint(int *cor, int *step, int *edg)
static std::string obtain_string_after_lastslash(const std::string s)
Definition: HDF5CFUtil.cc:115
virtual BaseType * ptr_duplicate()
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
static H5DataType H5type_to_H5DAPtype(hid_t h5_type_id)
Map HDF5 Datatype to the intermediate H5DAPtype for the future use.
Definition: HDF5CFUtil.cc:41