OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDFSPArray_RealField.cc
Go to the documentation of this file.
1 // This file is part of the hdf4 data handler for the OPeNDAP data server.
3 // It retrieves the real SDS field values for special HDF4 data products.
4 // Authors: MuQun Yang <myang6@hdfgroup.org> Eunsoo Seo
5 // Copyright (c) 2010-2012 The HDF Group
7 #include "HDFSPArray_RealField.h"
8 #include <iostream>
9 #include <sstream>
10 #include <cassert>
11 #include <debug.h>
12 #include "hdf.h"
13 #include "mfhdf.h"
14 #include "InternalErr.h"
15 #include <BESDebug.h>
16 #include "BESInternalError.h"
17 #include "HDFCFUtil.h"
18 
19 using namespace std;
20 #define SIGNED_BYTE_TO_INT32 1
21 
22 
23 bool
25 {
26 
27  BESDEBUG("h4","Coming to HDFSPArray_RealField read "<<endl);
28 
29  string check_pass_fileid_key_str="H4.EnablePassFileID";
30  bool check_pass_fileid_key = false;
31  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
32 
33  // Declare offset, count and step
34  vector<int>offset;
35  offset.resize(rank);
36  vector<int>count;
37  count.resize(rank);
38  vector<int>step;
39  step.resize(rank);
40 
41  // Obtain offset,step and count from the client expression constraint
42  int nelms = format_constraint (&offset[0], &step[0], &count[0]);
43 
44  // Just declare offset,count and step in the int32 type.
45  vector<int32>offset32;
46  offset32.resize(rank);
47  vector<int32>count32;
48  count32.resize(rank);
49  vector<int32>step32;
50  step32.resize(rank);
51 
52  // Just obtain the offset,count and step in the datatype of int32.
53  for (int i = 0; i < rank; i++) {
54  offset32[i] = (int32) offset[i];
55  count32[i] = (int32) count[i];
56  step32[i] = (int32) step[i];
57  }
58 
59 
60  int32 sdid = -1;
61 
62  // Obtain SD ID.
63  if(false == check_pass_fileid_key) {
64  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
65  if (sdid < 0) {
66  ostringstream eherr;
67  eherr << "File " << filename.c_str () << " cannot be open.";
68  throw InternalErr (__FILE__, __LINE__, eherr.str ());
69  }
70  }
71  else
72  sdid = sdfd;
73 
74  // Initialize SDS ID.
75  int32 sdsid = 0;
76 
77 
78  // Obtain the SDS index based on the input sds reference number.
79  int32 sdsindex = SDreftoindex (sdid, (int32) fieldref);
80  if (sdsindex == -1) {
81  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
82  ostringstream eherr;
83  eherr << "SDS index " << sdsindex << " is not right.";
84  throw InternalErr (__FILE__, __LINE__, eherr.str ());
85  }
86 
87  // Obtain this SDS ID.
88  sdsid = SDselect (sdid, sdsindex);
89  if (sdsid < 0) {
90  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
91  ostringstream eherr;
92  eherr << "SDselect failed.";
93  throw InternalErr (__FILE__, __LINE__, eherr.str ());
94  }
95 
96  // Initialize the temp. returned value.
97  int32 r = 0;
98 
99  // Loop through all the possible SDS datatype and then read the data.
100  switch (dtype) {
101 
102  case DFNT_INT8:
103  {
104  vector<int8>val;
105  val.resize(nelms);
106  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &val[0]);
107  if (r != 0) {
108  SDendaccess (sdsid);
109  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
110  ostringstream eherr;
111  eherr << "SDreaddata failed.";
112  throw InternalErr (__FILE__, __LINE__, eherr.str ());
113  }
114 
115 #ifndef SIGNED_BYTE_TO_INT32
116  set_value ((dods_byte *) &val[0], nelms);
117 #else
118  vector<int32>newval;
119  newval.resize(nelms);
120  for (int counter = 0; counter < nelms; counter++)
121  newval[counter] = (int32) (val[counter]);
122 
123  set_value ((dods_int32 *) &newval[0], nelms);
124 #endif
125  }
126 
127  break;
128  case DFNT_UINT8:
129  case DFNT_UCHAR8:
130  {
131  vector<uint8>val;
132  val.resize(nelms);
133  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &val[0]);
134  if (r != 0) {
135  SDendaccess (sdsid);
136  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
137  ostringstream eherr;
138 
139  eherr << "SDreaddata failed";
140  throw InternalErr (__FILE__, __LINE__, eherr.str ());
141  }
142 
143  set_value ((dods_byte *) &val[0], nelms);
144  }
145  break;
146 
147  case DFNT_INT16:
148  {
149  vector<int16>val;
150  val.resize(nelms);
151  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &val[0]);
152  if (r != 0) {
153  SDendaccess (sdsid);
154  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
155  ostringstream eherr;
156 
157  eherr << "SDreaddata failed";
158  throw InternalErr (__FILE__, __LINE__, eherr.str ());
159  }
160 
161  // WILL HANDLE this later if necessary. KY 2010-8-17
162  //if(sptype == TRMML2_V6)
163  // Find scale_factor, add_offset attributes
164  // create a new val to float32, remember to change int16 at HDFSP.cc to float32
165  // if(sptype == OBPGL3) 16-bit unsigned integer
166  // Find slope and intercept,
167  // CZCS: also find base. data = base**((slope*l3m_data)+intercept)
168  // Others : slope*data+intercept
169  // OBPGL2: 16-bit signed integer, (8-bit signed integer or 32-bit signed integer)
170  // If slope = 1 and intercept = 0 no need to do conversion
171 
172  set_value ((dods_int16 *) &val[0], nelms);
173  }
174  break;
175 
176  case DFNT_UINT16:
177  {
178  vector<uint16>val;
179  val.resize(nelms);
180  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &val[0]);
181  if (r != 0) {
182  SDendaccess (sdsid);
183  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
184  ostringstream eherr;
185  eherr << "SDreaddata failed";
186  throw InternalErr (__FILE__, __LINE__, eherr.str ());
187  }
188 
189  set_value ((dods_uint16 *) &val[0], nelms);
190  }
191  break;
192 
193  case DFNT_INT32:
194  {
195  vector<int32>val;
196  val.resize(nelms);
197  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &val[0]);
198  if (r != 0) {
199  SDendaccess (sdsid);
200  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
201  ostringstream eherr;
202 
203  eherr << "SDreaddata failed";
204  throw InternalErr (__FILE__, __LINE__, eherr.str ());
205  }
206 
207  set_value ((dods_int32 *) &val[0], nelms);
208  }
209  break;
210  case DFNT_UINT32:
211  {
212  vector<uint32>val;
213  val.resize(nelms);
214  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &val[0]);
215  if (r != 0) {
216  SDendaccess (sdsid);
217  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
218  ostringstream eherr;
219 
220  eherr << "SDreaddata failed";
221  throw InternalErr (__FILE__, __LINE__, eherr.str ());
222  }
223  set_value ((dods_uint32 *) &val[0], nelms);
224  }
225  break;
226  case DFNT_FLOAT32:
227  {
228  vector<float32>val;
229  val.resize(nelms);
230  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &val[0]);
231  if (r != 0) {
232  SDendaccess (sdsid);
233  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
234  ostringstream eherr;
235 
236  eherr << "SDreaddata failed";
237  throw InternalErr (__FILE__, __LINE__, eherr.str ());
238  }
239 
240  set_value ((dods_float32 *) &val[0], nelms);
241  }
242  break;
243  case DFNT_FLOAT64:
244  {
245  vector<float64>val;
246  val.resize(nelms);
247  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &val[0]);
248  if (r != 0) {
249  SDendaccess (sdsid);
250  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
251  ostringstream eherr;
252 
253  eherr << "SDreaddata failed";
254  throw InternalErr (__FILE__, __LINE__, eherr.str ());
255  }
256 
257  set_value ((dods_float64 *) &val[0], nelms);
258  }
259  break;
260  default:
261  SDendaccess (sdsid);
262  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
263  InternalErr (__FILE__, __LINE__, "unsupported data type.");
264  }
265 
266  // Close the SDS interface
267  r = SDendaccess (sdsid);
268  if (r != 0) {
269  ostringstream eherr;
270  eherr << "SDendaccess failed.";
271  throw InternalErr (__FILE__, __LINE__, eherr.str ());
272  }
273  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
274 
275 #if 0
276  // Close the SD interface
277  r = SDend (sdid);
278  if (r != 0) {
279  ostringstream eherr;
280  eherr << "SDend failed.";
281  throw InternalErr (__FILE__, __LINE__, eherr.str ());
282  }
283 #endif
284 
285  return true;
286 }
287 
288 // Standard way to pass the coordinates of the subsetted region from the client to the handlers
289 // Returns the number of elements
290 int
291 HDFSPArray_RealField::format_constraint (int *offset, int *step, int *count)
292 {
293  long nels = 1;
294  int id = 0;
295 
296  Dim_iter p = dim_begin ();
297 
298  while (p != dim_end ()) {
299 
300  int start = dimension_start (p, true);
301  int stride = dimension_stride (p, true);
302  int stop = dimension_stop (p, true);
303 
304 
305  // Check for illegical constraint
306  if (stride < 0 || start < 0 || stop < 0 || start > stop) {
307  ostringstream oss;
308 
309  oss << "Array/Grid hyperslab indices are bad: [" << start <<
310  ":" << stride << ":" << stop << "]";
311  throw Error (malformed_expr, oss.str ());
312  }
313 
314  // Check for an empty constraint and use the whole dimension if so.
315  if (start == 0 && stop == 0 && stride == 0) {
316  start = dimension_start (p, false);
317  stride = dimension_stride (p, false);
318  stop = dimension_stop (p, false);
319  }
320 
321  offset[id] = start;
322  step[id] = stride;
323  count[id] = ((stop - start) / stride) + 1; // count of elements
324  nels *= count[id]; // total number of values for variable
325 
326  BESDEBUG ("h4",
327  "=format_constraint():"
328  << "id=" << id << " offset=" << offset[id]
329  << " step=" << step[id]
330  << " count=" << count[id]
331  << endl);
332  id++;
333  p++;
334  }
335 
336  return nels;
337 }
int format_constraint(int *cor, int *step, int *edg)
STL namespace.
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Close HDF4 and HDF-EOS2 file IDs. For performance reasons, we want to keep HDF-EOS2/HDF4 IDs open for...
Definition: HDFCFUtil.cc:2881
static bool check_beskeys(const std::string &key)
Check the BES key. This function will check a BES key specified at the file h4.conf.in. If the key's value is either true or yes. The handler claims to find a key and will do some operations. Otherwise, will do different operations. For example, One may find a line H4.EnableCF=true at h4.conf.in. That means, the HDF4 handler will handle the HDF4 files by following CF conventions.
Definition: HDFCFUtil.cc:17
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64