Loading tools/mesh_converter/CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ ADD_EXECUTABLE( MeshConverter.cpp MeshParser.cpp parsers/DFISEParser.cpp parsers/SilvacoParser.cpp ${ALLPIX_SRC}/core/utils/log.cpp ${ALLPIX_SRC}/core/utils/text.cpp ${ALLPIX_SRC}/core/utils/unit.cpp Loading tools/mesh_converter/MeshParser.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ using namespace mesh_converter; std::shared_ptr<MeshParser> MeshParser::factory(const allpix::Configuration& config) { auto parser = config.get<std::string>("parser", "df-ise"); std::transform(parser.begin(), parser.end(), parser.begin(), ::tolower); LOG(DEBUG) << "Parser \"" << parser << "\"\n"; if(parser == "df-ise" || parser == "dfise") { return std::make_shared<DFISEParser>(); } else if(parser == "silvaco" || parser == "Silvaco") { return std::make_shared<SilvacoParser>(); } else { throw allpix::InvalidValueError(config, "parser", "Unknown parser type"); } Loading Loading @@ -80,6 +82,7 @@ MeshParser::getField(const std::string& file, const std::string& observable, con for(const auto& region : regions) { if(field_map_[file].find(region) != field_map_[file].end() && field_map_[file][region].find(observable) != field_map_[file][region].end()) { LOG(DEBUG) << "Region \"" << region << "\"\n"; field.insert( field.end(), field_map_[file][region][observable].begin(), field_map_[file][region][observable].end()); } else { Loading tools/mesh_converter/MeshParser.hpp +1 −0 Original line number Diff line number Diff line Loading @@ -69,5 +69,6 @@ namespace mesh_converter { } // namespace mesh_converter #include "parsers/DFISEParser.hpp" #include "parsers/SilvacoParser.hpp" #endif // ALLPIX_MESHPARSER_H tools/mesh_converter/parsers/SilvacoParser.cpp 0 → 100644 +225 −0 Original line number Diff line number Diff line /** * @file * * @copyright Copyright (c) 2017-2022 CERN and the Allpix Squared authors. * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md". * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an * Intergovernmental Organization or submit itself to any jurisdiction. * SPDX-License-Identifier: MIT */ #include "SilvacoParser.hpp" #include <cassert> #include <cstdlib> #include <exception> #include <fstream> #include <iostream> #include <regex> #include <set> #include <string> #include <sstream> #include "TFile.h" #include "TTree.h" #include "core/utils/log.h" #include "core/utils/text.h" using namespace mesh_converter; MeshMap SilvacoParser::read_meshes(const std::string& file_name) { /*// changing file extension std::string original_file_name = file_name; // save a copy just in case std::string silvaco_extension = "dat"; string::size_type i = file_name.rfind('.', file_name.length()); if (i != string::npos) { file_name.replace(i+1, silvaco_extension.length(), silvaco_extension); } */ std::ifstream file(file_name); if(!file) { throw std::runtime_error("file cannot be accessed"); } // Get the total number of lines to parse and reset file to the start: auto num_lines = std::count(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), '\n'); file.clear(); file.seekg(0, std::ios::beg); LOG(DEBUG) << "Grid file contains " << num_lines << " lines to parse"; std::vector<Point> vertices; std::string region = "Silicon"; long unsigned int dimension = 1; long unsigned int columns_count = 0; long long num_lines_parsed = 0; while(!file.eof()) { std::string line; std::getline(file, line); // Log the parsing progress: if(num_lines > 0 && num_lines_parsed % 1000 == 0) { LOG_PROGRESS(STATUS, "gridlines") << "Parsing grid file: " << (100 * num_lines_parsed / num_lines) << "%"; } num_lines_parsed++; line = allpix::trim(line); if(line.empty()) { continue; } // Determining number of columns by counting fields in first line if ( num_lines_parsed == 1 ) { std::istringstream iss; iss.str(line); double val; while ( iss >> val ) { columns_count++; } iss.clear(); } dimension = columns_count; // Handle data std::stringstream sstr(line); // Read vertex points if(dimension == 3) { double x = 0, y = 0, z = 0; while(sstr >> x >> y >> z) { vertices.emplace_back(x, y, z); } } if(dimension == 2) { double y = 0, z = 0; while(sstr >> y >> z) { vertices.emplace_back(y, z); } } } LOG_PROGRESS(STATUS, "gridlines") << "Parsing grid file: done."; std::map<std::string, std::vector<Point>> ret_map; // std::vector<Point> ret_vector; // same thing as vertices for Silvaco ret_map[region] = vertices; return ret_map; } FieldMap SilvacoParser::read_fields(const std::string& file_name) { std::ifstream file(file_name); if(!file) { throw std::runtime_error("file cannot be accessed"); } // Get the total number of lines to parse and reset file to the start: auto num_lines = std::count(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), '\n'); file.clear(); file.seekg(0, std::ios::beg); LOG(DEBUG) << "Field data file contains " << num_lines << " lines to parse"; // std::map<std::string, std::vector<Point>> region_electric_field_map; std::map<std::string, std::map<std::string, std::vector<Point>>> region_electric_field_map; std::vector<double> region_electric_field_num; std::string region = "Silicon"; std::string observable; long unsigned int dimension = 1; long long num_lines_parsed = 0; long unsigned int columns_count = 0; while(!file.eof()) { std::string line; std::getline(file, line); line = allpix::trim(line); // Log the parsing progress: if(num_lines > 0 && num_lines_parsed % 1000 == 0) { LOG_PROGRESS(STATUS, "fieldlines") << "Parsing field data file: " << (100 * num_lines_parsed / num_lines) << "%"; } num_lines_parsed++; if(line.empty()) { continue; } // Determining number of columns by counting fields in first line if ( num_lines_parsed == 1 ) { std::istringstream iss; iss.str(line); double val; while ( iss >> val ) { columns_count++; } dimension = columns_count; // Determining data type from dimensions // dimension == 1 -> Scalar potential // dimension == 2 -> 2D electric field // dimension == 3 -> 3D electric field if ( dimension == 1 ) { observable = "ElectrostaticPotential"; } else if ( dimension == 2 ) { observable = "ElectricField"; } else if ( dimension == 3 ) { observable = "ElectricField"; } else { throw std::runtime_error("incorrect dimension of observable"); } iss.clear(); } // Handle data std::stringstream sstr(line); double num = NAN; while(sstr >> num) { region_electric_field_num.push_back(num); } if( dimension == 1 ) { for(size_t i = 0; i < region_electric_field_num.size(); i += 1) { auto x = region_electric_field_num[i]; region_electric_field_map[region][observable].emplace_back(x, 0, 0); } region_electric_field_num.clear(); } if(dimension == 3) { for(size_t i = 0; i < region_electric_field_num.size(); i += 3) { auto x = region_electric_field_num[i]; auto y = region_electric_field_num[i + 1]; auto z = region_electric_field_num[i + 2]; region_electric_field_map[region][observable].emplace_back(x, y, z); } } if(dimension == 2) { for(size_t i = 0; i < region_electric_field_num.size(); i += 2) { auto x = region_electric_field_num[i]; auto y = region_electric_field_num[i + 1]; region_electric_field_map[region][observable].emplace_back(0, x, y); } } region_electric_field_num.clear(); } LOG_PROGRESS(STATUS, "fieldlines") << "Parsing field data file: done."; return region_electric_field_map; } tools/mesh_converter/parsers/SilvacoParser.hpp 0 → 100644 +53 −0 Original line number Diff line number Diff line /** * @file * * @copyright Copyright (c) 2017-2022 CERN and the Allpix Squared authors. * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md". * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an * Intergovernmental Organization or submit itself to any jurisdiction. * SPDX-License-Identifier: MIT */ #ifndef ALLPIX_MESHPARSER_SILVACO_H #define ALLPIX_MESHPARSER_SILVACO_H #include "../MeshParser.hpp" #include <iostream> #include <map> #include <vector> namespace mesh_converter { class SilvacoParser : public MeshParser { // Sections to read in extracted files enum class DFSection { NONE = 0, IGNORED, HEADER, INFO, REGION, COORDINATES, VERTICES, EDGES, FACES, ELEMENTS, DONOR_CONCENTRATION, DOPING_CONCENTRATION, ACCEPTOR_CONCENTRATION, ELECTRIC_FIELD, ELECTROSTATIC_POTENTIAL, VALUES }; private: // Read the grid MeshMap read_meshes(const std::string& file_name) override; // Read the electric field FieldMap read_fields(const std::string& file_name) override; }; } // namespace mesh_converter #endif // ALLPIX_MESHPARSER_SILVACO_H Loading
tools/mesh_converter/CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ ADD_EXECUTABLE( MeshConverter.cpp MeshParser.cpp parsers/DFISEParser.cpp parsers/SilvacoParser.cpp ${ALLPIX_SRC}/core/utils/log.cpp ${ALLPIX_SRC}/core/utils/text.cpp ${ALLPIX_SRC}/core/utils/unit.cpp Loading
tools/mesh_converter/MeshParser.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ using namespace mesh_converter; std::shared_ptr<MeshParser> MeshParser::factory(const allpix::Configuration& config) { auto parser = config.get<std::string>("parser", "df-ise"); std::transform(parser.begin(), parser.end(), parser.begin(), ::tolower); LOG(DEBUG) << "Parser \"" << parser << "\"\n"; if(parser == "df-ise" || parser == "dfise") { return std::make_shared<DFISEParser>(); } else if(parser == "silvaco" || parser == "Silvaco") { return std::make_shared<SilvacoParser>(); } else { throw allpix::InvalidValueError(config, "parser", "Unknown parser type"); } Loading Loading @@ -80,6 +82,7 @@ MeshParser::getField(const std::string& file, const std::string& observable, con for(const auto& region : regions) { if(field_map_[file].find(region) != field_map_[file].end() && field_map_[file][region].find(observable) != field_map_[file][region].end()) { LOG(DEBUG) << "Region \"" << region << "\"\n"; field.insert( field.end(), field_map_[file][region][observable].begin(), field_map_[file][region][observable].end()); } else { Loading
tools/mesh_converter/MeshParser.hpp +1 −0 Original line number Diff line number Diff line Loading @@ -69,5 +69,6 @@ namespace mesh_converter { } // namespace mesh_converter #include "parsers/DFISEParser.hpp" #include "parsers/SilvacoParser.hpp" #endif // ALLPIX_MESHPARSER_H
tools/mesh_converter/parsers/SilvacoParser.cpp 0 → 100644 +225 −0 Original line number Diff line number Diff line /** * @file * * @copyright Copyright (c) 2017-2022 CERN and the Allpix Squared authors. * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md". * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an * Intergovernmental Organization or submit itself to any jurisdiction. * SPDX-License-Identifier: MIT */ #include "SilvacoParser.hpp" #include <cassert> #include <cstdlib> #include <exception> #include <fstream> #include <iostream> #include <regex> #include <set> #include <string> #include <sstream> #include "TFile.h" #include "TTree.h" #include "core/utils/log.h" #include "core/utils/text.h" using namespace mesh_converter; MeshMap SilvacoParser::read_meshes(const std::string& file_name) { /*// changing file extension std::string original_file_name = file_name; // save a copy just in case std::string silvaco_extension = "dat"; string::size_type i = file_name.rfind('.', file_name.length()); if (i != string::npos) { file_name.replace(i+1, silvaco_extension.length(), silvaco_extension); } */ std::ifstream file(file_name); if(!file) { throw std::runtime_error("file cannot be accessed"); } // Get the total number of lines to parse and reset file to the start: auto num_lines = std::count(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), '\n'); file.clear(); file.seekg(0, std::ios::beg); LOG(DEBUG) << "Grid file contains " << num_lines << " lines to parse"; std::vector<Point> vertices; std::string region = "Silicon"; long unsigned int dimension = 1; long unsigned int columns_count = 0; long long num_lines_parsed = 0; while(!file.eof()) { std::string line; std::getline(file, line); // Log the parsing progress: if(num_lines > 0 && num_lines_parsed % 1000 == 0) { LOG_PROGRESS(STATUS, "gridlines") << "Parsing grid file: " << (100 * num_lines_parsed / num_lines) << "%"; } num_lines_parsed++; line = allpix::trim(line); if(line.empty()) { continue; } // Determining number of columns by counting fields in first line if ( num_lines_parsed == 1 ) { std::istringstream iss; iss.str(line); double val; while ( iss >> val ) { columns_count++; } iss.clear(); } dimension = columns_count; // Handle data std::stringstream sstr(line); // Read vertex points if(dimension == 3) { double x = 0, y = 0, z = 0; while(sstr >> x >> y >> z) { vertices.emplace_back(x, y, z); } } if(dimension == 2) { double y = 0, z = 0; while(sstr >> y >> z) { vertices.emplace_back(y, z); } } } LOG_PROGRESS(STATUS, "gridlines") << "Parsing grid file: done."; std::map<std::string, std::vector<Point>> ret_map; // std::vector<Point> ret_vector; // same thing as vertices for Silvaco ret_map[region] = vertices; return ret_map; } FieldMap SilvacoParser::read_fields(const std::string& file_name) { std::ifstream file(file_name); if(!file) { throw std::runtime_error("file cannot be accessed"); } // Get the total number of lines to parse and reset file to the start: auto num_lines = std::count(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), '\n'); file.clear(); file.seekg(0, std::ios::beg); LOG(DEBUG) << "Field data file contains " << num_lines << " lines to parse"; // std::map<std::string, std::vector<Point>> region_electric_field_map; std::map<std::string, std::map<std::string, std::vector<Point>>> region_electric_field_map; std::vector<double> region_electric_field_num; std::string region = "Silicon"; std::string observable; long unsigned int dimension = 1; long long num_lines_parsed = 0; long unsigned int columns_count = 0; while(!file.eof()) { std::string line; std::getline(file, line); line = allpix::trim(line); // Log the parsing progress: if(num_lines > 0 && num_lines_parsed % 1000 == 0) { LOG_PROGRESS(STATUS, "fieldlines") << "Parsing field data file: " << (100 * num_lines_parsed / num_lines) << "%"; } num_lines_parsed++; if(line.empty()) { continue; } // Determining number of columns by counting fields in first line if ( num_lines_parsed == 1 ) { std::istringstream iss; iss.str(line); double val; while ( iss >> val ) { columns_count++; } dimension = columns_count; // Determining data type from dimensions // dimension == 1 -> Scalar potential // dimension == 2 -> 2D electric field // dimension == 3 -> 3D electric field if ( dimension == 1 ) { observable = "ElectrostaticPotential"; } else if ( dimension == 2 ) { observable = "ElectricField"; } else if ( dimension == 3 ) { observable = "ElectricField"; } else { throw std::runtime_error("incorrect dimension of observable"); } iss.clear(); } // Handle data std::stringstream sstr(line); double num = NAN; while(sstr >> num) { region_electric_field_num.push_back(num); } if( dimension == 1 ) { for(size_t i = 0; i < region_electric_field_num.size(); i += 1) { auto x = region_electric_field_num[i]; region_electric_field_map[region][observable].emplace_back(x, 0, 0); } region_electric_field_num.clear(); } if(dimension == 3) { for(size_t i = 0; i < region_electric_field_num.size(); i += 3) { auto x = region_electric_field_num[i]; auto y = region_electric_field_num[i + 1]; auto z = region_electric_field_num[i + 2]; region_electric_field_map[region][observable].emplace_back(x, y, z); } } if(dimension == 2) { for(size_t i = 0; i < region_electric_field_num.size(); i += 2) { auto x = region_electric_field_num[i]; auto y = region_electric_field_num[i + 1]; region_electric_field_map[region][observable].emplace_back(0, x, y); } } region_electric_field_num.clear(); } LOG_PROGRESS(STATUS, "fieldlines") << "Parsing field data file: done."; return region_electric_field_map; }
tools/mesh_converter/parsers/SilvacoParser.hpp 0 → 100644 +53 −0 Original line number Diff line number Diff line /** * @file * * @copyright Copyright (c) 2017-2022 CERN and the Allpix Squared authors. * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md". * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an * Intergovernmental Organization or submit itself to any jurisdiction. * SPDX-License-Identifier: MIT */ #ifndef ALLPIX_MESHPARSER_SILVACO_H #define ALLPIX_MESHPARSER_SILVACO_H #include "../MeshParser.hpp" #include <iostream> #include <map> #include <vector> namespace mesh_converter { class SilvacoParser : public MeshParser { // Sections to read in extracted files enum class DFSection { NONE = 0, IGNORED, HEADER, INFO, REGION, COORDINATES, VERTICES, EDGES, FACES, ELEMENTS, DONOR_CONCENTRATION, DOPING_CONCENTRATION, ACCEPTOR_CONCENTRATION, ELECTRIC_FIELD, ELECTROSTATIC_POTENTIAL, VALUES }; private: // Read the grid MeshMap read_meshes(const std::string& file_name) override; // Read the electric field FieldMap read_fields(const std::string& file_name) override; }; } // namespace mesh_converter #endif // ALLPIX_MESHPARSER_SILVACO_H