bes  Updated for version 3.20.10
FONcBaseType.cc
1 // FONcBaseType.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 <libdap/D4Attributes.h>
33 
34 #include <BESInternalError.h>
35 #include <BESDebug.h>
36 
37 #include "FONcBaseType.h"
38 #include "FONcUtils.h"
39 
40 using namespace libdap;
41 
42 void FONcBaseType::convert(const vector<string> embed, bool _dap4, bool dap4_group)
43 {
44  _embed = embed;
45  _varname = name();
46  is_dap4_group = dap4_group;
47  is_dap4 = _dap4;
48 }
49 
60 void FONcBaseType::define(int ncid)
61 {
62  if (!_defined) {
63  _varname = FONcUtils::gen_name(_embed, _varname, _orig_varname);
64  BESDEBUG("fonc", "FONcBaseType::define - defining '" << _varname << "'" << endl);
65  int stax = nc_def_var(ncid, _varname.c_str(), type(), 0, nullptr, &_varid);
66  if (stax != NC_NOERR) {
67  string err = (string) "fileout.netcdf - " + "Failed to define variable " + _varname;
68  FONcUtils::handle_error(stax, err, __FILE__, __LINE__);
69  }
70  stax = nc_def_var_fill(ncid, _varid, NC_NOFILL, NULL );
71  if (stax != NC_NOERR) {
72  string err = (string) "fileout.netcdf - " + "Failed to clear fill value for " + _varname;
73  FONcUtils::handle_error(stax, err, __FILE__, __LINE__);
74  }
75 
76  BESDEBUG("fonc", "FONcBaseType::define - done defining " << _varname << endl);
77  }
78 }
79 
87 {
88  return NC_NAT; // the constant ncdf uses to define simple type
89 }
90 
94 {
95  _embed.clear();
96 }
97 
100 void FONcBaseType::setVersion(const string &version)
101 {
102  _ncVersion = version;
103 
104  BESDEBUG("fonc", "FONcBaseType::setVersion() - version: '" << _ncVersion << "'" << endl);
105 }
106 
109 void FONcBaseType::setNC4DataModel(const string &nc4_datamodel)
110 {
111  _nc4_datamodel = nc4_datamodel;
112 
113  BESDEBUG("fonc", "FONcBaseType::setNC4DataModel() - data model: '" << _nc4_datamodel << "'" << endl);
114 }
115 
119 {
120  return FONcBaseType::_ncVersion == RETURN_AS_NETCDF4;
121 }
122 
123 bool FONcBaseType::isNetCDF4_ENHANCED()
124 {
125  return FONcBaseType::_nc4_datamodel == NC4_ENHANCED;
126 }
127 
128 void FONcBaseType::updateD4AttrType(libdap::D4Attributes *d4_attrs, nc_type t)
129 {
130  for (auto ii = d4_attrs->attribute_begin(), ee = d4_attrs->attribute_end(); ii != ee; ++ii) {
131  if ((*ii)->name() == _FillValue) {
132  BESDEBUG("fonc", "FONcBaseType - attrtype " << getD4AttrType(t) << endl);
133  BESDEBUG("fonc", "FONcBaseType - attr_type " << (*ii)->type() << endl);
134  D4AttributeType correct_d4_attr_type = getD4AttrType(t);
135  if (correct_d4_attr_type != (*ii)->type())
136  (*ii)->set_type(correct_d4_attr_type);
137  break;
138  }
139  }
140 
141 
142 }
143 
144 void FONcBaseType::updateAttrType(libdap::AttrTable &attrs, nc_type t)
145 {
146  if (attrs.get_size()) {
147  for (auto iter = attrs.attr_begin(); iter != attrs.attr_end(); iter++) {
148  if (attrs.get_name(iter) == _FillValue) {
149  BESDEBUG("fonc", "FONcBaseType - attrtype " << getAttrType(t) << endl);
150  BESDEBUG("fonc", "FONcBaseType - attr_type " << attrs.get_attr_type(iter) << endl);
151  if (getAttrType(t) != attrs.get_attr_type(iter)) {
152  (*iter)->type = getAttrType(t);
153  }
154  break;
155  }
156  }
157  }
158 
159 }
160 
161 // This function is only used for handling _FillValue now. But it is a general routine that can be
162 // used for other purposes.
163 libdap::AttrType FONcBaseType::getAttrType(nc_type nct)
164 {
165  BESDEBUG("fonc", "FONcArray getAttrType " << endl);
166  libdap::AttrType atype = Attr_unknown;
167  switch (nct) {
168 
169  case NC_SHORT:
170  // The original code maps to Attr_byte. This is not right. Attr_byte is uint8, NC_BYTE is int8.
171  // Change to 16-bit integer to be consistent with other parts for the classic model.
172  // Note; In DAP2, no 8-bit integer type. So regardless the netCDF model, this has to be
173  // Attr_int16.
174  atype = Attr_int16;
175  break;
176  case NC_INT:
177  atype = Attr_int32;
178  break;
179  case NC_FLOAT:
180  atype = Attr_float32;
181  break;
182  case NC_DOUBLE:
183  atype = Attr_float64;
184  break;
185  case NC_UBYTE:
186  atype = Attr_byte;
187  break;
188  case NC_USHORT:
189  if (isNetCDF4_ENHANCED())
190  atype = Attr_uint16;
191  else
192  atype = Attr_int32;
193  break;
194  case NC_UINT:
195  if (isNetCDF4_ENHANCED())
196  atype = Attr_uint32;
197  break;
198  case NC_CHAR:
199  case NC_STRING:
200  atype = Attr_string;
201  break;
202  default:;
203  }
204  //Note: For DAP2, NC_BYTE(8-bit integer),NC_INT64,NC_UINT64 are not supported. So they should not
205  // appear here. NC_UINT is not supported by the classic model.
206  // So here we also treat it unknown type.
207  return atype;
208 }
209 
210 // Obtain DAP4 attribute type for both classic and enhanced model..
211 D4AttributeType FONcBaseType::getD4AttrType(nc_type nct)
212 {
213  D4AttributeType atype = attr_null_c;
214  switch (nct) {
215  case NC_BYTE:
216  if (isNetCDF4_ENHANCED())
217  atype = attr_int8_c;
218  else
219  atype = attr_int16_c;
220  break;
221  case NC_SHORT:
222  atype = attr_int16_c;
223  break;
224  case NC_INT:
225  atype = attr_int32_c;
226  break;
227  case NC_FLOAT:
228  atype = attr_float32_c;
229  break;
230  case NC_DOUBLE:
231  atype = attr_float64_c;
232  break;
233  case NC_UBYTE:
234  atype = attr_byte_c;
235  break;
236  case NC_USHORT:
237  if (isNetCDF4_ENHANCED())
238  atype = attr_uint16_c;
239  else
240  atype = attr_int32_c;
241  break;
242  case NC_UINT:
243  if (isNetCDF4_ENHANCED())
244  atype = attr_uint32_c;
245  break;
246  case NC_INT64:
247  if (isNetCDF4_ENHANCED())
248  atype = attr_int64_c;
249  break;
250  case NC_UINT64:
251  if (isNetCDF4_ENHANCED())
252  atype = attr_uint64_c;
253  break;
254  case NC_CHAR:
255  case NC_STRING:
256  atype = attr_str_c;
257  break;
258  default:;
259  }
260 
261  if(atype == attr_null_c)
262  throw BESInternalError("Cannot convert unknown netCDF attribute type", __FILE__, __LINE__);
263 
264  return atype;
265 }
exception thrown if internal error encountered
virtual void define(int ncid)
Define the variable in the netcdf file.
Definition: FONcBaseType.cc:60
virtual bool isNetCDF4()
Returns true if NetCDF4 features will be required.
virtual nc_type type()
Returns the type of data of this variable.
Definition: FONcBaseType.cc:86
virtual void clear_embedded()
Clears the list of embedded variable names.
Definition: FONcBaseType.cc:93
virtual void setNC4DataModel(const string &nc4_datamodel)
Identifies the netCDF4 data model (CLASSIC or ENHANCED)
virtual void setVersion(const std::string &version)
Identifies variable with use of NetCDF4 features.
static void handle_error(int stax, const string &err, const string &file, int line)
handle any netcdf errors
Definition: FONcUtils.cc:424
static string gen_name(const vector< string > &embed, const string &name, string &original)
generate a new name for the embedded variable
Definition: FONcUtils.cc:179