diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba3842349..a4d7986fa5 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 @@ -82,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 @@ -393,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/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) 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..a560c73e0f --- /dev/null +++ b/gconfig/g4Config.yaml @@ -0,0 +1,45 @@ +Geant4_UserGeometry: "geomRoot" +Geant4_PhysicsList: "FTFP_BERT_HP_EMZ" +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/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 + 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) 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..2cc5a03c59 --- /dev/null +++ b/gconfig/g4Config_basic.yaml @@ -0,0 +1,41 @@ +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/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) 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/ShipAna.py b/macro/ShipAna.py index bf976dcc4d..3d87098f77 100644 --- a/macro/ShipAna.py +++ b/macro/ShipAna.py @@ -73,7 +73,10 @@ 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..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 -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 8ff4480e37..bd522e026b 100644 --- a/macro/create_field_perturbation.py +++ b/macro/create_field_perturbation.py @@ -25,14 +25,17 @@ 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 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) + # 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 ba25e4ff4f..0096462524 100644 --- a/macro/inspectGeant4Geo.py +++ b/macro/inspectGeant4Geo.py @@ -20,9 +20,13 @@ run = ROOT.FairRunSim() ShipGeo = load_from_root_file(fgeo, "ShipGeo") modules = shipDet_conf.configure(run, ShipGeo) -run.SetUserConfig("g4Config.C") +# 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"))) +# 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 7faecdd771..257ad805c8 100644 --- a/macro/run_fixedTarget.py +++ b/macro/run_fixedTarget.py @@ -248,7 +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 -run.SetUserConfig("g4Config.C") # user configuration file default g4Config.C +# Use SHiP::VMCConfig for YAML configuration +run.SetSimulationConfig(ROOT.std.make_unique[ROOT.SHiP.VMCConfig]("g4Config", "g4Config.yaml")) rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -385,6 +386,7 @@ def get_work_dir(run_number, tag=None): run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ +# 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 bc073ff82f..bfba801776 100755 --- a/macro/run_simScript.py +++ b/macro/run_simScript.py @@ -375,7 +375,10 @@ 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 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 @@ -639,12 +642,15 @@ 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") +# ShipStack is now automatically created by SHiP::VMCConfig + # -----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..7ab00c7c0b 100644 --- a/muonShieldOptimization/study_GammaConv.py +++ b/muonShieldOptimization/study_GammaConv.py @@ -50,7 +50,10 @@ 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 SHiP::VMCConfig for YAML configuration +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' +) rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -111,6 +114,7 @@ def makeSensitive(self, sensPlane): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ +# 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 779b0e90db..91981dacdf 100644 --- a/muonShieldOptimization/study_muMSC.py +++ b/muonShieldOptimization/study_muMSC.py @@ -52,7 +52,10 @@ 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 SHiP::VMCConfig for YAML configuration +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' +) rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -108,6 +111,7 @@ def InitParContainers(): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ +# 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 77b0fcd41e..7d1e0e07d4 100644 --- a/muonShieldOptimization/study_thinTarget.py +++ b/muonShieldOptimization/study_thinTarget.py @@ -51,7 +51,10 @@ 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 SHiP::VMCConfig for YAML configuration +ROOT.gInterpreter.ProcessLine( + 'FairRunSim::Instance()->SetSimulationConfig(std::make_unique("g4Config", "g4Config.yaml"));' +) rtdb = run.GetRuntimeDb() # -----Materials---------------------------------------------- @@ -105,6 +108,7 @@ def InitParContainers(): # run.SetGenerator(primGen) # -----Initialize simulation run------------------------------------ +# 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..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 - 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..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 - 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..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"))) - 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..ecfbf0f3f8 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 + DEPENDENCIES Base EG Physics Core genfit2 FairLogger::FairLogger FairRoot::MCConfigurator ) 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..6ce6cda994 --- /dev/null +++ b/shipdata/VMCConfig.cxx @@ -0,0 +1,65 @@ +// ------------------------------------------------------------------------- +// ----- SHiP::VMCConfig source file ----- +// ------------------------------------------------------------------------- + +#include "VMCConfig.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; +} + +// ----- 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..31c0a29fe7 --- /dev/null +++ b/shipdata/VMCConfig.h @@ -0,0 +1,59 @@ +// ------------------------------------------------------------------------- +// ----- 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 + +#include "FairYamlVMCConfig.h" +#include "Rtypes.h" + +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_