LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
MuNuclearSplittingProcess.cxx
Go to the documentation of this file.
1 //
2 // Code adapted from EventBiasing from Jane Tinslay, SLAC. 2008. Now at Cisco,
3 // I think.
4 //
5 // This is a variance reduction technique.
6 //
7 // The point is to create Nsplit secondaries with each muNucl process, so
8 // that we may, e.g., create many, otherwise-rare, K0s which
9 // may charge exchange into pernicious K+s which then mimic proton dk.
10 //
11 // echurch@fnal.gov, May, 2011.
12 //
13 
15 
16 #include <stdexcept> // std::runtime_error
17 
18 #include "Geant4/G4VParticleChange.hh"
19 
20 #include "Geant4/G4DynamicParticle.hh"
21 #include "Geant4/G4KaonZeroLong.hh"
22 #include "Geant4/G4KaonZeroShort.hh"
23 #include "Geant4/G4LorentzVector.hh"
24 #include "Geant4/G4ParticleDefinition.hh"
25 #include "Geant4/G4String.hh"
26 #include "Geant4/G4ThreeVector.hh"
27 #include "Geant4/G4Track.hh"
28 #include "Geant4/G4VProcess.hh"
29 #include "Geant4/Randomize.hh"
30 
31 #include <TMath.h>
32 
33 namespace larg4 {
34 
35  G4VParticleChange* MuNuclearSplittingProcess::PostStepDoIt(const G4Track& track,
36  const G4Step& step)
37  {
38 
39  G4VParticleChange* particleChange = new G4VParticleChange();
40  G4double weight = track.GetWeight() / fNSplit;
41  std::vector<G4Track*> secondaries; // Secondary store
42 
43  // Loop over PostStepDoIt method to generate multiple secondaries.
44  // The point is for each value of ii up to Nsplit we want to re-toss
45  // all secondaries for the muNucl process. Each toss gives back numSec
46  // secondaries, which will be a different sample of species/momenta each time.
47  for (unsigned int ii = 0; ii < (unsigned int)fNSplit; ii++) {
48  particleChange = pRegProcess->PostStepDoIt(track, step);
49  if (!particleChange)
50  throw std::runtime_error("MuNuclearSplittingProcess::PostStepDoIt(): no particle change");
51  G4int j(0);
52  G4int numSec(particleChange->GetNumberOfSecondaries());
53  for (j = 0; j < numSec; j++) {
54  G4Track* newSec = new G4Track(*(particleChange->GetSecondary(j)));
55  G4String pdgstr = newSec->GetParticleDefinition()->GetParticleName();
56  G4double ke = newSec->GetKineticEnergy() / CLHEP::GeV;
57  G4int pdg = newSec->GetParticleDefinition()->GetPDGEncoding();
58  if (abs(pdg) == 310 || abs(pdg) == 311 || abs(pdg) == 3122 || abs(pdg) == 2112) {
59  // std::cout << "MuNuclSplProc: Creating " << pdgstr << " of Kinetic Energy " << ke << " GeV. numSec is " << j << std::endl;
60 
61  if (pdg == G4KaonZeroShort::KaonZeroShort()->GetPDGEncoding() && G4UniformRand() < 0.50) {
62  pdg = G4KaonZeroLong::KaonZeroLong()->GetPDGEncoding();
63  pdgstr = G4KaonZeroLong::KaonZeroLong()->GetParticleName();
64  G4LorentzVector pK0L(
65  newSec->GetMomentum(),
66  TMath::Sqrt(TMath::Power(G4KaonZeroLong::KaonZeroLong()->GetPDGMass(), 2) +
67  TMath::Power(newSec->GetMomentum().mag(), 2)));
68  G4DynamicParticle* newK0L = new G4DynamicParticle(G4KaonZeroLong::KaonZeroLong(), pK0L);
69 
70  G4Track* newSecK0L = new G4Track(newK0L, track.GetGlobalTime(), track.GetPosition());
71  secondaries.push_back(newSecK0L);
72  }
73  else {
74  secondaries.push_back(newSec);
75  }
76 
77  if (abs(pdg) == 130 || abs(pdg) == 310 || abs(pdg) == 311 || abs(pdg) == 3122) {
78  // WrappedmuNuclear always produces K0s if it produces a K0 at all.
79  // Let's make half of these K0Ls.
80  std::cout << "MuNuclSplProc: Creating " << pdgstr << " of Kinetic Energy " << ke
81  << " GeV. numSec is " << j << std::endl;
82  }
83  }
84  }
85  }
86 
87  particleChange->SetNumberOfSecondaries(secondaries.size());
88  particleChange->SetSecondaryWeightByProcess(true);
89  //int numSecAdd = secondaries.size();
90  std::vector<G4Track*>::iterator iter = secondaries.begin(); // Add all secondaries
91  while (iter != secondaries.end()) {
92  G4Track* myTrack = *iter;
93  G4String pdgstr = myTrack->GetParticleDefinition()->GetParticleName();
94  //G4double ke = myTrack->GetKineticEnergy()/GeV;
95  G4int pdg = myTrack->GetParticleDefinition()->GetPDGEncoding();
96  if (abs(pdg) == 130 || abs(pdg) == 310 || abs(pdg) == 311 || abs(pdg) == 3122 ||
97  abs(pdg) == 2112)
98  // std::cout << "MuNuclSplProc: Adding " << pdgstr << " of Kinetic Energy " << ke << " GeV." << std::endl;
99  // Will ask for PdgCode and only Add K0s.
100  myTrack->SetWeight(weight);
101  particleChange->AddSecondary(myTrack);
102  iter++;
103  }
104  return particleChange;
105  }
106 
107 } // end namespace
intermediate_table::iterator iterator
constexpr auto abs(T v)
Returns the absolute value of the argument.
Geant4 interface.
Check of Geant4 to run the LArSoft detector simulation.
double weight
Definition: plottest35.C:25
Float_t track
Definition: plot.C:35
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &step)