CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
NuclearInteractionFTFSimulator.cc
Go to the documentation of this file.
1 // Framework Headers
4 
5 // Fast Sim headers
10 
11 // Geant4 headers
12 #include "G4ParticleDefinition.hh"
13 #include "G4DynamicParticle.hh"
14 #include "G4Track.hh"
15 #include "G4Step.hh"
16 #include "G4StepPoint.hh"
17 #include "G4TheoFSGenerator.hh"
18 #include "G4FTFModel.hh"
19 #include "G4ExcitedStringDecay.hh"
20 #include "G4LundStringFragmentation.hh"
21 #include "G4GeneratorPrecompoundInterface.hh"
22 
23 #include "G4Proton.hh"
24 #include "G4Neutron.hh"
25 #include "G4PionPlus.hh"
26 #include "G4PionMinus.hh"
27 #include "G4AntiProton.hh"
28 #include "G4AntiNeutron.hh"
29 #include "G4KaonPlus.hh"
30 #include "G4KaonMinus.hh"
31 #include "G4KaonZeroLong.hh"
32 #include "G4KaonZeroShort.hh"
33 #include "G4KaonZero.hh"
34 #include "G4AntiKaonZero.hh"
35 #include "G4GenericIon.hh"
36 
37 #include "G4Lambda.hh"
38 #include "G4OmegaMinus.hh"
39 #include "G4SigmaMinus.hh"
40 #include "G4SigmaPlus.hh"
41 #include "G4SigmaZero.hh"
42 #include "G4XiMinus.hh"
43 #include "G4XiZero.hh"
44 #include "G4AntiLambda.hh"
45 #include "G4AntiOmegaMinus.hh"
46 #include "G4AntiSigmaMinus.hh"
47 #include "G4AntiSigmaPlus.hh"
48 #include "G4AntiSigmaZero.hh"
49 #include "G4AntiXiMinus.hh"
50 #include "G4AntiXiZero.hh"
51 #include "G4AntiAlpha.hh"
52 #include "G4AntiDeuteron.hh"
53 #include "G4AntiTriton.hh"
54 #include "G4AntiHe3.hh"
55 
56 #include "G4Material.hh"
57 #include "G4DecayPhysics.hh"
58 #include "G4ParticleTable.hh"
59 #include "G4SystemOfUnits.hh"
60 
61 const double fact = 1.0/CLHEP::GeV;
62 
64  unsigned int distAlgo,
65  double distCut) :
66  theDistCut(distCut),
67  distMin(1E99),
68  theDistAlgo(distAlgo)
69 {
71  currIdx = 0;
72 
73  // FTF model
74  theHadronicModel = new G4TheoFSGenerator("FTF");
75  theStringModel = new G4FTFModel();
76  G4GeneratorPrecompoundInterface* cascade
77  = new G4GeneratorPrecompoundInterface(new CMSDummyDeexcitation());
78  theLund = new G4LundStringFragmentation();
79  theStringDecay = new G4ExcitedStringDecay(theLund);
80  theStringModel->SetFragmentationModel(theStringDecay);
81 
82  theHadronicModel->SetTransport(cascade);
83  theHadronicModel->SetHighEnergyGenerator(theStringModel);
84  theHadronicModel->SetMinEnergy(theEnergyLimit);
85 
86  // Geant4 particles
87  numHadrons = 30;
88  theG4Hadron.resize(numHadrons,0);
89  theG4Hadron[0] = G4Proton::Proton();
90  theG4Hadron[1] = G4Neutron::Neutron();
91  theG4Hadron[2] = G4PionPlus::PionPlus();
92  theG4Hadron[3] = G4PionMinus::PionMinus();
93  theG4Hadron[4] = G4AntiProton::AntiProton();
94  theG4Hadron[5] = G4KaonPlus::KaonPlus();
95  theG4Hadron[6] = G4KaonMinus::KaonMinus();
96  theG4Hadron[7] = G4KaonZeroLong::KaonZeroLong();
97  theG4Hadron[8] = G4KaonZeroShort::KaonZeroShort();
98  theG4Hadron[9] = G4KaonZero::KaonZero();
99  theG4Hadron[10]= G4AntiKaonZero::AntiKaonZero();
100  theG4Hadron[11]= G4Lambda::Lambda();
101  theG4Hadron[12]= G4OmegaMinus::OmegaMinus();
102  theG4Hadron[13]= G4SigmaMinus::SigmaMinus();
103  theG4Hadron[14]= G4SigmaPlus::SigmaPlus();
104  theG4Hadron[15]= G4SigmaZero::SigmaZero();
105  theG4Hadron[16]= G4XiMinus::XiMinus();
106  theG4Hadron[17]= G4XiZero::XiZero();
107  theG4Hadron[18]= G4AntiNeutron::AntiNeutron();
108  theG4Hadron[19]= G4AntiLambda::AntiLambda();
109  theG4Hadron[20]= G4AntiOmegaMinus::AntiOmegaMinus();
110  theG4Hadron[21]= G4AntiSigmaMinus::AntiSigmaMinus();
111  theG4Hadron[22]= G4AntiSigmaPlus::AntiSigmaPlus();
112  theG4Hadron[23]= G4AntiSigmaZero::AntiSigmaZero();
113  theG4Hadron[24]= G4AntiXiMinus::AntiXiMinus();
114  theG4Hadron[25]= G4AntiXiZero::AntiXiZero();
115  theG4Hadron[26]= G4AntiAlpha::AntiAlpha();
116  theG4Hadron[27]= G4AntiDeuteron::AntiDeuteron();
117  theG4Hadron[28]= G4AntiTriton::AntiTriton();
118  theG4Hadron[29]= G4AntiHe3::AntiHe3();
119 
120  G4GenericIon::GenericIon();
121  G4DecayPhysics decays;
122  decays.ConstructParticle();
123  G4ParticleTable* partTable = G4ParticleTable::GetParticleTable();
124  partTable->SetReadiness();
125 
126  // interaction length in units of radiation length
127  // computed for 5 GeV projectile energy, default value for K0_L
128  theNuclIntLength.resize(numHadrons,6.46);
129  theNuclIntLength[0] = 4.528;
130  theNuclIntLength[1] = 4.524;
131  theNuclIntLength[2] = 4.493;
132  theNuclIntLength[3] = 4.493;
133  theNuclIntLength[4] = 3.593;
134  theNuclIntLength[5] = 7.154;
135  theNuclIntLength[6] = 5.889;
136  theNuclIntLength[11]= 4.986;
137  theNuclIntLength[12]= 4.983;
138  theNuclIntLength[13]= 4.986;
139  theNuclIntLength[14]= 4.986;
140  theNuclIntLength[15]= 4.986;
141  theNuclIntLength[16]= 4.986;
142  theNuclIntLength[17]= 4.986;
143  theNuclIntLength[18]= 3.597;
144  theNuclIntLength[19]= 3.608;
145  theNuclIntLength[20]= 3.639;
146  theNuclIntLength[21]= 3.613;
147  theNuclIntLength[22]= 3.613;
148  theNuclIntLength[23]= 3.613;
149  theNuclIntLength[24]= 3.62;
150  theNuclIntLength[25]= 3.62;
151  theNuclIntLength[26]= 1.971;
152  theNuclIntLength[27]= 2.301;
153  theNuclIntLength[28]= 1.997;
154  theNuclIntLength[29]= 1.997;
155 
156  // list of PDG codes
157  theId.resize(numHadrons,0);
158 
159  // local objects
160  currIdx = 0;
161  currTrack = 0;
163  vectProj.set(0.0,0.0,1.0);
164  theBoost.set(0.0,0.0,1.0);
165 
166  // fill projectile particle definitions
167  dummyStep = new G4Step();
168  dummyStep->SetPreStepPoint(new G4StepPoint());
169  for(int i=0; i<numHadrons; ++i) {
170  theId[i] = theG4Hadron[i]->GetPDGEncoding();
171  }
172 
173  // target is always Silicon
174  targetNucleus.SetParameters(28, 14);
175 }
176 
178 
179  delete theStringDecay;
180  delete theStringModel;
181  delete theLund;
182 }
183 
186 {
187  //std::cout << "#### Primary " << Particle.pid() << " E(GeV)= "
188  // << Particle.momentum().e() << std::endl;
189 
190  int thePid = Particle.pid();
191  if(thePid != theId[currIdx]) {
192  currParticle = 0;
193  currIdx = 0;
194  for(; currIdx<numHadrons; ++currIdx) {
195  if(theId[currIdx] == thePid) {
197  // neutral kaons
198  if(7 == currIdx || 8 == currIdx) {
200  if(random->flatShoot() > 0.5) { currParticle = theG4Hadron[10]; }
201  }
202  break;
203  }
204  }
205  }
206  if(!currParticle) { return; }
207 
208  // fill projectile for Geant4
209  double e = CLHEP::GeV*Particle.momentum().e();
210  double mass = currParticle->GetPDGMass();
211  /*
212  std::cout << " Primary " << currParticle->GetParticleName()
213  << " E(GeV)= " << e*fact << std::endl;
214  */
215  if(e <= theEnergyLimit + mass) { return; }
216 
217  double currInteractionLength = -G4Log(random->flatShoot())*theNuclIntLength[currIdx];
218  /*
219  std::cout << "*NuclearInteractionFTFSimulator::compute: R(X0)= " << radLengths
220  << " Rnuc(X0)= " << theNuclIntLength[currIdx] << " IntLength(X0)= "
221  << currInteractionLength << std::endl;
222  */
223  // Check position of nuclear interaction
224  if (currInteractionLength > radLengths) { return; }
225 
226  // fill projectile for Geant4
227  double px = Particle.momentum().px();
228  double py = Particle.momentum().py();
229  double pz = Particle.momentum().pz();
230  double norm = 1.0/sqrt(px*px + py*py + pz*pz);
231  G4ThreeVector dir(px*norm, py*norm, pz*norm);
232  /*
233  std::cout << " Primary " << currParticle->GetParticleName()
234  << " E(GeV)= " << e*fact << " P(GeV/c)= ("
235  << px << " " << py << " " << pz << ")" << std::endl;
236  */
237 
238  G4DynamicParticle* dynParticle = new G4DynamicParticle(theG4Hadron[currIdx],dir,e-mass);
239  currTrack = new G4Track(dynParticle, 0.0, vectProj);
240  currTrack->SetStep(dummyStep);
241 
242  theProjectile.Initialise(*currTrack);
243  delete currTrack;
244 
245  G4HadFinalState* result = theHadronicModel->ApplyYourself(theProjectile, targetNucleus);
246 
247  if(result) {
248 
249  int nsec = result->GetNumberOfSecondaries();
250  if(0 < nsec) {
251 
252  result->SetTrafoToLab(theProjectile.GetTrafoToLab());
253  _theUpdatedState.clear();
254 
255  //std::cout << " " << nsec << " secondaries" << std::endl;
256  // Generate angle
257  double phi = random->flatShoot()*CLHEP::twopi;
259  distMin = 1e99;
260 
261  // rotate and store secondaries
262  for (int j=0; j<nsec; ++j) {
263 
264  const G4DynamicParticle* dp = result->GetSecondary(j)->GetParticle();
265  int thePid = dp->GetParticleDefinition()->GetPDGEncoding();
266 
267  // rotate around primary direction
268  curr4Mom = dp->Get4Momentum();
269  curr4Mom.rotate(phi, vectProj);
270  curr4Mom *= result->GetTrafoToLab();
271  /*
272  std::cout << j << ". " << dp->GetParticleDefinition()->GetParticleName()
273  << " " << thePid
274  << " " << curr4Mom*fact << std::endl;
275  */
276  // prompt 2-gamma decay for pi0, eta, eta'p
277  if(111 == thePid || 221 == thePid || 331 == thePid) {
278  theBoost = curr4Mom.boostVector();
279  double e = 0.5*dp->GetParticleDefinition()->GetPDGMass();
280  double fi = random->flatShoot()*CLHEP::twopi;
281  double cth = 2*random->flatShoot() - 1.0;
282  double sth = sqrt((1.0 - cth)*(1.0 + cth));
283  G4LorentzVector lv(e*sth*cos(fi),e*sth*sin(fi),e*cth,e);
284  lv.boost(theBoost);
285  saveDaughter(Particle, lv, 22);
286  curr4Mom -= lv;
287  saveDaughter(Particle, curr4Mom, 22);
288  } else {
289  saveDaughter(Particle, curr4Mom, thePid);
290  }
291  }
292  }
293  }
294 }
295 
297  const G4LorentzVector& lv, int pdgid)
298 {
299  unsigned int idx = _theUpdatedState.size();
300  _theUpdatedState.push_back(Particle);
301  _theUpdatedState[idx].SetXYZT(lv.px()*fact,lv.py()*fact,lv.pz()*fact,lv.e()*fact);
302  _theUpdatedState[idx].setID(pdgid);
303 
304  // Store the closest daughter index (for later tracking purposes, so charged particles only)
305  double distance = distanceToPrimary(Particle,_theUpdatedState[idx]);
306  // Find the closest daughter, if closer than a given upper limit.
307  if ( distance < distMin && distance < theDistCut ) {
308  distMin = distance;
310  }
311  // std::cout << _theUpdatedState[idx] << std::endl;
312 }
313 
314 double
316  const RawParticle& aDaughter) const
317 {
318  double distance = 2E99;
319  // Compute the distance only for charged primaries
320  if ( fabs(Particle.charge()) > 1E-6 ) {
321 
322  // The secondary must have the same charge
323  double chargeDiff = fabs(aDaughter.charge()-Particle.charge());
324  if ( fabs(chargeDiff) < 1E-6 ) {
325 
326  // Here are two distance definitions * to be tuned *
327  switch ( theDistAlgo ) {
328 
329  case 1:
330  // sin(theta12)
331  distance = (aDaughter.Vect().Unit().Cross(Particle.Vect().Unit())).R();
332  break;
333 
334  case 2:
335  // sin(theta12) * p1/p2
336  distance = (aDaughter.Vect().Cross(Particle.Vect())).R()
337  /aDaughter.Vect().Mag2();
338  break;
339 
340  default:
341  // Should not happen
342  break;
343  }
344  }
345  }
346  return distance;
347 }
int i
Definition: DBlmapReader.cc:9
const double GeV
Definition: MathUtil.h:16
double flatShoot(double xmin=0.0, double xmax=1.0) const
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
int pid() const
get the HEP particle ID number
Definition: RawParticle.h:265
TRandom random
Definition: MVATrainer.cc:138
void compute(ParticlePropagator &Particle, RandomEngineAndDistribution const *)
Generate a nuclear interaction according to the probability that it happens.
const XYZTLorentzVector & momentum() const
the momentum fourvector
Definition: RawParticle.h:286
void saveDaughter(ParticlePropagator &Particle, const G4LorentzVector &lv, int pdgid)
T sqrt(T t)
Definition: SSEVec.h:48
tuple result
Definition: query.py:137
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
std::vector< const G4ParticleDefinition * > theG4Hadron
int j
Definition: DBlmapReader.cc:9
double charge() const
get the MEASURED charge
Definition: RawParticle.h:282
double distanceToPrimary(const RawParticle &Particle, const RawParticle &aDaughter) const
const G4ParticleDefinition * currParticle
const double fact
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
std::vector< RawParticle > _theUpdatedState
dbl *** dir
Definition: mlp_gen.cc:35
NuclearInteractionFTFSimulator(unsigned int distAlgo, double distCut)
Constructor.
Definition: DDAxes.h:10