Commit 048e7107 authored by Paul Schütze's avatar Paul Schütze
Browse files

Merge branch 'microelec-physics' into 'master'

Additional Geant4 Physics Lists

See merge request allpix-squared/allpix-squared!1095
parents e016e52f 8d3b9050
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ The following authors, in alphabetical order, have developed or contributed to A

* Babar Ali, Czech Technical University in Prague, [bali](https://gitlab.cern.ch/bali)
* Mohamed Moanis Ali, GSOC2019 Student, [mmoanis](https://github.com/mmoanis)
* Jay Archer, University of Wollongong, [jarcher](https://gitlab.cern.ch/jarcher)
* Mathieu Benoit, BNL, [mbenoit](https://gitlab.cern.ch/mbenoit)
* Thomas Billoud, Université de Montréal, [tbilloud](https://gitlab.cern.ch/tbilloud)
* Tobias Bisanz, CERN, [tbisanz](https://gitlab.cern.ch/tbisanz)
+42 −0
Original line number Diff line number Diff line
/**
 * @file
 * @brief Handler for implementation of additional PhysicsLists included in AllPix2 but not in the G4PhysListFactory.
 *
 * @copyright Copyright (c) 2017-2023 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_ADDITIONAL_PHYSICS_LISTS_H
#define ALLPIX_ADDITIONAL_PHYSICS_LISTS_H

#include <G4VModularPhysicsList.hh>

#include "MicroElecSiPhysics.hh"

/**
 * @brief Handler namespace for implementing additional PhysicsLists included in AllPix2 but not in the
 * G4PhysListFactory.
 */
namespace allpix::physicslists {

    /**
     * @brief Function to obtain
     * @param  list_name    Name of the additional physics list
     * @return              Pointer to the G4VModularPhysicsList of the found physics list, or a nullptr if not found.
     */
    inline G4VModularPhysicsList* getList(const std::string& list_name) {

        if(list_name == "MICROELEC-SIONLY") {
            // Downcasting from a G4VUserPhysicsList* to a G4VModularPhysicsList
            return dynamic_cast<G4VModularPhysicsList*>(new MicroElecSiPhysics());
        }

        return nullptr;
    }

} // namespace allpix::physicslists

#endif
+34 −0
Original line number Diff line number Diff line
@@ -18,6 +18,40 @@ ALLPIX_MODULE_SOURCES(
# Allpix Geant4 interface is required for this module
ALLPIX_MODULE_REQUIRE_GEANT4_INTERFACE(${MODULE_NAME} REQUIRED)

# If available, add additional physics lists form Geant4:
IF(DEFINED ENV{GEANT4_DATA_DIR})
    # Set variable to microelectronics example folder
    SET(GEANT4_EXAMPLES_DIR $ENV{GEANT4_DATA_DIR}/../examples)
ELSE()
    FIND_PROGRAM(G4CONFIG "geant4-config")
    IF(G4CONFIG)
        EXEC_PROGRAM(${G4CONFIG} ARGS --prefix OUTPUT_VARIABLE G4_PATH)
        EXEC_PROGRAM(${G4CONFIG} ARGS --version OUTPUT_VARIABLE G4_VERSION)
        IF(EXISTS "${G4_PATH}/share/Geant4-${G4_VERSION}" AND IS_DIRECTORY "${G4_PATH}/share/Geant4-${G4_VERSION}")
            SET(GEANT4_EXAMPLES_DIR ${G4_PATH}/share/Geant4-${G4_VERSION}/examples)
        ELSEIF(EXISTS "${G4_PATH}/share/Geant4" AND IS_DIRECTORY "${G4_PATH}/share/Geant4")
            SET(GEANT4_EXAMPLES_DIR ${G4_PATH}/share/Geant4/examples)
        ENDIF()
    ENDIF()
ENDIF()

IF(DEFINED GEANT4_EXAMPLES_DIR)
    MESSAGE(STATUS "  Found Geant4 Examples, building add. physics lists")
    CONFIGURE_FILE(
        ${GEANT4_EXAMPLES_DIR}/advanced/microelectronics/src/MicroElecSiPhysics.cc ${CMAKE_CURRENT_BINARY_DIR}/ COPYONLY)
    CONFIGURE_FILE(
        ${GEANT4_EXAMPLES_DIR}/advanced/microelectronics/src/ElectronCapture.cc ${CMAKE_CURRENT_BINARY_DIR}/ COPYONLY)

    TARGET_SOURCES(${MODULE_NAME} PRIVATE
        ${CMAKE_CURRENT_BINARY_DIR}/MicroElecSiPhysics.cc
        ${CMAKE_CURRENT_BINARY_DIR}/ElectronCapture.cc)

    SET_SOURCE_FILES_PROPERTIES(
        ${CMAKE_CURRENT_BINARY_DIR}/ElectronCapture.cc PROPERTIES COMPILE_FLAGS -Wno-zero-as-null-pointer-constant)
    # Add includes from the microelectronics example
    TARGET_INCLUDE_DIRECTORIES(${MODULE_NAME} SYSTEM PRIVATE ${GEANT4_EXAMPLES_DIR}/advanced/microelectronics/include)
ENDIF()

# Register module tests
ALLPIX_MODULE_TESTS(${MODULE_NAME} "tests")

+37 −4
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@
#include "tools/geant4/RunManager.hpp"
#include "tools/geant4/geant4.h"

#include "AdditionalPhysicsLists.hpp"

#include "ActionInitializationG4.hpp"
#include "GeneratorActionG4.hpp"
#include "SDAndFieldConstruction.hpp"
@@ -170,13 +172,20 @@ void DepositionGeant4Module::initialize() {
    auto physics_list = allpix::transform(config_.get<std::string>("physics_list"), ::toupper);
    G4PhysListFactory physListFactory;
    G4VModularPhysicsList* physicsList{nullptr};

    try {
        // Check if present in AdditionalPhysicsLists
        physicsList = physicslists::getList(physics_list);

        // Otherwise, attempt to get the physics list from the factory
        if(physicsList == nullptr) {
            // Geant4 throws an exception if the list is not found
            physicsList = physListFactory.GetReferencePhysList(physics_list);
            // ...but older versions of it don't, so let's do this ourselves:
            if(physicsList == nullptr) {
                throw ModuleError("");
            }
        }
    } catch(ModuleError&) {
        std::string message = "specified physics list does not exists";
        std::vector<G4String> base_lists = physListFactory.AvailablePhysLists();
@@ -211,6 +220,30 @@ void DepositionGeant4Module::initialize() {
        physicsList->RegisterPhysics(new G4RadioactiveDecayPhysics());
    }

    // If the specified physics list is one of the microelec variations, apply a target region to the volumes with silicon
    // materials
    if(physics_list == "MICROELEC" || physics_list == "MICROELEC-SIONLY") {
        // Create target region
        auto* region = new G4Region("Target");

        for(auto& detector : geo_manager_->getDetectors()) {
            // Get the logical volume
            auto logical_volume = geo_manager_->getExternalObject<G4LogicalVolume>(detector->getName(), "sensor_log");
            if(logical_volume == nullptr) {
                throw ModuleError("Detector " + detector->getName() + " has no sensitive device (broken Geant4 geometry)");
            }

            // Assign region to target if silicon
            if(logical_volume->GetMaterial()->GetName() == "G4_Si") {
                region->AddRootLogicalVolume(logical_volume.get());

                LOG(DEBUG) << "Added " << logical_volume->GetName() << " to region " << region->GetName()
                           << " for MicroElec physics"
                           << "\n";
            }
        }
    }

    // Set the range-cut off threshold for secondary production:
    double production_cut = NAN;
    if(config_.has("range_cut")) {
+2 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ The scale of the plot axis can be adjusted using the `output_plots_scale` parame
This module requires an installation Geant4.

## Parameters
* `physics_list`: Geant4-internal list of physical processes to simulate, defaults to FTFP_BERT_LIV. More information about possible physics list and recommendations for defaults are available on the Geant4 website \[[@g4physicslists]\].
* `physics_list`: Geant4-internal list of physical processes to simulate, defaults to FTFP_BERT_LIV. More information about possible physics list and recommendations for defaults are available on the Geant4 website \[[@g4physicslists]\]. The MicroElec track structure physics list \[[@microelec]\] can also be implemented for ions and electrons, currently in only silicon by specifying **microelec-sionly**.
* `enable_pai`: Determines if the Photoabsorption Ionization model is enabled in the sensors of all detectors. Defaults to false.
* `pai_model`: Model can be **pai** for the normal Photoabsorption Ionization model or **paiphoton** for the photon model. Default is **pai**. Only used if *enable_pai* is set to true.
* `charge_creation_energy` : Energy needed to create a charge deposit. Defaults to the energy needed to create an electron-hole pair in the respective sensor material (e.g. 3.64 eV for silicon sensors, \[[@chargecreation]\]). A full list of supported materials can be found elsewhere in the manual.
@@ -165,3 +165,4 @@ number_of_particles = 1
[@pai]: https://doi.org/10.1016/S0168-9002(00)00457-5
[@chargecreation]: https://doi.org/10.1103/PhysRevB.1.2945
[@fano]: https://doi.org/10.1103%2FPhysRevB.22.5565
[@microelec]: https://doi.org/10.1016/j.nimb.2020.11.016