LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
PhysicsList.cxx
Go to the documentation of this file.
1 //
8 // Don't be too confused by the names. PhysicsList.h and
9 // PhysicsList.cxx define what the name "LArG4::PhysicList" means.
10 // However, that definition is mainly in terms of
11 // LArG4::ModularPhysicsList, a class that inherits from
12 // G4VModularPhysicsList.
13 
15 
17 
18 #include "Geant4/G4ParallelWorldScoringProcess.hh"
19 #include "Geant4/G4ParticleDefinition.hh"
20 #include "Geant4/G4ParticleTable.hh"
21 #include "Geant4/G4VModularPhysicsList.hh"
22 
23 #include "Geant4/G4ChargeExchange.hh"
24 #include "Geant4/G4ChargeExchangeProcess.hh"
25 #include "Geant4/G4ProcessManager.hh"
26 
29 #include "Geant4/G4PhysListStamper.hh"
31 
32 #define G4MT_physicsVector ((G4VMPLsubInstanceManager.offset[g4vmplInstanceID]).physicsVector)
33 
34 namespace larg4 {
35 
36  // This is the method we have to modify to use the Geant4 parallel geometries.
38  {
39  // We don't need to modify G4VModularPhysicsList's
40  // AddTransportation method. Just invoke it directly.
41  G4VModularPhysicsList::AddTransportation();
42 
44  // This is the "new" code that has to be added to
45  // G4VModularPhysicsList::ConstructProcess() to handle the
46  // parallel geometry.
47 
49  bool DisableWireplanes = lgp->DisableWireplanes();
50 
51  G4ParallelWorldScoringProcess* LArVoxelParallelWorldScoringProcess =
52  new G4ParallelWorldScoringProcess("LArVoxelReadoutScoringProcess");
53 
54  G4ParallelWorldScoringProcess* OpDetParallelWorldScoringProcess =
55  new G4ParallelWorldScoringProcess("OpDetReadoutScoringProcess");
56 
57  // Note that the name below MUST match the name used in the
58  // LArVoxelReadoutGeometry or OpDetReadoutGeometry constructor.
59  LArVoxelParallelWorldScoringProcess->SetParallelWorld("LArVoxelReadoutGeometry");
60  OpDetParallelWorldScoringProcess->SetParallelWorld("OpDetReadoutGeometry");
61 
62  // Tell all the particles in the physics list to recognize the
63  // LAr voxel parallel world. "theParticleIterator" is defined in
64  // G4VUserPhysicsList.hh. Only photons recognise the OpDet parallel
65  // world.
66  static G4ParticleTable* fParticleTable = G4ParticleTable::GetParticleTable();
67  G4ParticleTable::G4PTblDicIterator* theParticleIterator;
68  theParticleIterator = fParticleTable->GetIterator();
69  theParticleIterator->reset();
70  while ((*theParticleIterator)()) {
71  G4ParticleDefinition* particle = theParticleIterator->value();
72 
73  if (particle->GetParticleType() == "opticalphoton") {
74  G4ProcessManager* pmanager = particle->GetProcessManager();
75  pmanager->AddProcess(OpDetParallelWorldScoringProcess);
76  pmanager->SetProcessOrderingToLast(OpDetParallelWorldScoringProcess, idxAtRest);
77  pmanager->SetProcessOrdering(OpDetParallelWorldScoringProcess, idxAlongStep, 1);
78  pmanager->SetProcessOrderingToLast(OpDetParallelWorldScoringProcess, idxPostStep);
79  }
80 
81  // Only apply voxel processing in the LAr TPC if the particles are
82  // charged and they have a significant life-time.
83  else if (particle->GetPDGCharge() != 0 && !particle->IsShortLived()) {
84  G4ProcessManager* pmanager = particle->GetProcessManager();
85  if (!DisableWireplanes) {
86  pmanager->AddProcess(LArVoxelParallelWorldScoringProcess);
87  pmanager->SetProcessOrderingToLast(LArVoxelParallelWorldScoringProcess, idxAtRest);
88  pmanager->SetProcessOrdering(LArVoxelParallelWorldScoringProcess, idxAlongStep, 1);
89  pmanager->SetProcessOrderingToLast(LArVoxelParallelWorldScoringProcess, idxPostStep);
90  }
91 
92  // Do secondary biasing under control of K0Bias switch.
93  G4bool genSecondaries(false);
94  G4bool cE(false);
95  if (((particle->GetParticleName() == G4MuonPlus::MuonPlus()->GetParticleName() ||
96  particle->GetParticleName() == G4MuonMinus::MuonMinus()->GetParticleName()) &&
97  lgp->UseCustomPhysics()) ||
98  ((particle->GetParticleName() == G4Proton::Proton()->GetParticleName() ||
99  particle->GetParticleName() == G4Neutron::Neutron()->GetParticleName() ||
100  particle->GetParticleName() == G4KaonZeroShort::KaonZeroShort()->GetParticleName() ||
101  particle->GetParticleName() == G4KaonZeroLong::KaonZeroLong()->GetParticleName() ||
102  particle->GetParticleName() == G4Lambda::Lambda()->GetParticleName()) &&
103  lgp->UseCustomPhysics())) {
104  std::vector<std::string> EnabledPhysics = lgp->EnabledPhysics();
105  for (std::vector<std::string>::const_iterator it = EnabledPhysics.begin();
106  it != EnabledPhysics.end();
107  it++) {
108  std::string PhysicsName = (*it);
109  if (!PhysicsName.compare("SynchrotronAndGN") && lgp->K0Bias()) {
110  genSecondaries = true;
111  }
112  if (!PhysicsName.compare("ChargeExchange")) { cE = true; }
113  } // end loop over enabled physics
114  } // end if using custom physics
115 
116  if (genSecondaries) {
117  G4int nSecondaries(lgp->K0Bias());
118  G4int fXSBias(lgp->MNXSBias());
119  G4int xSBias(lgp->MNXBias());
120  mf::LogInfo("PhysicsList: ")
121  << "Turning on WrappedMuNuclear for " << particle->GetParticleName() << "s with "
122  << nSecondaries << " appropriately weighted secondaries."
123  << " XSBias is set to " << xSBias
124  << " and the cross-section is increased by a factor of " << fXSBias << ".";
125  G4MuonNuclearProcess* g4MNI = new G4MuonNuclearProcess();
126  MuNuclearSplittingProcessXSecBias* munuclSplitting =
128  G4bool active(true);
129 
130  munuclSplitting->SetNSplit(nSecondaries, xSBias, fXSBias);
131  munuclSplitting->SetIsActive(active);
132  munuclSplitting->RegisterProcess(g4MNI);
133  // Middle -1 with no biasing.
134  // The middle +1 enforces AlongStepDoIt active for MuNuclear, I claim.
135  if (xSBias && (fXSBias > 1))
136  pmanager->AddProcess(munuclSplitting, -1, 1, 1);
137  else
138  pmanager->AddProcess(munuclSplitting, -1, -1, 1);
139  } // end if generating secondaries
140 
141  if (cE) {
142  mf::LogInfo("PhysicsList: ")
143  << "Turning on ChargeExchange for " << particle->GetParticleName() << "s.";
144  G4ChargeExchange* model = new G4ChargeExchange();
145  G4ChargeExchangeProcess* p = new G4ChargeExchangeProcess();
146 
147  p->RegisterMe(model);
148  pmanager->AddDiscreteProcess(p);
149 
150  } // end if doing charge exchange
151  } // end if short lived particle
152  } // end loop over particles
153 
154  // End of code "added" to G4VModularPhysicsList::ConstructProcess()
156 
157  // This code is also unchanged from
158  // G4VModularPhysicsList::ConstructProcess(); it means "activate
159  // the physics processes and particle combinations we've specified
160  // in physicsVector." The physicsVector is built up by the
161  // pre-supplied Geant4 physics list; see PhysicsList.h for the
162  // name of that list. "physicsVector" is defined in
163  // G4VModularPhysicsList.hh.
165  for (itr = G4MT_physicsVector->begin(); itr != G4MT_physicsVector->end(); ++itr) {
166  (*itr)->ConstructProcess();
167  }
168  } // end ConstructProcess
169 
170 } // namespace LArG4
intermediate_table::iterator iterator
Create the physics lists to be used by Geant4.
const std::vector< std::string > & EnabledPhysics() const
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void SetNSplit(G4int nTrx, G4int xB=0, G4double xFac=1)
#define G4MT_physicsVector
Definition: PhysicsList.cxx:32
Geant4 interface.
intermediate_table::const_iterator const_iterator
bool UseCustomPhysics() const
G4_DECLARE_PHYSLIST_FACTORY_NS(larg4::PhysicsList, larg4, PhysicsList)
virtual void ConstructProcess()
Definition: PhysicsList.cxx:37
bool DisableWireplanes() const