Commit 0f508ae4 authored by Marco Bomben's avatar Marco Bomben
Browse files

1st working version of SilvacoParser

parent 206d768c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
@@ -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");
    }
@@ -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 {
+1 −0
Original line number Diff line number Diff line
@@ -69,5 +69,6 @@ namespace mesh_converter {
} // namespace mesh_converter

#include "parsers/DFISEParser.hpp"
#include "parsers/SilvacoParser.hpp"

#endif // ALLPIX_MESHPARSER_H
+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;
}
+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