Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
vlsvreaderinterface.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2016 Finnish Meteorological Institute
4 *
5 * For details of usage, see the COPYING file and read the "Rules of the Road"
6 * at http://www.physics.helsinki.fi/vlasiator/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program 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
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22#include <iostream>
23#include "vlsvreaderinterface.h"
24
25using namespace std;
26
27namespace vlsvinterface {
28
29 static uint64_t convUInt(const char* ptr, const vlsv::datatype::type & dataType, const uint64_t& dataSize) {
30 if (dataType != vlsv::datatype::type::UINT) {
31 cerr << "Erroneous datatype given to convUInt" << endl;
32 exit(1);
33 }
34 switch (dataSize) {
35 case 1:
36 return *reinterpret_cast<const unsigned char*> (ptr);
37 break;
38 case 2:
39 return *reinterpret_cast<const unsigned short int*> (ptr);
40 break;
41 case 4:
42 return *reinterpret_cast<const unsigned int*> (ptr);
43 break;
44 case 8:
45 return *reinterpret_cast<const unsigned long int*> (ptr);
46 break;
47 }
48 return 0;
49 }
50
51 float checkVersion( const string & fname ) {
52 vlsv::Reader vlsvReader;
53 vlsvReader.open(fname);
54 string versionTag = "version";
55 float version;
56 if( vlsvReader.readParameter( versionTag, version ) == false ) {
57 //No version mark -- return 0
58 vlsvReader.close();
59 return 0;
60 }
61 vlsvReader.close();
62 if( version == 1.00 ) {
63 return version;
64 } else {
65 cerr << "Invalid version!" << endl;
66 exit(1);
67 return 0;
68 }
69 }
70
71 Reader::Reader() : vlsv::Reader() {
72 cellIdsSet = false;
73 cellsWithBlocksSet = false;
74 }
75
77
78 }
79
80 bool Reader::getMeshNames( list<string> & meshNames ) {
81 set<string> meshNames_set;
82 if (getUniqueAttributeValues("MESH", "name", meshNames_set) == false) {
83 cerr << "Failed to read mesh names" << endl;
84 return false;
85 }
86 //Input the mesh names:
87 for( set<string>::const_iterator it = meshNames_set.begin(); it != meshNames_set.end(); ++it ) {
88 meshNames.push_back( *it );
89 }
90 return true;
91 }
92
93 bool Reader::getMeshNames( set<string> & meshNames ) {
94 if (getUniqueAttributeValues("MESH", "name", meshNames) == false) {
95 cerr << "Failed to read mesh names" << endl;
96 return false;
97 }
98 return true;
99 }
100
101 bool Reader::getVariableNames( const string&, list<string> & meshNames ) {
102 set<string> meshNames_set;
103 if (getUniqueAttributeValues("VARIABLE", "name", meshNames_set) == false) {
104 cerr << "Failed to read mesh names" << endl;
105 return false;
106 }
107 //Input the mesh names:
108 for( set<string>::const_iterator it = meshNames_set.begin(); it != meshNames_set.end(); ++it ) {
109 meshNames.push_back( *it );
110 }
111 return true;
112 }
113
114 bool Reader::getVariableNames( set<string> & meshNames ) {
115 if (getUniqueAttributeValues("VARIABLE", "name", meshNames) == false) {
116 cerr << "Failed to read mesh names" << endl;
117 return false;
118 }
119 return true;
120 }
121
122 bool Reader::getCellIds( vector<uint64_t> & cellIds,const string& meshName) {
123 uint64_t vectorSize, byteSize;
124 uint64_t amountToReadIn;
125 vlsv::datatype::type dataType;
126 const string variableName = "CellID";
127 std::list< pair<std::string, std::string> > xmlAttributes;
128 xmlAttributes.push_back( make_pair( "name", variableName ) );
129 xmlAttributes.push_back( make_pair( "mesh", meshName ) );
130
131 if( getArrayInfo("VARIABLE", xmlAttributes, amountToReadIn, vectorSize, dataType, byteSize ) == false ) {
132 cerr << "ERROR, failed to read array info for variable '" << variableName << "' ";
133 cerr << "in mesh '" << meshName << "' at " << __FILE__ << ":" << __LINE__ << endl;
134 return false;
135 }
136 if( dataType != vlsv::datatype::type::UINT ) {
137 cerr << "ERROR, BAD DATATYPE AT " << __FILE__ << " " << __LINE__ << endl;
138 return false;
139 }
140 if( byteSize != sizeof(uint64_t) ) {
141 cerr << "ERROR, BAD DATASIZE AT " << __FILE__ << " " << __LINE__ << endl;
142 return false;
143 }
144 if( vectorSize != 1 ) {
145 cerr << "ERROR, BAD VECTORSIZE AT " << __FILE__ << " " << __LINE__ << endl;
146 return false;
147 }
148 uint64_t * cellIds_buffer = new uint64_t[amountToReadIn * vectorSize];
149 //Read in cell ids to the buffer:
150 const uint16_t begin = 0;
151 const bool allocateMemory = false;
152 if( read( "VARIABLE", xmlAttributes, begin, amountToReadIn, cellIds_buffer, allocateMemory ) == false ) {
153 cerr << "ERROR, Failed to read variable data at " << __FILE__ << ":" << __LINE__ << endl;
154 return false;
155 }
156 //Input cell ids:
157 cellIds.reserve( amountToReadIn * vectorSize );
158 for( uint64_t i = 0; i < amountToReadIn * vectorSize; ++i ) {
159 cellIds.push_back( cellIds_buffer[i] );
160 }
161 delete[] cellIds_buffer;
162 return true;
163 }
164
166 if( cellIdLocations.empty() == false ) {
167 //Clear the cell ids
168 cellIdLocations.clear();
169 }
170 uint64_t vectorSize, byteSize;
171 uint64_t amountToReadIn;
172 vlsv::datatype::type dataType;
173 const string variableName = "CellID";
174 std::list< pair<std::string, std::string> > xmlAttributes;
175 xmlAttributes.push_back( make_pair( "name", variableName ) );
176 xmlAttributes.push_back( make_pair( "mesh", "SpatialGrid" ) );
177 if( getArrayInfo( "VARIABLE", xmlAttributes, amountToReadIn, vectorSize, dataType, byteSize ) == false ) return false;
178 if( dataType != vlsv::datatype::type::UINT ) {
179 cerr << "ERROR, BAD DATATYPE AT " << __FILE__ << " " << __LINE__ << endl;
180 return false;
181 }
182 if( byteSize != sizeof(uint64_t) ) {
183 cerr << "ERROR, BAD DATASIZE AT " << __FILE__ << " " << __LINE__ << endl;
184 return false;
185 }
186 if( vectorSize != 1 ) {
187 cerr << "ERROR, BAD VECTORSIZE AT " << __FILE__ << " " << __LINE__ << endl;
188 return false;
189 }
190 uint64_t * cellIds_buffer = new uint64_t[amountToReadIn * vectorSize];
191 //Read in cell ids to the buffer:
192 const uint16_t begin = 0;
193 const bool allocateMemory = false;
194 if( read( "VARIABLE", xmlAttributes, begin, amountToReadIn, cellIds_buffer, allocateMemory ) == false ) return false;
195 //Input cell ids:
196 cellIdLocations.rehash( (uint64_t)(amountToReadIn * vectorSize * 1.25) );
197 for( uint64_t i = 0; i < amountToReadIn * vectorSize; ++i ) {
198 const uint64_t cellid = cellIds_buffer[i];
199 cellIdLocations[cellid] = i;
200 }
201 delete[] cellIds_buffer;
202 cellIdsSet = true;
203 return true;
204 }
205
206 bool Reader::setCellsWithBlocks(const std::string& meshName,const std::string& popName) {
207 if(cellsWithBlocksLocations.empty() == false) {
209 }
210 vlsv::datatype::type cwb_dataType;
211 uint64_t cwb_arraySize, cwb_vectorSize, cwb_dataSize;
212 list<pair<string, string> > attribs;
213
214 // Get the mesh name for reading in data from the correct place. Older Vlasiator VLSV
215 // files did not add particle population name to arrays, so for those files we do
216 // not require the popName to be present.
217 attribs.push_back(make_pair("mesh", meshName));
218 if (popName.size() > 0) attribs.push_back(make_pair("name", popName));
219
220 //Get array info
221 if (getArrayInfo("CELLSWITHBLOCKS", attribs, cwb_arraySize, cwb_vectorSize, cwb_dataType, cwb_dataSize) == false) {
222 cerr << "ERROR, COULD NOT FIND ARRAY CELLSWITHBLOCKS FOR POPULATION '" << popName << "' AT " << __FILE__ << ":" << __LINE__ << endl;
223 return false;
224 }
225
226 //Make sure the data format is correct:
227 if( cwb_vectorSize != 1 ) {
228 cerr << "ERROR, BAD VECTORSIZE AT " << __FILE__ << " " << __LINE__ << endl;
229 return false;
230 }
231 if( cwb_dataType != vlsv::datatype::type::UINT ) {
232 cerr << "ERROR, BAD DATATYPE AT " << __FILE__ << " " << __LINE__ << endl;
233 return false;
234 }
235 if( cwb_dataSize != sizeof(uint64_t) ) {
236 cerr << "ERROR, BAD DATASIZE AT " << __FILE__ << " " << __LINE__ << endl;
237 return false;
238 }
239
240 // Create buffer and read data:
241 const uint64_t cwb_amountToReadIn = cwb_arraySize * cwb_vectorSize * cwb_dataSize;
242 const uint16_t cwb_startingPoint = 0;
243 char * cwb_buffer = new char[cwb_amountToReadIn];
244 if (readArray("CELLSWITHBLOCKS", attribs, cwb_startingPoint, cwb_arraySize, cwb_buffer) == false) {
245 cerr << "Failed to read block metadata for mesh '" << meshName << "'" << endl;
246 delete[] cwb_buffer;
247 return false;
248 }
249
250 vlsv::datatype::type nb_dataType;
251 uint64_t nb_arraySize, nb_vectorSize, nb_dataSize;
252
253 //Get the mesh name for reading in data from the correct place
254 //Read array info -- stores output in nb_arraySize, nb_vectorSize, nb_dataType, nb_dataSize
255 if (getArrayInfo("BLOCKSPERCELL", attribs, nb_arraySize, nb_vectorSize, nb_dataType, nb_dataSize) == false) {
256 cerr << "ERROR, COULD NOT FIND ARRAY BLOCKSPERCELL AT " << __FILE__ << " " << __LINE__ << endl;
257 return false;
258 }
259
260 // Create buffers for number of blocks (nb) and read data:
261 const short int startingPoint = 0; //Read the array from 0 (the beginning)
262 char* nb_buffer = new char[nb_arraySize * nb_vectorSize * nb_dataSize];
263 if (readArray("BLOCKSPERCELL", attribs, startingPoint, nb_arraySize, nb_buffer) == false) {
264 cerr << "Failed to read number of blocks for mesh '" << meshName << "'" << endl;
265 delete[] nb_buffer;
266 delete[] cwb_buffer;
267 return false;
268 }
269
270 // Input cellswithblock locations:
271 uint64_t blockOffset = 0;
272 uint64_t N_blocks;
273 for (uint64_t cell = 0; cell < cwb_arraySize; ++cell) {
274 const uint64_t readCellID = convUInt(cwb_buffer + cell*cwb_dataSize, cwb_dataType, cwb_dataSize);
275 N_blocks = convUInt(nb_buffer + cell*nb_dataSize, nb_dataType, nb_dataSize);
276 const pair<uint64_t, uint32_t> input = make_pair( blockOffset, N_blocks );
277 //Insert the location and number of blocks into the map
278 cellsWithBlocksLocations.insert( make_pair(readCellID, input) );
279 blockOffset += N_blocks;
280 }
281
282 delete[] cwb_buffer;
283 delete[] nb_buffer;
284 cellsWithBlocksSet = true;
285 return true;
286 }
287
288 bool Reader::getBlockIds(const uint64_t& cellId,std::vector<uint64_t>& blockIds,const std::string& popName) {
289 if( cellsWithBlocksSet == false ) {
290 cerr << "ERROR, setCellsWithBlocks() NOT CALLED AT (CALL setCellsWithBlocks()) BEFORE CALLING getBlockIds " << __FILE__ << " " << __LINE__ << endl;
291 return false;
292 }
293 //Check if the cell id can be found:
294 unordered_map<uint64_t, pair<uint64_t, uint32_t>>::const_iterator it = cellsWithBlocksLocations.find( cellId );
295 if( it == cellsWithBlocksLocations.end() ) {
296 cerr << "COULDNT FIND CELL ID " << cellId << " AT " << __FILE__ << " " << __LINE__ << endl;
297 return false;
298 }
299 //Get offset and number of blocks:
300 pair<uint64_t, uint32_t> offsetAndBlocks = it->second;
301 const uint64_t blockOffset = get<0>(offsetAndBlocks);
302 const uint32_t N_blocks = get<1>(offsetAndBlocks);
303
304 // Get some required info from VLSV file:
305 list<pair<string, string> > attribs;
306 if (popName.size() > 0) attribs.push_back(make_pair("name",popName));
307
308 //READ BLOCK IDS:
309 uint64_t blockIds_arraySize, blockIds_vectorSize, blockIds_dataSize;
310 vlsv::datatype::type blockIds_dataType;
311 //Input blockIds_arraySize, blockIds_vectorSize, blockIds_dataSize blockIds_dataType: (Returns false if fails)
312 if (getArrayInfo("BLOCKIDS", attribs, blockIds_arraySize, blockIds_vectorSize, blockIds_dataType, blockIds_dataSize) == false) {
313 cerr << "ERROR, COULD NOT FIND BLOCKIDS FOR '" << popName << "' AT " << __FILE__ << " " << __LINE__ << endl;
314 return false;
315 }
316 //Make sure blockid's datatype is correct:
317 if( blockIds_dataType != vlsv::datatype::type::UINT ) {
318 cerr << "ERROR, bad datatype at " << __FILE__ << " " << __LINE__ << endl;
319 return false;
320 }
321 //Create buffer for reading in data: (Note: arraySize, vectorSize, etc were fetched from getArrayInfo)
322 char * blockIds_buffer = new char[N_blocks*blockIds_vectorSize*blockIds_dataSize];
323 //Read the data into the buffer:
324 if( readArray( "BLOCKIDS", attribs, blockOffset, N_blocks, blockIds_buffer ) == false ) {
325 cerr << "ERROR, FAILED TO READ BLOCKIDS AT " << __FILE__ << " " << __LINE__ << endl;
326 delete[] blockIds_buffer;
327 return false;
328 }
329 //Input the block ids:
330 blockIds.reserve(N_blocks);
331 for (uint64_t i = 0; i < N_blocks; ++i) {
332 const uint64_t blockId = convUInt(blockIds_buffer + i*blockIds_dataSize, blockIds_dataType, blockIds_dataSize);
333 blockIds.push_back( blockId );
334 }
335 delete[] blockIds_buffer;
336 return true;
337 }
338
339 bool Reader::getVelocityBlockVariables(const string & variableName,const uint64_t & cellId,char*& buffer,bool allocateMemory ) {
340 if( cellsWithBlocksSet == false ) {
341 cerr << "ERROR, CELLS WITH BLOCKS NOT SET AT " << __FILE__ << " " << __LINE__ << endl;
342 return false;
343 }
344
345 //Check if the cell id can be found:
346 unordered_map<uint64_t, pair<uint64_t, uint32_t>>::const_iterator it = cellsWithBlocksLocations.find( cellId );
347 if( it == cellsWithBlocksLocations.end() ) {
348 cerr << "COULDNT FIND CELL ID " << cellId << " AT " << __FILE__ << " " << __LINE__ << endl;
349 return false;
350 }
351
352 bool success = true;
353 list<pair<string, string> > attribs;
354 attribs.push_back(make_pair("name", variableName));
355 attribs.push_back(make_pair("mesh", "SpatialGrid"));
356
357 vlsv::datatype::type dataType;
358 uint64_t arraySize, vectorSize, dataSize;
359 if (getArrayInfo("BLOCKVARIABLE", attribs, arraySize, vectorSize, dataType, dataSize) == false) {
360 cerr << "Could not read BLOCKVARIABLE array info" << endl;
361 return false;
362 }
363
364 //Get offset and number of blocks
365 const uint64_t offset = get<0>(it->second);
366 const uint32_t amountToReadIn = get<1>(it->second);
367
368 if( allocateMemory == true ) {
369 buffer = new char[amountToReadIn * vectorSize * dataSize];
370 }
371
372 //Read the variables (Note: usually vectorSize = 64)
373 if (readArray("BLOCKVARIABLE", attribs, offset, amountToReadIn, buffer) == false) {
374 cerr << "ERROR could not read block variable" << endl;
375 if( allocateMemory == true ) {
376 delete[] buffer; buffer = NULL;
377 }
378 return false;
379 }
380 return true;
381 }
382
383} // namespace vlsvinterface
for i
Definition Dispersion.m:24
set(gca, 'YDir', 'normal')
bool getBlockIds(const uint64_t &cellId, std::vector< uint64_t > &blockIds, const std::string &popName)
bool getMeshNames(std::list< std::string > &meshNames)
bool setCellsWithBlocks(const std::string &meshName, const std::string &popName)
std::unordered_map< uint64_t, std::pair< uint64_t, uint32_t > > cellsWithBlocksLocations
bool getVariableNames(const std::string &, std::list< std::string > &meshNames)
bool getCellIds(std::vector< uint64_t > &cellIds, const std::string &meshName="SpatialGrid")
bool getVelocityBlockVariables(const std::string &variableName, const uint64_t &cellId, char *&buffer, bool allocateMemory=true)
std::unordered_map< uint64_t, uint64_t > cellIdLocations
static uint64_t convUInt(const char *ptr, const vlsv::datatype::type &dataType, const uint64_t &dataSize)
float checkVersion(const string &fname)