OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDFSPArrayGeoField.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 latitude and longitude fields for some special HDF4 data products.
4 // The products include TRMML2_V6,TRMML3B_V6,CER_AVG,CER_ES4,CER_CDAY,CER_CGEO,CER_SRB,CER_SYN,CER_ZAVG,OBPGL2,OBPGL3
5 // To know more information about these products,check HDFSP.h.
6 // Each product stores lat/lon in different way, so we have to retrieve them differently.
7 // Authors: MuQun Yang <myang6@hdfgroup.org>
8 // Copyright (c) 2010-2012 The HDF Group
10 
11 #include "HDFSPArrayGeoField.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 // The following macros provide names of latitude and longitude for specific HDF4 products.
26 #define NUM_PIXEL_NAME "Pixels per Scan Line"
27 #define NUM_POINTS_LINE_NAME "Number of Pixel Control Points"
28 #define NUM_SCAN_LINE_NAME "Number of Scan Lines"
29 #define NUM_LAT_NAME "Number of Lines"
30 #define NUM_LON_NAME "Number of Columns"
31 #define LAT_STEP_NAME "Latitude Step"
32 #define LON_STEP_NAME "Longitude Step"
33 #define SWP_LAT_NAME "SW Point Latitude"
34 #define SWP_LON_NAME "SW Point Longitude"
35 
36 
38 {
39 
40  BESDEBUG("h4","Coming to HDFSPArrayGeoField read "<<endl);
41 
42  // Declare offset, count and step
43  vector<int> offset;
44  offset.resize(rank);
45  vector<int> count;
46  count.resize(rank);
47  vector<int> step;
48  step.resize(rank);
49 
50  // Obtain offset, step and count from the client expression constraint
51  int nelms = -1;
52  nelms = format_constraint (&offset[0], &step[0], &count[0]);
53 
54  // Just declare offset,count and step in the int32 type.
55  vector<int32>offset32;
56  offset32.resize(rank);
57  vector<int32>count32;
58  count32.resize(rank);
59  vector<int32>step32;
60  step32.resize(rank);
61 
62 
63  // Just obtain the offset,count and step in the int32 type.
64  for (int i = 0; i < rank; i++) {
65  offset32[i] = (int32) offset[i];
66  count32[i] = (int32) count[i];
67  step32[i] = (int32) step[i];
68  }
69 
70  // Loop through the functions to obtain lat/lon for the specific HDF4 products the handler
71  // supports.
72  switch (sptype) {
73 
74  // TRMM swath
75  case TRMML2_V6:
76  {
77  readtrmml2_v6 (&offset32[0], &count32[0], &step32[0], nelms);
78  break;
79  }
80 
81  // TRMM grid
82  case TRMML3A_V6:
83  {
84  readtrmml3a_v6 (&offset32[0], &count32[0], &step32[0], nelms);
85  break;
86  }
87 
88  case TRMML3B_V6:
89  {
90  readtrmml3b_v6 (&offset32[0], &count32[0], &step32[0], nelms);
91  break;
92  }
93 
94  case TRMML3C_V6:
95  {
96  readtrmml3c_v6 (&offset32[0], &count32[0], &step32[0], nelms);
97  break;
98  }
99 
100 
101  // TRMM V7 grid
102  case TRMML3S_V7:
103  case TRMML3M_V7:
104  {
105  readtrmml3_v7 (&offset32[0], &count32[0], &step32[0], nelms);
106  break;
107  }
108  // CERES CER_AVG_Aqua-FM3-MODIS,CER_AVG_Terra-FM1-MODIS products
109  case CER_AVG:
110  {
111  readceravgsyn (&offset32[0], &count32[0], &step32[0], nelms);
112  break;
113  }
114 
115  // CERES CER_ES4_??? products
116  case CER_ES4:
117  {
118  readceres4ig (&offset32[0], &count32[0], &step32[0], nelms);
119  break;
120  }
121 
122  // CERES CER_ISCCP-D2like-Day product
123  case CER_CDAY:
124  {
125  readcersavgid2 (&offset[0], &count[0], &step[0], nelms);
126  break;
127  }
128 
129  // CERES CER_ISCCP-D2like-GEO product
130  case CER_CGEO:
131  {
132  readceres4ig (&offset32[0], &count32[0], &step32[0], nelms);
133  break;
134  }
135 
136  // CERES CER_SRBAVG3_Aqua product
137  case CER_SRB:
138  {
139  // When longitude is fixed
140  if (rank == 1) {
141  readcersavgid1 (&offset[0], &count[0], &step[0], nelms);
142  }
143  // When longitude is not fixed
144  else if (rank == 2) {
145  readcersavgid2 (&offset[0], &count[0], &step[0], nelms);
146  }
147  break;
148  }
149 
150  // CERES SYN Aqua products
151  case CER_SYN:
152  {
153  readceravgsyn (&offset32[0], &count32[0], &step32[0], nelms);
154  break;
155  }
156 
157  // CERES Zonal Average products
158  case CER_ZAVG:
159  {
160  readcerzavg (&offset32[0], &count32[0], &step32[0], nelms);
161  break;
162  }
163 
164  // OBPG level 2 products
165  case OBPGL2:
166  {
167  readobpgl2 (&offset32[0], &count32[0], &step32[0], nelms);
168  break;
169  }
170 
171  // OBPG level 3 products
172  case OBPGL3:
173  {
174  readobpgl3 (&offset[0], &count[0], &step[0], nelms);
175  break;
176  }
177 
178  // We don't handle any OtherHDF products
179  case OTHERHDF:
180  {
181  throw
182  InternalErr (__FILE__, __LINE__, "Unsupported HDF files");
183 
184  break;
185  }
186  default:
187  {
188 
189  throw
190  InternalErr (__FILE__, __LINE__, "Unsupported HDF files");
191 
192  break;
193  }
194  }
195 
196  return true;
197 
198 }
199 
200 
201 // Read TRMM level 2 lat/lon. We need to split geolocation field.
202 // geolocation[YDIM][XDIM][0] is latitude
203 // geolocation[YDIM][XDIM][1] is longitude
204 
205 void
206 HDFSPArrayGeoField::readtrmml2_v6 (int32 * offset32, int32 * count32,
207  int32 * step32, int nelms)
208 {
209 
210  string check_pass_fileid_key_str="H4.EnablePassFileID";
211  bool check_pass_fileid_key = false;
212  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
213  int32 sdid = -1;
214 
215  if(false == check_pass_fileid_key) {
216  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
217  if (sdid < 0) {
218  ostringstream eherr;
219  eherr << "File " << filename.c_str () << " cannot be open.";
220  throw InternalErr (__FILE__, __LINE__, eherr.str ());
221  }
222  }
223  else
224  sdid = sdfd;
225 
226  int32 sdsid = 0;
227 
228  vector<int32>geooffset32;
229  geooffset32.resize(rank+1);
230 
231  vector<int32>geocount32;
232  geocount32.resize(rank+1);
233 
234  vector<int32>geostep32;
235  geostep32.resize(rank+1);
236 
237  for (int i = 0; i < rank; i++) {
238  geooffset32[i] = offset32[i];
239  geocount32[i] = count32[i];
240  geostep32[i] = step32[i];
241  }
242 
243  if (fieldtype == 1) {
244  geooffset32[rank] = 0;
245  geocount32[rank] = 1;
246  geostep32[rank] = 1;
247  }
248 
249  if (fieldtype == 2) {
250  geooffset32[rank] = 1;
251  geocount32[rank] = 1;
252  geostep32[rank] = 1;
253  }
254 
255  int32 sdsindex = SDreftoindex (sdid, (int32) fieldref);
256 
257  if (sdsindex == -1) {
258  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
259  ostringstream eherr;
260  eherr << "SDS index " << sdsindex << " is not right.";
261  throw InternalErr (__FILE__, __LINE__, eherr.str ());
262  }
263 
264  sdsid = SDselect (sdid, sdsindex);
265  if (sdsid < 0) {
266  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
267  ostringstream eherr;
268  eherr << "SDselect failed.";
269  throw InternalErr (__FILE__, __LINE__, eherr.str ());
270  }
271 
272  int32 r = 0;
273 
274  switch (dtype) {
275 
276  case DFNT_INT8:
277  {
278  vector <int8> val;
279  val.resize(nelms);
280  r = SDreaddata (sdsid, &geooffset32[0], &geostep32[0], &geocount32[0], (void*)(&val[0]));
281  if (r != 0) {
282  SDendaccess (sdsid);
283  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
284  ostringstream eherr;
285  eherr << "SDreaddata failed.";
286  throw InternalErr (__FILE__, __LINE__, eherr.str ());
287  }
288 
289 #ifndef SIGNED_BYTE_TO_INT32
290  set_value ((dods_byte *) &val[0], nelms);
291 #else
292  vector<int32>newval;
293  newval.resize(nelms);
294 
295  for (int counter = 0; counter < nelms; counter++)
296  newval[counter] = (int32) (val[counter]);
297  set_value ((dods_int32 *) &newval[0], nelms);
298 #endif
299  }
300 
301  break;
302  case DFNT_UINT8:
303  case DFNT_UCHAR8:
304  {
305  vector<uint8> val;
306  val.resize(nelms);
307  r = SDreaddata (sdsid, &geooffset32[0], &geostep32[0], &geocount32[0], (void*)(&val[0]));
308  if (r != 0) {
309  SDendaccess (sdsid);
310  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
311  ostringstream eherr;
312  eherr << "SDreaddata failed";
313  throw InternalErr (__FILE__, __LINE__, eherr.str ());
314  }
315 
316  set_value ((dods_byte *) &val[0], nelms);
317  }
318  break;
319 
320  case DFNT_INT16:
321  {
322  vector<int16> val;
323  val.resize(nelms);
324  r = SDreaddata (sdsid, &geooffset32[0], &geostep32[0], &geocount32[0], (void*)(&val[0]));
325  if (r != 0) {
326  SDendaccess (sdsid);
327  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
328  ostringstream eherr;
329  eherr << "SDreaddata failed";
330  throw InternalErr (__FILE__, __LINE__, eherr.str ());
331  }
332 
333  set_value ((dods_int16 *) &val[0], nelms);
334  }
335  break;
336 
337  case DFNT_UINT16:
338  {
339  vector<uint16>val;
340  val.resize(nelms);
341  r = SDreaddata (sdsid, &geooffset32[0], &geostep32[0], &geocount32[0], (void*)(&val[0]));
342  if (r != 0) {
343  SDendaccess (sdsid);
344  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
345  ostringstream eherr;
346  eherr << "SDreaddata failed";
347  throw InternalErr (__FILE__, __LINE__, eherr.str ());
348  }
349 
350  set_value ((dods_uint16 *) &val[0], nelms);
351  }
352  break;
353  case DFNT_INT32:
354  {
355  vector<int32>val;
356  val.resize(nelms);
357  r = SDreaddata (sdsid, &geooffset32[0], &geostep32[0], &geocount32[0], (void*)(&val[0]));
358  if (r != 0) {
359  SDendaccess (sdsid);
360  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
361  ostringstream eherr;
362  eherr << "SDreaddata failed";
363  throw InternalErr (__FILE__, __LINE__, eherr.str ());
364  }
365 
366  set_value ((dods_int32 *) &val[0], nelms);
367  }
368  break;
369  case DFNT_UINT32:
370  {
371  vector<uint32>val;
372  val.resize(nelms);
373  r = SDreaddata (sdsid, &geooffset32[0], &geostep32[0], &geocount32[0], (void*)(&val[0]));
374  if (r != 0) {
375  SDendaccess (sdsid);
376  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
377  ostringstream eherr;
378  eherr << "SDreaddata failed";
379  throw InternalErr (__FILE__, __LINE__, eherr.str ());
380  }
381  set_value ((dods_uint32 *) &val[0], nelms);
382  }
383  break;
384  case DFNT_FLOAT32:
385  {
386  vector<float32>val;
387  val.resize(nelms);
388  r = SDreaddata (sdsid, &geooffset32[0], &geostep32[0], &geocount32[0], (void*)(&val[0]));
389  if (r != 0) {
390  SDendaccess (sdsid);
391  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
392  ostringstream eherr;
393  eherr << "SDreaddata failed";
394  throw InternalErr (__FILE__, __LINE__, eherr.str ());
395  }
396 
397  set_value ((dods_float32 *) &val[0], nelms);
398  }
399  break;
400  case DFNT_FLOAT64:
401  {
402  vector<float64>val;
403  val.resize(nelms);
404  r = SDreaddata (sdsid, &geooffset32[0], &geostep32[0], &geocount32[0], (void*)(&val[0]));
405  if (r != 0) {
406  SDendaccess (sdsid);
407  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
408  ostringstream eherr;
409  eherr << "SDreaddata failed";
410  throw InternalErr (__FILE__, __LINE__, eherr.str ());
411  }
412 
413  set_value ((dods_float64 *) &val[0], nelms);
414  }
415  break;
416  default:
417  SDendaccess (sdsid);
418  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
419  InternalErr (__FILE__, __LINE__, "unsupported data type.");
420  }
421 
422  r = SDendaccess (sdsid);
423  if (r != 0) {
424  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
425  ostringstream eherr;
426  eherr << "SDendaccess failed.";
427  throw InternalErr (__FILE__, __LINE__, eherr.str ());
428  }
429 
430  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
431 
432 }
433 
434 // Read TRMM level 3a version 6 lat/lon.
435 // We follow TRMM document to retrieve the lat and lon.
436 void
437 HDFSPArrayGeoField::readtrmml3a_v6 (int32 * offset32, int32 * count32,
438  int32 * step32, int nelms)
439 {
440 
441  const float slat = 89.5;
442  const float slon = 0.5;
443  vector<float> val;
444  val.resize(nelms);
445 
446  if (fieldtype == 1) {//latitude
447 
448  int icount = 0;
449  float sval = slat - offset32[0];
450 
451  while (icount < (int) (count32[0])) {
452  val[icount] = sval - step32[0] * icount;
453  icount++;
454  }
455  }
456 
457  if (fieldtype == 2) { //longitude
458  int icount = 0;
459  float sval = slon + offset32[0];
460 
461  while (icount < (int) (count32[0])) {
462  val[icount] = sval + step32[0] * icount;
463  icount++;
464  }
465  }
466  set_value ((dods_float32 *) &val[0], nelms);
467 }
468 
469 
470 // TRMM level 3 case. Have to follow http://disc.sci.gsfc.nasa.gov/additional/faq/precipitation_faq.shtml#lat_lon
471 // to calculate lat/lon.
472 void
473 HDFSPArrayGeoField::readtrmml3b_v6 (int32 * offset32, int32 * count32,
474  int32 * step32, int nelms)
475 {
476 
477  const float slat = -49.875;
478  const float slon = -179.875;
479  vector<float> val;
480  val.resize(nelms);
481 
482  if (fieldtype == 1) {//latitude
483 
484  int icount = 0;
485  float sval = slat + 0.25 * (int) (offset32[0]);
486 
487  while (icount < (int) (count32[0])) {
488  val[icount] = sval + 0.25 * (int) (step32[0]) * icount;
489  icount++;
490  }
491  }
492 
493  if (fieldtype == 2) { //longitude
494  int icount = 0;
495  float sval = slon + 0.25 * (int) (offset32[0]);
496 
497  while (icount < (int) (count32[0])) {
498  val[icount] = sval + 0.25 * (int) (step32[0]) * icount;
499  icount++;
500  }
501  }
502  set_value ((dods_float32 *) &val[0], nelms);
503 }
504 
505 // Read TRMM level 3c(CSH) version 6 lat/lon.
506 // We follow TRMM document to retrieve the lat and lon.
507 void
508 HDFSPArrayGeoField::readtrmml3c_v6 (int32 * offset32, int32 * count32,
509  int32 * step32, int nelms)
510 {
511 
512  const float slat = -36.75;
513  const float slon = -179.75;
514  vector<float> val;
515  val.resize(nelms);
516 
517  if (fieldtype == 1) {//latitude
518 
519  int icount = 0;
520  float sval = slat + 0.5 * (int) (offset32[0]);
521 
522  while (icount < (int) (count32[0])) {
523  val[icount] = sval + 0.5 * (int) (step32[0]) * icount;
524  icount++;
525  }
526  }
527 
528  if (fieldtype == 2) { //longitude
529  int icount = 0;
530  float sval = slon + 0.5 * (int) (offset32[0]);
531 
532  while (icount < (int) (count32[0])) {
533  val[icount] = sval + 0.5 * (int) (step32[0]) * icount;
534  icount++;
535  }
536  }
537  set_value ((dods_float32 *) &val[0], nelms);
538 }
539 // Read latlon of TRMM version 7 products.
540 // Lat/lon parameters can be retrieved from attribute GridHeader.
541 void
542 HDFSPArrayGeoField::readtrmml3_v7 (int32 * offset32, int32 * count32,
543  int32 * step32, int nelms)
544 {
545 
546  string check_pass_fileid_key_str="H4.EnablePassFileID";
547  bool check_pass_fileid_key = false;
548  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
549  int32 sdid = -1;
550 
551  if(false == check_pass_fileid_key) {
552  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
553  if (sdid < 0) {
554  ostringstream eherr;
555  eherr << "File " << filename.c_str () << " cannot be open.";
556  throw InternalErr (__FILE__, __LINE__, eherr.str ());
557  }
558  }
559  else
560  sdid = sdfd;
561 
562 
563  string gridinfo_name = "GridHeader";
564  intn status = 0;
565 
566  if(fieldref != -1) {
567 
568  if (fieldref >9) {
569  throw InternalErr (__FILE__,__LINE__,
570  "The maximum number of grids to be supported in the current implementation is 9.");
571  }
572 
573  else {
574  ostringstream fieldref_str;
575  fieldref_str << fieldref;
576  gridinfo_name = gridinfo_name + fieldref_str.str();
577  }
578  }
579 
580  int32 attr_index = 0;
581  attr_index = SDfindattr (sdid, gridinfo_name.c_str());
582  if (attr_index == FAIL) {
583  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
584  string err_mesg = "SDfindattr failed,should find attribute "+gridinfo_name+" .";
585  throw InternalErr (__FILE__, __LINE__, err_mesg);
586  }
587 
588  int32 attr_dtype = 0;
589  int32 n_values = 0;
590 
591  char attr_name[H4_MAX_NC_NAME];
592  status =
593  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
594  if (status == FAIL) {
595  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
596  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
597  }
598 
599  vector<char> attr_value;
600  attr_value.resize(n_values * DFKNTsize(attr_dtype));
601 
602  status = SDreadattr (sdid, attr_index, &attr_value[0]);
603  if (status == FAIL) {
604  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
605  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
606  }
607 
608  float lat_start = 0;;
609  float lon_start = 0.;
610  float lat_res = 0.;
611  float lon_res = 0.;
612 
613  int latsize = 0;
614  int lonsize = 0;
615 
616  HDFCFUtil::parser_trmm_v7_gridheader(attr_value,latsize,lonsize,
617  lat_start,lon_start,lat_res,lon_res,false);
618 //cerr<<"lat_start is "<<lat_start <<endl;
619 //cerr<<"lon_start is "<<lon_start<<endl;
620 //cerr <<"lat_res is "<<lat_res <<endl;
621 //cerr<<"lon_res is "<<lon_res <<endl;
622 
623  if(0 == latsize || 0 == lonsize) {
624  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
625  throw InternalErr (__FILE__, __LINE__, "Either latitude or longitude size is 0. ");
626  }
627 
628 
629  vector<float>val;
630  val.resize(nelms);
631 
632  if(fieldtype == 1) {
633  for (int i = 0; i < nelms; ++i)
634  val[i] = lat_start+offset32[0]*lat_res+lat_res/2 + i*lat_res*step32[0];
635  }
636  else if(fieldtype == 2) {
637  for (int i = 0; i < nelms; ++i)
638  val[i] = lon_start+offset32[0]*lon_res+lon_res/2 + i*lon_res*step32[0];
639  }
640 
641  set_value ((dods_float32 *) &val[0], nelms);
642 
643  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
644 }
645 
646 
647 
648 // OBPG Level 2 lat/lon including CZCS, MODISA, MODIST, OCTS and SewWIFS.
649 // We need to use information retrieved from the attribute to interpoloate
650 // the latitude/longitude. This is similar to the Swath dimension map case.
651 // "Pixels per Scan Line" and "Number of Pixel Control Points"
652 // should be used to interpolate.
653 // "Pixels per Scan Line" is the final number of elements for lat/lon along the 2nd dimension
654 // "Number of Pixel Control Points" includes the original number of elements for lat/lon along
655 // the 2nd dimension.
656 void
657 HDFSPArrayGeoField::readobpgl2 (int32 * offset32, int32 * count32,
658  int32 * step32, int nelms)
659 {
660  string check_pass_fileid_key_str="H4.EnablePassFileID";
661  bool check_pass_fileid_key = false;
662  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
663  int32 sdid = -1;
664 
665  if(false == check_pass_fileid_key) {
666  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
667  if (sdid < 0) {
668  ostringstream eherr;
669  eherr << "File " << filename.c_str () << " cannot be open.";
670  throw InternalErr (__FILE__, __LINE__, eherr.str ());
671  }
672  }
673  else
674  sdid = sdfd;
675 
676  int32 sdsid = -1;
677  intn status = 0;
678 
679  // Read File attributes to otain the segment
680  int32 attr_index = 0;
681  int32 attr_dtype = 0;
682  int32 n_values = 0;
683  int32 num_pixel_data = 0;
684  int32 num_point_data = 0;
685  int32 num_scan_data = 0;
686 
687  attr_index = SDfindattr (sdid, NUM_PIXEL_NAME);
688  if (attr_index == FAIL) {
689  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
690  string attr_name(NUM_PIXEL_NAME);
691  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
692  throw InternalErr (__FILE__, __LINE__, err_mesg);
693  }
694 
695  char attr_name[H4_MAX_NC_NAME];
696  status =
697  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
698  if (status == FAIL) {
699  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
700  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
701  }
702 
703  if (n_values != 1) {
704  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
705  throw InternalErr (__FILE__, __LINE__,
706  "Only one value of number of scan line ");
707  }
708 
709  status = SDreadattr (sdid, attr_index, &num_pixel_data);
710  if (status == FAIL) {
711  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
712  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
713  }
714 
715  attr_index = SDfindattr (sdid, NUM_POINTS_LINE_NAME);
716  if (attr_index == FAIL) {
717  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
718  string attr_name(NUM_POINTS_LINE_NAME);
719  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
720  throw InternalErr (__FILE__, __LINE__, err_mesg);
721 
722  }
723 
724  status =
725  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
726  if (status == FAIL) {
727  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
728  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
729  }
730 
731  if (n_values != 1) {
732  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
733  throw InternalErr (__FILE__, __LINE__,
734  "Only one value of number of point ");
735  }
736 
737  status = SDreadattr (sdid, attr_index, &num_point_data);
738  if (status == FAIL) {
739  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
740  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
741  }
742 
743  attr_index = SDfindattr (sdid, NUM_SCAN_LINE_NAME);
744  if (attr_index == FAIL) {
745  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
746  string attr_name(NUM_SCAN_LINE_NAME);
747  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
748  throw InternalErr (__FILE__, __LINE__, err_mesg);
749 
750  }
751 
752  status =
753  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
754  if (status == FAIL) {
755  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
756  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
757  }
758 
759  if (n_values != 1) {
760  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
761  throw InternalErr (__FILE__, __LINE__,"Only one value of number of point ");
762  }
763 
764  status = SDreadattr (sdid, attr_index, &num_scan_data);
765  if (status == FAIL) {
766  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
767  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
768  }
769 
770 
771  if ( 0 == num_scan_data || 0 == num_point_data || 0 == num_pixel_data) {
772  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
773  throw InternalErr (__FILE__, __LINE__, "num_scan or num_point or num_pixel should not be zero. ");
774  }
775 
776  if ( 1 == num_point_data && num_pixel_data != 1) {
777  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
778  throw InternalErr (__FILE__, __LINE__,
779  "num_point is 1 and num_pixel is not 1, interpolation cannot be done ");
780  }
781 
782  bool compmapflag = false;
783  if (num_pixel_data == num_point_data)
784  compmapflag = true;
785 
786  int32 sdsindex = SDreftoindex (sdid, (int32) fieldref);
787  if (sdsindex == -1) {
788  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
789  ostringstream eherr;
790  eherr << "SDS index " << sdsindex << " is not right.";
791  throw InternalErr (__FILE__, __LINE__, eherr.str ());
792  }
793 
794  sdsid = SDselect (sdid, sdsindex);
795  if (sdsid < 0) {
796  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
797  ostringstream eherr;
798  eherr << "SDselect failed.";
799  throw InternalErr (__FILE__, __LINE__, eherr.str ());
800  }
801 
802  int32 r = 0;
803 
804  switch (dtype) {
805  case DFNT_INT8:
806  case DFNT_UINT8:
807  case DFNT_UCHAR8:
808  case DFNT_CHAR8:
809  case DFNT_INT16:
810  case DFNT_UINT16:
811  case DFNT_INT32:
812  case DFNT_UINT32:
813  case DFNT_FLOAT64:
814  SDendaccess (sdsid);
815  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
816  throw InternalErr (__FILE__, __LINE__,"datatype is not float, unsupported.");
817  break;
818  case DFNT_FLOAT32:
819  {
820  vector<float32> val;
821  val.resize(nelms);
822  if (compmapflag) {
823  r = SDreaddata (sdsid, offset32, step32, count32, &val[0]);
824  if (r != 0) {
825  SDendaccess (sdsid);
826  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
827  ostringstream eherr;
828  eherr << "SDreaddata failed";
829  throw InternalErr (__FILE__, __LINE__, eherr.str ());
830  }
831  }
832  else {
833 
834  int total_elm = num_scan_data * num_point_data;
835  vector<float32>orival;
836  orival.resize(total_elm);
837  int32 all_start[2],all_edges[2];
838 
839  all_start[0] = 0;
840  all_start[1] = 0;
841  all_edges[0] = num_scan_data;
842  all_edges[1] = num_point_data;
843 
844  r = SDreaddata (sdsid, all_start, NULL, all_edges,
845  &orival[0]);
846  if (r != 0) {
847  SDendaccess (sdsid);
848  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
849  ostringstream eherr;
850  eherr << "SDreaddata failed";
851  throw InternalErr (__FILE__, __LINE__, eherr.str ());
852  }
853  int interpolate_elm = num_scan_data *num_pixel_data;
854 
855  vector<float32> interp_val;
856  interp_val.resize(interpolate_elm);
857 
858  // Number of scan line doesn't change, so just interpolate according to the fast changing dimension
859  int tempseg = 0;
860  float tempdiff = 0;
861 
862  if (num_pixel_data % num_point_data == 0)
863  tempseg = num_pixel_data / num_point_data;
864  else
865  tempseg = num_pixel_data / num_point_data + 1;
866 
867  int last_tempseg =
868  (num_pixel_data%num_point_data)?(num_pixel_data-1-(tempseg*(num_point_data-2))):tempseg;
869 
870  if ( 0 == last_tempseg || 0 == tempseg) {
871  SDendaccess(sdsid);
872  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
873  throw InternalErr(__FILE__,__LINE__,"Segments cannot be zero");
874  }
875 
876  int interp_val_index = 0;
877 
878  for (int i = 0; i <num_scan_data; i++) {
879 
880  // All the segements except the last one
881  for( int j =0; j <num_point_data -2; j ++) {
882  tempdiff = orival[i*num_point_data+j+1] - orival[i*num_point_data+j];
883  for (int k = 0; k <tempseg; k++) {
884  interp_val[interp_val_index] = orival[i*num_point_data+j] +
885  tempdiff/tempseg *k;
886  interp_val_index++;
887  }
888  }
889 
890  // The last segment
891  tempdiff = orival[i*num_point_data+num_point_data-1]
892  -orival[i*num_point_data+num_point_data-2];
893  for (int k = 0; k <last_tempseg; k++) {
894  interp_val[interp_val_index] = orival[i*num_point_data+num_point_data-2] +
895  tempdiff/last_tempseg *k;
896  interp_val_index++;
897  }
898 
899  interp_val[interp_val_index] = orival[i*num_point_data+num_point_data-1];
900  interp_val_index++;
901 
902  }
903 
904  LatLon2DSubset(&val[0],num_scan_data,num_pixel_data,&interp_val[0],
905  offset32,count32,step32);
906 
907  }
908  // Leave the following comments
909 #if 0
910  // WE SHOULD INTERPOLATE ACCORDING TO THE FAST CHANGING DIMENSION
911  // THis method will save some memory, but it will cause greater error
912  // if the step is very large. However, we should still take advantage
913  // of the small memory approach in the future implementation. KY 2012-09-04
914  float tempdiff;
915  int i, j, k, k2;
916  int32 realcount2 = oricount32[1] - 1;
917 
918  for (i = 0; i < (int) count32[0]; i++) {
919  for (j = 0; j < (int) realcount2 - 1; j++) {
920  tempdiff =
921  orival[i * (int) oricount32[1] + j + 1] -
922  orival[i * (int) oricount32[1] + j];
923  for (k = 0; k < tempnewseg; k++) {
924  val[i * (int) count32[1] + j * tempnewseg + k] =
925  orival[i * (int) oricount32[1] + j] +
926  tempdiff / tempnewseg * k;
927  }
928  }
929  tempdiff =
930  orival[i * (int) oricount32[1] + j + 1] -
931  orival[i * (int) oricount32[1] + j];
932  // There are three cases:
933  // 1. when the oricount is 1
934  // int lastseg = num_pixel_data - tempnewseg*((int)oricount32[1]-1)-1;
935  int lastseg =
936  (int) (count32[1] -
937  tempnewseg * (int) (realcount2 - 1));
938  for (k2 = 0; k2 <= lastseg; k2++)
939  val[i * (int) count32[1] + j * tempnewseg + k2] =
940  orival[i * (int) oricount32[1] + j] +
941  tempdiff / lastseg * k2;
942  }
943 
944  delete[](float32 *) orival;
945  }
946 #endif
947 
948  set_value ((dods_float32 *) &val[0], nelms);
949  }
950  break;
951  default:
952  SDendaccess (sdsid);
953  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
954  InternalErr (__FILE__, __LINE__, "unsupported data type.");
955  }
956 
957  r = SDendaccess (sdsid);
958  if (r != 0) {
959  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
960  ostringstream eherr;
961  eherr << "SDendaccess failed.";
962  throw InternalErr (__FILE__, __LINE__, eherr.str ());
963  }
964 
965  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
966 }
967 
968 // Obtain lat/lon for OBPG CZCS, MODISA, MODIST,OCTS and SeaWIFS products
969 // lat/lon should be calculated based on the file attribute.
970 // Geographic projection: lat,lon starting point and also lat/lon steps.
971 void
972 HDFSPArrayGeoField::readobpgl3 (int *offset, int *count, int *step, int nelms)
973 {
974 
975  string check_pass_fileid_key_str="H4.EnablePassFileID";
976  bool check_pass_fileid_key = false;
977  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
978  int32 sdid = -1;
979 
980  if(false == check_pass_fileid_key) {
981  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
982  if (sdid < 0) {
983  ostringstream eherr;
984  eherr << "File " << filename.c_str () << " cannot be open.";
985  throw InternalErr (__FILE__, __LINE__, eherr.str ());
986  }
987  }
988  else
989  sdid = sdfd;
990 
991  intn status = 0;
992 
993  // Read File attributes to otain the segment
994  int32 attr_index = 0;
995  int32 attr_dtype = 0;
996  int32 n_values = 0;
997  int32 num_lat_data = 0;
998  int32 num_lon_data = 0;
999  float32 lat_step = 0.;
1000  float32 lon_step = 0.;
1001  float32 swp_lat = 0.;
1002  float32 swp_lon = 0.;
1003 
1004  // Obtain number of latitude
1005  attr_index = SDfindattr (sdid, NUM_LAT_NAME);
1006  if (attr_index == FAIL) {
1007  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1008  string attr_name(NUM_LAT_NAME);
1009  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
1010  throw InternalErr (__FILE__, __LINE__, err_mesg);
1011  //throw InternalErr (__FILE__, __LINE__, "SDfindattr failed,should find this attribute. ");
1012  }
1013 
1014  char attr_name[H4_MAX_NC_NAME];
1015  status =
1016  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
1017  if (status == FAIL) {
1018  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1019  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
1020  }
1021 
1022  if (n_values != 1) {
1023  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1024  throw InternalErr (__FILE__, __LINE__, "Only should have one value ");
1025  }
1026 
1027  status = SDreadattr (sdid, attr_index, &num_lat_data);
1028  if (status == FAIL) {
1029  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1030  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
1031  }
1032 
1033  // Obtain number of longitude
1034  attr_index = SDfindattr (sdid, NUM_LON_NAME);
1035  if (attr_index == FAIL) {
1036  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1037  string attr_name(NUM_LON_NAME);
1038  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
1039  throw InternalErr (__FILE__, __LINE__, err_mesg);
1040 // throw InternalErr (__FILE__, __LINE__, "SDfindattr failed ");
1041  }
1042 
1043  status =
1044  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
1045  if (status == FAIL) {
1046  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1047  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
1048  }
1049 
1050  if (n_values != 1) {
1051  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1052  throw InternalErr (__FILE__, __LINE__, "Only should have one value ");
1053  }
1054 
1055  status = SDreadattr (sdid, attr_index, &num_lon_data);
1056  if (status == FAIL) {
1057  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1058  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
1059  }
1060 
1061  // obtain latitude step
1062  attr_index = SDfindattr (sdid, LAT_STEP_NAME);
1063  if (attr_index == FAIL) {
1064  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1065  string attr_name(LAT_STEP_NAME);
1066  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
1067  throw InternalErr (__FILE__, __LINE__, err_mesg);
1068 // throw InternalErr (__FILE__, __LINE__, "SDfindattr failed ");
1069  }
1070 
1071  status =
1072  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
1073  if (status == FAIL) {
1074  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1075  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
1076  }
1077 
1078  if (n_values != 1) {
1079  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1080  throw InternalErr (__FILE__, __LINE__, "Only should have one value ");
1081  }
1082 
1083  status = SDreadattr (sdid, attr_index, &lat_step);
1084  if (status == FAIL) {
1085  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1086  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
1087  }
1088 
1089  // Obtain longitude step
1090  attr_index = SDfindattr (sdid, LON_STEP_NAME);
1091  if (attr_index == FAIL) {
1092  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1093  string attr_name(LON_STEP_NAME);
1094  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
1095  throw InternalErr (__FILE__, __LINE__, err_mesg);
1096 // throw InternalErr (__FILE__, __LINE__, "SDfindattr failed ");
1097  }
1098 
1099  status =
1100  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
1101  if (status == FAIL) {
1102  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1103  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
1104  }
1105 
1106  if (n_values != 1) {
1107  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1108  throw InternalErr (__FILE__, __LINE__, "Only should have one value ");
1109  }
1110 
1111  status = SDreadattr (sdid, attr_index, &lon_step);
1112  if (status == FAIL) {
1113  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1114  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
1115  }
1116 
1117  // obtain south west corner latitude
1118  attr_index = SDfindattr (sdid, SWP_LAT_NAME);
1119  if (attr_index == FAIL) {
1120  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1121  string attr_name(SWP_LAT_NAME);
1122  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
1123  throw InternalErr (__FILE__, __LINE__, err_mesg);
1124 //throw InternalErr (__FILE__, __LINE__, "SDfindattr failed ");
1125  }
1126 
1127  status =
1128  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
1129  if (status == FAIL) {
1130  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1131  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
1132  }
1133 
1134  if (n_values != 1) {
1135  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1136  throw InternalErr (__FILE__, __LINE__, "Only should have one value ");
1137  }
1138 
1139  status = SDreadattr (sdid, attr_index, &swp_lat);
1140  if (status == FAIL) {
1141  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1142  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
1143  }
1144 
1145  // obtain south west corner longitude
1146  attr_index = SDfindattr (sdid, SWP_LON_NAME);
1147  if (attr_index == FAIL) {
1148  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1149  string attr_name(SWP_LON_NAME);
1150  string err_mesg = "SDfindattr failed,should find attribute "+attr_name+" .";
1151  throw InternalErr (__FILE__, __LINE__, err_mesg);
1152 //throw InternalErr (__FILE__, __LINE__, "SDfindattr failed,should find this attribute. ");
1153  }
1154 
1155  status =
1156  SDattrinfo (sdid, attr_index, attr_name, &attr_dtype, &n_values);
1157  if (status == FAIL) {
1158  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1159  throw InternalErr (__FILE__, __LINE__, "SDattrinfo failed ");
1160  }
1161 
1162  if (n_values != 1) {
1163  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1164  throw InternalErr (__FILE__, __LINE__, "Only should have one value ");
1165  }
1166 
1167  status = SDreadattr (sdid, attr_index, &swp_lon);
1168  if (status == FAIL) {
1169  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1170  throw InternalErr (__FILE__, __LINE__, "SDreadattr failed ");
1171  }
1172 
1173 
1174  if (fieldtype == 1) {
1175 
1176  vector<float32> allval;
1177  allval.resize(num_lat_data);
1178 
1179  // The first index is from the north, so we need to reverse the calculation of the index
1180 
1181  for (int j = 0; j < num_lat_data; j++)
1182  allval[j] = (num_lat_data - j - 1) * lat_step + swp_lat;
1183 
1184  vector<float32>val;
1185  val.resize(nelms);
1186 
1187  for (int k = 0; k < nelms; k++)
1188  val[k] = allval[(int) (offset[0] + step[0] * k)];
1189 
1190  set_value ((dods_float32 *) &val[0], nelms);
1191  }
1192 
1193  if (fieldtype == 2) {
1194 
1195  vector<float32>allval;
1196  allval.resize(num_lon_data);
1197  for (int j = 0; j < num_lon_data; j++)
1198  allval[j] = swp_lon + j * lon_step;
1199 
1200  vector<float32>val;
1201  val.resize(nelms);
1202  for (int k = 0; k < nelms; k++)
1203  val[k] = allval[(int) (offset[0] + step[0] * k)];
1204 
1205  set_value ((dods_float32 *) &val[0], nelms);
1206 
1207  }
1208 
1209  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1210 
1211 }
1212 
1213 
1214 // CERES SAVG and ISSP DAY case(CER_SAVG and CER_ISCCP_.._DAY )
1215 // We need to calculate latitude/longitude based on CERES nested grid formula
1216 // http://eosweb.larc.nasa.gov/PRODOCS/ceres/SRBAVG/Quality_Summaries/srbavg_ed2d/nestedgrid.html
1217 // or https://eosweb.larc.nasa.gov/sites/default/files/project/ceres/quality_summaries/srbavg_ed2d/nestedgrid.pdf
1218 void
1219 HDFSPArrayGeoField::readcersavgid2 (int *offset, int *count, int *step,
1220  int nelms)
1221 {
1222 
1223  const int dimsize0 = 180;
1224  const int dimsize1 = 360;
1225  float32 val[count[0]][count[1]];
1226  float32 orival[dimsize0][dimsize1];
1227 
1228  // Following CERES Nested grid
1229  // URL http://eosweb.larc.nasa.gov/PRODOCS/ceres/SRBAVG/Quality_Summaries/srbavg_ed2d/nestedgrid.html
1230  // or https://eosweb.larc.nasa.gov/sites/default/files/project/ceres/quality_summaries/srbavg_ed2d/nestedgrid.pdf
1231  if (fieldtype == 1) {// Calculate the latitude
1232  for (int i = 0; i < dimsize0; i++)
1233  for (int j = 0; j < dimsize1; j++)
1234  orival[i][j] = 89.5 - i;
1235 
1236  for (int i = 0; i < count[0]; i++) {
1237  for (int j = 0; j < count[1]; j++) {
1238  val[i][j] =
1239  orival[offset[0] + step[0] * i][offset[1] + step[1] * j];
1240  }
1241  }
1242  }
1243 
1244  if (fieldtype == 2) {// Calculate the longitude
1245 
1246  int i = 0;
1247  int j = 0;
1248  int k = 0;
1249 
1250  // Longitude extent
1251  int lonextent;
1252 
1253  // Latitude index
1254  int latindex_south;
1255 
1256  // Latitude index
1257  int latindex_north;
1258 
1259  // Latitude range
1260  int latrange;
1261 
1262 
1263  //latitude 89-90 (both south and north) 1 value each part
1264  for (j = 0; j < dimsize1; j++) {
1265  orival[0][j] = -179.5;
1266  orival[dimsize0 - 1][j] = -179.5;
1267  }
1268 
1269  //latitude 80-89 (both south and north) 45 values each part
1270  // longitude extent is 8
1271  lonextent = 8;
1272  // From 89 N to 80 N
1273  latindex_north = 1;
1274  latrange = 9;
1275  for (i = 0; i < latrange; i++)
1276  for (j = 0; j < (dimsize1 / lonextent); j++)
1277  for (k = 0; k < lonextent; k++)
1278  orival[i + latindex_north][j * lonextent + k] =
1279  -179.5 + lonextent * j;
1280 
1281  // From 89 S to 80 S
1282  latindex_south = dimsize0 - 1 - latrange;
1283  for (i = 0; i < latrange; i++)
1284  for (j = 0; j < (dimsize1 / lonextent); j++)
1285  for (k = 0; k < lonextent; k++)
1286  orival[i + latindex_south][j * lonextent + k] =
1287  -179.5 + lonextent * j;
1288 
1289  // From 80 N to 70 N
1290  latindex_north = latindex_north + latrange;
1291  latrange = 10;
1292  lonextent = 4;
1293 
1294  for (i = 0; i < latrange; i++)
1295  for (j = 0; j < (dimsize1 / lonextent); j++)
1296  for (k = 0; k < lonextent; k++)
1297  orival[i + latindex_north][j * lonextent + k] =
1298  -179.5 + lonextent * j;
1299 
1300  // From 80 S to 70 S
1301  latindex_south = latindex_south - latrange;
1302  for (i = 0; i < latrange; i++)
1303  for (j = 0; j < (dimsize1 / lonextent); j++)
1304  for (k = 0; k < lonextent; k++)
1305  orival[i + latindex_south][j * lonextent + k] =
1306  -179.5 + lonextent * j;
1307 
1308  // From 70 N to 45 N
1309  latindex_north = latindex_north + latrange;
1310  latrange = 25;
1311  lonextent = 2;
1312 
1313  for (i = 0; i < latrange; i++)
1314  for (j = 0; j < (dimsize1 / lonextent); j++)
1315  for (k = 0; k < lonextent; k++)
1316  orival[i + latindex_north][j * lonextent + k] =
1317  -179.5 + lonextent * j;
1318 
1319  // From 70 S to 45 S
1320  latindex_south = latindex_south - latrange;
1321 
1322  for (i = 0; i < latrange; i++)
1323  for (j = 0; j < (dimsize1 / lonextent); j++)
1324  for (k = 0; k < lonextent; k++)
1325  orival[i + latindex_south][j * lonextent + k] =
1326  -179.5 + lonextent * j;
1327 
1328  // From 45 N to 0 N
1329  latindex_north = latindex_north + latrange;
1330  latrange = 45;
1331  lonextent = 1;
1332 
1333  for (i = 0; i < latrange; i++)
1334  for (j = 0; j < (dimsize1 / lonextent); j++)
1335  for (k = 0; k < lonextent; k++)
1336  orival[i + latindex_north][j * lonextent + k] =
1337  -179.5 + lonextent * j;
1338 
1339  // From 45 S to 0 S
1340  latindex_south = latindex_south - latrange;
1341  for (i = 0; i < latrange; i++)
1342  for (j = 0; j < (dimsize1 / lonextent); j++)
1343  for (k = 0; k < lonextent; k++)
1344  orival[i + latindex_south][j * lonextent + k] =
1345  -179.5 + lonextent * j;
1346 
1347  for (int i = 0; i < count[0]; i++) {
1348  for (int j = 0; j < count[1]; j++) {
1349  val[i][j] =
1350  orival[offset[0] + step[0] * i][offset[1] + step[1] * j];
1351  }
1352  }
1353  }
1354  set_value ((dods_float32 *) (&val[0][0]), nelms);
1355 
1356 }
1357 
1358 // This function calculate zonal average(longitude is fixed) of CERES SAVG and CERES_ISCCP_DAY_LIKE.
1359 void
1360 HDFSPArrayGeoField::readcersavgid1 (int *offset, int *count, int *step,
1361  int nelms)
1362 {
1363 
1364  // Following CERES Nested grid
1365  // URL http://eosweb.larc.nasa.gov/PRODOCS/ceres/SRBAVG/Quality_Summaries/srbavg_ed2d/nestedgrid.html
1366  // or https://eosweb.larc.nasa.gov/sites/default/files/project/ceres/quality_summaries/srbavg_ed2d/nestedgrid.pdf
1367  if (fieldtype == 1) { // Calculate the latitude
1368  const int dimsize0 = 180;
1369  float32 val[count[0]];
1370  float32 orival[dimsize0];
1371 
1372  for (int i = 0; i < dimsize0; i++)
1373  orival[i] = 89.5 - i;
1374 
1375  for (int i = 0; i < count[0]; i++) {
1376  val[i] = orival[offset[0] + step[0] * i];
1377  }
1378  set_value ((dods_float32 *) (&val[0]), nelms);
1379 
1380  }
1381 
1382  if (fieldtype == 2) { // Calculate the longitude
1383 
1384  // Assume the longitude is 0 in average
1385  float32 val = 0;
1386  if (nelms > 1)
1387  InternalErr (__FILE__, __LINE__,
1388  "the number of element must be 1");
1389  set_value ((dods_float32 *) (&val), nelms);
1390 
1391  }
1392 
1393 }
1394 
1395 // Calculate CERES AVG and SYN lat and lon.
1396 // We just need to retrieve lat/lon from the field.
1397 void
1398 HDFSPArrayGeoField::readceravgsyn (int32 * offset32, int32 * count32,
1399  int32 * step32, int nelms)
1400 {
1401 
1402  string check_pass_fileid_key_str="H4.EnablePassFileID";
1403  bool check_pass_fileid_key = false;
1404  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
1405  int32 sdid = -1;
1406 
1407  if(false == check_pass_fileid_key) {
1408  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
1409  if (sdid < 0) {
1410  ostringstream eherr;
1411  eherr << "File " << filename.c_str () << " cannot be open.";
1412  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1413  }
1414  }
1415  else
1416  sdid = sdfd;
1417 
1418  int i = 0;
1419  int32 sdsid = -1;
1420 
1421  int32 sdsindex = SDreftoindex (sdid, fieldref);
1422 
1423  if (sdsindex == -1) {
1424  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1425  ostringstream eherr;
1426  eherr << "SDS index " << sdsindex << " is not right.";
1427  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1428  }
1429 
1430  sdsid = SDselect (sdid, sdsindex);
1431  if (sdsid < 0) {
1432  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1433  ostringstream eherr;
1434  eherr << "SDselect failed.";
1435  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1436  }
1437 
1438  int32 r;
1439 
1440  switch (dtype) {
1441  case DFNT_INT8:
1442  case DFNT_UINT8:
1443  case DFNT_UCHAR8:
1444  case DFNT_CHAR8:
1445  case DFNT_INT16:
1446  case DFNT_UINT16:
1447  case DFNT_INT32:
1448  case DFNT_UINT32:
1449  SDendaccess (sdsid);
1450  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1451  throw InternalErr (__FILE__, __LINE__,
1452  "datatype is not float, unsupported.");
1453  case DFNT_FLOAT32:
1454  {
1455  vector<float32>val;
1456  val.resize(nelms);
1457  r = SDreaddata (sdsid, offset32, step32, count32, &val[0]);
1458  if (r != 0) {
1459  SDendaccess (sdsid);
1460  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1461  ostringstream eherr;
1462  eherr << "SDreaddata failed";
1463  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1464  }
1465 
1466  if (fieldtype == 1) {
1467  for (i = 0; i < nelms; i++)
1468  val[i] = 90 - val[i];
1469  }
1470  if (fieldtype == 2) {
1471  for (i = 0; i < nelms; i++)
1472  if (val[i] > 180.0)
1473  val[i] = val[i] - 360.0;
1474  }
1475 
1476  set_value ((dods_float32 *) &val[0], nelms);
1477  break;
1478  }
1479  case DFNT_FLOAT64:
1480  {
1481  vector<float64>val;
1482  val.resize(nelms);
1483 
1484  r = SDreaddata (sdsid, offset32, step32, count32, &val[0]);
1485  if (r != 0) {
1486  SDendaccess (sdsid);
1487  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1488  ostringstream eherr;
1489  eherr << "SDreaddata failed";
1490  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1491  }
1492 
1493  if (fieldtype == 1) {
1494  for (i = 0; i < nelms; i++)
1495  val[i] = 90 - val[i];
1496  }
1497  if (fieldtype == 2) {
1498  for (i = 0; i < nelms; i++)
1499  if (val[i] > 180.0)
1500  val[i] = val[i] - 360.0;
1501  }
1502  set_value ((dods_float64 *) &val[0], nelms);
1503  break;
1504  }
1505  default:
1506  SDendaccess (sdsid);
1507  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1508  InternalErr (__FILE__, __LINE__, "unsupported data type.");
1509  }
1510 
1511  r = SDendaccess (sdsid);
1512  if (r != 0) {
1513  ostringstream eherr;
1514  eherr << "SDendaccess failed.";
1515  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1516  }
1517 
1518  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1519 }
1520 
1521 // Calculate CERES ES4 and GEO lat/lon.
1522 // We have to retrieve the original lat/lon and condense it from >1-D to 1-D.
1523 void
1524 HDFSPArrayGeoField::readceres4ig (int32 * offset32, int32 * count32,
1525  int32 * step32, int nelms)
1526 {
1527  string check_pass_fileid_key_str="H4.EnablePassFileID";
1528  bool check_pass_fileid_key = false;
1529  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
1530  int32 sdid = -1;
1531 
1532  if(false == check_pass_fileid_key) {
1533  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
1534  if (sdid < 0) {
1535  ostringstream eherr;
1536  eherr << "File " << filename.c_str () << " cannot be open.";
1537  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1538  }
1539  }
1540  else
1541  sdid = sdfd;
1542 
1543 
1544  int32 sdsid = -1;
1545  intn status = 0;
1546 
1547  int32 sdsindex = SDreftoindex (sdid, (int32) fieldref);
1548  if (sdsindex == -1) {
1549  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1550  ostringstream eherr;
1551  eherr << "SDS index " << sdsindex << " is not right.";
1552  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1553  }
1554 
1555  sdsid = SDselect (sdid, sdsindex);
1556  if (sdsid < 0) {
1557  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1558  ostringstream eherr;
1559  eherr << "SDselect failed.";
1560  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1561  }
1562 
1563  int32 sdsrank = 0;
1564  int32 sds_dtype = 0;
1565  int32 n_attrs = 0;
1566  char sdsname[H4_MAX_NC_NAME];
1567  int32 dim_sizes[H4_MAX_VAR_DIMS];
1568 
1569  status =
1570  SDgetinfo (sdsid, sdsname, &sdsrank, dim_sizes, &sds_dtype, &n_attrs);
1571  if (status < 0) {
1572  SDendaccess (sdsid);
1573  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1574  ostringstream eherr;
1575  eherr << "SDgetinfo failed.";
1576  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1577  }
1578 
1579  vector<int32> orioffset32;
1580  vector<int32> oricount32;
1581  vector<int32> oristep32;
1582  orioffset32.resize(sdsrank);
1583  oricount32.resize(sdsrank);
1584  oristep32.resize(sdsrank);
1585 
1586  int32 r;
1587 
1588  switch (sds_dtype) {
1589  case DFNT_INT8:
1590  case DFNT_UINT8:
1591  case DFNT_UCHAR8:
1592  case DFNT_CHAR8:
1593  case DFNT_INT16:
1594  case DFNT_UINT16:
1595  case DFNT_INT32:
1596  case DFNT_UINT32:
1597  case DFNT_FLOAT64:
1598  SDendaccess (sdsid);
1599  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1600  throw InternalErr (__FILE__, __LINE__,
1601  "datatype is not float, unsupported.");
1602  case DFNT_FLOAT32:
1603  {
1604  vector<float32> val;
1605  val.resize(nelms);
1606  if (fieldtype == 1) {
1607  if (sptype == CER_CGEO) {
1608  if (sdsrank != 3) {
1609  SDendaccess (sdsid);
1610  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1611  throw InternalErr (__FILE__, __LINE__,
1612  "For CER_ISCCP-D2like-GEO case, lat/lon must be 3-D");
1613  }
1614  orioffset32[0] = 0;
1615 
1616  // The second dimension of the original latitude should be condensed
1617  orioffset32[1] = offset32[0];
1618  orioffset32[2] = 0;
1619  oricount32[0] = 1;
1620  oricount32[1] = count32[0];
1621  oricount32[2] = 1;
1622  oristep32[0] = 1;
1623  oristep32[1] = step32[0];
1624  oristep32[2] = 1;
1625  }
1626  if (sptype == CER_ES4) {
1627  if (sdsrank != 2) {
1628  SDendaccess (sdsid);
1629  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1630  throw InternalErr (__FILE__, __LINE__,
1631  "For CER_ES4 case, lat/lon must be 2-D");
1632  }
1633  // The first dimension of the original latitude should be condensed
1634  orioffset32[0] = offset32[0];
1635  orioffset32[1] = 0;
1636  oricount32[0] = count32[0];
1637  oricount32[1] = 1;
1638  oristep32[0] = step32[0];
1639  oristep32[1] = 1;
1640  }
1641  }
1642 
1643  if (fieldtype == 2) {
1644  if (sptype == CER_CGEO) {
1645  if (sdsrank != 3) {
1646  SDendaccess (sdsid);
1647  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1648  throw InternalErr (__FILE__, __LINE__,
1649  "For CER_ISCCP-D2like-GEO case, lat/lon must be 3-D");
1650  }
1651  orioffset32[0] = 0;
1652  orioffset32[2] = offset32[0];// The third dimension of the original latitude should be condensed
1653  orioffset32[1] = 0;
1654  oricount32[0] = 1;
1655  oricount32[2] = count32[0];
1656  oricount32[1] = 1;
1657  oristep32[0] = 1;
1658  oristep32[2] = step32[0];
1659  oristep32[1] = 1;
1660  }
1661  if (sptype == CER_ES4) {
1662  if (sdsrank != 2) {
1663  SDendaccess (sdsid);
1664  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1665  throw InternalErr (__FILE__, __LINE__,
1666  "For CER_ES4 case, lat/lon must be 2-D");
1667  }
1668  orioffset32[1] = offset32[0]; // The second dimension of the original latitude should be condensed
1669  orioffset32[0] = 0;
1670  oricount32[1] = count32[0];
1671  oricount32[0] = 1;
1672  oristep32[1] = step32[0];
1673  oristep32[0] = 1;
1674  }
1675  }
1676 
1677  r = SDreaddata (sdsid, &orioffset32[0], &oristep32[0], &oricount32[0], &val[0]);
1678  if (r != 0) {
1679  SDendaccess (sdsid);
1680  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1681  ostringstream eherr;
1682  eherr << "SDreaddata failed";
1683  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1684  }
1685 
1686  if (fieldtype == 1)
1687  for (int i = 0; i < nelms; i++)
1688  val[i] = 90 - val[i];
1689  if (fieldtype == 2) {
1690  // Since Panoply cannot handle the case when the longitude is jumped from 180 to -180
1691  // So turn it off and see if it works with other clients,
1692  // change my mind, should contact Panoply developer to solve this
1693  // Just check Panoply(3.2.1) with the latest release(1.9). This is no longer an issue.
1694  for (int i = 0; i < nelms; i++)
1695  if (val[i] > 180.0)
1696  val[i] = val[i] - 360.0;
1697  }
1698 
1699  set_value ((dods_float32 *) &val[0], nelms);
1700  break;
1701  }
1702  default:
1703  SDendaccess (sdsid);
1704  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1705  InternalErr (__FILE__, __LINE__, "unsupported data type.");
1706  }
1707 
1708  r = SDendaccess (sdsid);
1709  if (r != 0) {
1710  ostringstream eherr;
1711  eherr << "SDendaccess failed.";
1712  throw InternalErr (__FILE__, __LINE__, eherr.str ());
1713  }
1714 
1715  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
1716 }
1717 
1718 // Read CERES Zonal average latitude field
1719 void
1720 HDFSPArrayGeoField::readcerzavg (int32 * offset32, int32 * count32,
1721  int32 * step32, int nelms)
1722 {
1723  if (fieldtype == 1) {
1724 
1725  vector<float32>val;
1726  val.resize(nelms);
1727 
1728  float32 latstep = 1.0;
1729 
1730  for (int i = 0; i < nelms; i++)
1731  val[i] =
1732  89.5 - ((int) (offset32[0]) +
1733  ((int) (step32[0])) * i) * latstep;
1734  set_value ((dods_float32 *) &val[0], nelms);
1735  }
1736 
1737  if (fieldtype == 2) {
1738  if (count32[0] != 1 || nelms != 1)
1739  throw InternalErr (__FILE__, __LINE__,
1740  "Longitude should only have one value for zonal mean");
1741 
1742  // We don't need to specify the longitude value.
1743  float32 val = 0.;// our convention
1744  set_value ((dods_float32 *) & val, nelms);
1745  }
1746 }
1747 
1748 
1749 // Standard way of DAP handlers to pass the coordinates of the subsetted region to the handlers
1750 // Return the number of elements to read.
1751 int
1752 HDFSPArrayGeoField::format_constraint (int *offset, int *step, int *count)
1753 {
1754  long nels = 1;
1755  int id = 0;
1756 
1757  Dim_iter p = dim_begin ();
1758 
1759  while (p != dim_end ()) {
1760 
1761  int start = dimension_start (p, true);
1762  int stride = dimension_stride (p, true);
1763  int stop = dimension_stop (p, true);
1764 
1765  // Check for illegical constraint
1766  if (stride < 0 || start < 0 || stop < 0 || start > stop) {
1767  ostringstream oss;
1768  oss << "Array/Grid hyperslab indices are bad: [" << start <<
1769  ":" << stride << ":" << stop << "]";
1770  throw Error (malformed_expr, oss.str ());
1771  }
1772 
1773  // Check for an empty constraint and use the whole dimension if so.
1774  if (start == 0 && stop == 0 && stride == 0) {
1775  start = dimension_start (p, false);
1776  stride = dimension_stride (p, false);
1777  stop = dimension_stop (p, false);
1778  }
1779 
1780  offset[id] = start;
1781  step[id] = stride;
1782  count[id] = ((stop - start) / stride) + 1; // count of elements
1783  nels *= count[id]; // total number of values for variable
1784 
1785  BESDEBUG("h4",
1786  "=format_constraint():" << "id=" << id << " offset=" <<
1787  offset[id]
1788  << " step=" << step[id]
1789  << " count=" << count[id]
1790  << endl);
1791 
1792  id++;
1793  p++;
1794  }
1795 
1796  return nels;
1797 }
1798 
1799 // Subset of latitude and longitude to follow the parameters from the DAP expression constraint
1800 template < typename T >
1801 void HDFSPArrayGeoField::LatLon2DSubset (T * outlatlon,
1802  int majordim,
1803  int minordim,
1804  T * latlon,
1805  int32 * offset,
1806  int32 * count,
1807  int32 * step)
1808 {
1809 
1810  // float64 templatlon[majordim][minordim];
1811  T (*templatlonptr)[majordim][minordim] = (typeof templatlonptr) latlon;
1812  int i = 0;
1813  int j = 0;
1814  int k = 0;
1815 
1816  // do subsetting
1817  // Find the correct index
1818  const int dim0count = count[0];
1819  const int dim1count = count[1];
1820  int dim0index[dim0count], dim1index[dim1count];
1821 
1822  for (i = 0; i < count[0]; i++) // count[0] is the least changing dimension
1823  dim0index[i] = offset[0] + i * step[0];
1824 
1825  for (j = 0; j < count[1]; j++)
1826  dim1index[j] = offset[1] + j * step[1];
1827 
1828  // Now assign the subsetting data
1829  k = 0;
1830 
1831  for (i = 0; i < count[0]; i++) {
1832  for (j = 0; j < count[1]; j++) {
1833  outlatlon[k] = (*templatlonptr)[dim0index[i]][dim1index[j]];
1834  k++;
1835  }
1836  }
1837 }
1838 
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)
Definition: HDFCFUtil.cc:2534
#define NUM_POINTS_LINE_NAME
#define NUM_PIXEL_NAME
#define LON_STEP_NAME
#define SWP_LON_NAME
#define NUM_LON_NAME
int format_constraint(int *cor, int *step, int *edg)
#define NUM_SCAN_LINE_NAME
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
#define NUM_LAT_NAME
#define SWP_LAT_NAME
#define NULL
Definition: wcsUtil.h:65
#define LAT_STEP_NAME
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