OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDFSPArray_VDField.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 Vdata fields from NASA HDF4 data products.
4 // Each Vdata will be decomposed into individual Vdata fields.
5 // Each field will be mapped to A DAP variable.
6 
7 // Authors: MuQun Yang <myang6@hdfgroup.org>
8 // Copyright (c) 2010-2012 The HDF Group
10 
11 #include "HDFSPArray_VDField.h"
12 #include <iostream>
13 #include <sstream>
14 #include <cassert>
15 #include <debug.h>
16 #include "hdf.h"
17 #include "mfhdf.h"
18 #include "InternalErr.h"
19 #include <BESDebug.h>
20 #include "HDFCFUtil.h"
21 
22 using namespace std;
23 #define SIGNED_BYTE_TO_INT32 1
24 
25 
26 bool
28 {
29 
30  BESDEBUG("h4","Coming to HDFSPArray_VDField read "<<endl);
31 
32  string check_pass_fileid_key_str="H4.EnablePassFileID";
33  bool check_pass_fileid_key = false;
34  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
35 
36  // Declaration of offset,count and step
37  vector<int>offset;
38  offset.resize(rank);
39  vector<int>count;
40  count.resize(rank);
41  vector<int>step;
42  step.resize(rank);
43 
44  // Obtain offset,step and count from the client expression constraint
45  int nelms = format_constraint(&offset[0],&step[0],&count[0]);
46 
47  int32 file_id = -1;
48 
49  if(true == check_pass_fileid_key)
50  file_id = fileid;
51 
52  else {
53  // Open the file
54  file_id = Hopen (filename.c_str (), DFACC_READ, 0);
55  if (file_id < 0) {
56  ostringstream eherr;
57  eherr << "File " << filename.c_str () << " cannot be open.";
58  throw InternalErr (__FILE__, __LINE__, eherr.str ());
59  }
60  }
61 
62  // Start the Vdata interface
63  int32 vdata_id = 0;
64  if (Vstart (file_id) < 0) {
65  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
66  ostringstream eherr;
67  eherr << "This file cannot be open.";
68  throw InternalErr (__FILE__, __LINE__, eherr.str ());
69  }
70 
71  // Attach the vdata
72  vdata_id = VSattach (file_id, vdref, "r");
73  if (vdata_id == -1) {
74  Vend (file_id);
75  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
76  ostringstream eherr;
77  eherr << "Vdata cannot be attached.";
78  throw InternalErr (__FILE__, __LINE__, eherr.str ());
79  }
80 
81  try {
82  int32 r = -1;
83 
84  // Seek the position of the starting point
85  if (VSseek (vdata_id, (int32) offset[0]) == -1) {
86  ostringstream eherr;
87  eherr << "VSseek failed at " << offset[0];
88  throw InternalErr (__FILE__, __LINE__, eherr.str ());
89  }
90 
91  // Prepare the vdata field
92  if (VSsetfields (vdata_id, fdname.c_str ()) == -1) {
93  ostringstream eherr;
94  eherr << "VSsetfields failed with the name " << fdname;
95  throw InternalErr (__FILE__, __LINE__, eherr.str ());
96  }
97 
98  int32 vdfelms = fdorder * count[0] * step[0];
99 
100  // Loop through each data type
101  switch (dtype) {
102  case DFNT_INT8:
103  {
104  vector<int8> val;
105  val.resize(nelms);
106 
107  vector<int8>orival;
108  orival.resize(vdfelms);
109 
110  // Read the data
111  r = VSread (vdata_id, (uint8 *) &orival[0], 1+(count[0] -1)* step[0],
112  FULL_INTERLACE);
113 
114  if (r == -1) {
115  ostringstream eherr;
116  eherr << "VSread failed.";
117  throw InternalErr (__FILE__, __LINE__, eherr.str ());
118  }
119 
120  // Obtain the subset portion of the data
121  if (fdorder > 1) {
122  for (int i = 0; i < count[0]; i++)
123  for (int j = 0; j < count[1]; j++)
124  val[i * count[1] + j] =
125  orival[i * fdorder * step[0] + offset[1] + j * step[1]];
126  }
127  else {
128  for (int i = 0; i < count[0]; i++)
129  val[i] = orival[i * step[0]];
130  }
131 
132 
133 #ifndef SIGNED_BYTE_TO_INT32
134  set_value ((dods_byte *) &val[0], nelms);
135 #else
136  vector<int32>newval;
137  newval.resize(nelms);
138 
139  for (int counter = 0; counter < nelms; counter++)
140  newval[counter] = (int32) (val[counter]);
141 
142  set_value ((dods_int32 *) &newval[0], nelms);
143 
144 #endif
145  }
146 
147  break;
148  case DFNT_UINT8:
149  case DFNT_UCHAR8:
150  {
151 
152  vector<uint8>val;
153  val.resize(nelms);
154 
155  vector<uint8>orival;
156  orival.resize(vdfelms);
157 
158  r = VSread (vdata_id, &orival[0], 1+(count[0] -1)* step[0], FULL_INTERLACE);
159  if (r == -1) {
160  ostringstream eherr;
161  eherr << "VSread failed.";
162  throw InternalErr (__FILE__, __LINE__, eherr.str ());
163  }
164 
165  if (fdorder > 1) {
166  for (int i = 0; i < count[0]; i++)
167  for (int j = 0; j < count[1]; j++)
168  val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
169  }
170  else {
171  for (int i = 0; i < count[0]; i++)
172  val[i] = orival[i * step[0]];
173  }
174 
175  set_value ((dods_byte *) &val[0], nelms);
176  }
177 
178  break;
179 
180  case DFNT_INT16:
181  {
182  vector<int16>val;
183  val.resize(nelms);
184  vector<int16>orival;
185  orival.resize(vdfelms);
186 
187  r = VSread (vdata_id, (uint8 *) &orival[0], 1+(count[0] -1)* step[0],
188  FULL_INTERLACE);
189  if (r == -1) {
190  ostringstream eherr;
191  eherr << "VSread failed.";
192  throw InternalErr (__FILE__, __LINE__, eherr.str ());
193  }
194 
195  if (fdorder > 1) {
196  for (int i = 0; i < count[0]; i++)
197  for (int j = 0; j < count[1]; j++)
198  val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
199  }
200  else {
201  for (int i = 0; i < count[0]; i++)
202  val[i] = orival[i * step[0]];
203  }
204 
205  set_value ((dods_int16 *) &val[0], nelms);
206  }
207  break;
208 
209  case DFNT_UINT16:
210 
211  {
212  vector<uint16>val;
213  val.resize(nelms);
214 
215  vector<uint16>orival;
216  orival.resize(vdfelms);
217 
218  r = VSread (vdata_id, (uint8 *) &orival[0], 1+(count[0] -1)* step[0],
219  FULL_INTERLACE);
220  if (r == -1) {
221  ostringstream eherr;
222  eherr << "VSread failed.";
223  throw InternalErr (__FILE__, __LINE__, eherr.str ());
224  }
225 
226  if (fdorder > 1) {
227  for (int i = 0; i < count[0]; i++)
228  for (int j = 0; j < count[1]; j++)
229  val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
230  }
231  else {
232  for (int i = 0; i < count[0]; i++)
233  val[i] = orival[i * step[0]];
234  }
235 
236  set_value ((dods_uint16 *) &val[0], nelms);
237  }
238  break;
239  case DFNT_INT32:
240  {
241  vector<int32>val;
242  val.resize(nelms);
243  vector<int32>orival;
244  orival.resize(vdfelms);
245 
246  r = VSread (vdata_id, (uint8 *) &orival[0], 1+(count[0] -1)* step[0],
247  FULL_INTERLACE);
248  if (r == -1) {
249  ostringstream eherr;
250  eherr << "VSread failed.";
251  throw InternalErr (__FILE__, __LINE__, eherr.str ());
252  }
253 
254  if (fdorder > 1) {
255  for (int i = 0; i < count[0]; i++)
256  for (int j = 0; j < count[1]; j++)
257  val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
258  }
259  else {
260  for (int i = 0; i < count[0]; i++)
261  val[i] = orival[i * step[0]];
262  }
263 
264  set_value ((dods_int32 *) &val[0], nelms);
265  }
266  break;
267 
268  case DFNT_UINT32:
269  {
270 
271  vector<uint32>val;
272  val.resize(nelms);
273 
274  vector<uint32>orival;
275  orival.resize(vdfelms);
276 
277  r = VSread (vdata_id, (uint8 *) &orival[0], 1+(count[0] -1)* step[0],
278  FULL_INTERLACE);
279  if (r == -1) {
280  ostringstream eherr;
281  eherr << "VSread failed.";
282  throw InternalErr (__FILE__, __LINE__, eherr.str ());
283  }
284 
285  if (fdorder > 1) {
286  for (int i = 0; i < count[0]; i++)
287  for (int j = 0; j < count[1]; j++)
288  val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
289  }
290  else {
291  for (int i = 0; i < count[0]; i++)
292  val[i] = orival[i * step[0]];
293  }
294 
295  set_value ((dods_uint32 *) &val[0], nelms);
296  }
297  break;
298  case DFNT_FLOAT32:
299  {
300  vector<float32>val;
301  val.resize(nelms);
302  vector<float32>orival;
303  orival.resize(vdfelms);
304 
305  r = VSread (vdata_id, (uint8 *) &orival[0], 1+(count[0] -1)* step[0],
306  FULL_INTERLACE);
307  if (r == -1) {
308  ostringstream eherr;
309  eherr << "VSread failed.";
310  throw InternalErr (__FILE__, __LINE__, eherr.str ());
311  }
312 
313  if (fdorder > 1) {
314  for (int i = 0; i < count[0]; i++)
315  for (int j = 0; j < count[1]; j++)
316  val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
317  }
318  else {
319  for (int i = 0; i < count[0]; i++)
320  val[i] = orival[i * step[0]];
321  }
322 
323  set_value ((dods_float32 *) &val[0], nelms);
324  }
325  break;
326  case DFNT_FLOAT64:
327  {
328 
329  vector<float64>val;
330  val.resize(nelms);
331 
332  vector<float64>orival;
333  orival.resize(vdfelms);
334 
335  r = VSread (vdata_id, (uint8 *) &orival[0], 1+(count[0] -1)* step[0],
336  FULL_INTERLACE);
337  if (r == -1) {
338  ostringstream eherr;
339  eherr << "VSread failed.";
340  throw InternalErr (__FILE__, __LINE__, eherr.str ());
341  }
342 
343  if (fdorder > 1) {
344  for (int i = 0; i < count[0]; i++)
345  for (int j = 0; j < count[1]; j++)
346  val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
347  }
348  else {
349  for (int i = 0; i < count[0]; i++)
350  val[i] = orival[i * step[0]];
351  }
352 
353  set_value ((dods_float64 *) &val[0], nelms);
354  }
355  break;
356  default:
357  InternalErr (__FILE__, __LINE__, "unsupported data type.");
358  }
359 
360  if (VSdetach (vdata_id) == -1) {
361  ostringstream eherr;
362  eherr << "VSdetach failed.";
363  throw InternalErr (__FILE__, __LINE__, eherr.str ());
364  }
365 
366  if (Vend (file_id) == -1) {
367  ostringstream eherr;
368 
369  eherr << "VSdetach failed.";
370  throw InternalErr (__FILE__, __LINE__, eherr.str ());
371  }
372  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
373  }
374  catch(...) {
375  VSdetach(vdata_id);
376  Vend(file_id);
377  HDFCFUtil::close_fileid(-1,fileid,-1,-1,check_pass_fileid_key);
378  throw;
379 
380  }
381 
382 #if 0
383  if (Hclose (file_id) == -1) {
384 
385  ostringstream eherr;
386 
387  eherr << "VSdetach failed.";
388  throw InternalErr (__FILE__, __LINE__, eherr.str ());
389  }
390 #endif
391 
392  return true;
393 }
394 
395 // Standard way of DAP handlers to pass the coordinates of the subsetted region to the handlers
396 // Return the number of elements to read.
397 int
398 HDFSPArray_VDField::format_constraint (int *offset, int *step, int *count)
399 {
400  long nels = 1;
401  int id = 0;
402 
403  Dim_iter p = dim_begin ();
404 
405  while (p != dim_end ()) {
406 
407  int start = dimension_start (p, true);
408  int stride = dimension_stride (p, true);
409  int stop = dimension_stop (p, true);
410 
411 
412  // Check for illegical constraint
413  if (stride < 0 || start < 0 || stop < 0 || start > stop) {
414  ostringstream oss;
415 
416  oss << "Array/Grid hyperslab indices are bad: [" << start <<
417  ":" << stride << ":" << stop << "]";
418  throw Error (malformed_expr, oss.str ());
419  }
420 
421  // Check for an empty constraint and use the whole dimension if so.
422  if (start == 0 && stop == 0 && stride == 0) {
423  start = dimension_start (p, false);
424  stride = dimension_stride (p, false);
425  stop = dimension_stop (p, false);
426  }
427 
428  offset[id] = start;
429  step[id] = stride;
430  count[id] = ((stop - start) / stride) + 1; // count of elements
431  nels *= count[id]; // total number of values for variable
432 
433  BESDEBUG ("h4",
434  "=format_constraint():"
435  << "id=" << id << " offset=" << offset[id]
436  << " step=" << step[id]
437  << " count=" << count[id]
438  << endl);
439 
440  id++;
441  p++;
442  }
443 
444  return nels;
445 }
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