From 5c1e3938577f9fe7f169be048a3486e7a42d15ab Mon Sep 17 00:00:00 2001 From: Oliver Lantwin Date: Fri, 8 Aug 2025 00:32:50 +0200 Subject: [PATCH 1/8] feat!(sim): Use g4Config.yaml instead of deprecated .C Add YAML config including all settings from .C. Set ShipStack and its options explicitly in simulation scripts. Thorough testing needed. Fixed #543 --- CHANGELOG.md | 1 + gconfig/g4Config.C | 61 ---------------------- gconfig/g4Config.yaml | 45 ++++++++++++++++ gconfig/g4Config_basic.C | 60 --------------------- gconfig/g4Config_basic.yaml | 43 +++++++++++++++ gconfig/g4config.in | 39 -------------- gconfig/g4config_basic.in | 28 ---------- macro/create_field_perturbation.py | 13 ++++- macro/inspectGeant4Geo.py | 12 ++++- macro/run_fixedTarget.py | 12 ++++- macro/run_simScript.py | 15 +++++- muonShieldOptimization/study_GammaConv.py | 12 ++++- muonShieldOptimization/study_muMSC.py | 12 ++++- muonShieldOptimization/study_thinTarget.py | 12 ++++- 14 files changed, 169 insertions(+), 196 deletions(-) delete mode 100644 gconfig/g4Config.C create mode 100644 gconfig/g4Config.yaml delete mode 100644 gconfig/g4Config_basic.C create mode 100644 gconfig/g4Config_basic.yaml delete mode 100644 gconfig/g4config.in delete mode 100644 gconfig/g4config_basic.in diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba3842349..2d41efb270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ it in future. * Bump minimum ROOT version to 6.36 * Bump minimum CMake version to 3.20 (same as ROOT) * Change naming convention for simulation files to `{sim,geo,params}_{uuid4}.root`, with optional `--tag` parameter to specify custom identifier +* Use g4Config.yaml instead of deprecated .C macro for Geant4 VMC configuration ### Fixed diff --git a/gconfig/g4Config.C b/gconfig/g4Config.C deleted file mode 100644 index 39ac567706..0000000000 --- a/gconfig/g4Config.C +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// SPDX-FileCopyrightText: Copyright CERN for the benefit of the SHiP -// Collaboration - -// Configuration macro for Geant4 VirtualMC -void Config() { - /// Create the run configuration - /// In constructor user has to specify the geometry input - /// and select geometry navigation via the following options: - /// - geomVMCtoGeant4 - geometry defined via VMC, G4 native navigation - /// - geomVMCtoRoot - geometry defined via VMC, Root navigation - /// - geomRoot - geometry defined via Root, Root navigation - /// - geomRootToGeant4 - geometry defined via Root, G4 native navigation - /// - geomGeant4 - geometry defined via Geant4, G4 native navigation - /// - /// The second argument in the constructor selects physics list: - /// - emStandard - standard em physics (default) - /// - emStandard+optical - standard em physics + optical physics - /// - XYZ - selected hadron physics list ( XYZ = LHEP, QGSP, - /// ...) - /// - XYZ+optical - selected hadron physics list + optical physics - /// - /// The third argument activates the special processes in the - /// TG4SpecialPhysicsList, which implement VMC features: - /// - stepLimiter - step limiter (default) - /// - specialCuts - VMC cuts - /// - specialControls - VMC controls for activation/inactivation selected - /// processes - /// - stackPopper - stackPopper process - /// When more than one options are selected, they should be separated with '+' - /// character: eg. stepLimit+specialCuts. - TG4RunConfiguration* runConfiguration = - new TG4RunConfiguration("geomRoot", "FTFP_BERT_HP_EMZ", - "stepLimiter+specialCuts+specialControls"); - - /// Create the G4 VMC - TGeant4* geant4 = - new TGeant4("TGeant4", "The Geant4 Monte Carlo", runConfiguration); - /// create the Specific stack - ShipStack* stack = new ShipStack(1000); - stack->StoreSecondaries(kTRUE); - stack->SetMinPoints(0); - geant4->SetStack(stack); - // if(FairRunSim::Instance()->IsExtDecayer()){ - // // does not work ! TVirtualMCDecayer* decayer = - // TPythia8Decayer::Instance(); - // TVirtualMCDecayer* decayer = TVirtualMCDecayer* TPythia8Decayer(); - // geant4->SetExternalDecayer(decayer); - // } - - /// Customise Geant4 setting - /// (verbose level, global range cut, ..) - - TString configm(gSystem->Getenv("VMCWORKDIR")); - TString configm1 = configm + "/gconfig/g4config.in"; - cout << " -I g4Config() using g4conf macro: " << configm1 << endl; - // set geant4 specific stuff - // still stupid bug in geant4_vmc - // geant4->SetMaxNStep(10000.); // default is 30000 - geant4->ProcessGeantMacro(configm1.Data()); -} diff --git a/gconfig/g4Config.yaml b/gconfig/g4Config.yaml new file mode 100644 index 0000000000..62bcbacacc --- /dev/null +++ b/gconfig/g4Config.yaml @@ -0,0 +1,45 @@ +Geant4_UserGeometry: "geomRoot" +Geant4_PhysicsList: "QGSP_BERT_HP_PEN" +Geant4_SpecialProcess: "stepLimiter+specialCuts+specialControls" +Geant4_SpecialStacking: false +Geant4_Multithreaded: false + +Geant4_MaxNStep: 10000 #default is 30000 +Geant4_Commands: + - /mcVerbose/all 0 + - /mcTracking/loopVerbose 0 + - /mcPhysics/g4NeutronHPVerbose 0 + - /mcPhysics/g4HadronicProcessStoreVerbose 0 + - /physics_lists/em/PositronToMuons true + - /physics_lists/em/GammaToMuons true + - /process/em/verbose 0 + - /process/eLoss/verbose 0 + - /mcDet/setIsLocalMagField true + +MonteCarlo_Process: + PAIR: 1 #pair production + COMP: 1 #Compton scattering + PHOT: 1 #photo electric effect + PFIS: 0 #photofission + DRAY: 1 #delta-ray + ANNI: 1 #annihilation + BREM: 1 #bremsstrahlung + HADR: 1 #hadronic process + MUNU: 1 #muon nuclear interaction + DCAY: 1 #decay + LOSS: 1 #energy loss + MULS: 1 #multiple scattering + +MonteCarlo_Cut: + CUTGAM: 1.0E-3 #gammas (GeV) + CUTELE: 1.0E-3 #electrons (GeV) + CUTNEU: 1.0E-3 #neutral hadrons (GeV) + CUTHAD: 1.0E-3 #charged hadrons (GeV) + CUTMUO: 1.0E-3 #muons (GeV) + BCUTE: 1.0E-3 #electron bremsstrahlung (GeV) + BCUTM: 1.0E-3 #muon and hadron bremsstrahlung (GeV) + DCUTE: 1.0E-3 #electron delta-rays (GeV) + DCUTM: 1.0E-3 #muon and hadron delta-rays (GeV) + PPCUTM: 1.0E-3 #direct pair production by muons (GeV) + TOFMAX: 1.E10 #time of flight cut (s) + GCUTS: 1.0E-3 #gamma transport cut (GeV) diff --git a/gconfig/g4Config_basic.C b/gconfig/g4Config_basic.C deleted file mode 100644 index 97709c0f39..0000000000 --- a/gconfig/g4Config_basic.C +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// SPDX-FileCopyrightText: Copyright CERN for the benefit of the SHiP -// Collaboration - -// Configuration macro for Geant4 VirtualMC -void Config() { - /// Create the run configuration - /// In constructor user has to specify the geometry input - /// and select geometry navigation via the following options: - /// - geomVMCtoGeant4 - geometry defined via VMC, G4 native navigation - /// - geomVMCtoRoot - geometry defined via VMC, Root navigation - /// - geomRoot - geometry defined via Root, Root navigation - /// - geomRootToGeant4 - geometry defined via Root, G4 native navigation - /// - geomGeant4 - geometry defined via Geant4, G4 native navigation - /// - /// The second argument in the constructor selects physics list: - /// - emStandard - standard em physics (default) - /// - emStandard+optical - standard em physics + optical physics - /// - XYZ - selected hadron physics list ( XYZ = LHEP, QGSP, - /// ...) - /// - XYZ+optical - selected hadron physics list + optical physics - /// - /// The third argument activates the special processes in the - /// TG4SpecialPhysicsList, which implement VMC features: - /// - stepLimiter - step limiter (default) - /// - specialCuts - VMC cuts - /// - specialControls - VMC controls for activation/inactivation selected - /// processes - /// - stackPopper - stackPopper process - /// When more than one options are selected, they should be separated with '+' - /// character: eg. stepLimit+specialCuts. - TG4RunConfiguration* runConfiguration = - new TG4RunConfiguration("geomRoot", "emStandard"); - - /// Create the G4 VMC - TGeant4* geant4 = - new TGeant4("TGeant4", "The Geant4 Monte Carlo", runConfiguration); - /// create the Specific stack - ShipStack* stack = new ShipStack(1000); - stack->StoreSecondaries(kTRUE); - stack->SetMinPoints(0); - geant4->SetStack(stack); - // if(FairRunSim::Instance()->IsExtDecayer()){ - // // does not work ! TVirtualMCDecayer* decayer = - // TPythia8Decayer::Instance(); - // TVirtualMCDecayer* decayer = TVirtualMCDecayer* TPythia8Decayer(); - // geant4->SetExternalDecayer(decayer); - // } - - /// Customise Geant4 setting - /// (verbose level, global range cut, ..) - - TString configm(gSystem->Getenv("VMCWORKDIR")); - TString configm1 = configm + "/gconfig/g4config_basic.in"; - cout << " -I g4Config() using g4conf macro: " << configm1 << endl; - // set geant4 specific stuff - // still stupid bug in geant4_vmc - // geant4->SetMaxNStep(10000.); // default is 30000 - geant4->ProcessGeantMacro(configm1.Data()); -} diff --git a/gconfig/g4Config_basic.yaml b/gconfig/g4Config_basic.yaml new file mode 100644 index 0000000000..1618124d42 --- /dev/null +++ b/gconfig/g4Config_basic.yaml @@ -0,0 +1,43 @@ +Geant4_UserGeometry: "geomRoot" +Geant4_PhysicsList: "emStandard" +Geant4_SpecialProcess: "" +Geant4_SpecialStacking: false +Geant4_Multithreaded: false + +Geant4_MaxNStep: 10000 #default is 30000 +Geant4_Commands: + - /mcVerbose/all 0 + - /mcTracking/loopVerbose 0 + - /mcPhysics/g4NeutronHPVerbose 0 + - /mcPhysics/g4HadronicProcessStoreVerbose 0 + - /process/em/verbose 0 + - /process/eLoss/verbose 0 + - /mcDet/setIsLocalMagField true + +MonteCarlo_Process: + PAIR: 1 #pair production + COMP: 1 #Compton scattering + PHOT: 1 #photo electric effect + PFIS: 0 #photofission + DRAY: 1 #delta-ray + ANNI: 1 #annihilation + BREM: 1 #bremsstrahlung + HADR: 1 #hadronic process + MUNU: 1 #muon nuclear interaction + DCAY: 1 #decay + LOSS: 1 #energy loss + MULS: 1 #multiple scattering + +MonteCarlo_Cut: + CUTGAM: 1.0E-3 #gammas (GeV) + CUTELE: 1.0E-3 #electrons (GeV) + CUTNEU: 1.0E-3 #neutral hadrons (GeV) + CUTHAD: 1.0E-3 #charged hadrons (GeV) + CUTMUO: 1.0E-3 #muons (GeV) + BCUTE: 1.0E-3 #electron bremsstrahlung (GeV) + BCUTM: 1.0E-3 #muon and hadron bremsstrahlung (GeV) + DCUTE: 1.0E-3 #electron delta-rays (GeV) + DCUTM: 1.0E-3 #muon and hadron delta-rays (GeV) + PPCUTM: 1.0E-3 #direct pair production by muons (GeV) + TOFMAX: 1.E10 #time of flight cut (s) + GCUTS: 1.0E-3 #gamma transport cut (GeV) diff --git a/gconfig/g4config.in b/gconfig/g4config.in deleted file mode 100644 index 9a1dfe4bf9..0000000000 --- a/gconfig/g4config.in +++ /dev/null @@ -1,39 +0,0 @@ -# -# Geant4 configuration macro for Example02 -# (called from Root macro Config.C) - -/mcVerbose/all 0 -/mcTracking/loopVerbose 0 # suggested by Ivana Hrivnacova to switch off *** Particle reached max step number .... -/mcPhysics/g4HadronicProcessStoreVerbose 0 - -/mcVerbose/all 0 - -# switch on other sources of di muon -/physics_lists/em/PositronToMuons true -/physics_lists/em/GammaToMuons true -# turn off UseGeneralProcess to access GammaToMuons directly when cross-sections need to be changed -/process/em/UseGeneralProcess false - -# drives me crazy how to stop this tons of output !!! -/process/em/verbose 0 -/process/eLoss/verbose 0 - -#/mcVerbose/composedPhysicsList 0 -#/mcVerbose/trackManager 2 - -#/mcVerbose/regionsManager 3 - -#/run/particle/applyCuts -#/mcTracking/saveSecondariesInStep true - -#/tracking/verbose 1 -#/control/cout/ignoreThreadsExcept 0 - -# Enable local magnetic fields -/mcDet/setIsLocalMagField true - -# Force J/psi to use external decayer instead of GEANT4 internal decay table -/mcPhysics/setExtDecayerSelection J/psi - -# Enable verbosity for VMC geometry manager -#/mcVerbose/geometryManager 2 diff --git a/gconfig/g4config_basic.in b/gconfig/g4config_basic.in deleted file mode 100644 index 0e840597e7..0000000000 --- a/gconfig/g4config_basic.in +++ /dev/null @@ -1,28 +0,0 @@ -# -# Geant4 configuration macro for Example02 -# (called from Root macro Config.C) - -/mcVerbose/all 0 -/mcTracking/loopVerbose 0 # suggested by Ivana Hrivnacova to switch off *** Particle reached max step number .... -/mcPhysics/g4NeutronHPVerbose 0 # - suppress the warnings about missing neutron data -/mcPhysics/g4HadronicProcessStoreVerbose 0 - -# drives me crazy how to stop this tons of output !!! -/process/em/verbose 0 -/process/eLoss/verbose 0 - -#/mcVerbose/composedPhysicsList 0 -#/mcVerbose/trackManager 2 - -#/mcVerbose/regionsManager 3 - -#/run/particle/applyCuts -#/mcTracking/saveSecondariesInStep true - -#/tracking/verbose 1 -#/control/cout/ignoreThreadsExcept 0 - -# Enable local magnetic fields -/mcDet/setIsLocalMagField true -# Enable verbosity for VMC geometry manager -#/mcVerbose/geometryManager 2 diff --git a/macro/create_field_perturbation.py b/macro/create_field_perturbation.py index 8ff4480e37..3573b6f76a 100644 --- a/macro/create_field_perturbation.py +++ b/macro/create_field_perturbation.py @@ -25,14 +25,23 @@ def create_csv_field_map(options): run = r.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(r.FairRootFileSink("tmp_file")) # Output file - # user configuration file default g4Config.C - run.SetUserConfig("g4Config.C") + # Use FairYamlVMCConfig for YAML configuration + yamlConfig = r.FairYamlVMCConfig("g4Config", "g4Config.yaml") + yamlConfig.Setup() shipDet_conf.configure(run, ship_geo) primGen = r.FairPrimaryGenerator() primGen.SetTarget(ship_geo.target.z0 + 70.845 * u.m, 0.0) # run.SetGenerator(primGen) run.SetStoreTraj(r.kFALSE) + # Create and set custom ShipStack for YAML config compatibility + stack = r.ShipStack(1000) + stack.StoreSecondaries(r.kTRUE) + stack.SetMinPoints(0) + # Get the Geant4 VMC instance and set our custom stack + geant4 = r.TVirtualMC.GetMC() + if geant4: + geant4.SetStack(stack) run.Init() fieldMaker = geomGeant4.addVMCFields(ship_geo, "", True) diff --git a/macro/inspectGeant4Geo.py b/macro/inspectGeant4Geo.py index ba25e4ff4f..686409b0f7 100644 --- a/macro/inspectGeant4Geo.py +++ b/macro/inspectGeant4Geo.py @@ -20,9 +20,19 @@ run = ROOT.FairRunSim() ShipGeo = load_from_root_file(fgeo, "ShipGeo") modules = shipDet_conf.configure(run, ShipGeo) -run.SetUserConfig("g4Config.C") +# Use FairYamlVMCConfig for YAML configuration +yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") +yamlConfig.Setup() run.SetName("TGeant4") run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) +# Create and set custom ShipStack for YAML config compatibility +stack = ROOT.ShipStack(1000) +stack.StoreSecondaries(ROOT.kTRUE) +stack.SetMinPoints(0) +# Get the Geant4 VMC instance and set our custom stack +geant4 = ROOT.TVirtualMC.GetMC() +if geant4: + geant4.SetStack(stack) run.Init() run.Run(0) import geomGeant4 diff --git a/macro/run_fixedTarget.py b/macro/run_fixedTarget.py index 7faecdd771..b4efeef1f8 100644 --- a/macro/run_fixedTarget.py +++ b/macro/run_fixedTarget.py @@ -248,7 +248,9 @@ def get_work_dir(run_number, tag=None): run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -run.SetUserConfig("g4Config.C") # user configuration file default g4Config.C +# Use FairYamlVMCConfig for YAML configuration +yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") +yamlConfig.Setup() rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -385,6 +387,14 @@ def get_work_dir(run_number, tag=None): run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ +# Create and set custom ShipStack for YAML config compatibility +stack = ROOT.ShipStack(1000) +stack.StoreSecondaries(ROOT.kTRUE) +stack.SetMinPoints(0) +# Get the Geant4 VMC instance and set our custom stack +geant4 = ROOT.TVirtualMC.GetMC() +if geant4: + geant4.SetStack(stack) run.Init() gMC = ROOT.TVirtualMC.GetMC() diff --git a/macro/run_simScript.py b/macro/run_simScript.py index bc073ff82f..22c5018c36 100755 --- a/macro/run_simScript.py +++ b/macro/run_simScript.py @@ -375,7 +375,9 @@ run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -run.SetUserConfig("g4Config.C") # user configuration file default g4Config.C +# Use FairYamlVMCConfig for YAML configuration +yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") +yamlConfig.Setup() rtdb = run.GetRuntimeDb() # -----Create geometry---------------------------------------------- # import shipMuShield_only as shipDet_conf # special use case for an attempt to convert active shielding geometry for use with FLUKA @@ -639,12 +641,23 @@ else: run.SetStoreTraj(ROOT.kFALSE) + # -----Configure external decayer globally------------------------------------ # Override any previous SetPythiaDecayer calls if EvtGenDecayer is requested if options.evtgen_decayer: run.SetPythiaDecayer("DecayConfigTEvtGen.C") print("Using TEvtGenDecayer for J/psi and quarkonium decays with EvtGen") +# -----Create and set custom ShipStack for YAML config compatibility----- +if mcEngine == "TGeant4": + stack = ROOT.ShipStack(1000) + stack.StoreSecondaries(ROOT.kTRUE) + stack.SetMinPoints(0) + # Get the Geant4 VMC instance and set our custom stack + geant4 = ROOT.TVirtualMC.GetMC() + if geant4: + geant4.SetStack(stack) + # -----Initialize simulation run------------------------------------ run.Init() if options.dryrun: # Early stop after setting up Pythia 8 diff --git a/muonShieldOptimization/study_GammaConv.py b/muonShieldOptimization/study_GammaConv.py index eb57b84499..1a7b531172 100644 --- a/muonShieldOptimization/study_GammaConv.py +++ b/muonShieldOptimization/study_GammaConv.py @@ -50,7 +50,9 @@ run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -run.SetUserConfig("g4Config.C") # user configuration file default g4Config.C +# Use FairYamlVMCConfig for YAML configuration +yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") +yamlConfig.Setup() rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -111,6 +113,14 @@ def makeSensitive(self, sensPlane): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ +# Create and set custom ShipStack for YAML config compatibility +stack = ROOT.ShipStack(1000) +stack.StoreSecondaries(ROOT.kTRUE) +stack.SetMinPoints(0) +# Get the Geant4 VMC instance and set our custom stack +geant4 = ROOT.TVirtualMC.GetMC() +if geant4: + geant4.SetStack(stack) run.Init() gMC = ROOT.TVirtualMC.GetMC() diff --git a/muonShieldOptimization/study_muMSC.py b/muonShieldOptimization/study_muMSC.py index 779b0e90db..8f91fc230d 100644 --- a/muonShieldOptimization/study_muMSC.py +++ b/muonShieldOptimization/study_muMSC.py @@ -52,7 +52,9 @@ run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -run.SetUserConfig("g4Config.C") # user configuration file default g4Config.C +# Use FairYamlVMCConfig for YAML configuration +yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") +yamlConfig.Setup() rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -108,6 +110,14 @@ def InitParContainers(): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ +# Create and set custom ShipStack for YAML config compatibility +stack = ROOT.ShipStack(1000) +stack.StoreSecondaries(ROOT.kTRUE) +stack.SetMinPoints(0) +# Get the Geant4 VMC instance and set our custom stack +geant4 = ROOT.TVirtualMC.GetMC() +if geant4: + geant4.SetStack(stack) run.Init() gMC = ROOT.TVirtualMC.GetMC() diff --git a/muonShieldOptimization/study_thinTarget.py b/muonShieldOptimization/study_thinTarget.py index 77b0fcd41e..a38ecceb86 100644 --- a/muonShieldOptimization/study_thinTarget.py +++ b/muonShieldOptimization/study_thinTarget.py @@ -51,7 +51,9 @@ run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -run.SetUserConfig("g4Config.C") # user configuration file default g4Config.C +# Use FairYamlVMCConfig for YAML configuration +yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") +yamlConfig.Setup() rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -105,6 +107,14 @@ def InitParContainers(): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ +# Create and set custom ShipStack for YAML config compatibility +stack = ROOT.ShipStack(1000) +stack.StoreSecondaries(ROOT.kTRUE) +stack.SetMinPoints(0) +# Get the Geant4 VMC instance and set our custom stack +geant4 = ROOT.TVirtualMC.GetMC() +if geant4: + geant4.SetStack(stack) run.Init() gMC = ROOT.TVirtualMC.GetMC() From eec7282c39f2c22d64b86ccaf60419167d4f1efc Mon Sep 17 00:00:00 2001 From: Oliver Lantwin Date: Tue, 26 Aug 2025 17:51:31 +0200 Subject: [PATCH 2/8] feat(sim): Add ShipVMCConfig class to setup VMC --- CHANGELOG.md | 4 ++ macro/ShipAna.py | 3 +- macro/ShipReco.py | 2 +- macro/create_field_perturbation.py | 14 +---- macro/inspectGeant4Geo.py | 14 +---- macro/run_fixedTarget.py | 14 +---- macro/run_simScript.py | 15 +---- muonShieldOptimization/study_GammaConv.py | 14 +---- muonShieldOptimization/study_muMSC.py | 14 +---- muonShieldOptimization/study_thinTarget.py | 14 +---- python/SciFiMapping.py | 2 +- python/convertToACTS.py | 2 +- python/shipStrawTracking.py | 2 +- shipdata/CMakeLists.txt | 2 +- shipdata/LinkDef.h | 1 + shipdata/VMCConfig.cxx | 72 ++++++++++++++++++++++ shipdata/VMCConfig.h | 58 +++++++++++++++++ 17 files changed, 163 insertions(+), 84 deletions(-) create mode 100644 shipdata/VMCConfig.cxx create mode 100644 shipdata/VMCConfig.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d41efb270..631ee295da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,10 @@ it in future. - The geometry configuration and detector setup (`geometry/geometry_config.py`, `python/shipDet_conf.py`) have been updated to instantiate all requested SND detectors. - This enables running with multiple SND subdetectors simultaneously and is future-proof for additional SND designs. * Added the hole for SND in the Muon Shield, that is created automatically if SND key is enabled (works so far for SND_design == 2) +* Added YAML configuration files for Geant4 VMC setup (`g4Config.yaml`, `g4Config_basic.yaml`) to replace deprecated C macros + - Includes physics lists, Monte Carlo processes/cuts, and Geant4 macro commands + - Maintains full compatibility with original C configuration functionality +* Add SHiP::VMCConfig class to setup VMC from the YAML configuration #### Geometry and Target Station diff --git a/macro/ShipAna.py b/macro/ShipAna.py index bf976dcc4d..895210d6d7 100644 --- a/macro/ShipAna.py +++ b/macro/ShipAna.py @@ -73,7 +73,8 @@ run = ROOT.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # Dummy output file -run.SetUserConfig("g4Config_basic.C") # geant4 transport not used, only needed for the mag field +# geant4 transport not used, only needed for the mag field +ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') rtdb = run.GetRuntimeDb() # -----Create geometry---------------------------------------------- modules = shipDet_conf.configure(run, ShipGeo) diff --git a/macro/ShipReco.py b/macro/ShipReco.py index 9a4fd9571c..1b3f740fdc 100644 --- a/macro/ShipReco.py +++ b/macro/ShipReco.py @@ -136,7 +136,7 @@ def mem_monitor(): run = ROOT.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # Dummy output file -run.SetUserConfig("g4Config_basic.C") # geant4 transport not used, only needed for creating VMC field +ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') # geant4 transport not used, only needed for creating VMC field rtdb = run.GetRuntimeDb() # -----Create geometry---------------------------------------------- modules = shipDet_conf.configure(run, ShipGeo) diff --git a/macro/create_field_perturbation.py b/macro/create_field_perturbation.py index 3573b6f76a..32ba528c8f 100644 --- a/macro/create_field_perturbation.py +++ b/macro/create_field_perturbation.py @@ -25,23 +25,15 @@ def create_csv_field_map(options): run = r.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(r.FairRootFileSink("tmp_file")) # Output file - # Use FairYamlVMCConfig for YAML configuration - yamlConfig = r.FairYamlVMCConfig("g4Config", "g4Config.yaml") - yamlConfig.Setup() + # Use SHiP::VMCConfig for YAML configuration + r.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') shipDet_conf.configure(run, ship_geo) primGen = r.FairPrimaryGenerator() primGen.SetTarget(ship_geo.target.z0 + 70.845 * u.m, 0.0) # run.SetGenerator(primGen) run.SetStoreTraj(r.kFALSE) - # Create and set custom ShipStack for YAML config compatibility - stack = r.ShipStack(1000) - stack.StoreSecondaries(r.kTRUE) - stack.SetMinPoints(0) - # Get the Geant4 VMC instance and set our custom stack - geant4 = r.TVirtualMC.GetMC() - if geant4: - geant4.SetStack(stack) + # ShipStack is now automatically created by SHiP::VMCConfig run.Init() fieldMaker = geomGeant4.addVMCFields(ship_geo, "", True) diff --git a/macro/inspectGeant4Geo.py b/macro/inspectGeant4Geo.py index 686409b0f7..b897284bbe 100644 --- a/macro/inspectGeant4Geo.py +++ b/macro/inspectGeant4Geo.py @@ -20,19 +20,11 @@ run = ROOT.FairRunSim() ShipGeo = load_from_root_file(fgeo, "ShipGeo") modules = shipDet_conf.configure(run, ShipGeo) -# Use FairYamlVMCConfig for YAML configuration -yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") -yamlConfig.Setup() +# Use SHiP::VMCConfig for YAML configuration +ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') run.SetName("TGeant4") run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) -# Create and set custom ShipStack for YAML config compatibility -stack = ROOT.ShipStack(1000) -stack.StoreSecondaries(ROOT.kTRUE) -stack.SetMinPoints(0) -# Get the Geant4 VMC instance and set our custom stack -geant4 = ROOT.TVirtualMC.GetMC() -if geant4: - geant4.SetStack(stack) +# ShipStack is now automatically created by SHiP::VMCConfig run.Init() run.Run(0) import geomGeant4 diff --git a/macro/run_fixedTarget.py b/macro/run_fixedTarget.py index b4efeef1f8..257ad805c8 100644 --- a/macro/run_fixedTarget.py +++ b/macro/run_fixedTarget.py @@ -248,9 +248,8 @@ def get_work_dir(run_number, tag=None): run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -# Use FairYamlVMCConfig for YAML configuration -yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") -yamlConfig.Setup() +# Use SHiP::VMCConfig for YAML configuration +run.SetSimulationConfig(ROOT.std.make_unique[ROOT.SHiP.VMCConfig]("g4Config", "g4Config.yaml")) rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -387,14 +386,7 @@ def get_work_dir(run_number, tag=None): run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ -# Create and set custom ShipStack for YAML config compatibility -stack = ROOT.ShipStack(1000) -stack.StoreSecondaries(ROOT.kTRUE) -stack.SetMinPoints(0) -# Get the Geant4 VMC instance and set our custom stack -geant4 = ROOT.TVirtualMC.GetMC() -if geant4: - geant4.SetStack(stack) +# ShipStack is now automatically created by SHiP::VMCConfig run.Init() gMC = ROOT.TVirtualMC.GetMC() diff --git a/macro/run_simScript.py b/macro/run_simScript.py index 22c5018c36..a3f2eecdee 100755 --- a/macro/run_simScript.py +++ b/macro/run_simScript.py @@ -375,9 +375,8 @@ run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -# Use FairYamlVMCConfig for YAML configuration -yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") -yamlConfig.Setup() +# Use SHiP::VMCConfig for YAML configuration via C++ interpreter +ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') rtdb = run.GetRuntimeDb() # -----Create geometry---------------------------------------------- # import shipMuShield_only as shipDet_conf # special use case for an attempt to convert active shielding geometry for use with FLUKA @@ -648,15 +647,7 @@ run.SetPythiaDecayer("DecayConfigTEvtGen.C") print("Using TEvtGenDecayer for J/psi and quarkonium decays with EvtGen") -# -----Create and set custom ShipStack for YAML config compatibility----- -if mcEngine == "TGeant4": - stack = ROOT.ShipStack(1000) - stack.StoreSecondaries(ROOT.kTRUE) - stack.SetMinPoints(0) - # Get the Geant4 VMC instance and set our custom stack - geant4 = ROOT.TVirtualMC.GetMC() - if geant4: - geant4.SetStack(stack) +# ShipStack is now automatically created by SHiP::VMCConfig # -----Initialize simulation run------------------------------------ run.Init() diff --git a/muonShieldOptimization/study_GammaConv.py b/muonShieldOptimization/study_GammaConv.py index 1a7b531172..30c79c7b50 100644 --- a/muonShieldOptimization/study_GammaConv.py +++ b/muonShieldOptimization/study_GammaConv.py @@ -50,9 +50,8 @@ run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -# Use FairYamlVMCConfig for YAML configuration -yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") -yamlConfig.Setup() +# Use SHiP::VMCConfig for YAML configuration +ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -113,14 +112,7 @@ def makeSensitive(self, sensPlane): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ -# Create and set custom ShipStack for YAML config compatibility -stack = ROOT.ShipStack(1000) -stack.StoreSecondaries(ROOT.kTRUE) -stack.SetMinPoints(0) -# Get the Geant4 VMC instance and set our custom stack -geant4 = ROOT.TVirtualMC.GetMC() -if geant4: - geant4.SetStack(stack) +# ShipStack is now automatically created by SHiP::VMCConfig run.Init() gMC = ROOT.TVirtualMC.GetMC() diff --git a/muonShieldOptimization/study_muMSC.py b/muonShieldOptimization/study_muMSC.py index 8f91fc230d..bf9e34aa39 100644 --- a/muonShieldOptimization/study_muMSC.py +++ b/muonShieldOptimization/study_muMSC.py @@ -52,9 +52,8 @@ run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -# Use FairYamlVMCConfig for YAML configuration -yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") -yamlConfig.Setup() +# Use SHiP::VMCConfig for YAML configuration +ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -110,14 +109,7 @@ def InitParContainers(): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ -# Create and set custom ShipStack for YAML config compatibility -stack = ROOT.ShipStack(1000) -stack.StoreSecondaries(ROOT.kTRUE) -stack.SetMinPoints(0) -# Get the Geant4 VMC instance and set our custom stack -geant4 = ROOT.TVirtualMC.GetMC() -if geant4: - geant4.SetStack(stack) +# ShipStack is now automatically created by SHiP::VMCConfig run.Init() gMC = ROOT.TVirtualMC.GetMC() diff --git a/muonShieldOptimization/study_thinTarget.py b/muonShieldOptimization/study_thinTarget.py index a38ecceb86..3366f7c531 100644 --- a/muonShieldOptimization/study_thinTarget.py +++ b/muonShieldOptimization/study_thinTarget.py @@ -51,9 +51,8 @@ run = ROOT.FairRunSim() run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file -# Use FairYamlVMCConfig for YAML configuration -yamlConfig = ROOT.FairYamlVMCConfig("g4Config", "g4Config.yaml") -yamlConfig.Setup() +# Use SHiP::VMCConfig for YAML configuration +ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -107,14 +106,7 @@ def InitParContainers(): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ -# Create and set custom ShipStack for YAML config compatibility -stack = ROOT.ShipStack(1000) -stack.StoreSecondaries(ROOT.kTRUE) -stack.SetMinPoints(0) -# Get the Geant4 VMC instance and set our custom stack -geant4 = ROOT.TVirtualMC.GetMC() -if geant4: - geant4.SetStack(stack) +# ShipStack is now automatically created by SHiP::VMCConfig run.Init() gMC = ROOT.TVirtualMC.GetMC() diff --git a/python/SciFiMapping.py b/python/SciFiMapping.py index 4eb2584f24..60dbce7428 100644 --- a/python/SciFiMapping.py +++ b/python/SciFiMapping.py @@ -843,7 +843,7 @@ def mapping_validation(self): run = ROOT.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # Output file - run.SetUserConfig("g4Config_basic.C") # geant4 transport not used + ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') # geant4 transport not used rtdb = run.GetRuntimeDb() modules = shipDet_conf.configure(run, ship_geo) run.Init() diff --git a/python/convertToACTS.py b/python/convertToACTS.py index 0a6c94f434..b17e3fc7c0 100644 --- a/python/convertToACTS.py +++ b/python/convertToACTS.py @@ -30,7 +30,7 @@ def main(): run = ROOT.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # Dummy output file - run.SetUserConfig("g4Config_basic.C") # geant4 transport not used, only needed for creating VMC field + ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') # geant4 transport not used, only needed for creating VMC field run.GetRuntimeDb() shipDet_conf.configure(run, ShipGeo) diff --git a/python/shipStrawTracking.py b/python/shipStrawTracking.py index e1f0889cc0..0b89c5a82f 100644 --- a/python/shipStrawTracking.py +++ b/python/shipStrawTracking.py @@ -72,7 +72,7 @@ def run_track_pattern_recognition(input_file, geo_file, output_file, method, dy= # Create dummy output file as the input file is updated directly and # histograms are written to output file (hists.root by default) run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) - run.SetUserConfig("g4Config_basic.C") # geant4 transport not used, only needed for the mag field + ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') # geant4 transport not used, only needed for the mag field run.GetRuntimeDb() shipDet_conf.configure(run, ShipGeo) diff --git a/shipdata/CMakeLists.txt b/shipdata/CMakeLists.txt index c19167639a..b839a4a7b6 100644 --- a/shipdata/CMakeLists.txt +++ b/shipdata/CMakeLists.txt @@ -3,7 +3,7 @@ ship_add_library( NAME ShipData - SOURCES ShipHit.cxx ShipStack.cxx ShipMCTrack.cxx ShipParticle.cxx TrackInfo.cxx + SOURCES ShipHit.cxx ShipStack.cxx ShipMCTrack.cxx ShipParticle.cxx TrackInfo.cxx VMCConfig.cxx LINKDEF LinkDef.h DEPENDENCIES Base EG Physics Core genfit2 FairLogger::FairLogger ) diff --git a/shipdata/LinkDef.h b/shipdata/LinkDef.h index 697bd19d69..7e0adff170 100644 --- a/shipdata/LinkDef.h +++ b/shipdata/LinkDef.h @@ -13,5 +13,6 @@ #pragma link C++ class ShipMCTrack+; #pragma link C++ class ShipParticle+; #pragma link C++ class TrackInfo+; +#pragma link C++ class SHiP::VMCConfig+; #endif diff --git a/shipdata/VMCConfig.cxx b/shipdata/VMCConfig.cxx new file mode 100644 index 0000000000..ff1749cefc --- /dev/null +++ b/shipdata/VMCConfig.cxx @@ -0,0 +1,72 @@ +// ------------------------------------------------------------------------- +// ----- SHiP::VMCConfig source file ----- +// ------------------------------------------------------------------------- + +#include "VMCConfig.h" +#include "ShipStack.h" + +#include "TVirtualMC.h" +#include "FairLogger.h" + +#include + + +namespace SHiP { + +// ----- Constructor --------------------------------------------------- +VMCConfig::VMCConfig(const std::string& name, const std::string& yamlFile) + : FairYamlVMCConfig() + , fYamlFile(yamlFile) +{ + LOG(info) << "SHiP::VMCConfig: Constructor called with YAML file: " << fYamlFile; +} + +// ----- Destructor ---------------------------------------------------- +VMCConfig::~VMCConfig() +{ +} + +// ----- Setup method -------------------------------------------------- +void VMCConfig::Setup(const char* mcEngine) +{ + LOG(info) << "SHiP::VMCConfig: Setting up VMC for engine: " << mcEngine; + + // Call parent Setup method to handle YAML configuration loading + // FairYamlVMCConfig will automatically find the YAML file based on mcEngine + FairYamlVMCConfig::Setup(mcEngine); + + LOG(info) << "SHiP::VMCConfig: Setup completed successfully"; +} + +// ----- SetupStack method (pure virtual from base class) ----------------- +void VMCConfig::SetupStack() +{ + LOG(info) << "SHiP::VMCConfig: Setting up stack"; + + // Create and configure ShipStack for SHiP-specific functionality + CreateShipStack(); +} + +// ----- Private method to create ShipStack --------------------------- +void VMCConfig::CreateShipStack() +{ + LOG(info) << "SHiP::VMCConfig: Creating and configuring ShipStack"; + + // Create ShipStack with default size of 1000 + ShipStack* stack = new ShipStack(1000); + + // Configure stack settings + stack->StoreSecondaries(kTRUE); + stack->SetMinPoints(0); + + // Set the stack to the VMC engine + TVirtualMC* mc = TVirtualMC::GetMC(); + if (mc) { + mc->SetStack(stack); + LOG(info) << "SHiP::VMCConfig: ShipStack successfully set to VMC engine"; + } else { + LOG(error) << "SHiP::VMCConfig: Could not get VMC instance to set stack"; + } +} + +} // namespace SHiP diff --git a/shipdata/VMCConfig.h b/shipdata/VMCConfig.h new file mode 100644 index 0000000000..5839e66b45 --- /dev/null +++ b/shipdata/VMCConfig.h @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------- +// ----- SHiP::VMCConfig header file ----- +// ------------------------------------------------------------------------- + +/** VMCConfig.h + ** + ** Custom VMC configuration class for SHiP experiment that inherits from + ** FairYamlVMCConfig and provides SHiP-specific functionality including: + ** - Automatic ShipStack instantiation and configuration + ** - YAML configuration file loading from specified path + ** - Integration with SHiP simulation framework + **/ + +#ifndef SHIPDATA_VMCCONFIG_H_ +#define SHIPDATA_VMCCONFIG_H_ + +#include "FairYamlVMCConfig.h" +#include "Rtypes.h" +#include + +class ShipStack; + +namespace SHiP { + +class VMCConfig : public FairYamlVMCConfig +{ + public: + /** Constructor with YAML file path + *@param name Configuration name (unused - kept for compatibility) + *@param yamlFile Path to YAML configuration file (unused - auto-discovered) + **/ + explicit VMCConfig(const std::string& name = "g4Config", const std::string& yamlFile = "g4Config.yaml"); + + /** Destructor **/ + virtual ~VMCConfig(); + + /** Setup VMC configuration + *@param mcEngine Monte Carlo engine name (e.g. "TGeant4") + **/ + void Setup(const char* mcEngine) override; + + protected: + /** Setup stack (pure virtual from FairYamlVMCConfig) **/ + void SetupStack() override; + + private: + /** Create and configure ShipStack **/ + void CreateShipStack(); + + /** YAML configuration file path **/ + std::string fYamlFile; + + ClassDef(VMCConfig, 1) +}; + +} // namespace SHiP + +#endif // SHIPDATA_VMCCONFIG_H_ From 002df2c2bbfe04da40269d3febbafa2f10eef0c0 Mon Sep 17 00:00:00 2001 From: Oliver Lantwin Date: Wed, 27 Aug 2025 18:28:53 +0200 Subject: [PATCH 3/8] fix(sim): Remove GCUTS (replaced by CUTGAM in Geant4) --- CHANGELOG.md | 2 ++ gconfig/g4Config.yaml | 1 - gconfig/g4Config_basic.yaml | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 631ee295da..a4d7986fa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -398,7 +398,9 @@ it in future. * Remove reloading of the `geometry_config.py` in `shipDet_conf.py` * Removed unused run_simPgun.py * Remove TTCluster.py +* Removed deprecated Geant4 VMC configuration files (`g4Config.C`, `g4Config_basic.C`, `g4config.in`, `g4config_basic.in`) * Remove pid class +* Remove GCUTS (replaced by CUTGAM in Geant4) #### Build System diff --git a/gconfig/g4Config.yaml b/gconfig/g4Config.yaml index 62bcbacacc..267a3224f3 100644 --- a/gconfig/g4Config.yaml +++ b/gconfig/g4Config.yaml @@ -42,4 +42,3 @@ MonteCarlo_Cut: DCUTM: 1.0E-3 #muon and hadron delta-rays (GeV) PPCUTM: 1.0E-3 #direct pair production by muons (GeV) TOFMAX: 1.E10 #time of flight cut (s) - GCUTS: 1.0E-3 #gamma transport cut (GeV) diff --git a/gconfig/g4Config_basic.yaml b/gconfig/g4Config_basic.yaml index 1618124d42..276ed44d69 100644 --- a/gconfig/g4Config_basic.yaml +++ b/gconfig/g4Config_basic.yaml @@ -40,4 +40,3 @@ MonteCarlo_Cut: DCUTM: 1.0E-3 #muon and hadron delta-rays (GeV) PPCUTM: 1.0E-3 #direct pair production by muons (GeV) TOFMAX: 1.E10 #time of flight cut (s) - GCUTS: 1.0E-3 #gamma transport cut (GeV) From 4abbe9538ae2944d86330d25142042eea4ca24fc Mon Sep 17 00:00:00 2001 From: Oliver Lantwin Date: Tue, 3 Feb 2026 14:16:48 +0100 Subject: [PATCH 4/8] fix(sim): align YAML configs with master g4Config.C MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Physics list: QGSP_BERT_HP_PEN → FTFP_BERT_HP_EMZ - Restore /process/em/UseGeneralProcess false - Restore /mcPhysics/setExtDecayerSelection J/psi - Comment out Geant4_MaxNStep (keep default 30000) - Remove /mcPhysics/g4NeutronHPVerbose (removed in newer Geant4) --- gconfig/g4Config.yaml | 7 ++++--- gconfig/g4Config_basic.yaml | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gconfig/g4Config.yaml b/gconfig/g4Config.yaml index 267a3224f3..a560c73e0f 100644 --- a/gconfig/g4Config.yaml +++ b/gconfig/g4Config.yaml @@ -1,20 +1,21 @@ Geant4_UserGeometry: "geomRoot" -Geant4_PhysicsList: "QGSP_BERT_HP_PEN" +Geant4_PhysicsList: "FTFP_BERT_HP_EMZ" Geant4_SpecialProcess: "stepLimiter+specialCuts+specialControls" Geant4_SpecialStacking: false Geant4_Multithreaded: false -Geant4_MaxNStep: 10000 #default is 30000 +#Geant4_MaxNStep: 10000 #default is 30000 Geant4_Commands: - /mcVerbose/all 0 - /mcTracking/loopVerbose 0 - - /mcPhysics/g4NeutronHPVerbose 0 - /mcPhysics/g4HadronicProcessStoreVerbose 0 - /physics_lists/em/PositronToMuons true - /physics_lists/em/GammaToMuons true + - /process/em/UseGeneralProcess false - /process/em/verbose 0 - /process/eLoss/verbose 0 - /mcDet/setIsLocalMagField true + - /mcPhysics/setExtDecayerSelection J/psi MonteCarlo_Process: PAIR: 1 #pair production diff --git a/gconfig/g4Config_basic.yaml b/gconfig/g4Config_basic.yaml index 276ed44d69..2cc5a03c59 100644 --- a/gconfig/g4Config_basic.yaml +++ b/gconfig/g4Config_basic.yaml @@ -4,11 +4,10 @@ Geant4_SpecialProcess: "" Geant4_SpecialStacking: false Geant4_Multithreaded: false -Geant4_MaxNStep: 10000 #default is 30000 +#Geant4_MaxNStep: 10000 #default is 30000 Geant4_Commands: - /mcVerbose/all 0 - /mcTracking/loopVerbose 0 - - /mcPhysics/g4NeutronHPVerbose 0 - /mcPhysics/g4HadronicProcessStoreVerbose 0 - /process/em/verbose 0 - /process/eLoss/verbose 0 From e67cc1ece7563e5e0ad634318ad23e837e285bb1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 09:53:05 +0000 Subject: [PATCH 5/8] style: pre-commit fixes --- shipdata/VMCConfig.cxx | 83 +++++++++++++++++++----------------------- shipdata/VMCConfig.h | 65 +++++++++++++++++---------------- 2 files changed, 71 insertions(+), 77 deletions(-) diff --git a/shipdata/VMCConfig.cxx b/shipdata/VMCConfig.cxx index ff1749cefc..6ce6cda994 100644 --- a/shipdata/VMCConfig.cxx +++ b/shipdata/VMCConfig.cxx @@ -3,70 +3,63 @@ // ------------------------------------------------------------------------- #include "VMCConfig.h" -#include "ShipStack.h" - -#include "TVirtualMC.h" -#include "FairLogger.h" #include +#include "FairLogger.h" +#include "ShipStack.h" +#include "TVirtualMC.h" namespace SHiP { // ----- Constructor --------------------------------------------------- VMCConfig::VMCConfig(const std::string& name, const std::string& yamlFile) - : FairYamlVMCConfig() - , fYamlFile(yamlFile) -{ - LOG(info) << "SHiP::VMCConfig: Constructor called with YAML file: " << fYamlFile; + : FairYamlVMCConfig(), fYamlFile(yamlFile) { + LOG(info) << "SHiP::VMCConfig: Constructor called with YAML file: " + << fYamlFile; } // ----- Destructor ---------------------------------------------------- -VMCConfig::~VMCConfig() -{ -} +VMCConfig::~VMCConfig() {} // ----- Setup method -------------------------------------------------- -void VMCConfig::Setup(const char* mcEngine) -{ - LOG(info) << "SHiP::VMCConfig: Setting up VMC for engine: " << mcEngine; - - // Call parent Setup method to handle YAML configuration loading - // FairYamlVMCConfig will automatically find the YAML file based on mcEngine - FairYamlVMCConfig::Setup(mcEngine); - - LOG(info) << "SHiP::VMCConfig: Setup completed successfully"; +void VMCConfig::Setup(const char* mcEngine) { + LOG(info) << "SHiP::VMCConfig: Setting up VMC for engine: " << mcEngine; + + // Call parent Setup method to handle YAML configuration loading + // FairYamlVMCConfig will automatically find the YAML file based on mcEngine + FairYamlVMCConfig::Setup(mcEngine); + + LOG(info) << "SHiP::VMCConfig: Setup completed successfully"; } // ----- SetupStack method (pure virtual from base class) ----------------- -void VMCConfig::SetupStack() -{ - LOG(info) << "SHiP::VMCConfig: Setting up stack"; - - // Create and configure ShipStack for SHiP-specific functionality - CreateShipStack(); +void VMCConfig::SetupStack() { + LOG(info) << "SHiP::VMCConfig: Setting up stack"; + + // Create and configure ShipStack for SHiP-specific functionality + CreateShipStack(); } // ----- Private method to create ShipStack --------------------------- -void VMCConfig::CreateShipStack() -{ - LOG(info) << "SHiP::VMCConfig: Creating and configuring ShipStack"; - - // Create ShipStack with default size of 1000 - ShipStack* stack = new ShipStack(1000); - - // Configure stack settings - stack->StoreSecondaries(kTRUE); - stack->SetMinPoints(0); - - // Set the stack to the VMC engine - TVirtualMC* mc = TVirtualMC::GetMC(); - if (mc) { - mc->SetStack(stack); - LOG(info) << "SHiP::VMCConfig: ShipStack successfully set to VMC engine"; - } else { - LOG(error) << "SHiP::VMCConfig: Could not get VMC instance to set stack"; - } +void VMCConfig::CreateShipStack() { + LOG(info) << "SHiP::VMCConfig: Creating and configuring ShipStack"; + + // Create ShipStack with default size of 1000 + ShipStack* stack = new ShipStack(1000); + + // Configure stack settings + stack->StoreSecondaries(kTRUE); + stack->SetMinPoints(0); + + // Set the stack to the VMC engine + TVirtualMC* mc = TVirtualMC::GetMC(); + if (mc) { + mc->SetStack(stack); + LOG(info) << "SHiP::VMCConfig: ShipStack successfully set to VMC engine"; + } else { + LOG(error) << "SHiP::VMCConfig: Could not get VMC instance to set stack"; + } } } // namespace SHiP diff --git a/shipdata/VMCConfig.h b/shipdata/VMCConfig.h index 5839e66b45..31c0a29fe7 100644 --- a/shipdata/VMCConfig.h +++ b/shipdata/VMCConfig.h @@ -4,7 +4,7 @@ /** VMCConfig.h ** - ** Custom VMC configuration class for SHiP experiment that inherits from + ** Custom VMC configuration class for SHiP experiment that inherits from ** FairYamlVMCConfig and provides SHiP-specific functionality including: ** - Automatic ShipStack instantiation and configuration ** - YAML configuration file loading from specified path @@ -14,45 +14,46 @@ #ifndef SHIPDATA_VMCCONFIG_H_ #define SHIPDATA_VMCCONFIG_H_ +#include + #include "FairYamlVMCConfig.h" #include "Rtypes.h" -#include class ShipStack; namespace SHiP { -class VMCConfig : public FairYamlVMCConfig -{ - public: - /** Constructor with YAML file path - *@param name Configuration name (unused - kept for compatibility) - *@param yamlFile Path to YAML configuration file (unused - auto-discovered) - **/ - explicit VMCConfig(const std::string& name = "g4Config", const std::string& yamlFile = "g4Config.yaml"); - - /** Destructor **/ - virtual ~VMCConfig(); - - /** Setup VMC configuration - *@param mcEngine Monte Carlo engine name (e.g. "TGeant4") - **/ - void Setup(const char* mcEngine) override; - - protected: - /** Setup stack (pure virtual from FairYamlVMCConfig) **/ - void SetupStack() override; - - private: - /** Create and configure ShipStack **/ - void CreateShipStack(); - - /** YAML configuration file path **/ - std::string fYamlFile; - - ClassDef(VMCConfig, 1) +class VMCConfig : public FairYamlVMCConfig { + public: + /** Constructor with YAML file path + *@param name Configuration name (unused - kept for compatibility) + *@param yamlFile Path to YAML configuration file (unused - auto-discovered) + **/ + explicit VMCConfig(const std::string& name = "g4Config", + const std::string& yamlFile = "g4Config.yaml"); + + /** Destructor **/ + virtual ~VMCConfig(); + + /** Setup VMC configuration + *@param mcEngine Monte Carlo engine name (e.g. "TGeant4") + **/ + void Setup(const char* mcEngine) override; + + protected: + /** Setup stack (pure virtual from FairYamlVMCConfig) **/ + void SetupStack() override; + + private: + /** Create and configure ShipStack **/ + void CreateShipStack(); + + /** YAML configuration file path **/ + std::string fYamlFile; + + ClassDef(VMCConfig, 1) }; } // namespace SHiP -#endif // SHIPDATA_VMCCONFIG_H_ +#endif // SHIPDATA_VMCCONFIG_H_ From 1a3cc96453c2e8658ecaaae5b978e8d76969b592 Mon Sep 17 00:00:00 2001 From: Oliver Lantwin Date: Thu, 5 Feb 2026 18:45:13 +0100 Subject: [PATCH 6/8] fix(build): link ShipData against FairRoot::MCConfigurator VMCConfig inherits from FairYamlVMCConfig but the MCConfigurator library was missing from the link dependencies, causing undefined symbol errors. --- shipdata/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shipdata/CMakeLists.txt b/shipdata/CMakeLists.txt index b839a4a7b6..ecfbf0f3f8 100644 --- a/shipdata/CMakeLists.txt +++ b/shipdata/CMakeLists.txt @@ -5,5 +5,5 @@ ship_add_library( NAME ShipData SOURCES ShipHit.cxx ShipStack.cxx ShipMCTrack.cxx ShipParticle.cxx TrackInfo.cxx VMCConfig.cxx LINKDEF LinkDef.h - DEPENDENCIES Base EG Physics Core genfit2 FairLogger::FairLogger + DEPENDENCIES Base EG Physics Core genfit2 FairLogger::FairLogger FairRoot::MCConfigurator ) From a4b10470996a24d9f9e3ac84e8bcb324f1537cec Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 09:58:25 +0000 Subject: [PATCH 7/8] style: pre-commit fixes --- macro/ShipAna.py | 4 +++- macro/ShipReco.py | 4 +++- macro/create_field_perturbation.py | 4 +++- macro/inspectGeant4Geo.py | 4 +++- macro/run_simScript.py | 4 +++- muonShieldOptimization/study_GammaConv.py | 4 +++- muonShieldOptimization/study_muMSC.py | 4 +++- muonShieldOptimization/study_thinTarget.py | 4 +++- python/SciFiMapping.py | 4 +++- python/convertToACTS.py | 4 +++- python/shipStrawTracking.py | 4 +++- 11 files changed, 33 insertions(+), 11 deletions(-) diff --git a/macro/ShipAna.py b/macro/ShipAna.py index 895210d6d7..3d87098f77 100644 --- a/macro/ShipAna.py +++ b/macro/ShipAna.py @@ -74,7 +74,9 @@ run.SetName("TGeant4") # Transport engine run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # Dummy output file # geant4 transport not used, only needed for the mag field -ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));' +) rtdb = run.GetRuntimeDb() # -----Create geometry---------------------------------------------- modules = shipDet_conf.configure(run, ShipGeo) diff --git a/macro/ShipReco.py b/macro/ShipReco.py index 1b3f740fdc..cb78c2794f 100644 --- a/macro/ShipReco.py +++ b/macro/ShipReco.py @@ -136,7 +136,9 @@ def mem_monitor(): run = ROOT.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # Dummy output file -ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') # geant4 transport not used, only needed for creating VMC field +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));' +) # geant4 transport not used, only needed for creating VMC field rtdb = run.GetRuntimeDb() # -----Create geometry---------------------------------------------- modules = shipDet_conf.configure(run, ShipGeo) diff --git a/macro/create_field_perturbation.py b/macro/create_field_perturbation.py index 32ba528c8f..bd522e026b 100644 --- a/macro/create_field_perturbation.py +++ b/macro/create_field_perturbation.py @@ -26,7 +26,9 @@ def create_csv_field_map(options): run.SetName("TGeant4") # Transport engine run.SetSink(r.FairRootFileSink("tmp_file")) # Output file # Use SHiP::VMCConfig for YAML configuration - r.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') + r.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' + ) shipDet_conf.configure(run, ship_geo) primGen = r.FairPrimaryGenerator() primGen.SetTarget(ship_geo.target.z0 + 70.845 * u.m, 0.0) diff --git a/macro/inspectGeant4Geo.py b/macro/inspectGeant4Geo.py index b897284bbe..0096462524 100644 --- a/macro/inspectGeant4Geo.py +++ b/macro/inspectGeant4Geo.py @@ -21,7 +21,9 @@ ShipGeo = load_from_root_file(fgeo, "ShipGeo") modules = shipDet_conf.configure(run, ShipGeo) # Use SHiP::VMCConfig for YAML configuration -ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' +) run.SetName("TGeant4") run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # ShipStack is now automatically created by SHiP::VMCConfig diff --git a/macro/run_simScript.py b/macro/run_simScript.py index a3f2eecdee..bfba801776 100755 --- a/macro/run_simScript.py +++ b/macro/run_simScript.py @@ -376,7 +376,9 @@ run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file # Use SHiP::VMCConfig for YAML configuration via C++ interpreter -ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' +) rtdb = run.GetRuntimeDb() # -----Create geometry---------------------------------------------- # import shipMuShield_only as shipDet_conf # special use case for an attempt to convert active shielding geometry for use with FLUKA diff --git a/muonShieldOptimization/study_GammaConv.py b/muonShieldOptimization/study_GammaConv.py index 30c79c7b50..7ab00c7c0b 100644 --- a/muonShieldOptimization/study_GammaConv.py +++ b/muonShieldOptimization/study_GammaConv.py @@ -51,7 +51,9 @@ run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file # Use SHiP::VMCConfig for YAML configuration -ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' +) rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- diff --git a/muonShieldOptimization/study_muMSC.py b/muonShieldOptimization/study_muMSC.py index bf9e34aa39..91981dacdf 100644 --- a/muonShieldOptimization/study_muMSC.py +++ b/muonShieldOptimization/study_muMSC.py @@ -53,7 +53,9 @@ run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file # Use SHiP::VMCConfig for YAML configuration -ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' +) rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- diff --git a/muonShieldOptimization/study_thinTarget.py b/muonShieldOptimization/study_thinTarget.py index 3366f7c531..7d1e0e07d4 100644 --- a/muonShieldOptimization/study_thinTarget.py +++ b/muonShieldOptimization/study_thinTarget.py @@ -52,7 +52,9 @@ run.SetName(mcEngine) # Transport engine run.SetSink(ROOT.FairRootFileSink(outFile)) # Output file # Use SHiP::VMCConfig for YAML configuration -ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));') +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' +) rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- diff --git a/python/SciFiMapping.py b/python/SciFiMapping.py index 60dbce7428..c53e70fd7a 100644 --- a/python/SciFiMapping.py +++ b/python/SciFiMapping.py @@ -843,7 +843,9 @@ def mapping_validation(self): run = ROOT.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # Output file - ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') # geant4 transport not used + ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));' + ) # geant4 transport not used rtdb = run.GetRuntimeDb() modules = shipDet_conf.configure(run, ship_geo) run.Init() diff --git a/python/convertToACTS.py b/python/convertToACTS.py index b17e3fc7c0..8c1306f33e 100644 --- a/python/convertToACTS.py +++ b/python/convertToACTS.py @@ -30,7 +30,9 @@ def main(): run = ROOT.FairRunSim() run.SetName("TGeant4") # Transport engine run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) # Dummy output file - ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') # geant4 transport not used, only needed for creating VMC field + ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));' + ) # geant4 transport not used, only needed for creating VMC field run.GetRuntimeDb() shipDet_conf.configure(run, ShipGeo) diff --git a/python/shipStrawTracking.py b/python/shipStrawTracking.py index 0b89c5a82f..f9d6387533 100644 --- a/python/shipStrawTracking.py +++ b/python/shipStrawTracking.py @@ -72,7 +72,9 @@ def run_track_pattern_recognition(input_file, geo_file, output_file, method, dy= # Create dummy output file as the input file is updated directly and # histograms are written to output file (hists.root by default) run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate"))) - ROOT.gInterpreter.ProcessLine('FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));') # geant4 transport not used, only needed for the mag field + ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config_basic.yaml"));' + ) # geant4 transport not used, only needed for the mag field run.GetRuntimeDb() shipDet_conf.configure(run, ShipGeo) From 59bc8a1f909de099ec6ef5c36359ac3f5412cb29 Mon Sep 17 00:00:00 2001 From: Oliver Lantwin Date: Fri, 6 Feb 2026 15:14:27 +0100 Subject: [PATCH 8/8] fix(build): find Geant4 before FairRoot for MCConfigurator deps FairRoot::MCConfigurator has transitive dependencies on Geant4 CMake targets (via FairRoot::FastSim -> Geant4::G4processes). Call native find_package(Geant4) before FairRoot to ensure these targets exist. --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dcd1aa747..34cb07903e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,7 +118,9 @@ include(ShipMacros) find_package2(PUBLIC Pythia8 REQUIRED) find_package2(PUBLIC EvtGen REQUIRED) # (GENERATORS REQUIRED) -find_package2(PUBLIC GEANT4) +# FairRoot::MCConfigurator has transitive dependencies on Geant4 CMake targets +# (via FairRoot::FastSim -> Geant4::G4processes), so Geant4 must be found first. +find_package2(PUBLIC GEANT4 REQUIRED) find_package2(PUBLIC GEANT4DATA) find_package2(PUBLIC GEANT4VMC) find_package2(PUBLIC HEPMC)