Commit 5ddc9ffe0f40411a34772747f9e216a31cbe4696
1 parent
03e8f845
Exists in
master
and in
98 other branches
NetCDF file reader for LocalFileInterface
Showing
9 changed files
with
390 additions
and
11 deletions
Show diff stats
config/xsd/localbase/base.xsd
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | <xs:enumeration value="ASCII" /> |
22 | 22 | <xs:enumeration value="CDF" /> |
23 | 23 | <xs:enumeration value="VOT" /> |
24 | + <xs:enumeration value="NC" /> | |
24 | 25 | </xs:restriction> |
25 | 26 | </xs:simpleType> |
26 | 27 | </xs:attribute> |
... | ... | @@ -33,4 +34,4 @@ |
33 | 34 | <xs:attribute name="start" type="xs:string" use="required" /> |
34 | 35 | <xs:attribute name="stop" type="xs:string" use="required" /> |
35 | 36 | </xs:complexType> |
36 | -</xs:schema> | |
37 | 37 | \ No newline at end of file |
38 | +</xs:schema> | ... | ... |
src/ParamGetImpl/LocalFileInterface/FileReaderNetCDF.cc
... | ... | @@ -18,6 +18,7 @@ namespace LocalFileInterface { |
18 | 18 | |
19 | 19 | FileReaderNetCDF::FileReaderNetCDF() |
20 | 20 | { |
21 | + resetFile(); | |
21 | 22 | } |
22 | 23 | |
23 | 24 | FileReaderNetCDF::~FileReaderNetCDF() |
... | ... | @@ -26,38 +27,170 @@ FileReaderNetCDF::~FileReaderNetCDF() |
26 | 27 | |
27 | 28 | bool FileReaderNetCDF::open(std::string filePath) |
28 | 29 | { |
29 | - return false; | |
30 | + boost::mutex::scoped_lock scoped_lock(AMDA::Parameters::ParameterManager::mutexNetCDFLib); | |
31 | + if (isOpened()) { | |
32 | + return true; | |
33 | + } | |
34 | + | |
35 | + int status = nc_open(filePath.c_str(), 0, &_file.id); | |
36 | + if (status != NC_NOERR) { | |
37 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::open - Cannot open netCDF file : " << getErrorMessage(status)) | |
38 | + resetFile(); | |
39 | + return false; | |
40 | + } | |
41 | + return loadNetCDFFileInfo(); | |
30 | 42 | } |
31 | 43 | |
32 | 44 | bool FileReaderNetCDF::close(void) |
33 | 45 | { |
34 | - return false; | |
46 | + boost::mutex::scoped_lock scoped_lock(AMDA::Parameters::ParameterManager::mutexNetCDFLib); | |
47 | + if (!isOpened()) { | |
48 | + return true; | |
49 | + } | |
50 | + int status = nc_close(_file.id); | |
51 | + if (status != NC_NOERR) { | |
52 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::close - Cannot close netCDF file : " << getErrorMessage(status)) | |
53 | + return false; | |
54 | + } | |
55 | + resetFile(); | |
56 | + return true; | |
35 | 57 | } |
36 | 58 | |
37 | 59 | bool FileReaderNetCDF::isOpened(void) |
38 | 60 | { |
39 | - return false; | |
61 | + return (_file.id != 0); | |
40 | 62 | } |
41 | 63 | |
42 | 64 | std::string FileReaderNetCDF::getTimeParamId(void) |
43 | 65 | { |
66 | + if (!isOpened()) { | |
67 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::getTimeParamId - File not opened") | |
68 | + return ""; | |
69 | + } | |
70 | + | |
71 | + for (std::vector<NetCDFVar>::iterator it = _file.vars.begin(); it != _file.vars.end(); ++it) { | |
72 | + std::string name = it->name; | |
73 | + std::transform(name.begin(), name.end(), name.begin(), ::tolower); | |
74 | + if ((std::strcmp(name.c_str(),"time") == 0) && (it->type == NC_DOUBLE)) { | |
75 | + return it->name; | |
76 | + } | |
77 | + } | |
78 | + | |
79 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::getTimeParamId - Cannot find the time variable") | |
44 | 80 | return ""; |
45 | 81 | } |
46 | 82 | |
47 | 83 | bool FileReaderNetCDF::getParamInfo(std::string& paramId, LocalParamType& paramType, int& dim1Size, int& dim2Size) |
48 | 84 | { |
49 | - return false; | |
85 | + for (std::vector<NetCDFVar>::iterator it = _file.vars.begin(); it != _file.vars.end(); ++it) { | |
86 | + if (std::strcmp(it->name, paramId.c_str()) == 0) { | |
87 | + if (it->dimids.size() == 1) { | |
88 | + //scalar | |
89 | + dim1Size = 1; | |
90 | + dim2Size = 1; | |
91 | + } | |
92 | + else if (it->dimids.size() == 2) { | |
93 | + //vector | |
94 | + dim1Size = _file.dims[it->dimids[1]].length; | |
95 | + dim2Size = 1; | |
96 | + } | |
97 | + else if (it->dimids.size() == 3) { | |
98 | + //Tab2D | |
99 | + dim1Size = _file.dims[it->dimids[1]].length; | |
100 | + dim2Size = _file.dims[it->dimids[2]].length; | |
101 | + } | |
102 | + else { | |
103 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::getParamInfo - Variable dimensions not supported") | |
104 | + return false; | |
105 | + } | |
106 | + switch (it->type) { | |
107 | + case NC_FLOAT : | |
108 | + paramType = LocalParamType::TYPE_FLOAT; | |
109 | + break; | |
110 | + case NC_DOUBLE : | |
111 | + paramType = LocalParamType::TYPE_DOUBLE; | |
112 | + break; | |
113 | + case NC_SHORT : | |
114 | + paramType = LocalParamType::TYPE_SHORT; | |
115 | + break; | |
116 | + case NC_INT : | |
117 | + paramType = LocalParamType::TYPE_INT; | |
118 | + break; | |
119 | + default: | |
120 | + paramType = LocalParamType::TYPE_UNKNOWN; | |
121 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::getParamInfo - Unknown variable type") | |
122 | + return false; | |
123 | + } | |
124 | + } | |
125 | + } | |
126 | + return true; | |
50 | 127 | } |
51 | 128 | |
52 | 129 | int FileReaderNetCDF::getRecordIndex(std::string& timeId, double time) |
53 | 130 | { |
131 | + boost::mutex::scoped_lock scoped_lock(AMDA::Parameters::ParameterManager::mutexNetCDFLib); | |
132 | + for (std::vector<NetCDFVar>::iterator it = _file.vars.begin(); it != _file.vars.end(); ++it) { | |
133 | + if (std::strcmp(it->name, timeId.c_str()) == 0) { | |
134 | + if (!loadData(*it)) { | |
135 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::getRecordIndex - Cannot load time data") | |
136 | + return -1; | |
137 | + } | |
138 | + double* buffer = (double*)it->buffer; | |
139 | + for (int i = 0; i < getNbVarRecords(*it); ++i) { | |
140 | + if (time <= buffer[i]) { | |
141 | + return i; | |
142 | + } | |
143 | + } | |
144 | + } | |
145 | + } | |
54 | 146 | return -1; |
55 | 147 | } |
56 | 148 | |
57 | 149 | FileReaderStatus FileReaderNetCDF::getParamPacketData(std::string& timeId, std::string& paramId, |
58 | 150 | int recordIndex, double stopTime, LocalParamDataPacket *packet) |
59 | 151 | { |
60 | - return FRS_ERROR; | |
152 | + boost::mutex::scoped_lock scoped_lock(AMDA::Parameters::ParameterManager::mutexNetCDFLib); | |
153 | + | |
154 | + NetCDFVar* timeVar = NULL; | |
155 | + NetCDFVar* paramVar = NULL; | |
156 | + for (std::vector<NetCDFVar>::iterator it = _file.vars.begin(); it != _file.vars.end(); ++it) { | |
157 | + if (std::strcmp(it->name, timeId.c_str()) == 0) { | |
158 | + timeVar = &(*it); | |
159 | + } | |
160 | + if (std::strcmp(it->name, paramId.c_str()) == 0) { | |
161 | + paramVar = &(*it); | |
162 | + } | |
163 | + } | |
164 | + | |
165 | + if ((timeVar == NULL) || (paramVar == NULL)) { | |
166 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::getParamPacketData - Cannot retrieve time or param variable") | |
167 | + return FRS_ERROR; | |
168 | + } | |
169 | + | |
170 | + if (!loadData(*timeVar) || !loadData(*paramVar)) { | |
171 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::getParamPacketData - Cannot load time or param data") | |
172 | + return FRS_ERROR; | |
173 | + } | |
174 | + | |
175 | + double* time_buffer = (double*)timeVar->buffer; | |
176 | + bool packetFull = false; | |
177 | + int nbValues = getNbVarValuesByRecord(*paramVar); | |
178 | + for (int i = recordIndex; i < getNbVarRecords(*paramVar); ++i) { | |
179 | + double crtTime = time_buffer[i]; | |
180 | + void* pos = (void*)((char*)paramVar->buffer + paramVar->valuesize * nbValues * i); | |
181 | + if (crtTime > stopTime) { | |
182 | + return FRS_FINISH; | |
183 | + } | |
184 | + if (!packet->addData(crtTime, pos, packetFull)) | |
185 | + { | |
186 | + if (packetFull) | |
187 | + return FRS_MORE; | |
188 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::getParamPacketData - Error to add data in packet"); | |
189 | + return FRS_ERROR; | |
190 | + } | |
191 | + } | |
192 | + | |
193 | + return FRS_EOF; | |
61 | 194 | } |
62 | 195 | |
63 | 196 | bool FileReaderNetCDF::getInfo(const char* /*pInfoName*/, std::vector<double>& /*res*/) |
... | ... | @@ -65,5 +198,167 @@ bool FileReaderNetCDF::getInfo(const char* /*pInfoName*/, std::vector<double>& / |
65 | 198 | return false; |
66 | 199 | } |
67 | 200 | |
201 | +void FileReaderNetCDF::resetFile() { | |
202 | + _file.id = 0; | |
203 | + _file.dims.clear(); | |
204 | + for (std::vector<NetCDFVar>::iterator it = _file.vars.begin(); it != _file.vars.end(); ++it) { | |
205 | + if (it->buffer != NULL) { | |
206 | + std::free(it->buffer); | |
207 | + it->buffer = NULL; | |
208 | + } | |
209 | + } | |
210 | + _file.vars.clear(); | |
211 | + _file.atts.clear(); | |
212 | +} | |
213 | + | |
214 | +bool FileReaderNetCDF::loadNetCDFFileInfo() { | |
215 | + if (!isOpened()) { | |
216 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadNetCDFFileInfo - File not opened") | |
217 | + return false; | |
218 | + } | |
219 | + | |
220 | + int status, ndims, nvars, ngatts, unlimdimid; | |
221 | + status = nc_inq(_file.id, &ndims, &nvars, &ngatts, &unlimdimid); | |
222 | + | |
223 | + if (status != NC_NOERR) { | |
224 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadNetCDFFileInfo - Cannot load info in netCDF file : " << getErrorMessage(status)) | |
225 | + return false; | |
226 | + } | |
227 | + | |
228 | + //Load dims | |
229 | + for (int i = 0; i < ndims; ++i) { | |
230 | + NetCDFDim dim; | |
231 | + status = nc_inq_dim(_file.id, i, dim.name, &dim.length); | |
232 | + if (status != NC_NOERR) { | |
233 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadNetCDFFileInfo - Cannot load dimension info : " << getErrorMessage(status)) | |
234 | + return false; | |
235 | + } | |
236 | + dim.isUnlimited = (i == unlimdimid); | |
237 | + _file.dims.push_back(dim); | |
238 | + } | |
239 | + | |
240 | + //Load global attributes | |
241 | + for (int i = 0; i < ngatts; ++i) { | |
242 | + NetCDFAtt att; | |
243 | + status = nc_inq_attname(_file.id, NC_GLOBAL, i, att.name); | |
244 | + if (status != NC_NOERR) { | |
245 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadNetCDFFileInfo - Cannot load global attribute name : " << getErrorMessage(status)) | |
246 | + return false; | |
247 | + } | |
248 | + status = nc_inq_att(_file.id, NC_GLOBAL, att.name, &att.type, &att.length); | |
249 | + if (status != NC_NOERR) { | |
250 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadNetCDFFileInfo - Cannot load global attribute info : " << getErrorMessage(status)) | |
251 | + return false; | |
252 | + } | |
253 | + _file.atts.push_back(att); | |
254 | + } | |
255 | + | |
256 | + //Load variables | |
257 | + for (int i = 0; i < nvars; ++i) { | |
258 | + int natts; | |
259 | + int ndims; | |
260 | + int dimids[NC_MAX_VAR_DIMS]; | |
261 | + NetCDFVar var; | |
262 | + var.buffer = NULL; | |
263 | + status = nc_inq_var(_file.id, i, var.name, &var.type, &ndims, dimids, &natts); | |
264 | + if (status != NC_NOERR) { | |
265 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadNetCDFFileInfo - Cannot load variable info : " << getErrorMessage(status)) | |
266 | + return false; | |
267 | + } | |
268 | + if (ndims > 3) { | |
269 | + //Not supported by the kernel | |
270 | + continue; | |
271 | + } | |
272 | + for (int j = 0; j < ndims; ++j) { | |
273 | + var.dimids.push_back(dimids[j]); | |
274 | + } | |
275 | + //Load variable attributes | |
276 | + for (int j = 0; j < natts; ++j) { | |
277 | + NetCDFAtt att; | |
278 | + status = nc_inq_attname(_file.id, i, j, att.name); | |
279 | + if (status != NC_NOERR) { | |
280 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadNetCDFFileInfo - Cannot load variable attribute : " << getErrorMessage(status)) | |
281 | + return false; | |
282 | + } | |
283 | + status = nc_inq_att(_file.id, i, att.name, &att.type, &att.length); | |
284 | + if (status != NC_NOERR) { | |
285 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadNetCDFFileInfo - Cannot load variable attribute : " << getErrorMessage(status)) | |
286 | + return false; | |
287 | + } | |
288 | + var.atts.push_back(att); | |
289 | + } | |
290 | + _file.vars.push_back(var); | |
291 | + } | |
292 | + return true; | |
293 | +} | |
294 | + | |
295 | +int FileReaderNetCDF::getNbVarValuesByRecord(const NetCDFVar& var) { | |
296 | + if (var.dimids.size() == 1) { | |
297 | + //scalar | |
298 | + return 1; | |
299 | + } | |
300 | + else if (var.dimids.size() == 2) { | |
301 | + //vector | |
302 | + return _file.dims[var.dimids[1]].length; | |
303 | + } | |
304 | + else if (var.dimids.size() == 3) { | |
305 | + //tab2d | |
306 | + return _file.dims[var.dimids[1]].length * _file.dims[var.dimids[2]].length; | |
307 | + } | |
308 | + return 1; | |
309 | +} | |
310 | + | |
311 | +int FileReaderNetCDF::getNbVarRecords(const NetCDFVar& var) { | |
312 | + if (var.dimids.size() < 1) | |
313 | + return 0; | |
314 | + return _file.dims[var.dimids[0]].length; | |
315 | +} | |
316 | + | |
317 | +bool FileReaderNetCDF::loadData(NetCDFVar& var) { | |
318 | + if (var.buffer != NULL) { | |
319 | + return true; | |
320 | + } | |
321 | + int nbRecords = getNbVarRecords(var); | |
322 | + int nbValues = getNbVarValuesByRecord(var); | |
323 | + int varid; | |
324 | + int status = nc_inq_varid (_file.id, var.name, &varid); | |
325 | + if (status != NC_NOERR) { | |
326 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadData - Cannot load variable data : " << getErrorMessage(status)) | |
327 | + return false; | |
328 | + } | |
329 | + switch (var.type) { | |
330 | + case NC_FLOAT : | |
331 | + var.valuesize = sizeof(float); | |
332 | + break; | |
333 | + case NC_DOUBLE : | |
334 | + var.valuesize = sizeof(double); | |
335 | + break; | |
336 | + case NC_SHORT : | |
337 | + var.valuesize = sizeof(short); | |
338 | + break; | |
339 | + case NC_INT : | |
340 | + var.valuesize = sizeof(int); | |
341 | + break; | |
342 | + default: | |
343 | + return false; | |
344 | + } | |
345 | + var.buffer = std::malloc(nbRecords*nbValues*var.valuesize); | |
346 | + status = nc_get_var(_file.id, varid, var.buffer); | |
347 | + if (status != NC_NOERR) { | |
348 | + LOG4CXX_ERROR(gLogger, "FileReaderNetCDF::loadData - Cannot load variable data : " << getErrorMessage(status)) | |
349 | + std::free(var.buffer); | |
350 | + var.buffer = NULL; | |
351 | + return false; | |
352 | + } | |
353 | + return true; | |
354 | +} | |
355 | + | |
356 | +std::string FileReaderNetCDF::getErrorMessage(int status) { | |
357 | + if (status == NC_NOERR) { | |
358 | + return "NO ERROR"; | |
359 | + } | |
360 | + return nc_strerror(status); | |
361 | +} | |
362 | + | |
68 | 363 | } /* LocalFileInterface */ |
69 | 364 | } /* AMDA */ | ... | ... |
src/ParamGetImpl/LocalFileInterface/FileReaderNetCDF.hh
... | ... | @@ -12,6 +12,8 @@ |
12 | 12 | |
13 | 13 | #include "netcdf.h" |
14 | 14 | |
15 | +#include <vector> | |
16 | + | |
15 | 17 | namespace AMDA { |
16 | 18 | namespace LocalFileInterface { |
17 | 19 | |
... | ... | @@ -72,6 +74,51 @@ public: |
72 | 74 | */ |
73 | 75 | virtual bool getInfo(const char* pInfoName, std::vector<double>& res); |
74 | 76 | |
77 | +private: | |
78 | + struct NetCDFDim { | |
79 | + int id; | |
80 | + char name[NC_MAX_NAME+1]; | |
81 | + size_t length; | |
82 | + bool isUnlimited; | |
83 | + }; | |
84 | + | |
85 | + struct NetCDFAtt { | |
86 | + int id; | |
87 | + char name[NC_MAX_NAME+1]; | |
88 | + size_t length; | |
89 | + nc_type type; | |
90 | + }; | |
91 | + | |
92 | + struct NetCDFVar { | |
93 | + int id; | |
94 | + char name[NC_MAX_NAME+1]; | |
95 | + std::vector<int> dimids; | |
96 | + std::vector<NetCDFAtt> atts; | |
97 | + nc_type type; | |
98 | + void* buffer; | |
99 | + int valuesize; | |
100 | + }; | |
101 | + | |
102 | + struct NetCDFFile { | |
103 | + int id; | |
104 | + std::vector<NetCDFDim> dims; | |
105 | + std::vector<NetCDFVar> vars; | |
106 | + std::vector<NetCDFAtt> atts; | |
107 | + }; | |
108 | + | |
109 | + NetCDFFile _file; | |
110 | + | |
111 | + void resetFile(); | |
112 | + | |
113 | + bool loadNetCDFFileInfo(); | |
114 | + | |
115 | + int getNbVarRecords(const NetCDFVar& var); | |
116 | + | |
117 | + int getNbVarValuesByRecord(const NetCDFVar& var); | |
118 | + | |
119 | + bool loadData(NetCDFVar& var); | |
120 | + | |
121 | + std::string getErrorMessage(int status); | |
75 | 122 | }; |
76 | 123 | |
77 | 124 | } /* LocalFileInterface */ | ... | ... |
src/ParamGetImpl/LocalFileInterface/VirtualInstrumentBaseParser.cc
... | ... | @@ -115,7 +115,7 @@ public: |
115 | 115 | lVI->setFilesFormat(VIFileFormat::FORMAT_CDF); |
116 | 116 | else if (loadedVIFormat == "VOT") |
117 | 117 | lVI->setFilesFormat(VIFileFormat::FORMAT_VOT); |
118 | - else if (loadedVIFormat == "NETCDF") | |
118 | + else if (loadedVIFormat == "NC") | |
119 | 119 | lVI->setFilesFormat(VIFileFormat::FORMAT_NETCDF); |
120 | 120 | else |
121 | 121 | { | ... | ... |
src/Parameters/ParameterManager.cc
... | ... | @@ -41,6 +41,13 @@ log4cxx::LoggerPtr ParameterManager::_logger( |
41 | 41 | */ |
42 | 42 | boost::mutex ParameterManager::mutexCDFLib; |
43 | 43 | |
44 | +/* | |
45 | + * @brief Mutex used to protect multi-thread access to NetCDF lib (NetCDF lib is not thread-safe!) | |
46 | + * This mutex is a part of the ParameterManager to be shared between by FileWriterNetCDF (DownloadOutput plugin) | |
47 | + * and class and FileReaderNetCDF (ParamGetLocalFile) | |
48 | + */ | |
49 | +boost::mutex ParameterManager::mutexNetCDFLib; | |
50 | + | |
44 | 51 | #define DEFAULT_GAP_THRESHOLD_VALUE 5 |
45 | 52 | |
46 | 53 | ParameterManager::ParameterManager() : | ... | ... |
src/Parameters/ParameterManager.hh
... | ... | @@ -55,6 +55,13 @@ namespace AMDA |
55 | 55 | */ |
56 | 56 | static boost::mutex mutexCDFLib; |
57 | 57 | |
58 | + /* | |
59 | + * @brief Mutex used to protect multi-thread access to netCDF lib (netCDF lib is not thread-safe!) | |
60 | + * This mutex is a part of the ParameterManager to be shared between by FileWriterNetCDF (DownloadOutput plugin) | |
61 | + * and class and FileReaderNetCDF (ParamGetLocalFile) | |
62 | + */ | |
63 | + static boost::mutex mutexNetCDFLib; | |
64 | + | |
58 | 65 | /** |
59 | 66 | * @return no return, do a getParameter |
60 | 67 | */ | ... | ... |
test/data/DataBaseParameters/local_netcdf_b.xml
1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | 2 | <param xml:id="local_netcdf_b"> |
3 | 3 | <info> |
4 | - <name>Mag Field vector</name> | |
5 | - <short_name>Mag Field</short_name> | |
6 | - <components>Bx,By,Bz</components> | |
4 | + <name>B Mag</name> | |
5 | + <short_name>|B|</short_name> | |
6 | + <components></components> | |
7 | 7 | <units>nT</units> |
8 | 8 | <coordinates_system></coordinates_system> |
9 | 9 | <tensor_order>1</tensor_order> | ... | ... |
... | ... | @@ -0,0 +1,22 @@ |
1 | +<?xml version="1.0" encoding="UTF-8"?> | |
2 | +<param xml:id="local_netcdf_v"> | |
3 | + <info> | |
4 | + <name>Velocity</name> | |
5 | + <short_name>V</short_name> | |
6 | + <components></components> | |
7 | + <units>km/s</units> | |
8 | + <coordinates_system></coordinates_system> | |
9 | + <tensor_order>1</tensor_order> | |
10 | + <si_conversion></si_conversion> | |
11 | + <fill_value></fill_value> | |
12 | + <ucd></ucd> | |
13 | + <dataset_id></dataset_id> | |
14 | + </info> | |
15 | + <get> | |
16 | + <localvi id="15"> | |
17 | + <param id="V" minSampling="3600" maxSampling="3600"/> | |
18 | + </localvi> | |
19 | + </get> | |
20 | + <process/> | |
21 | + <output/> | |
22 | +</param> | ... | ... |
test/data/LocalBase/base.xml
... | ... | @@ -87,7 +87,7 @@ |
87 | 87 | <file name="mms1_scm_brst_l2_scb_20150815130334_v1.1.0.cdf" start="1439643815.000000" |
88 | 88 | stop="1439643925.000000" /> |
89 | 89 | </vi> |
90 | - <vi id="15" format="NETCDF" start="662691600.000000" stop="694223999.000000"> | |
90 | + <vi id="15" format="NC" start="662691600.000000" stop="694223999.000000"> | |
91 | 91 | <file name="venus_1991.nc" start="662691600.000000" |
92 | 92 | stop="694223999.000000" /> |
93 | 93 | </vi> | ... | ... |