Peano
Loading...
Searching...
No Matches
convert.cpp
Go to the documentation of this file.
1#include <iostream>
2#include <fstream>
3#include <vector>
4#include <string>
5#include <limits>
6
7#include "config.h"
8
9
10#include "output/VTUWriter.h"
11#include "output/PeanoWriter.h"
12
14
15#include "filter/Copy.h"
16#include "filter/Intersection.h"
17#include "filter/SelectValue.h"
20
21
22#include "tarch/Assertions.h"
24#include "tarch/mpi/Rank.h"
25
26
27#include <filesystem>
28
29
30const std::string OutputFormatPeano = "peano";
31const std::string OutputFormatVTU = "vtu";
32
33
34void createDirectory( const std::string& directory ) {
35 static tarch::logging::Log _log( "/" );
36 if (
37 !std::filesystem::is_directory(directory)
38 ||
39 !std::filesystem::exists(directory)
40 ) {
41 try {
42 std::filesystem::create_directory(directory);
43 logInfo( "createDirectory(...)", "created directory " << directory );
44 }
45 catch (std::exception exc) {
46 logError( "createDirectory(...)", "failed to create directory " << directory );
47 logError( "createDirectory(...)", "error message: " << exc.what() );
49 }
50 }
51}
52
53
54void inspect( std::string filename ) {
55 static tarch::logging::Log _log( "/" );
56
58 reader.parse();
59
60 std::vector< convert::data::DataSet > data = reader.getData();
61
62 int datasetCounter = 0;
63 for (auto& pp: data) {
64 logInfo( "inspect", "dataset #" << datasetCounter );
65 datasetCounter++;
66 for (auto& p: pp.getVariables()) {
67 logInfo( "inspect", "variable " << p.name );
68 logInfo( "inspect", "\ttype\t\t\t" << (p.type==convert::data::PeanoDataType::Cell_Values ? "cell values" : "vertex values" ));
69 logInfo( "inspect", "\tdofs per axis\t\t" << p.dofsPerAxis );
70 logInfo( "inspect", "\tunknowns per dof\t" << p.unknowns );
71 }
72 }
73}
74
75
76std::string getFileNameWithoutExtensionAndWithoutPatch( std::string& file ) {
77 static tarch::logging::Log _log( "/" );
78
79 std::string result = file;
80 logDebug( "getFileNameWithoutExtensionAndWithoutPatch(std::string)", "in=" << result );
81 if ( result.find_last_of(".")!=std::string::npos ) {
82 result = result.erase(result.find_last_of(".") );
83 }
84 if ( result.find_last_of("/")!=std::string::npos ) {
85 result = result.erase(0,result.find_last_of("/")+1 );
86 }
87 logDebug( "getFileNameWithoutExtensionAndWithoutPatch(std::string)", "out=" << result );
88 return result;
89}
90
91
92void convertFile( const std::string& outputDirectory, const std::string& truncatedFile, const std::string& format, convert::data::Variable variable, const convert::data::DataSet& data ) {
93 static tarch::logging::Log _log( "/" );
94
95 convert::output::PeanoWriter::Writer* writer = nullptr;
96
97 const std::string fileWithCorrectSelector = truncatedFile + "-" + variable.name;
98 if (format==OutputFormatPeano) {
99 writer = new convert::output::PeanoWriter( outputDirectory, fileWithCorrectSelector );
100 }
101 else if (format==OutputFormatVTU) {
102 writer = new convert::output::VTUWriter( outputDirectory, fileWithCorrectSelector );
103 }
104 else {
105 logError( "convertFile(...)", "unknown output format " << format );
106 return;
107 }
108
109 writer->writeFile( variable, data.getData(variable) );
110
111 delete writer;
112}
113
114
115void convertFile( std::string filename, const std::string& outputDirectory, const std::string& selector, const std::string& format ) {
116 static tarch::logging::Log _log( "/" );
117
118 createDirectory( outputDirectory );
119
121 reader.parse();
122 std::vector< convert::data::DataSet > data = reader.getData();
123
124 std::string truncatedFile = getFileNameWithoutExtensionAndWithoutPatch( filename );
125 logDebug( "convertFile(...)", "read " << filename << " and write into " << truncatedFile << " in directory " << outputDirectory );
126
127 if (data.empty() ){
128 logError( "convertFile(...)", "data file is empty" );
129 }
130 else if (selector=="all") {
131 #pragma omp parallel for
132 for (int i=0; i<data.size(); i++) {
133 for (auto variable: data[i].getVariables()) {
135 outputDirectory, truncatedFile + "-" + std::to_string(i), format,
136 variable, data[i]
137 );
138 }
139 }
140 }
141 else if (data[0].hasVariable(selector)) {
142 #pragma omp parallel for
143 for (int i=0; i<data.size(); i++) {
144 convert::data::Variable variable = data[i].getVariable(selector);
146 outputDirectory, truncatedFile + "-" + std::to_string(i), format,
147 variable, data[i]
148 );
149 }
150 }
151 else {
152 logError( "convertFile(...)", "data file does not contain any data set with name " << selector );
153 }
154
155 for (auto& p: data) {
156 p.free();
157 }
158}
159
160
168
169
170std::string toString( Filter filter ) {
171 switch (filter) {
172 case Filter::Copy:
173 return "copy";
175 return "extract-fine-grid";
177 return "select-value";
179 return "separate-resolutions";
181 return "plot-domain-decomposition";
182 }
183 return "undef";
184}
185
186
187void applyFilter( std::string filename, std::string outputDirectory, std::string selector, std::string filterName, std::string targetSelector) {
188 static tarch::logging::Log _log( "/" );
189
190 createDirectory( outputDirectory );
191
192 std::string truncatedFile = getFileNameWithoutExtensionAndWithoutPatch( filename );
193 logInfo( "applyFilter(...)", "writing file " << truncatedFile );
194
196 reader.parse();
197 std::vector< convert::data::DataSet > data = reader.getData();
198
199 if (data.empty()) {
200 logError( "applyFilter(...)", "file already contains data set with name " << targetSelector );
201 }
202 else if (data[0].hasVariable(selector)) {
203 logInfo( "applyFilter(...)", "apply filter to " << data.size() << " file(s)" );
204
205 convert::output::PeanoWriter writer( outputDirectory, truncatedFile );
206
207 const int numberOfDataSets = data.size();
208 #pragma omp parallel for
209 for (int i=0; i<numberOfDataSets; i++) {
210 if (data[i].hasVariable(targetSelector)) {
211 logError( "applyFilter(...)", "file already contains data set with name " << targetSelector );
212 }
213 else {
214 convert::data::Variable variable = data[i].getVariable(selector);
215
216 convert::filter::Filter* filter = nullptr;
217 if (filterName==toString(Filter::Copy)) {
218 filter = new convert::filter::Copy();
219 }
220 else if (filterName==toString(Filter::ExtractFineGrid)) {
222 }
223 else if (filterName==toString(Filter::PlotDomainDecomposition)) {
225 }
226 else if (filterName==toString(Filter::SeparateResolutions)) {
228 }
229 else if (filterName.compare(toString(Filter::SelectValue))>0) {
230 std::string rangeToken = filterName.substr( filterName.find(':')+1 );
231 std::string fromToken = rangeToken.substr( 0, rangeToken.find(':') );
232 std::string toToken = rangeToken.substr( rangeToken.find(':')+1 );
233
234 logDebug( "applyFilter(...)", "use range token " << rangeToken << " split into " << fromToken << " and " << toToken );
235 filter = new convert::filter::SelectValue( std::stod(fromToken), std::stod(toToken) );
236 }
237 else {
238 logError( "applyFilter(...)", "unknown filter " << filterName );
239 }
240
241 if (filter!=nullptr) {
242 filter->apply( data[i], variable, targetSelector );
243 // for most filters, this assertion would be correct. But there are
244 // filters which use targetSelector as prefix and do derive various
245 // selectors from thereon. The resolution splitting is an example.
246 // assertion2( data[i].hasVariable(targetSelector), targetSelector, i );
247 delete filter;
248 }
249 }
250 }
251 writer.writeFile( data );
252 }
253 else {
254 logError( "applyFilter(...)", "data file does not contain any data set with name " << selector );
255 }
256
257 for (auto& p: data) {
258 p.free();
259 }
260}
261
262
263int main(int argc, char* argv[]) {
264 std::cout << "Peano file format converter/inspector" << std::endl;
265 std::cout << "(C) 2018/2019 Dan Tuthill-Jones, Tobias Weinzierl" << std::endl << std::endl;
266 bool validParams = true;
267
268 if(argc < 3) {
269 std::cerr << "too few arguments" << std::endl;
270 validParams = false;
271 }
272 else {
274
275 std::string mode = argv[1];
276 if (mode.compare("inspect")==0 and argc>=3) {
277 for (int i=2; i<argc; i++) {
278 inspect( argv[i] );
279 }
280 }
281 else if (mode.compare("convert-file")==0 and argc>=5) {
282 std::string selector = argv[ argc-3 ];
283 std::string outputDirectory = argv[ argc-2 ];
284 std::string format = argv[ argc-1 ];
285 for (int i=2; i<argc-3; i++) {
286 convertFile( argv[i], outputDirectory, selector, format );
287 }
288 }
289 else if (mode.compare("apply-filter")==0 and argc>=7) {
290 std::string selector = argv[ argc-4 ];
291 std::string outputDirectory = argv[ argc-3 ];
292 std::string filter = argv[ argc-2 ];
293 std::string targetSelector = argv[ argc-1 ];
294 for (int i=2; i<argc-4; i++) {
295 applyFilter( argv[i], outputDirectory, selector, filter, targetSelector);
296 }
297 }
298 else {
299 std::cerr << "unknown command or invalid number of parameters for particular command" << std::endl;
300 validParams = false;
301 }
302 }
303
304 if (!validParams) {
305 std::cerr << std::endl << std::endl;
306 std::cerr << "Usage:";
307 std::cerr << "\t./executable inspect InputFile1 [InputFile2 ...] " << std::endl;
308 std::cerr << "\t./executable convert-file InputFile1 [InputFile2 ...] Selector OutputFolder Format" << std::endl;
309 std::cerr << "\t./executable apply-filter InputFile1 [InputFile2 ...] Selector OutputFolder Filter TargetSelector" << std::endl;
310
311 std::cerr << std::endl << std::endl;
312 std::cerr << "Variants:" << std::endl;
313 std::cerr << "\tinspect Inspect which data sets are stored within file (cmp Selector below)" << std::endl;
314 std::cerr << "\tconvert-file Convert a single file" << std::endl;
315 std::cerr << "\tapply-filter Take a data set from the input file (identified by Selector), apply a filter to" << std::endl;
316 std::cerr << "\t this set and add the result to the file with a given TargetSelector name" << std::endl;
317
318 std::cerr << std::endl << std::endl;
319 std::cerr << "Options:" << std::endl;
320 std::cerr << "\tFormat Either " << OutputFormatPeano << " or " << OutputFormatVTU << std::endl;
321 std::cerr << "\tSelector Use inspect to see which data sets are stored within your patch file, i.e. which you can select. Pass all to convert all data sets (works only with convert-file)" << std::endl;
322
323 std::cerr << std::endl << std::endl;
324 std::cerr << "Filters:" << std::endl;
325 std::cerr << "\t" << toString(Filter::Copy) << " Create 1:1 copy of dataset with different name (for debugging)" << std::endl;
326 std::cerr << "\t" << toString(Filter::ExtractFineGrid) << " Extract fine grid" << std::endl;
327 std::cerr << "\t" << toString(Filter::SelectValue) << " Extract grid patches that hold values of a certain range. Append :from:to to filter to specify range" << std::endl;
328 std::cerr << "\t" << toString(Filter::SeparateResolutions) << " Splits up the tree mesh into its resolutions" << std::endl;
329 std::cerr << "\t" << toString(Filter::PlotDomainDecomposition) << " Don't plot any data but display which mesh parts are handled by which tree (please use this as first filter if you apply a series of filters)" << std::endl;
330
331 std::cerr << std::endl << std::endl;
332 std::cerr << "Output directory plus filename can be the same as the input file. In this case, the original file is overwritten/augmented with new data" << std::endl;
333 return -1;
334 }
335 else return 0;
336}
#define logError(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:464
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:411
tarch::logging::Log _log("::")
int main()
Definition main.cpp:321
A dataset is a wrapper around one big map.
Definition DataSet.h:34
Represents one variable that is subsequently attached to the patches of a file.
Definition Variable.h:18
const std::string name
Definition Variable.h:22
virtual void writeFile(const convert::data::Variable &variable, const std::vector< convert::data::PatchData > &data) override
Our writers write only one variable at a time even though the Peano file format can hold multiple var...
void setOutputFile(const std::string &outputLogFileName)
Is redundant, as you could use setLogFormat() instead.
static ChromeTraceFileLogger & getInstance()
Log Device.
Definition Log.h:516
static void abort(int errorCode)
A proper abort in an MPI context has to use MPI_Abort.
Definition Rank.cpp:596
void inspect(std::string filename)
Definition convert.cpp:54
void convertFile(const std::string &outputDirectory, const std::string &truncatedFile, const std::string &format, convert::data::Variable variable, const convert::data::DataSet &data)
Definition convert.cpp:92
std::string toString(Filter filter)
Definition convert.cpp:170
void createDirectory(const std::string &directory)
Definition convert.cpp:34
const std::string OutputFormatPeano
Definition convert.cpp:30
std::string getFileNameWithoutExtensionAndWithoutPatch(std::string &file)
Definition convert.cpp:76
Filter
Definition convert.cpp:161
@ SeparateResolutions
@ PlotDomainDecomposition
@ SelectValue
@ ExtractFineGrid
void applyFilter(std::string filename, std::string outputDirectory, std::string selector, std::string filterName, std::string targetSelector)
Definition convert.cpp:187
const std::string OutputFormatVTU
Definition convert.cpp:31