bes  Updated for version 3.20.5
build_dmrpp.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of the Hyrax data server.
4 
5 // Copyright (c) 2018 OPeNDAP, Inc.
6 // Author: James Gallagher <jgallagher@opendap.org>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 //
22 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
23 
24 #include <iostream>
25 #include <fstream>
26 #include <sstream>
27 #include <memory>
28 #include <iterator>
29 #include <algorithm>
30 
31 #include <cstdlib>
32 
33 //#define H5D_FRIEND // Workaround, needed to use H5D_chunk_rec_t
34 //#include <H5Dpkg.h>
35 #define H5S_MAX_RANK 32
36 #define H5O_LAYOUT_NDIMS (H5S_MAX_RANK+1)
37 #include <H5Ppublic.h>
38 #include <H5Dpublic.h>
39 #include <H5Epublic.h>
40 #include <H5Zpublic.h> // Constants for compression filters
41 #include <H5Spublic.h>
42 
43 /*
44  * "Generic" chunk record. Each chunk is keyed by the minimum logical
45  * N-dimensional coordinates and the datatype size of the chunk.
46  * The fastest-varying dimension is assumed to reference individual bytes of
47  * the array, so a 100-element 1-D array of 4-byte integers would really be a
48  * 2-D array with the slow varying dimension of size 100 and the fast varying
49  * dimension of size 4 (the storage dimensionality has very little to do with
50  * the real dimensionality).
51  *
52  * The chunk's file address, filter mask and size on disk are not key values.
53  */
54 typedef struct H5D_chunk_rec_t {
55  hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Logical offset to start */
56  uint32_t nbytes; /* Size of stored data */
57  uint32_t filter_mask; /* Excluded filters */
58  haddr_t chunk_addr; /* Address of chunk in file */
59 } H5D_chunk_rec_t;
60 
61 #include <DMRpp.h>
62 #include <D4Attributes.h>
63 #include <BaseType.h>
64 #include <D4ParserSax2.h>
65 #include <GetOpt.h>
66 
67 #include <TheBESKeys.h>
68 #include <BESUtil.h>
69 #include <BESDebug.h>
70 #include <BESNotFoundError.h>
71 #include <BESInternalError.h>
72 
73 #include "DmrppTypeFactory.h"
74 #include "DmrppD4Group.h"
75 #include "DmrppMetadataStore.h"
76 
77 using namespace std;
78 using namespace libdap;
79 using namespace dmrpp;
80 
81 static bool verbose = false;
82 #define VERBOSE(x) do { if (verbose) x; } while(false)
83 
84 #define DEBUG_KEY "metadata_store,dmrpp_store,dmrpp"
85 #define ROOT_DIRECTORY "BES.Catalog.catalog.RootDirectory"
86 
97 static void print_dataset_type_info(hid_t dataset, uint8_t layout_type)
98 {
99  hid_t dtype_id = H5Dget_type(dataset);
100  if (dtype_id < 0) {
101  throw BESInternalError("Cannot obtain the correct HDF5 datatype.", __FILE__, __LINE__);
102  }
103 
104  if (H5Tget_class(dtype_id) == H5T_INTEGER || H5Tget_class(dtype_id) == H5T_FLOAT) {
105  hid_t dcpl_id = H5Dget_create_plist(dataset);
106  if (dcpl_id < 0) {
107  throw BESInternalError("Cannot obtain the HDF5 dataset creation property list.", __FILE__, __LINE__);
108  }
109 
110  try {
111  // Wrap the resources like dcpl_id in try/catch blocks so that the
112  // calls to H5Pclose(dcpl_id) for each error can be removed. jhrg 5/7/18
113  H5D_fill_value_t fvalue_status;
114  if (H5Pfill_value_defined(dcpl_id, &fvalue_status) < 0) {
115  H5Pclose(dcpl_id);
116  throw BESInternalError("Cannot obtain the fill value status.", __FILE__, __LINE__);
117  }
118  if (fvalue_status == H5D_FILL_VALUE_UNDEFINED) {
119  // Replace with switch(), here and elsewhere. jhrg 5/7/18
120  if (layout_type == 1)
121  cerr << " The storage size is 0 and the storage type is contiguous." << endl;
122  else if (layout_type == 2)
123  cerr << " The storage size is 0 and the storage type is chunking." << endl;
124  else if (layout_type == 3) cerr << " The storage size is 0 and the storage type is compact." << endl;
125 
126  cerr << " The Fillvalue is undefined ." << endl;
127  }
128  else {
129  if (layout_type == 1)
130  cerr << " The storage size is 0 and the storage type is contiguous." << endl;
131  else if (layout_type == 2)
132  cerr << " The storage size is 0 and the storage type is chunking." << endl;
133  else if (layout_type == 3) cerr << " The storage size is 0 and the storage type is compact." << endl;
134 
135  char* fvalue = NULL;
136  size_t fv_size = H5Tget_size(dtype_id);
137  if (fv_size == 1)
138  fvalue = (char*) (malloc(1));
139  else if (fv_size == 2)
140  fvalue = (char*) (malloc(2));
141  else if (fv_size == 4)
142  fvalue = (char*) (malloc(4));
143  else if (fv_size == 8) fvalue = (char*) (malloc(8));
144 
145  if (fv_size <= 8) {
146  if (H5Pget_fill_value(dcpl_id, dtype_id, (void*) (fvalue)) < 0) {
147  H5Pclose(dcpl_id);
148  throw BESInternalError("Cannot obtain the fill value status.", __FILE__, __LINE__);
149  }
150  if (H5Tget_class(dtype_id) == H5T_INTEGER) {
151  H5T_sign_t fv_sign = H5Tget_sign(dtype_id);
152  if (fv_size == 1) {
153  if (fv_sign == H5T_SGN_NONE) {
154  cerr << "This dataset's datatype is unsigned char " << endl;
155  cerr << "and the fillvalue is " << *fvalue << endl;
156  }
157  else {
158  cerr << "This dataset's datatype is char and the fillvalue is " << *fvalue << endl;
159  }
160  }
161  else if (fv_size == 2) {
162  if (fv_sign == H5T_SGN_NONE) {
163  cerr << "This dataset's datatype is unsigned short and the fillvalue is " << *fvalue << endl;
164  }
165  else {
166  cerr << "This dataset's datatype is short and the fillvalue is " << *fvalue << endl;
167  }
168  }
169  else if (fv_size == 4) {
170  if (fv_sign == H5T_SGN_NONE) {
171  cerr << "This dataset's datatype is unsigned int and the fillvalue is " << *fvalue << endl;
172  }
173  else {
174  cerr << "This dataset's datatype is int and the fillvalue is " << *fvalue << endl;
175  }
176  }
177  else if (fv_size == 8) {
178  if (fv_sign == H5T_SGN_NONE) {
179  cerr << "This dataset's datatype is unsigned long long and the fillvalue is " << *fvalue << endl;
180  }
181  else {
182  cerr << "This dataset's datatype is long long and the fillvalue is " << *fvalue << endl;
183  }
184  }
185  }
186  if (H5Tget_class(dtype_id) == H5T_FLOAT) {
187  if (fv_size == 4) {
188  cerr << "This dataset's datatype is float and the fillvalue is " << *fvalue << endl;
189  }
190  else if (fv_size == 8) {
191  cerr << "This dataset's datatype is double and the fillvalue is " << *fvalue << endl;
192  }
193  }
194 
195  if (fvalue != NULL) free(fvalue);
196  }
197  else
198  cerr
199  << "The size of the datatype is greater than 8 bytes, Use HDF5 API H5Pget_fill_value() to retrieve the fill value of this dataset."
200  << endl;
201  }
202  }
203  catch (...) {
204  H5Pclose(dcpl_id);
205  throw;
206  }
207  H5Pclose(dcpl_id);
208  }
209  else {
210  if (layout_type == 1)
211  cerr << " The storage size is 0 and the storage type is contiguous." << endl;
212  else if (layout_type == 2)
213  cerr << " The storage size is 0 and the storage type is chunking." << endl;
214  else if (layout_type == 3) cerr << " The storage size is 0 and the storage type is compact." << endl;
215 
216  cerr << "The datatype is neither float nor integer,use HDF5 API H5Pget_fill_value() to retrieve the fill value of this dataset." << endl;
217  }
218 }
219 
220 // FYI: Filter IDs
221 // H5Z_FILTER_ERROR (-1) no filter
222 // H5Z_FILTER_NONE 0 reserved indefinitely
223 // H5Z_FILTER_DEFLATE 1 deflation like gzip
224 // H5Z_FILTER_SHUFFLE 2 shuffle the data
225 // H5Z_FILTER_FLETCHER32 3 fletcher32 checksum of EDC
226 // H5Z_FILTER_SZIP 4 szip compression
227 // H5Z_FILTER_NBIT 5 nbit compression
228 // H5Z_FILTER_SCALEOFFSET 6 scale+offset compression
229 // H5Z_FILTER_RESERVED 256 filter ids below this value are reserved for library use
230 
237 static void set_filter_information(hid_t dataset_id, DmrppCommon *dc)
238 {
239  hid_t plist_id = H5Dget_create_plist(dataset_id);
240 
241  try {
242  int numfilt = H5Pget_nfilters(plist_id);
243  VERBOSE(cerr << "Number of filters associated with dataset: " << numfilt << endl);
244 
245  for (int filter = 0; filter < numfilt; filter++) {
246  size_t nelmts = 0;
247  unsigned int flags, filter_info;
248  H5Z_filter_t filter_type = H5Pget_filter2(plist_id, filter, &flags, &nelmts, NULL, 0, NULL, &filter_info);
249  VERBOSE(cerr << "Filter Type: ");
250 
251  switch (filter_type) {
252  case H5Z_FILTER_DEFLATE:
253  VERBOSE(cerr << "H5Z_FILTER_DEFLATE" << endl);
254  dc->set_deflate(true);
255  break;
256  case H5Z_FILTER_SHUFFLE:
257  VERBOSE(cerr << "H5Z_FILTER_SHUFFLE" << endl);
258  dc->set_shuffle(true);
259  break;
260  default: {
261  ostringstream oss("Unsupported HDF5 filter: ", std::ios::ate);
262  oss << filter_type;
263  throw BESInternalError(oss.str(), __FILE__, __LINE__);
264  }
265  }
266  }
267  }
268  catch (...) {
269  H5Pclose(plist_id);
270  throw;
271  }
272 
273  H5Pclose(plist_id);
274 }
275 
286 static void get_variable_chunk_info(hid_t dataset, DmrppCommon *dc)
287 {
288  try {
289  hid_t dcpl = H5Dget_create_plist(dataset);
290  uint8_t layout_type = H5Pget_layout(dcpl);
291 
292  hid_t fspace_id = H5Dget_space(dataset);
293 
294  unsigned int dataset_rank = H5Sget_simple_extent_ndims(fspace_id);
295 
296  /* layout_type: 1 contiguous 2 chunk 3 compact */
297  switch (layout_type) {
298 
299  case H5D_CONTIGUOUS: { /* Contiguous storage */
300  haddr_t cont_addr = 0;
301  hsize_t cont_size = 0;
302  VERBOSE(cerr << "Storage: contiguous" << endl);
303 
304  cont_addr = H5Dget_offset(dataset);
305  if (cont_addr < 0) {
306  throw BESInternalError("Cannot obtain the offset.", __FILE__, __LINE__);
307  }
308  cont_size = H5Dget_storage_size(dataset);
309  if (cont_size < 0) {
310  throw BESInternalError("Cannot obtain the storage size.", __FILE__, __LINE__);
311  }
312  VERBOSE(cerr << " Addr: " << cont_addr << endl);
313  VERBOSE(cerr << " Size: " << cont_size << endl);
314 
315  if (dc) dc->add_chunk("", cont_size, cont_addr, "" /*pos in array*/);
316 
317  break;
318  }
319 
320  case H5D_CHUNKED: { /*chunking storage */
321  hsize_t num_chunks = 0;
322  herr_t status = H5Dget_num_chunks(dataset, fspace_id, &num_chunks);
323  if (status < 0) {
324  throw BESInternalError("Could not get the number of chunks",
325  __FILE__, __LINE__);
326  }
327 
328  VERBOSE(cerr << "storage: chunked." << endl);
329  VERBOSE(cerr << "Number of chunks is " << num_chunks << endl);
330 
331  if (dc)
332  set_filter_information(dataset, dc);
333 
334  // Get chunking information: rank and dimensions
335  vector<size_t> chunk_dims(dataset_rank);
336  unsigned int chunk_rank = H5Pget_chunk(dcpl, dataset_rank, (hsize_t*) &chunk_dims[0]);
337  if (chunk_rank != dataset_rank)
338  throw BESNotFoundError("Found a chunk with rank different than the dataset's (aka variables's) rank", __FILE__, __LINE__);
339 
340  if (dc) dc->set_chunk_dimension_sizes(chunk_dims);
341 
342  for (unsigned int i = 0; i < num_chunks; ++i) {
343 
344  vector<hsize_t> temp_coords(dataset_rank);
345  vector<unsigned int> chunk_coords(dataset_rank); //FIXME - see below
346 
347  haddr_t addr = 0;
348  hsize_t size = 0;
349 
350  //H5_DLL herr_t H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t chk_idx, hsize_t *coord, unsigned *filter_mask, haddr_t *addr, hsize_t *size);
351  status = H5Dget_chunk_info(dataset, fspace_id, i, &temp_coords[0], NULL, &addr, &size);
352  if (status < 0) {
353  VERBOSE(cerr << "ERROR" << endl);
354  throw BESInternalError("Cannot get HDF5 dataset storage info.", __FILE__, __LINE__);
355  }
356 
357  VERBOSE(cerr << "chk_idk: " << i << ", addr: " << addr << ", size: " << size << endl);
358 
359  //The coords need to be of type 'unsigned int' when passed into add_chunk()
360  // This loop simply copies the values from the temp_coords to chunk_coords - kln 5/1/19
361  for (unsigned int j = 0; j < chunk_coords.size(); ++j) {
362  chunk_coords[j] = temp_coords[j];
363  }
364 
365  // FIXME Modify add_chunk so that it takes a vector<unsigned long long> or <unsined long>
366  // (depending on the machine/OS/compiler). Limiting the offset to 32-bits won't work
367  // for large files. jhrg 5/21/19
368  if (dc) dc->add_chunk("", size, addr, chunk_coords);
369  }
370 
371  break;
372  }
373 
374  case H5D_COMPACT: { /* Compact storage */
375  //else if (layout_type == 3) {
376  VERBOSE(cerr << "Storage: compact" << endl);
377  size_t comp_size = 0;
378  //if (H5Dget_dataset_compact_storage_info(dataset, &comp_size) < 0) {
379  // throw BESInternalError("Cannot obtain the compact storage info.", __FILE__, __LINE__);
380  //}
381  comp_size = H5Dget_storage_size(dataset);
382  if (comp_size < 0) {
383  throw BESInternalError("Cannot obtain the compact storage size.", __FILE__, __LINE__);
384  }
385  VERBOSE(cerr << " Size: " << comp_size << endl);
386 
387  break;
388  }
389 
390  default: {
391  ostringstream oss("Unsupported HDF5 dataset layout type: ", std::ios::ate);
392  oss << layout_type << ".";
393  BESInternalError(oss.str(), __FILE__, __LINE__);
394  }
395  } // end switch
396  }
397  catch (...) {
398  H5Dclose(dataset);
399  throw;
400  }
401 
402  H5Dclose(dataset);
403 }
404 
412 static void get_chunks_for_all_variables(hid_t file, D4Group *group)
413 {
414  // variables in the group
415  for (Constructor::Vars_iter v = group->var_begin(), ve = group->var_end(); v != ve; ++v) {
416  // if this variable has a 'fullnamepath' attribute, use that and not the
417  // FQN value.
418  D4Attributes *d4_attrs = (*v)->attributes();
419  if (!d4_attrs)
420  throw BESInternalError("Expected to find an attribute table for " + (*v)->name() + " but did not.", __FILE__, __LINE__);
421 
422  // Look for the full name path for this variable
423  // If one was not given via an attribute, use BaseType::FQN() which
424  // relies on the varaible's position in the DAP dataset hierarchy.
425  D4Attribute *attr = d4_attrs->get("fullnamepath");
426  string FQN;
427  if (attr && attr->num_values() == 1)
428  FQN = attr->value(0);
429  else
430  FQN = (*v)->FQN();
431 
432  VERBOSE(cerr << "Working on: " << FQN << endl);
433  hid_t dataset = H5Dopen2(file, FQN.c_str(), H5P_DEFAULT);
434  // It's not an error if a DAP variable in a DMR from the hdf5 handler
435  // doesn't exist in the file _if_ there's no 'fullnamepath' because
436  // that variable was synthesized (likely for CF compliance)
437  if (dataset < 0 && attr == 0)
438  continue;
439  else if (dataset < 0)
440  throw BESInternalError("HDF5 dataset '" + FQN + "' cannot be opened.", __FILE__, __LINE__);
441 
442  get_variable_chunk_info(dataset, dynamic_cast<DmrppCommon*>(*v));
443  }
444 
445  // all groups in the group
446  D4Group::groupsIter g = group->grp_begin();
447  D4Group::groupsIter ge = group->grp_end();
448  while (g != ge)
449  get_chunks_for_all_variables(file, *g++);
450 }
451 
452 int main(int argc, char*argv[])
453 {
454  string h5_file_name = "";
455  string h5_dset_path = "";
456  string dmr_name = "";
457  string url_name = "";
458  int status=0;
459 
460  GetOpt getopt(argc, argv, "c:f:r:u:dhv");
461  int option_char;
462  while ((option_char = getopt()) != -1) {
463  switch (option_char) {
464  case 'v':
465  verbose = true; // verbose hdf5 errors
466  break;
467 
468  case 'd':
469  BESDebug::SetUp(string("cerr,").append(DEBUG_KEY));
470  break;
471 
472  case 'f':
473  h5_file_name = getopt.optarg;
474  break;
475  case 'r':
476  dmr_name = getopt.optarg;
477  break;
478  case 'u':
479  url_name = getopt.optarg;
480  break;
481  case 'c':
482  TheBESKeys::ConfigFile = getopt.optarg;
483  break;
484  case 'h':
485  cerr << "build_dmrpp [-v] -c <bes.conf> -f <data file> [-u <href url>] | build_dmrpp -f <data file> -r <dmr file> | build_dmrpp -h" << endl;
486  exit(1);
487  default:
488  break;
489  }
490  }
491 
492  if (h5_file_name.empty()) {
493  cerr << "HDF5 file name must be given (-f <input>)." << endl;
494  return 1;
495  }
496 
497  hid_t file = 0;
498  try {
499  // Turn off automatic hdf5 error printing.
500  // See: https://support.hdfgroup.org/HDF5/doc1.8/RM/RM_H5E.html#Error-SetAuto2
501  //if (!verbose) H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
502 
503  // For a given HDF5, get info for all the HDF5 datasets in a DMR or for a
504  // given HDF5 dataset
505  if (!dmr_name.empty()) {
506  // Get dmr:
507  auto_ptr<DMRpp> dmrpp(new DMRpp);
508  DmrppTypeFactory dtf;
509  dmrpp->set_factory(&dtf);
510 
511  ifstream in(dmr_name.c_str());
512  D4ParserSax2 parser;
513  parser.intern(in, dmrpp.get(), false);
514 
515  // Open the hdf5 file
516  file = H5Fopen(h5_file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
517  if (file < 0) {
518  cerr << "Error: HDF5 file '" + h5_file_name + "' cannot be opened." << endl;
519  return 1;
520  }
521 
522  // iterate over all the variables in the DMR
523  get_chunks_for_all_variables(file, dmrpp->root());
524 
525  XMLWriter writer;
526  dmrpp->print_dmrpp(writer, url_name);
527 
528  cout << writer.get_doc();
529  }
530  else {
531  bool found;
532  string bes_data_root;
533  try {
534  TheBESKeys::TheKeys()->get_value(ROOT_DIRECTORY, bes_data_root, found);
535  if (!found) {
536  cerr << "Error: Could not find the BES root directory key." << endl;
537  return 1;
538  }
539  }
540  catch (BESError &e) {
541  cerr << "BESError: " << e.get_message() << endl;
542  return 1;
543  }
544 
545  // Use the values from the bes.conf file... jhrg 5/21/18
547  if (!mds) {
548  cerr << "The Metadata Store (MDS) must be configured for this command to work." << endl;
549  return 1;
550  }
551 
552  // Use the full path to open the file, but use the 'name' (which is the
553  // path relative to the BES Data Root) with the MDS.
554  // Changed this to utilze assmeblePath() because simply concatenating the strings
555  // is fragile. - ndp 6/6/18
556  string h5_file_path = BESUtil::assemblePath(bes_data_root,h5_file_name);
557 
558  bes::DmrppMetadataStore::MDSReadLock lock = mds->is_dmr_available(h5_file_name /*h5_file_path*/);
559  if (lock()) {
560  // parse the DMR into a DMRpp (that uses the DmrppTypes)
561  auto_ptr<DMRpp> dmrpp(dynamic_cast<DMRpp*>(mds->get_dmr_object(h5_file_name /*h5_file_path*/)));
562  if (!dmrpp.get()) {
563  cerr << "Expected a DMR++ object from the DmrppMetadataStore." << endl;
564  return 1;
565  }
566 
567  // Open the hdf5 file
568  file = H5Fopen(h5_file_path.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
569  if (file < 0) {
570  cerr << "Error: HDF5 file '" + h5_file_path + "' cannot be opened." << endl;
571  return 1;
572  }
573 
574  get_chunks_for_all_variables(file, dmrpp->root());
575 
576  dmrpp->set_href(url_name);
577 
578  mds->add_dmrpp_response(dmrpp.get(), h5_file_name /*h5_file_path*/);
579 
580  XMLWriter writer;
581  dmrpp->set_print_chunks(true);
582  dmrpp->print_dap4(writer);
583 
584  cout << writer.get_doc();
585  }
586  else {
587  cerr << "Error: Could not get a lock on the DMR for '" + h5_file_path + "'." << endl;
588  return 1;
589  }
590  }
591  }
592  catch (BESError &e) {
593  cerr << "BESError: " << e.get_message() << endl;
594  status = 1;
595  }
596  catch (std::exception &e) {
597  cerr << "std::exception: " << e.what() << endl;
598  status = 1;
599  }
600  catch (...) {
601  cerr << "Unknown error." << endl;
602  status = 1;
603  }
604 
605  H5Fclose(file);
606 
607  return status;
608 }
TheBESKeys::ConfigFile
static std::string ConfigFile
Definition: TheBESKeys.h:147
bes::GlobalMetadataStore::MDSReadLock
Unlock and close the MDS item when the ReadLock goes out of scope.
Definition: GlobalMetadataStore.h:188
dmrpp::DmrppTypeFactory
Definition: DmrppTypeFactory.h:39
BESNotFoundError
error thrown if the resource requested cannot be found
Definition: BESNotFoundError.h:40
BESError::get_message
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
dmrpp::DmrppCommon
Size and offset information of data included in DMR++ files.
Definition: DmrppCommon.h:62
BESUtil::assemblePath
static string assemblePath(const string &firstPart, const string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
Definition: BESUtil.cc:818
dmrpp::DmrppCommon::add_chunk
virtual unsigned long add_chunk(const std::string &data_url, unsigned long long size, unsigned long long offset, std::string position_in_array="")
Add a new chunk as defined by an h4:byteStream element.
Definition: DmrppCommon.cc:153
BESDebug::SetUp
static void SetUp(const std::string &values)
Sets up debugging for the bes.
Definition: BESDebug.cc:64
bes::DmrppMetadataStore::get_dmr_object
virtual libdap::DMR * get_dmr_object(const string &name)
Use the DMR response to build a DMR with Dmrpp Types.
Definition: DmrppMetadataStore.cc:242
libdap
Definition: BESDapFunctionResponseCache.h:35
TheBESKeys::TheKeys
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:61
bes::DmrppMetadataStore::get_instance
static DmrppMetadataStore * get_instance()
Definition: DmrppMetadataStore.cc:137
dmrpp::DmrppCommon::set_deflate
void set_deflate(bool value)
Set the value of the deflate property.
Definition: DmrppCommon.h:112
dmrpp::DmrppCommon::set_shuffle
void set_shuffle(bool value)
Set the value of the shuffle property.
Definition: DmrppCommon.h:122
bes::DmrppMetadataStore
Store the DAP DMR++ metadata responses.
Definition: DmrppMetadataStore.h:83
BESInternalError
exception thrown if inernal error encountered
Definition: BESInternalError.h:43
TheBESKeys::get_value
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:420
dmrpp::DmrppCommon::set_chunk_dimension_sizes
void set_chunk_dimension_sizes(const std::vector< size_t > &chunk_dims)
Set the value of the chunk dimension sizes given a vector of HDF5 hsize_t.
Definition: DmrppCommon.h:155
dmrpp::DMRpp
Provide a way to print the DMR++ response.
Definition: DMRpp.h:42
BESError
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
bes::GlobalMetadataStore::is_dmr_available
virtual MDSReadLock is_dmr_available(const std::string &name)
Is the DMR response for.
Definition: GlobalMetadataStore.cc:752