OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
FONcTransform.cc
Go to the documentation of this file.
1 // FONcTransform.cc
2 
3 // This file is part of BES Netcdf File Out Module
4 
5 // Copyright (c) 2004,2005 University Corporation for Atmospheric Research
6 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
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 University Corporation for Atmospheric Research at
23 // 3080 Center Green Drive, Boulder, CO 80301
24 
25 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
26 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
27 //
28 // Authors:
29 // pwest Patrick West <pwest@ucar.edu>
30 // jgarcia Jose Garcia <jgarcia@ucar.edu>
31 
32 #include "config.h"
33 
34 #include <sstream>
35 
36 using std::ostringstream;
37 using std::istringstream;
38 
39 #include "FONcTransform.h"
40 #include "FONcUtils.h"
41 #include "FONcBaseType.h"
42 #include "FONcAttributes.h"
43 
44 #include <DDS.h>
45 #include <Structure.h>
46 #include <Array.h>
47 #include <Grid.h>
48 #include <Sequence.h>
49 #include <BESDebug.h>
50 #include <BESInternalError.h>
51 
52 #define ATTRIBUTE_SEPARATOR "."
53 #define FONC_ORIGINAL_NAME "fonc_original_name"
54 
55 #define RETURNAS_NETCDF "netcdf"
56 #define RETURNAS_NETCDF4 "netcdf-4"
57 
58 
70 FONcTransform::FONcTransform(DDS *dds, BESDataHandlerInterface &dhi, const string &localfile, const string &ncVersion) :
71  _ncid(0), _dds(0)
72 {
73  if (!dds) {
74  string s = (string) "File out netcdf, " + "null DDS passed to constructor";
75  throw BESInternalError(s, __FILE__, __LINE__);
76  }
77  if (localfile.empty()) {
78  string s = (string) "File out netcdf, " + "empty local file name passed to constructor";
79  throw BESInternalError(s, __FILE__, __LINE__);
80  }
81  _localfile = localfile;
82  _dds = dds;
83  _returnAs = ncVersion;
84 
85  // if there is a variable, attribute, dimension name that is not
86  // compliant with netcdf naming conventions then we will create
87  // a new name. If the new name does not begin with an alpha
88  // character then we will prefix it with name_prefix. We will
89  // get this prefix from the type of data that we are reading in,
90  // such as nc, h4, h5, ff, jg, etc...
91  dhi.first_container();
92  if (dhi.container) {
94  }
95  else {
96  FONcUtils::name_prefix = "nc_";
97  }
98 }
99 
105 {
106  bool done = false;
107  while (!done) {
108  vector<FONcBaseType *>::iterator i = _fonc_vars.begin();
109  vector<FONcBaseType *>::iterator e = _fonc_vars.end();
110  if (i == e) {
111  done = true;
112  }
113  else {
114  // These are the FONc types, not the actual ones
115  FONcBaseType *b = (*i);
116  delete b;
117  _fonc_vars.erase(i);
118  }
119  }
120 }
121 
131 {
133 
134  // Convert the DDS into an internal format to keep track of
135  // variables, arrays, shared dimensions, grids, common maps,
136  // embedded structures. It only grabs the variables that are to be
137  // sent.
138  DDS::Vars_iter vi = _dds->var_begin();
139  DDS::Vars_iter ve = _dds->var_end();
140  for (; vi != ve; vi++) {
141  if ((*vi)->send_p()) {
142  BaseType *v = *vi;
143  BESDEBUG("fonc", "converting " << v->name() << endl);
145  fb->setVersion( FONcTransform::_returnAs );
146  _fonc_vars.push_back(fb);
147  vector<string> embed;
148  fb->convert(embed);
149  }
150  }
151  BESDEBUG("fonc", *this << endl);
152 
153  // Open the file for writing
154  int stax;
155 
156 
157  if ( FONcTransform::_returnAs == RETURNAS_NETCDF4 ) {
158  stax = nc_create(_localfile.c_str(), NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &_ncid);
159  }
160  else {
161  stax = nc_create(_localfile.c_str(), NC_CLOBBER, &_ncid);
162  }
163 
164  if (stax != NC_NOERR) {
165  string err = (string) "File out netcdf, " + "unable to open file " + _localfile;
166  FONcUtils::handle_error(stax, err, __FILE__, __LINE__);
167  }
168 
169  try {
170  // Here we will be defining the variables of the netcdf and
171  // adding attributes. To do this we must be in define mode.
172  nc_redef(_ncid);
173 
174  // For each conerted FONc object, call define on it to define
175  // that object to the netcdf file. This also adds the attributes
176  // for the variables to the netcdf file
177  vector<FONcBaseType *>::iterator i = _fonc_vars.begin();
178  vector<FONcBaseType *>::iterator e = _fonc_vars.end();
179  for (; i != e; i++) {
180  FONcBaseType *fbt = *i;
181  fbt->define(_ncid);
182  }
183 
184  // Add any global attributes to the netcdf file
185  AttrTable &globals = _dds->get_attr_table();
186  BESDEBUG("fonc", "Adding Global Attributes" << endl << globals << endl);
187  FONcAttributes::addattrs(_ncid, NC_GLOBAL, globals, "", "");
188 
189  // We are done defining the variables, dimensions, and
190  // attributes of the netcdf file. End the define mode.
191  int stax = nc_enddef(_ncid);
192 
193  // Check error for nc_enddef. Handling of HDF failures
194  // can be detected here rather than later. KY 2012-10-25
195  if (stax != NC_NOERR) {
196  string err = (string) "File out netcdf, " + "unable to end the define mode " + _localfile;
197  FONcUtils::handle_error(stax, err, __FILE__, __LINE__);
198  }
199 
200  // Write everything out
201  i = _fonc_vars.begin();
202  e = _fonc_vars.end();
203  for (; i != e; i++) {
204  FONcBaseType *fbt = *i;
205  fbt->write(_ncid);
206  }
207  }
208  catch (BESError &e) {
209  nc_close(_ncid);
210  throw;
211  }
212 
213  nc_close(_ncid);
214 }
215 
225 void FONcTransform::dump(ostream &strm) const
226 {
227  strm << BESIndent::LMarg << "FONcTransform::dump - (" << (void *) this << ")" << endl;
229  strm << BESIndent::LMarg << "ncid = " << _ncid << endl;
230  strm << BESIndent::LMarg << "temporary file = " << _localfile << endl;
232  vector<FONcBaseType *>::const_iterator i = _fonc_vars.begin();
233  vector<FONcBaseType *>::const_iterator e = _fonc_vars.end();
234  for (; i != e; i++) {
235  FONcBaseType *fbt = *i;
236  fbt->dump(strm);
237  }
240 }
241 
exception thrown if inernal error encountered
#define RETURNAS_NETCDF4
virtual void dump(ostream &strm) const =0
dump the contents of this object to the specified ostream
virtual ~FONcTransform()
Destructor.
string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:208
virtual void define(int ncid)
Define the variable in the netcdf file.
Definition: FONcBaseType.cc:58
static void Indent()
Definition: BESIndent.cc:38
virtual void dump(ostream &strm) const
dumps information about this transformation object for debugging purposes
static string name_prefix
If a variable name, dimension name, or attribute name begins with a character that is not supported b...
Definition: FONcUtils.h:58
Abstract exception class for the BES with basic string message.
Definition: BESError.h:51
FONcTransform(DDS *dds, BESDataHandlerInterface &dhi, const string &localfile, const string &netcdfVersion="netcdf")
Build a FONcTransform object.
static ostream & LMarg(ostream &strm)
Definition: BESIndent.cc:73
static void handle_error(int stax, string &err, const string &file, int line)
handle any netcdf errors
Definition: FONcUtils.cc:238
virtual void transform()
Transforms each of the variables of the DataDDS to the NetCDF file.
static void reset()
Resets the FONc transformation for a new input and out file.
Definition: FONcUtils.cc:56
virtual void write(int)
Definition: FONcBaseType.h:65
A DAP BaseType with file out netcdf information included.
Definition: FONcBaseType.h:48
Structure storing information used by the BES to handle the request.
void first_container()
set the container pointer to the first container in the containers list
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
static FONcBaseType * convert(BaseType *v)
creates a FONc object for the given DAP object
Definition: FONcUtils.cc:178
static void UnIndent()
Definition: BESIndent.cc:44
BESContainer * container
pointer to current container in this interface