ATLAS Offline Software
PhysicsListSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "PhysicsListSvc.h"
6 
7 #include "G4VUserPhysicsList.hh"
8 #include "G4StateManager.hh"
9 #include "G4RunManager.hh"
10 #include "G4EmParameters.hh"
11 #include "G4UImanager.hh"
12 #include "G4PhysListFactory.hh"
13 #include "G4AntiNeutron.hh"
14 #include "G4HadronicProcessStore.hh"
15 
16 #include "CLHEP/Units/PhysicalConstants.h"
17 
19 
20 #include <limits>
21 
22 PhysicsListSvc::PhysicsListSvc(const std::string& name, ISvcLocator* pSvcLocator)
23  : base_class(name,pSvcLocator)
24 {
25 }
26 
27 
29 {
30  ATH_MSG_DEBUG("PhysicsListSvc::initialize()");
31  if (m_phys_option.size())
32  {
33  ATH_MSG_INFO( "Initializing list of " << m_phys_option.size() << " physics options" );
34  CHECK( m_phys_option.retrieve() );
35  }
36 
37  if (m_phys_decay.size())
38  {
39  ATH_MSG_INFO( "Initializing list of " << m_phys_decay.size() << " Decays " );
40  CHECK( m_phys_decay.retrieve() );
41  }
42 
44 
45  return StatusCode::SUCCESS;
46 }
47 
48 
50 {
51  ATH_MSG_DEBUG("PhysicsListSvc::CreatePhysicsList()");
52  if (m_physicsListName.value() != ""){
53  G4PhysListFactory factory;
54  if (m_quietMode) { factory.SetVerbose(0); } // HACK
55  AtlasPhysListFactory Atlasfactory;
56  if (m_quietMode) {
57  Atlasfactory.SetVerbose(0); // HACK
58  G4HadronicProcessStore::Instance()->SetVerbose(0);
59  }
60  if (factory.IsReferencePhysList(m_physicsListName.value()))
61  {
62  ATH_MSG_INFO("Creating Geant4 PhysicsList: " << m_physicsListName.value());
63  m_physicsList = factory.GetReferencePhysList(m_physicsListName.value());
64  }
65  else if (Atlasfactory.IsReferencePhysList(m_physicsListName.value()))
66  {
67  ATH_MSG_INFO("Creating ATLAS PhysicsList: " << m_physicsListName.value());
69  }
70  }
71 
72  if (!m_physicsList)
73  {
74  ATH_MSG_ERROR("Unable to initialize physics List: " << m_physicsList);
75  throw "PhysicsListInitializationError";
76  }
77  // Call these as functions. As this could be used as a base class, having
78  // these as separate functions lets someone who is inheriting from this use
79  // them...
80 
81  // sort m_phys_option list
82  std::vector<IPhysicsOptionTool*> sortedPhysicsOptions;
83  sortedPhysicsOptions.reserve(m_phys_option.size());
84  // Manually sorting ToolHandleArray
85  {
86  // BSM Physics
87  for (auto& physOptTool: m_phys_option) {
88  if (physOptTool->GetOptionType() == G4AtlasPhysicsOption::Type::BSMPhysics) {
89  sortedPhysicsOptions.push_back(&*physOptTool);
90  }
91  }
92 
93  // Add particles from the PDG Table not currently known to Geant4
94  for (auto& physOptTool: m_phys_option) {
95  if (physOptTool->GetOptionType() == G4AtlasPhysicsOption::Type::QS_ExtraParticles) {
96  sortedPhysicsOptions.push_back(&*physOptTool);
97  }
98  }
99 
100  // Add MSC and Ionisation processes for specific particles (possibly merge with the next one?)
101  for (auto& physOptTool: m_phys_option) {
102  if (physOptTool->GetOptionType() == G4AtlasPhysicsOption::Type::QS_ExtraProc) {
103  sortedPhysicsOptions.push_back(&*physOptTool);
104  }
105  }
106 
107  // G4StepLimitation, LUCID Op Process, TRT XTR process
108  for (auto& physOptTool: m_phys_option) {
109  if (physOptTool->GetOptionType() == G4AtlasPhysicsOption::Type::GlobalProcesses) {
110  sortedPhysicsOptions.push_back(&*physOptTool);
111  }
112  }
113 
114  // Unknown
115  for (auto& physOptTool: m_phys_option) {
116  if (physOptTool->GetOptionType() == G4AtlasPhysicsOption::Type::UnknownType) {
117  ATH_MSG_ERROR(physOptTool->name() << "set as UnknownType. This tool will not be used to modify the physics list of this job.");
118  }
119  }
120  }
121 
122  //Register physics options to the G4VModularPhysicsList
123  for (auto& physOptTool: sortedPhysicsOptions)
124  {
125  ATH_MSG_DEBUG("Registering " << physOptTool->name());
126  m_physicsList->RegisterPhysics(physOptTool->GetPhysicsOption().release());
127  }
128  //Register decays to the G4VModularPhysicsList
129  for (auto& physDecayTool: m_phys_decay)
130  {
131  ATH_MSG_DEBUG("Registering " << physDecayTool->name());
132  m_physicsList->RegisterPhysics(physDecayTool->GetPhysicsOption().release());
133  }
134 
135  m_physicsList->RegisterPhysics(m_fastSimulationConstructor->GetPhysicsOption().release());
136 
137  //ConstructProcess();
138  ATH_MSG_DEBUG("end of PhysicsListSvc::CreatePhysicsList()");
139 }
140 
141 
142 G4VUserPhysicsList* PhysicsListSvc::GetPhysicsList()
143 {
144  if (!m_physicsList) {
145  this->CreatePhysicsList();
146  }
147  return m_physicsList;
148 }
149 
150 
152 {
153  if(!m_physicsList) {
154  this->CreatePhysicsList();
155  }
156  G4RunManager::GetRunManager()->SetUserInitialization(m_physicsList);
157 }
158 
159 
161 {
162  if (!m_physicsList)
163  {
164  ATH_MSG_WARNING("Physics list not initialized before calling ConstructProcess()");
165  return;
166  }
167 
168  if(m_generalCut.value() > 0. && std::abs(m_generalCut.value())>std::numeric_limits<double>::epsilon())
169  {
170  m_physicsList->SetDefaultCutValue(m_generalCut.value());
171  }
172 
173  std::vector<std::string> g4commands;
174  if (m_neutronTimeCut.value() > 0. && std::abs(m_neutronTimeCut.value())>std::numeric_limits<double>::epsilon())
175  {
176  std::ostringstream oss;
177  oss<<"/physics_engine/neutron/timeLimit "<<m_neutronTimeCut.value()<<" ns";
178  g4commands.push_back(oss.str());
179  }
180 
181  if (m_neutronEnergyCut.value() > 0. && std::abs(m_neutronEnergyCut.value())>std::numeric_limits<double>::epsilon())
182  {
183  std::ostringstream oss;
184  oss<<"/physics_engine/neutron/energyLimit "<<m_neutronEnergyCut.value()<<" MeV";
185  g4commands.push_back(oss.str());
186  }
187 
188  if(!g4commands.empty()) {
189  // Send UI commands
190  ATH_MSG_DEBUG("G4 Command: Trying in SetPhysicsOptions()");
191  G4UImanager* ui = G4UImanager::GetUIpointer();
192  for (const auto& g4command : g4commands) {
193  int returnCode = ui->ApplyCommand( g4command );
194  CommandLog(returnCode, g4command);
195  }
196  }
197 
198  G4EmParameters* emp = G4EmParameters::Instance();
199  if (m_emMaxEnergy.value()>=0) emp->SetMaxEnergy(m_emMaxEnergy.value());
200  if (m_emNumberOfBinsPerDecade.value()>=0) emp->SetNumberOfBinsPerDecade(m_emNumberOfBinsPerDecade.value());
201  if (m_emMinEnergy.value()>=0) emp->SetMinEnergy(m_emMinEnergy.value());
202  if (m_applyEMCuts.value())
203  {
204  emp->SetApplyCuts(true);
205  }
206 
208  G4AntiNeutron::Definition()->SetPDGStable(false);
209  }
210 
211  return;
212 }
213 
214 
215 void PhysicsListSvc::CommandLog(int returnCode, const std::string& commandString) const
216 {
217  switch(returnCode) {
218  case 0: { ATH_MSG_DEBUG("G4 Command: " << commandString << " - Command Succeeded"); } break;
219  case 100: { ATH_MSG_ERROR("G4 Command: " << commandString << " - Command Not Found!"); } break;
220  case 200: {
221  auto* stateManager = G4StateManager::GetStateManager();
222  ATH_MSG_DEBUG("G4 Command: " << commandString << " - Illegal Application State (" <<
223  stateManager->GetStateString(stateManager->GetCurrentState()) << ")!");
224  } break;
225  case 300: { ATH_MSG_ERROR("G4 Command: " << commandString << " - Parameter Out of Range!"); } break;
226  case 400: { ATH_MSG_ERROR("G4 Command: " << commandString << " - Parameter Unreadable!"); } break;
227  case 500: { ATH_MSG_ERROR("G4 Command: " << commandString << " - Parameter Out of Candidates!"); } break;
228  case 600: { ATH_MSG_ERROR("G4 Command: " << commandString << " - Alias Not Found!"); } break;
229  default: { ATH_MSG_ERROR("G4 Command: " << commandString << " - Unknown Status!"); } break;
230  }
231 
232 }
PhysicsListSvc::m_quietMode
Gaudi::Property< bool > m_quietMode
!< Switch for the G4 "apply cuts" EM physics flag
Definition: PhysicsListSvc.h:62
G4AtlasPhysicsOption::QS_ExtraProc
@ QS_ExtraProc
Definition: IPhysicsOptionTool.h:25
PhysicsListSvc::m_generalCut
Gaudi::Property< double > m_generalCut
!< Energy cut for neutrons (in the neutron killer process)
Definition: PhysicsListSvc.h:51
PhysicsListSvc::m_unstableAntiNeutrons
Gaudi::Property< bool > m_unstableAntiNeutrons
Definition: PhysicsListSvc.h:63
PhysicsListSvc::CreatePhysicsList
virtual void CreatePhysicsList() override
Definition: PhysicsListSvc.cxx:49
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
AtlasPhysListFactory::IsReferencePhysList
G4bool IsReferencePhysList(const G4String &)
CaloClusterMLCalib::epsilon
constexpr float epsilon
Definition: CaloClusterMLGaussianMixture.h:16
PhysicsListSvc::PhysicsListSvc
PhysicsListSvc(const std::string &name, ISvcLocator *pSvcLocator)
Definition: PhysicsListSvc.cxx:22
AtlasPhysListFactory
Definition: AtlasPhysListFactory.h:12
AtlasPhysListFactory::SetVerbose
void SetVerbose(G4int val)
Definition: AtlasPhysListFactory.h:31
PhysicsListSvc::m_physicsListName
Gaudi::Property< std::string > m_physicsListName
!< Handle on the physics list
Definition: PhysicsListSvc.h:48
AtlasPhysListFactory.h
PhysicsListSvc::m_emMaxEnergy
Gaudi::Property< double > m_emMaxEnergy
!< A general cut - this isn't normally used in our simulation
Definition: PhysicsListSvc.h:52
PhysicsListSvc::m_phys_option
ToolHandleArray< IPhysicsOptionTool > m_phys_option
Definition: PhysicsListSvc.h:45
PhysicsListSvc::m_emMinEnergy
Gaudi::Property< double > m_emMinEnergy
!< Maximum energy of the pre-calculated EM cross-section tables
Definition: PhysicsListSvc.h:53
PhysicsListSvc::m_phys_decay
ToolHandleArray< IPhysicsOptionTool > m_phys_decay
Definition: PhysicsListSvc.h:46
PhysicsListSvc::CommandLog
void CommandLog(int returnCode, const std::string &commandString) const
This command prints a message about a G4Command depending on its returnCode.
Definition: PhysicsListSvc.cxx:215
PhysicsListSvc::m_neutronTimeCut
Gaudi::Property< double > m_neutronTimeCut
!< Name for the physics list (property to be set in the tool)
Definition: PhysicsListSvc.h:49
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
PhysicsListSvc::initialize
virtual StatusCode initialize() override
Definition: PhysicsListSvc.cxx:28
PhysicsListSvc::m_neutronEnergyCut
Gaudi::Property< double > m_neutronEnergyCut
!< Time cut for neutrons (in the neutron killer process)
Definition: PhysicsListSvc.h:50
PhysicsListSvc::m_emNumberOfBinsPerDecade
Gaudi::Property< int > m_emNumberOfBinsPerDecade
!< Minimum energy of the pre-calculated EM cross-section tables
Definition: PhysicsListSvc.h:60
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
PhysicsListSvc::m_physicsList
G4VModularPhysicsList * m_physicsList
Definition: PhysicsListSvc.h:47
G4AtlasPhysicsOption::GlobalProcesses
@ GlobalProcesses
Definition: IPhysicsOptionTool.h:26
G4AtlasPhysicsOption::UnknownType
@ UnknownType
Definition: IPhysicsOptionTool.h:27
PhysicsListSvc.h
AtlasPhysListFactory::GetReferencePhysList
G4VModularPhysicsList * GetReferencePhysList(const G4String &)
PhysicsListSvc::m_applyEMCuts
Gaudi::Property< bool > m_applyEMCuts
!< Number of bins per Energy decade. Used for both DeDx and for the Lambda binning.
Definition: PhysicsListSvc.h:61
G4AtlasPhysicsOption::QS_ExtraParticles
@ QS_ExtraParticles
Definition: IPhysicsOptionTool.h:24
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
G4AtlasPhysicsOption::BSMPhysics
@ BSMPhysics
Definition: IPhysicsOptionTool.h:23
PhysicsListSvc::GetPhysicsList
virtual G4VUserPhysicsList * GetPhysicsList() override
Definition: PhysicsListSvc.cxx:142
PhysicsListSvc::SetPhysicsList
virtual void SetPhysicsList() override
Definition: PhysicsListSvc.cxx:151
PhysicsListSvc::m_fastSimulationConstructor
ToolHandle< IPhysicsOptionTool > m_fastSimulationConstructor
Definition: PhysicsListSvc.h:43
PhysicsListSvc::SetPhysicsOptions
virtual void SetPhysicsOptions() override
Definition: PhysicsListSvc.cxx:160