bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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
40using namespace libdap;
41
42void FONcBaseType::convert(const vector<string> embed, bool _dap4, bool dap4_group)
43{
44 d_embed = embed;
45 d_varname = name();
46 d_is_dap4_group = dap4_group;
47 d_is_dap4 = _dap4;
48}
49
61{
62 if (!d_defined) {
63 d_varname = FONcUtils::gen_name(d_embed, d_varname, d_orig_varname);
64 BESDEBUG("fonc", "FONcBaseType::define - defining '" << d_varname << "'" << endl);
65 int stax = nc_def_var(ncid, d_varname.c_str(), type(), 0, nullptr, &d_varid);
66 if (stax != NC_NOERR) {
67 string err = (string) "fileout.netcdf - " + "Failed to define variable " + d_varname;
68 FONcUtils::handle_error(stax, err, __FILE__, __LINE__);
69 }
70 stax = nc_def_var_fill(ncid, d_varid, NC_NOFILL, NULL );
71 if (stax != NC_NOERR) {
72 string err = (string) "fileout.netcdf - " + "Failed to clear fill value for " + d_varname;
73 FONcUtils::handle_error(stax, err, __FILE__, __LINE__);
74 }
75
76 BESDEBUG("fonc", "FONcBaseType::define - done defining " << d_varname << endl);
77 }
78}
79
87{
88 return NC_NAT; // the constant ncdf uses to define simple type
89}
90
94{
95 d_embed.clear();
96}
97
100void FONcBaseType::setVersion(const string &version)
101{
102 d_ncVersion = version;
103
104 BESDEBUG("fonc", "FONcBaseType::setVersion() - version: '" << d_ncVersion << "'" << endl);
105}
106
109void FONcBaseType::setNC4DataModel(const string &nc4_datamodel)
110{
111 d_nc4_datamodel = nc4_datamodel;
112
113 BESDEBUG("fonc", "FONcBaseType::setNC4DataModel() - data model: '" << d_nc4_datamodel << "'" << endl);
114}
115
119{
120 return FONcBaseType::d_ncVersion == FONC_RETURN_AS_NETCDF4;
121}
122
123bool FONcBaseType::isNetCDF4_ENHANCED()
124{
125 return FONcBaseType::d_nc4_datamodel == FONC_NC4_ENHANCED;
126}
127
128void 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
144void 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.
163libdap::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..
211D4AttributeType FONcBaseType::getD4AttrType(nc_type nct)
212{
213 D4AttributeType atype = attr_null_c;
214 switch (nct) {
215 case NC_BYTE:
216 // netCDF-classic also supports 8-bit signed integer
217 atype = attr_int8_c;
218 break;
219 case NC_SHORT:
220 atype = attr_int16_c;
221 break;
222 case NC_INT:
223 atype = attr_int32_c;
224 break;
225 case NC_FLOAT:
226 atype = attr_float32_c;
227 break;
228 case NC_DOUBLE:
229 atype = attr_float64_c;
230 break;
231 case NC_UBYTE:
232 atype = attr_byte_c;
233 break;
234 case NC_USHORT:
235 if (isNetCDF4_ENHANCED())
236 atype = attr_uint16_c;
237 else
238 atype = attr_int32_c;
239 break;
240 case NC_UINT:
241 if (isNetCDF4_ENHANCED())
242 atype = attr_uint32_c;
243 break;
244 case NC_INT64:
245 if (isNetCDF4_ENHANCED())
246 atype = attr_int64_c;
247 break;
248 case NC_UINT64:
249 if (isNetCDF4_ENHANCED())
250 atype = attr_uint64_c;
251 break;
252 case NC_CHAR:
253 case NC_STRING:
254 atype = attr_str_c;
255 break;
256 default:;
257 }
258
259 if(atype == attr_null_c)
260 throw BESInternalError("Cannot convert unknown netCDF attribute type", __FILE__, __LINE__);
261
262 return atype;
263}
virtual void define(int ncid)
Define the variable in the netcdf file.
virtual bool isNetCDF4()
Returns true if NetCDF4 features will be required.
virtual nc_type type()
Returns the type of data of this variable.
virtual void clear_embedded()
Clears the list of embedded variable names.
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:429
static string gen_name(const vector< string > &embed, const string &name, string &original)
generate a new name for the embedded variable
Definition FONcUtils.cc:182
STL class.
STL class.