src/modules/GeometryBuilderGeant4/GeometryBuilderGeant4Module.cpp
Implementation of Geant4 geometry construction module. More…
Functions
Name | |
---|---|
void | check_dataset_g4(const std::string & env_name) Checks if a particular Geant4 dataset is available in the environment. |
Detailed Description
Implementation of Geant4 geometry construction module.
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
Functions Documentation
function check_dataset_g4
static void check_dataset_g4(
const std::string & env_name
)
Checks if a particular Geant4 dataset is available in the environment.
Exceptions:
- ModuleError If a certain Geant4 dataset is not set or not available
Source code
#include "GeometryBuilderGeant4Module.hpp"
#include <cassert>
#include <memory>
#include <string>
#include <utility>
#include <G4GlobalConfig.hh>
#include <G4StateManager.hh>
#include <G4UImanager.hh>
#include <G4UIterminal.hh>
#include <G4Version.hh>
#include <G4VisManager.hh>
#include <Math/Vector3D.h>
#include "DetectorConstructionG4.hpp"
#include "GeometryConstructionG4.hpp"
#include "PassiveMaterialConstructionG4.hpp"
#include "tools/ROOT.h"
#include "tools/geant4/geant4.h"
#include "core/config/ConfigReader.hpp"
#include "core/config/exceptions.h"
#include "core/geometry/GeometryManager.hpp"
#include "core/utils/log.h"
#include "tools/geant4/G4ExceptionHandler.hpp"
#include "tools/geant4/G4LoggingDestination.hpp"
#include "tools/geant4/MTRunManager.hpp"
#include "tools/geant4/RunManager.hpp"
using namespace allpix;
using namespace ROOT;
GeometryBuilderGeant4Module::GeometryBuilderGeant4Module(Configuration& config, Messenger*, GeometryManager* geo_manager)
: Module(config), geo_manager_(geo_manager), run_manager_g4_(nullptr) {
// Register an exception handler for Geant4:
G4StateManager::GetStateManager()->SetExceptionHandler(new G4ExceptionHandler());
// Enable multithreading for Geant4 if it has been built with support for it:
#ifdef G4MULTITHREADED
LOG(INFO) << "Detected Geant4 multithreading capabilities, enabling multithreading support";
allow_multithreading();
#else
LOG(ERROR) << "Geant4 has been built without multithreading support, forcing multithreading off." << std::endl
<< "To allow multithreading, rebuild Geant4 with the GEANT4_BUILD_MULTITHREADED option enabled.";
#endif
// Read Geant4 verbosity configuration
auto g4cerr_log_level = config_.get<std::string>("log_level_g4cerr", "WARNING");
std::transform(g4cerr_log_level.begin(), g4cerr_log_level.end(), g4cerr_log_level.begin(), ::toupper);
auto g4cout_log_level = config_.get<std::string>("log_level_g4cout", "TRACE");
std::transform(g4cout_log_level.begin(), g4cout_log_level.end(), g4cout_log_level.begin(), ::toupper);
// Set Geant4 G4cerr log level
try {
LogLevel log_level = Log::getLevelFromString(g4cerr_log_level);
G4LoggingDestination::setG4cerrReportingLevel(log_level);
} catch(std::invalid_argument& e) {
throw InvalidValueError(config_, "log_level_g4cerr", "invalid log level provided");
}
// Set Geant G4cout log level
try {
LogLevel log_level = Log::getLevelFromString(g4cout_log_level);
G4LoggingDestination::setG4coutReportingLevel(log_level);
} catch(std::invalid_argument& e) {
throw InvalidValueError(config_, "log_level_g4cout", "invalid log level provided");
}
// Set up UI manager with logging destination
G4UImanager* ui_g4 = G4UImanager::GetUIpointer();
ui_g4->SetCoutDestination(G4LoggingDestination::getInstance());
geometry_construction_ = new GeometryConstructionG4(geo_manager_, config_);
}
static void check_dataset_g4(const std::string& env_name) {
#if G4VERSION_NUMBER >= 1110
const char* file_name = G4FindDataDir(env_name.c_str());
#else
const char* file_name = std::getenv(env_name.c_str());
#endif
if(file_name == nullptr) {
throw ModuleError("Geant4 environment variable " + env_name +
" is not set, make sure to source a Geant4 "
"environment with all datasets");
}
std::ifstream file(file_name);
if(!file.good()) {
throw ModuleError("Geant4 environment variable " + env_name +
" does not point to existing dataset, the Geant4 "
"environment is invalid");
}
// FIXME: check if file does actually contain a correct dataset
}
void GeometryBuilderGeant4Module::initialize() {
// Check if all the required geant4 datasets are defined
LOG(DEBUG) << "Checking Geant4 datasets";
check_dataset_g4("G4LEVELGAMMADATA");
check_dataset_g4("G4RADIOACTIVEDATA");
check_dataset_g4("G4PIIDATA");
check_dataset_g4("G4SAIDXSDATA");
check_dataset_g4("G4ABLADATA");
check_dataset_g4("G4REALSURFACEDATA");
check_dataset_g4("G4NEUTRONHPDATA");
check_dataset_g4("G4ENSDFSTATEDATA");
check_dataset_g4("G4LEDATA");
// Check for Neutron XS data only for Geant4 version prior to 10.5, deprecated dataset from 10.5
#if G4VERSION_NUMBER < 1050
check_dataset_g4("G4NEUTRONXSDATA");
#endif
// Create the G4 run manager. If multithreading was requested we use the custom run manager
// that support calling BeamOn operations in parallel. Otherwise we use default manager.
if(multithreadingEnabled()) {
LOG(DEBUG) << "Making a multi-thread RunManager";
run_manager_g4_ = std::make_unique<MTRunManager>();
} else {
LOG(DEBUG) << "Making a single-thread RunManager";
run_manager_g4_ = std::make_unique<RunManager>();
LOG(INFO) << "Using Geant4 modules without multithreading might reduce performance when using complex geometries, "
"please check the documentation for details";
}
// Set the geometry construction to use
run_manager_g4_->SetUserInitialization(geometry_construction_);
// Run the geometry construct function in GeometryConstructionG4
LOG(TRACE) << "Building Geant4 geometry";
run_manager_g4_->InitializeGeometry();
}
Updated on 2024-12-13 at 08:31:37 +0000