src/core/config/ConfigManager.cpp
Implementation of config manager. More…
Detailed Description
Implementation of config manager.
Copyright: Copyright (c) 2017-2024 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
Source code
#include "ConfigManager.hpp"
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>
#include "Configuration.hpp"
#include "core/config/exceptions.h"
#include "core/utils/log.h"
using namespace allpix;
ConfigManager::ConfigManager(std::filesystem::path file_name,
std::initializer_list<std::string> global,
std::initializer_list<std::string> ignore) {
// Check if the file exists
std::ifstream file(file_name);
if(!file || !std::filesystem::is_regular_file(file_name)) {
throw ConfigFileUnavailableError(file_name);
}
// Convert main file to absolute path
file_name = std::filesystem::canonical(file_name);
LOG(TRACE) << "Reading main configuration";
// Read the file
ConfigReader reader(file, std::move(file_name));
// Convert all global and ignored names to lower case and store them
auto lowercase = [](const std::string& in) { return allpix::transform(in, ::tolower); };
std::transform(global.begin(), global.end(), std::inserter(global_names_, global_names_.end()), lowercase);
std::transform(ignore.begin(), ignore.end(), std::inserter(ignore_names_, ignore_names_.end()), lowercase);
// Initialize global base configuration
global_config_ = reader.getHeaderConfiguration();
// Store all the configurations read
for(auto& config : reader.getConfigurations()) {
// Skip all ignored sections
std::string config_name = allpix::transform(config.getName(), ::tolower);
if(ignore_names_.find(config_name) != ignore_names_.end()) {
continue;
}
// Merge all global section with the global config
if(global_names_.find(config_name) != global_names_.end()) {
global_config_.merge(config);
continue;
}
module_configs_.push_back(config);
}
}
void ConfigManager::parse_detectors() {
// If detector configurations have been parsed already, skip:
if(!detector_configs_.empty()) {
return;
}
// Reading detector file
std::string detector_file_name = global_config_.getPath("detectors_file", true);
LOG(TRACE) << "Reading detector configuration";
std::ifstream detector_file(detector_file_name);
ConfigReader detector_reader(detector_file, detector_file_name);
auto detector_configs = detector_reader.getConfigurations();
detector_configs_ = std::list<Configuration>(detector_configs.begin(), detector_configs.end());
}
bool ConfigManager::loadModuleOptions(const std::vector<std::string>& options) {
bool optionsApplied = false;
// Parse the options
for(const auto& option : options) {
module_option_parser_.parseOption(option);
}
// Apply global options
optionsApplied = module_option_parser_.applyGlobalOptions(global_config_) || optionsApplied;
// Apply module options
for(auto& config : module_configs_) {
optionsApplied = module_option_parser_.applyOptions(config.getName(), config) || optionsApplied;
}
return optionsApplied;
}
bool ConfigManager::loadDetectorOptions(const std::vector<std::string>& options) {
bool optionsApplied = false;
// Create the parser
OptionParser detector_option_parser;
// Parse the options
for(const auto& option : options) {
detector_option_parser.parseOption(option);
}
// Apply detector options
parse_detectors();
for(auto& config : detector_configs_) {
optionsApplied = detector_option_parser.applyOptions(config.getName(), config) || optionsApplied;
}
return optionsApplied;
}
std::list<Configuration>& ConfigManager::getDetectorConfigurations() {
parse_detectors();
return detector_configs_;
}
Configuration& ConfigManager::addInstanceConfiguration(const ModuleIdentifier& identifier, const Configuration& config) {
// Check uniqueness
if(instance_identifier_to_config_.find(identifier) != instance_identifier_to_config_.end()) {
throw ModuleIdentifierAlreadyAddedError(identifier);
}
// Add configuration
instance_configs_.push_back(config);
Configuration& ret_config = instance_configs_.back();
instance_identifier_to_config_[identifier] = --instance_configs_.end();
// Add identifier key to config
ret_config.set<std::string>("identifier", identifier.getIdentifier());
// Apply instance options
module_option_parser_.applyOptions(identifier.getUniqueName(), ret_config);
return ret_config;
}
void ConfigManager::dropInstanceConfiguration(const ModuleIdentifier& identifier) {
// Remove config from instance configs and from instance identifier map
if(instance_identifier_to_config_.find(identifier) != instance_identifier_to_config_.end()) {
instance_configs_.erase(instance_identifier_to_config_[identifier]);
instance_identifier_to_config_.erase(identifier);
} else {
throw ModuleIdentifierNotFoundError(identifier);
}
}
Updated on 2024-12-13 at 08:31:37 +0000