OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDFEOS2ArraySwathGeoField.cc
Go to the documentation of this file.
1 // Retrieves the latitude and longitude of the HDF-EOS2 Swath without using dimension maps
3 //
4 // Authors: MuQun Yang <myang6@hdfgroup.org>
5 // Copyright (c) 2010-2012 The HDF Group
7 // For the swath without using dimension maps, for most cases, the retrieving of latitude and
8 // longitude is the same as retrieving other fields. Some MODIS latitude and longitude need
9 // to be arranged specially.
10 
11 #ifdef USE_HDFEOS2_LIB
12 
14 #include <iostream>
15 #include <sstream>
16 #include <cassert>
17 #include <debug.h>
18 #include "InternalErr.h"
19 #include "BESDebug.h"
20 
21 using namespace std;
22 #define SIGNED_BYTE_TO_INT32 1
23 
24 bool
25 HDFEOS2ArraySwathGeoField::read ()
26 {
27 
28  BESDEBUG("h4","Coming to HDFEOS2ArraySwathGeoField read "<<endl);
29 
30  string check_pass_fileid_key_str="H4.EnablePassFileID";
31  bool check_pass_fileid_key = false;
32  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
33 
34  // Declare offset, count and step
35  vector<int>offset;
36  offset.resize(rank);
37  vector<int>count;
38  count.resize(rank);
39  vector<int>step;
40  step.resize(rank);
41 
42  // Obtain offset,step and count from the client expression constraint
43  int nelms = format_constraint (&offset[0], &step[0], &count[0]);
44 
45  // Just declare offset,count and step in the int32 type.
46  vector<int32>offset32;
47  offset32.resize(rank);
48  vector<int32>count32;
49  count32.resize(rank);
50  vector<int32>step32;
51  step32.resize(rank);
52 
53  // Just obtain the offset,count and step in the datatype of int32.
54  for (int i = 0; i < rank; i++) {
55  offset32[i] = (int32) offset[i];
56  count32[i] = (int32) count[i];
57  step32[i] = (int32) step[i];
58  }
59 
60  int32 (*openfunc) (char *, intn);
61  intn (*closefunc) (int32);
62  int32 (*attachfunc) (int32, char *);
63  intn (*detachfunc) (int32);
64  intn (*fieldinfofunc) (int32, char *, int32 *, int32 *, int32 *, char *);
65  intn (*readfieldfunc) (int32, char *, int32 *, int32 *, int32 *, void *);
66 
67  // Define function pointers to handle the swath
68  string datasetname;
69  openfunc = SWopen;
70  closefunc = SWclose;
71  attachfunc = SWattach;
72  detachfunc = SWdetach;
73  fieldinfofunc = SWfieldinfo;
74  readfieldfunc = SWreadfield;
75  datasetname = swathname;
76 
77  // We may eventually combine the following code with other code, so
78  // we don't add many comments from here to the end of the file.
79  // The jira ticket about combining code is HFRHANDLER-166.
80  int32 sfid = -1, swathid = -1;
81 
82  if(false == check_pass_fileid_key) {
83  sfid = openfunc (const_cast < char *>(filename.c_str ()), DFACC_READ);
84  if (sfid < 0) {
85  ostringstream eherr;
86  eherr << "File " << filename.c_str () << " cannot be open.";
87  throw InternalErr (__FILE__, __LINE__, eherr.str ());
88  }
89  }
90  else
91  sfid = swathfd;
92 
93  swathid = attachfunc (sfid, const_cast < char *>(datasetname.c_str ()));
94 
95  if (swathid < 0) {
96  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
97  ostringstream eherr;
98  eherr << "Swath " << datasetname.c_str () << " cannot be attached.";
99  throw InternalErr (__FILE__, __LINE__, eherr.str ());
100  }
101 
102 
103  int32 tmp_rank, tmp_dims[rank];
104  char tmp_dimlist[1024];
105  int32 type;
106  intn r;
107  r = fieldinfofunc (swathid, const_cast < char *>(fieldname.c_str ()),
108  &tmp_rank, tmp_dims, &type, tmp_dimlist);
109  if (r != 0) {
110  detachfunc (swathid);
111  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
112  ostringstream eherr;
113  eherr << "Field " << fieldname.c_str () << " information cannot be obtained.";
114  throw InternalErr (__FILE__, __LINE__, eherr.str ());
115  }
116 
117 
118  switch (type) {
119  case DFNT_INT8:
120  {
121  vector<int8>val;
122  val.resize(nelms);
123  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
124  if (r != 0) {
125  detachfunc (swathid);
126  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
127  ostringstream eherr;
128  eherr << "field " << fieldname.c_str () << "cannot be read.";
129  throw InternalErr (__FILE__, __LINE__, eherr.str ());
130 
131  }
132 
133 
134 #ifndef SIGNED_BYTE_TO_INT32
135  set_value ((dods_byte *) &val[0], nelms);
136 #else
137  vector<int32>newval;
138  newval.resize(nelms);
139 
140  for (int counter = 0; counter < nelms; counter++)
141  newval[counter] = (int32) (val[counter]);
142  set_value ((dods_int32 *) &newval[0], nelms);
143 #endif
144  }
145  break;
146  case DFNT_UINT8:
147  case DFNT_UCHAR8:
148  {
149  vector<uint8>val;
150  val.resize(nelms);
151  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
152  if (r != 0) {
153  detachfunc (swathid);
154  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
155  ostringstream eherr;
156  eherr << "field " << fieldname.c_str () << "cannot be read.";
157  throw InternalErr (__FILE__, __LINE__, eherr.str ());
158  }
159 
160  set_value ((dods_byte *) &val[0], nelms);
161  }
162  break;
163 
164  case DFNT_INT16:
165  {
166  vector<int16>val;
167  val.resize(nelms);
168  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
169  if (r != 0) {
170  detachfunc (swathid);
171  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
172  ostringstream eherr;
173  eherr << "field " << fieldname.c_str () << "cannot be read.";
174  throw InternalErr (__FILE__, __LINE__, eherr.str ());
175  }
176  // We found a special MODIS file that used int16 to store lat/lon. The scale-factor is 0.01.
177  // We cannot retrieve attributes from EOS. To make this work, we have to manually check the values of lat/lon;
178  // If lat/lon value is in thousands, we will hard code by applying the scale factor to calculate the latitude and longitude.
179  // We will see and may find a good solution in the future. KY 2010-7-12
180  bool needadjust = false;
181 
182  if ((val[0] < -1000) || (val[0] > 1000))
183  needadjust = true;
184  if (!needadjust)
185  if ((val[nelms / 2] < -1000)
186  || (val[nelms / 2] > 1000))
187  needadjust = true;
188  if (!needadjust)
189  if ((val[nelms - 1] < -1000)
190  || (val[nelms - 1] > 1000))
191  needadjust = true;
192  if (true == needadjust) {
193  vector<float32>newval;
194  newval.resize(nelms);
195  float scale_factor = 0.01;
196 
197  for (int i = 0; i < nelms; i++)
198  newval[i] = scale_factor * (float32) val[i];
199  set_value ((dods_float32 *) &newval[0], nelms);
200  }
201 
202  else {
203  set_value ((dods_int16 *) &val[0], nelms);
204  }
205  }
206  break;
207 
208  case DFNT_UINT16:
209  {
210  vector<uint16>val;
211  val.resize(nelms);
212  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
213  if (r != 0) {
214  detachfunc (swathid);
215  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
216  ostringstream eherr;
217  eherr << "field " << fieldname.c_str () << "cannot be read.";
218  throw InternalErr (__FILE__, __LINE__, eherr.str ());
219  }
220 
221  set_value ((dods_uint16 *) &val[0], nelms);
222  }
223  break;
224 
225  case DFNT_INT32:
226  {
227  vector<int32>val;
228  val.resize(nelms);
229  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
230  if (r != 0) {
231  detachfunc (swathid);
232  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
233  ostringstream eherr;
234  eherr << "field " << fieldname.c_str () << "cannot be read.";
235  throw InternalErr (__FILE__, __LINE__, eherr.str ());
236  }
237 
238  set_value ((dods_int32 *) &val[0], nelms);
239  }
240  break;
241 
242  case DFNT_UINT32:
243  {
244  vector<uint32>val;
245  val.resize(nelms);
246  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
247  if (r != 0) {
248  detachfunc (swathid);
249  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
250  ostringstream eherr;
251  eherr << "field " << fieldname.c_str () << "cannot be read.";
252  throw InternalErr (__FILE__, __LINE__, eherr.str ());
253  }
254 
255  set_value ((dods_uint32 *) &val[0], nelms);
256  }
257  break;
258  case DFNT_FLOAT32:
259  {
260 
261  vector<float32>val;
262  val.resize(nelms);
263  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
264  if (r != 0) {
265  detachfunc (swathid);
266  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
267  ostringstream eherr;
268  eherr << "field " << fieldname.c_str () << "cannot be read.";
269  throw InternalErr (__FILE__, __LINE__, eherr.str ());
270  }
271  set_value ((dods_float32 *) &val[0], nelms);
272  }
273  break;
274  case DFNT_FLOAT64:
275  {
276  vector<float64>val;
277  val.resize(nelms);
278  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
279  if (r != 0) {
280  detachfunc (swathid);
281  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
282  ostringstream eherr;
283  eherr << "field " << fieldname.c_str () << "cannot be read.";
284  throw InternalErr (__FILE__, __LINE__, eherr.str ());
285  }
286 
287  set_value ((dods_float64 *) &val[0], nelms);
288  }
289  break;
290  default:
291  detachfunc (swathid);
292  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
293  InternalErr (__FILE__, __LINE__, "unsupported data type.");
294  }
295 
296  r = detachfunc (swathid);
297  if (r != 0) {
298  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
299  ostringstream eherr;
300  eherr << "Swath " << datasetname.c_str () << " cannot be detached.";
301  throw InternalErr (__FILE__, __LINE__, eherr.str ());
302  }
303 
304  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
305 
306 #if 0
307  r = closefunc (sfid);
308  if (r != 0) {
309  ostringstream eherr;
310  eherr << "Swath " << filename.c_str () << " cannot be closed.";
311  throw InternalErr (__FILE__, __LINE__, eherr.str ());
312  }
313 #endif
314 
315  return false;
316 }
317 
318 // Standard way of DAP handlers to pass the coordinates of the subsetted region to the handlers
319 // Return the number of elements to read.
320 int
321 HDFEOS2ArraySwathGeoField::format_constraint (int *offset, int *step, int *count)
322 {
323  long nels = 1;
324  int id = 0;
325 
326  Dim_iter p = dim_begin ();
327 
328  while (p != dim_end ()) {
329 
330  int start = dimension_start (p, true);
331  int stride = dimension_stride (p, true);
332  int stop = dimension_stop (p, true);
333 
334 
335  // Check for illegical constraint
336  if (stride < 0 || start < 0 || stop < 0 || start > stop) {
337  ostringstream oss;
338 
339  oss << "Array/Grid hyperslab indices are bad: [" << start <<
340  ":" << stride << ":" << stop << "]";
341  throw Error (malformed_expr, oss.str ());
342  }
343 
344  // Check for an empty constraint and use the whole dimension if so.
345  if (start == 0 && stop == 0 && stride == 0) {
346  start = dimension_start (p, false);
347  stride = dimension_stride (p, false);
348  stop = dimension_stop (p, false);
349  }
350 
351  offset[id] = start;
352  step[id] = stride;
353  count[id] = ((stop - start) / stride) + 1; // count of elements
354  nels *= count[id]; // total number of values for variable
355 
356  BESDEBUG ("h4",
357  "=format_constraint():"
358  << "id=" << id << " offset=" << offset[id]
359  << " step=" << step[id]
360  << " count=" << count[id]
361  << endl);
362  id++;
363  p++;
364  }
365 
366  return nels;
367 }
368 #endif
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