20#include <G4Electron.hh>
21#include <G4EmParameters.hh>
23#include <G4GammaConversionToMuons.hh>
24#include <G4HadronicProcess.hh>
25#include <G4PhysicsListHelper.hh>
26#include <G4Positron.hh>
27#include <G4ProcessManager.hh>
28#include <G4ProcessTable.hh>
30#include <G4RegionStore.hh>
31#include <G4SystemOfUnits.hh>
32#include <G4Transportation.hh>
33#include <G4VUserPhysicsList.hh>
38G4Transportation* FindTransportation(
41 const auto* processManager = particleDefinition->GetProcessManager();
42 return dynamic_cast<G4Transportation*
>(
43 processManager->GetProcess(
"Transportation"));
46G4String GetProcessTypeName(G4int hadronicProcessSubType)
48 switch(hadronicProcessSubType) {
50 case fHadronElastic:
return "HadronElastic";
break;
51 case fNeutronGeneral:
return "NeutronGeneral";
break;
52 case fHadronInelastic:
return "HadronInelastic";
break;
53 case fCapture:
return "Capture";
break;
54 case fMuAtomicCapture:
return "MuAtomicCapture";
break;
55 case fFission:
return "Fission";
break;
56 case fHadronAtRest:
return "HadronAtRest";
break;
57 case fLeptonAtRest:
return "LeptonAtRest";
break;
58 case fChargeExchange:
return "ChargeExchange";
break;
59 case fNuOscillation:
return "NuOscillation";
break;
60 case fNuElectron:
return "NuElectron";
break;
61 case fNuNucleus:
return "NuNucleus";
break;
62 case fRadioactiveDecay:
return "RadioactiveDecay";
break;
63 case fEMDissociation:
return "EMDissociation";
break;
72 text += hadronicProcessSubType;
74 "TG4ComposedPhysicsList",
"GetProcessTypeName:",
75 "Unknown hadronic process type: " + text);
76 G4cout << hadronicProcessSubType << G4endl;
80G4int GetProcessSubType(
81 const G4String& processTypeName, G4int& errorCode)
86 if (processTypeName ==
"HadronElastic")
return fHadronElastic;
87 if (processTypeName ==
"NeutronGeneral")
return fNeutronGeneral;
88 if (processTypeName ==
"HadronInelastic")
return fHadronInelastic;
89 if (processTypeName ==
"Capture")
return fCapture;
90 if (processTypeName ==
"MuAtomicCapture")
return fMuAtomicCapture;
91 if (processTypeName ==
"Fission")
return fFission;
92 if (processTypeName ==
"HadronAtRest")
return fHadronAtRest;
93 if (processTypeName ==
"LeptonAtRest")
return fLeptonAtRest;
94 if (processTypeName ==
"ChargeExchange")
return fChargeExchange;
95 if (processTypeName ==
"NuOscillation")
return fNuOscillation;
96 if (processTypeName ==
"NuElectron")
return fNuElectron;
97 if (processTypeName ==
"NuNucleus")
return fNuNucleus;
98 if (processTypeName ==
"RadioactiveDecay")
return fRadioactiveDecay;
99 if (processTypeName ==
"EMDissociation")
return fEMDissociation;
104 if (processTypeName ==
"MuonNuclear")
return fMuonNuclear;
108 "TG4ComposedPhysicsList",
"GetProcessSubType:",
109 "Unknown process type name: " + TString(processTypeName.data()));
111 return fHadronInelastic;
119 auto processList = particle->GetProcessManager()->GetProcessList();
120 std::vector<G4VProcess*> foundProcesses;
121 for (std::size_t i = 0; i < processList->size(); ++i) {
122 if ((*processList)[i]->GetProcessSubType() == processSubType) {
123 foundProcesses.push_back((*processList)[i]);
127 if (foundProcesses.empty()) {
129 text += processSubType;
131 "TG4ComposedPhysicsList",
"GetProcess:",
132 "Unknown process sub type: " + text);
136 if (foundProcesses.size()>1) {
138 text += processSubType;
140 "TG4ComposedPhysicsList",
"GetProcess:",
141 "More than one process of sub type: " + text +
" exists.");
144 return foundProcesses[0];
157 fIsProductionCutsTableEnergyRange(false),
158 fProductionCutsTableEnergyMin(0.),
159 fProductionCutsTableEnergyMax(0.),
160 fGammaToMuonsCrossSectionFactor(-1.),
161 fLooperThresholdsLevel(fgkDefautLooperThresholdsLevel)
166 G4cout <<
"TG4ComposedPhysicsList::TG4ComposedPhysicsList" << G4endl;
192 G4ProcessManager* processManager = gamma->GetProcessManager();
193 G4ProcessVector* processVector = processManager->GetProcessList();
196 for (
size_t i = 0; i < processVector->length(); i++) {
197 G4GammaConversionToMuons* gammaToMuMu =
198 dynamic_cast<G4GammaConversionToMuons*
>((*processVector)[i]);
201 G4cout <<
"### Set gamma to muons cross section factor user value: "
211 "ApplyGammaToMuonsCrossSectionFactor",
212 "Cannot set gamma to muons cross section factor, GammaToMuons must be "
220 const G4String& particleName,
const G4String& processDef, G4double factor,
221 G4bool isProcessName)
226 auto particleDefinition =
227 G4ParticleTable::GetParticleTable()->FindParticle(particleName);
228 if (particleDefinition ==
nullptr) {
230 "G4ParticleTable::FindParticle() for particle " +
231 TString(particleName.data()) +
" failed.");
238 process = particleDefinition->GetProcessManager()->GetProcess(processDef);
243 auto processSubType = GetProcessSubType(processDef, errorCode);
246 "GetProcessSubType for processTypeName " +
247 TString(processDef.data()) +
" failed.");
250 process = GetProcess(particleDefinition, processSubType);
255 if (process ==
nullptr) {
256 TString by = (isProcessName) ?
" by name" :
" by type";
258 "Get process " + TString(processDef.data()) + by +
" failed.");
263 if (process->GetProcessType() != fHadronic) {
265 "Process " + TString(processDef.data()) +
" is not hadronic.");
270 (
static_cast<G4HadronicProcess*
>(process))->MultiplyCrossSectionBy(factor);
274 <<
"### Applied cross section factor " << factor
275 <<
" for " << particleDefinition->GetParticleName()
276 <<
" process " << process->GetProcessName()
277 <<
" process type: " << GetProcessTypeName(process->GetProcessSubType())
287 for (
const auto& [particleName, processType, factor, isProcessName] :
297 auto plHelper = G4PhysicsListHelper::GetPhysicsListHelper();
300 G4cout <<
"### Use low looper thresholds" << G4endl;
302 plHelper->UseLowLooperThresholds();
309 G4cout <<
"### Use high looper thresholds" << G4endl;
311 plHelper->UseHighLooperThresholds();
314 TString message =
"The level";
316 message +=
" is not supported (the value must be 0, 1 or 2.)";
318 "TG4ComposedPhysicsList",
"SetPresetLooperThresholds", message);
340 G4cout <<
"TG4ComposedPhysicsList::ConstructParticle" << G4endl;
346 G4cout <<
"TG4ComposedPhysicsList::ConstructParticle done" << G4endl;
355 G4cout <<
"TG4ComposedPhysicsList::ConstructProcess" << G4endl;
359 g3PhysicsManager->
Lock();
379 auto transportation = FindTransportation(G4Electron::Electron());
380 if (transportation) {
381 transportation->ReportLooperThresholds();
385 G4cout <<
"TG4ComposedPhysicsList::ConstructProcess done" << G4endl;
393 if (
VerboseLevel() > 1) G4cout <<
"TG4ComposedPhysicsList::SetCuts" << G4endl;
396 G4ProductionCutsTable::GetProductionCutsTable()->SetEnergyRange(
408 SetCutValue(rangeCutGam,
"gamma");
409 SetCutValue(rangeCutEle,
"e-");
410 SetCutValue(rangeCutPos,
"e+");
411 SetCutValue(rangeCutPro,
"proton");
419 G4RegionStore* regionStore = G4RegionStore::GetInstance();
420 for (G4int i = 0; i < G4int(regionStore->size()); i++) {
421 G4Region* region = (*regionStore)[i];
424 if (region->GetProductionCuts())
continue;
426 G4ProductionCuts* cuts =
new G4ProductionCuts();
427 cuts->SetProductionCut(rangeCutGam, 0);
428 cuts->SetProductionCut(rangeCutEle, 1);
429 cuts->SetProductionCut(rangeCutPos, 2);
430 cuts->SetProductionCut(rangeCutPro, 3);
431 region->SetProductionCuts(cuts);
442 SetParticleCuts(cut, G4Gamma::Gamma());
450 SetParticleCuts(cut, G4Electron::Electron());
458 SetParticleCuts(cut, G4Positron::Positron());
466 SetParticleCuts(cut, G4Proton::Proton());
471 G4double min, G4double max)
482 const G4String& particleName,
const G4String& processTypeOrName,
483 G4double factor, G4bool isProcessName)
490 std::make_tuple(particleName, processTypeOrName, factor, isProcessName));
498 G4cout <<
"Instantiated processes: " << G4endl;
499 G4cout <<
"======================= " << G4endl;
501 G4ProcessTable* processTable = G4ProcessTable::GetProcessTable();
502 G4ProcessTable::G4ProcNameVector* processNameList =
503 processTable->GetNameList();
505 for (G4int i = 0; i < G4int(processNameList->size()); i++) {
506 G4cout <<
" " << (*processNameList)[i] << G4endl;
515 G4cout <<
"Instantiated particles and processes: " << G4endl;
516 G4cout <<
"===================================== " << G4endl;
518 auto theParticleIterator = GetParticleIterator();
519 theParticleIterator->reset();
520 while ((*theParticleIterator)()) {
522 G4cout <<
"Particle: " << theParticleIterator->value()->GetParticleName()
526 G4ProcessVector* processVector =
527 theParticleIterator->value()->GetProcessManager()->GetProcessList();
528 for (
size_t i = 0; i < processVector->length(); i++)
529 (*processVector)[i]->DumpInfo();
551 SetVerboseLevel(level);
Definition of the TG4ComposedPhysicsList class.
Definition of the TG4G3PhysicsManager class.
Definition of the TG4PhysicsManager class.
Definition of the TG4ProcessMapPhysics class.
G4bool fIsProductionCutsTableEnergyRange
Info if the production cuts table energy range is redefined by user.
static const G4double fgkDefautLooperThresholdsLevel
the default cut value
void SetCutForProton(G4double cut)
G4double fProductionCutsTableEnergyMax
The production cuts table energy range maximum redefined by user.
virtual void ConstructProcess()
void SetLooperThresholds()
void ApplyGammaToMuonsCrossSectionFactor()
G4int fLooperThresholdsLevel
Looper threshold level (can have valuee 0,1,2)
void AddPhysicsList(G4VUserPhysicsList *physicsList)
G4double fProductionCutsTableEnergyMin
The production cuts table energy range minimum redefined by user.
virtual G4int VerboseLevel() const
std::vector< std::tuple< G4String, G4String, G4double, G4bool > > fCrossSectionFactors
Cross section factors by process type or name.
std::vector< G4VUserPhysicsList * > fPhysicsLists
physics lists
virtual void ConstructParticle()
void DumpAllProcesses() const
G4double fGammaToMuonsCrossSectionFactor
Gamma to muons cross section factor.
void PrintAllProcesses() const
void SetProductionCutsTableEnergyRange(G4double min, G4double max)
virtual ~TG4ComposedPhysicsList()
void ApplyCrossSectionFactor(const G4String &particleName, const G4String &processDef, G4double value, G4bool isProcessName)
void SetCutForGamma(G4double cut)
void SetCutForElectron(G4double cut)
void SetCutForPositron(G4double cut)
void SetCrossSectionFactor(const G4String &particleName, const G4String &processDef, G4double value, G4bool isProcessName)
void ApplyCrossSectionFactors()
Provides a Geant3 way control to Geant4 physics.
static TG4G3PhysicsManager * Instance()
static void Warning(const TString &className, const TString &methodName, const TString &text)
G4double GetCutForPositron() const
G4double GetCutForProton() const
static TG4PhysicsManager * Instance()
G4double GetCutForElectron() const
G4double GetCutForGamma() const
Base class for defining the verbose level and a common messenger.
virtual G4int VerboseLevel() const
virtual void VerboseLevel(G4int level)