CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ToyModelHadronicProcess.cc
Go to the documentation of this file.
1 //Geant4 include
2 #include "G4ProcessManager.hh"
3 #include "G4ParticleTable.hh"
4 #include "G4Track.hh"
5 #include "Randomize.hh"
6 //Our includes
7 #include "SimG4Core/CustomPhysics/interface/ToyModelHadronicProcess.hh"
10 #include "SimG4Core/CustomPhysics/interface/HadronicProcessHelper.hh"
12 
13 using namespace CLHEP;
14 
15 ToyModelHadronicProcess::ToyModelHadronicProcess(HadronicProcessHelper * aHelper, const G4String& processName) :
16  G4VDiscreteProcess(processName), m_verboseLevel(0), m_helper(aHelper), m_detachCloud(true)
17 {
18  // Instantiating helper class
19  //m_helper = HadronicProcessHelper::instance();
20  //m_verboseLevel=0;
21  //m_detachCloud=true;
22 
23 }
24 
25 
26 G4bool ToyModelHadronicProcess::IsApplicable(const G4ParticleDefinition& aP)
27 {
28  return m_helper->applicabilityTester(aP);
29 }
30 
31 G4double ToyModelHadronicProcess::GetMicroscopicCrossSection(const G4DynamicParticle *particle,
32  const G4Element *element,
33  G4double /*temperature*/)
34 {
35  //Get the cross section for this particle/element combination from the ProcessHelper
36  G4double inclusiveCrossSection = m_helper->inclusiveCrossSection(particle,element);
37 
38  // Need to provide Set-methods for these in time
39  G4double highestEnergyLimit = 10 * TeV ;
40  G4double lowestEnergyLimit = 1 * eV;
41  G4double particleEnergy = particle->GetKineticEnergy();
42 
43  if (particleEnergy > highestEnergyLimit || particleEnergy < lowestEnergyLimit){
44  if(m_verboseLevel >= 1) std::cout << "ToyModelHadronicProcess: Energy out of bounds [" <<
45  lowestEnergyLimit / MeV << "MeV , " <<
46  highestEnergyLimit / MeV << "MeV ] while it is " << particleEnergy/MeV <<
47  std::endl;
48  return 0;
49  } else {
50  if(m_verboseLevel >= 3) std::cout << "ToyModelHadronicProcess: Return cross section " << inclusiveCrossSection << std::endl;
51  return inclusiveCrossSection;
52  }
53 
54 }
55 
56 
57 G4double ToyModelHadronicProcess::GetMeanFreePath(const G4Track& aTrack, G4double, G4ForceCondition*)
58 {
59  G4Material *aMaterial = aTrack.GetMaterial();
60  const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
61  G4double sigma = 0.0;
62 
63  G4int nElements = aMaterial->GetNumberOfElements();
64 
65  const G4double *theAtomicNumDensityVector =
66  aMaterial->GetAtomicNumDensityVector();
67  G4double aTemp = aMaterial->GetTemperature();
68 
69  for( G4int i=0; i<nElements; ++i )
70  {
71  G4double xSection =
72  GetMicroscopicCrossSection( aParticle, (*aMaterial->GetElementVector())[i], aTemp);
73  sigma += theAtomicNumDensityVector[i] * xSection;
74  }
75 
76  return 1.0/sigma;
77 
78 }
79 
80 
81 G4VParticleChange* ToyModelHadronicProcess::PostStepDoIt(const G4Track& track,
82  const G4Step& /* step*/)
83 {
84 
85  const G4TouchableHandle thisTouchable(track.GetTouchableHandle());
86 
87  // A little setting up
88  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
89  m_particleChange.Initialize(track);
90  // G4DynamicParticle* incidentRHadron = const_cast<G4DynamicParticle*>(track.GetDynamicParticle()); //This will contain RHadron Def + RHad momentum
91  const G4DynamicParticle* incidentRHadron = track.GetDynamicParticle(); //This will contain RHadron Def + RHad momentum
92 // double E_0 = incidentRHadron->GetKineticEnergy();
93 // const G4int theIncidentPDG = incidentRHadron->GetDefinition()->GetPDGEncoding();
94  const G4ThreeVector aPosition = track.GetPosition();
95 
96 // double gamma = incidentRHadron->GetTotalEnergy()/incidentRHadron->GetDefinition()->GetPDGMass();
97 
98  CustomParticle* CustomIncident = dynamic_cast<CustomParticle*>(incidentRHadron->GetDefinition());
99  G4DynamicParticle* cloudParticle = new G4DynamicParticle(); //This will contain Cloud Def + scaled momentum
100 
101  // G4int rHadronPdg = incidentRHadron->GetDefinition()->GetPDGEncoding();
102 
103  //set cloud definition
104  if(CustomIncident==0)
105  {
106  std::cout << "ToyModelHadronicProcess::PostStepDoIt Definition of particle cloud not available!!" << std::endl;
107  } else {
108  cloudParticle->SetDefinition(CustomIncident->GetCloud());
109  }
110 
111  //compute scaled momentum
112  double scale=cloudParticle->GetDefinition()->GetPDGMass()/incidentRHadron->GetDefinition()->GetPDGMass();
113  G4LorentzVector cloudMomentum;
114  cloudMomentum.setVectM(incidentRHadron->GetMomentum()*scale,cloudParticle->GetDefinition()->GetPDGMass());
115  G4LorentzVector gluinoMomentum;
116  gluinoMomentum.setVectM(incidentRHadron->GetMomentum()*(1.-scale),CustomIncident->GetSpectator()->GetPDGMass());
117 
118  cloudParticle->Set4Momentum(cloudMomentum);
119 
120  const G4DynamicParticle *incidentParticle;
121  if(! m_detachCloud) incidentParticle = incidentRHadron;
122  else incidentParticle= cloudParticle;
123 
124  if(m_verboseLevel >= 3)
125  {
126  std::cout << "ToyModelHadronicProcess::PostStepDoIt After scaling " << std::endl;
127  std::cout << " RHadron "<<incidentRHadron->GetDefinition()->GetParticleName()<<" pdgmass= " << incidentRHadron->GetDefinition()->GetPDGMass() / GeV
128  << " P= " << incidentRHadron->Get4Momentum() / GeV<<" mass= "<< incidentRHadron->Get4Momentum().m() / GeV <<std::endl;
129  std::cout << " Cloud "<<cloudParticle->GetDefinition()->GetParticleName()<<" pdgmass= " << cloudParticle->GetDefinition()->GetPDGMass() / GeV
130  << " P= " << cloudParticle->Get4Momentum() / GeV<<" mass= "<< cloudParticle->Get4Momentum().m() / GeV <<std::endl;
131  std::cout << " Incident pdgmass= " << incidentParticle->GetDefinition()->GetPDGMass() / GeV
132  << " P= " << incidentParticle->Get4Momentum() / GeV<<" mass= "<< incidentParticle->Get4Momentum().m() / GeV <<std::endl;
133  }
134 
135  const G4ThreeVector position = track.GetPosition();
136  const G4int incidentParticlePDG = incidentRHadron->GetDefinition()->GetPDGEncoding();
137  std::vector<G4ParticleDefinition*> newParticles; // this will contain clouds
138  std::vector<G4ParticleDefinition*> newParticlesRHadron; // this will contain r-hadron
139 
140  G4bool incidentSurvives = false;
141 
142  //Get the final state particles and target
143  G4ParticleDefinition* targetParticle;
144  HadronicProcessHelper::ReactionProduct reactionProduct = m_helper->finalState(incidentRHadron,track.GetMaterial(),targetParticle);
145 
146  // Fill a list of the new particles to create
147  //(i.e. reaction products without the incident if it survives)
148 
149  for(HadronicProcessHelper::ReactionProduct::iterator it = reactionProduct.begin();
150  it != reactionProduct.end() ;
151  it++)
152  {
153  G4ParticleDefinition * productDefinition =theParticleTable->FindParticle(*it);
154 
155  if (productDefinition->GetPDGEncoding()==incidentParticlePDG)
156  incidentSurvives = true;
157 
158  newParticlesRHadron.push_back(productDefinition);
159 
160  CustomParticle* cProd = 0;
161  cProd = dynamic_cast<CustomParticle*>(productDefinition);
162 
163  if( cProd!=0 && m_detachCloud)
164  productDefinition=cProd->GetCloud();
165 
166  newParticles.push_back(productDefinition);
167  }
168 
169  int numberOfSecondaries = reactionProduct.size();
170 
171  if(m_verboseLevel >= 2) std::cout << "ToyModelHadronicProcess::PostStepDoIt N secondaries: "
172  << numberOfSecondaries << std::endl;
173 
174 
175  //************ My toy model ********************
176  // 2 -> 2 goes to CM, chooses a random direction and fires the particles off back to back
177  // 2 -> 3 Effectively two two-body decays
178 
179  // Getting fourmomenta
180  const G4LorentzVector incident4Momentum = incidentParticle->Get4Momentum();
181  const G4LorentzVector target4Momentum(0,0,0,targetParticle->GetPDGMass());
182  const G4LorentzVector sum4Momentum = incident4Momentum + target4Momentum;
183  const G4ThreeVector cmBoost = sum4Momentum.boostVector();//The boost from CM to lab
184  const G4LorentzVector cm4Momentum = sum4Momentum.rest4Vector();
185 
186  if(m_verboseLevel >= 2) std::cout << "ToyModelHadronicProcess::PostStepDoIt Kinematics in GeV: " << std::endl
187  << " Boost = " << cmBoost / GeV<< std::endl
188  << " 4P CM = " << cm4Momentum / GeV << std::endl
189  << " 4P Inc = " << incident4Momentum / GeV << std::endl
190  << " 4P Targ = " << target4Momentum / GeV<< std::endl;
191 
192  //Choosing random direction
193  const G4double phi_p = 2*pi*G4UniformRand()-pi ;
194  const G4double theta_p = pi*G4UniformRand() ;
195  const G4ThreeVector randomDirection(sin(theta_p)*cos(phi_p),
196  sin(theta_p)*sin(phi_p),
197  cos(theta_p));
198 
199 
200  std::vector<G4double> m;
201  std::vector<G4LorentzVector> fourMomenta;
202 
203  //Fill the masses
204  for(int ip=0;ip<numberOfSecondaries;ip++)
205  {
206  m.push_back(newParticles[ip]->GetPDGMass());
207  }
208 
209 
210  if (numberOfSecondaries==2){
211  // 2 -> 2
212 
213  //Get the CM energy
214  G4double energy = cm4Momentum.e();
215  G4ThreeVector p[2];
216 
217  //Size of momenta in CM
218 
219 
220  // Energy conservation:
221  G4double cmMomentum = 1/(2*energy)*sqrt(energy*energy*energy*energy + m[0]*m[0]*m[0]*m[0] + m[1]*m[1]*m[1]*m[1]
222  - 2*(m[0]*m[0] + m[1]*m[1])*energy*energy -2*m[0]*m[0]*m[1]*m[1]);
223  p[0] = cmMomentum * randomDirection;
224  p[1] = -p[0];
225 
226  if(m_verboseLevel >= 2) std::cout << "ToyModelHadronicProcess::PostStepDoIt 2->2: " << std::endl
227  << " Pcm(GeV) = " << cmMomentum / GeV << std::endl;
228 
229  for(int ip=0;ip<2;ip++)
230  {
231  //Compute energy
232  G4double e = sqrt(p[ip].mag2() + m[ip]*m[ip]);
233  //Set 4-vectory
234  fourMomenta.push_back(G4LorentzVector(p[ip],e));
235  //Boost back to lab
236  fourMomenta[ip].boost(cmBoost);
237 
238  if(m_verboseLevel >= 2) std::cout << " particle " << ip <<" Plab(GeV) = " << fourMomenta[ip] /GeV << std::endl;
239  }
240 
241  } else if (numberOfSecondaries==3) {
242 
243  // 2 -> 3
244  //Size of momenta in CM
245  for (std::vector<G4double>::iterator it=m.begin();it!=m.end();it++)
246  fourMomenta.push_back(G4LorentzVector(0,0,0,*it));
247 
248  Decay3Body KinCalc;
249  KinCalc.doDecay(cm4Momentum, fourMomenta[0], fourMomenta[1], fourMomenta[2] );
250 
251  //Rotating the plane to a random orientation, and boosting home
252  CLHEP::HepRotation rotation(randomDirection,G4UniformRand()*2*pi);
253  for (std::vector<G4LorentzVector>::iterator it = fourMomenta.begin();
254  it!=fourMomenta.end();
255  it++)
256  {
257  *it *= rotation;
258  (*it).boost(cmBoost);
259  }
260  if(m_verboseLevel >= 3) G4cout<<"Momentum-check: "<<incident4Momentum /GeV<<" GeV vs "
261  << (fourMomenta[0]+fourMomenta[1]+fourMomenta[2])/GeV<<G4endl;
262 
263  }
264 
265 
266  //Now we have the fourMomenta of all the products (coming from 2->2 or 2->3)
267  if(incidentSurvives){
268  //if incident particle survives the number of secondaries is n-1
269  m_particleChange.SetNumberOfSecondaries(numberOfSecondaries-1);
270  if(m_verboseLevel >= 3) std::cout << "Incident survives: set num secondaries to " << numberOfSecondaries-1 << std::endl;
271 
272  } else {
273  //incident particle has to be killed and number of secondaries is n
274  m_particleChange.SetNumberOfSecondaries(numberOfSecondaries);
275  m_particleChange.ProposeTrackStatus(fStopAndKill);
276  if(m_verboseLevel >= 3) std::cout << "Incident does not survive: stopAndKill + set num secondaries to " << numberOfSecondaries << std::endl;
277  }
278  // double e_kin;
279 
280  for (int ip=0; ip <numberOfSecondaries;ip++)
281  {
282  if (newParticlesRHadron[ip]==incidentRHadron->GetDefinition()) // does incident paricle survive?
283  {
284  // incidentSurvives = true; //yes! Modify its dynamic properties
285  if(m_detachCloud)
286  {
287  if(m_verboseLevel >= 3)
288  std::cout << "ToyModelHadronicProcess::PostStepDoIt Add gluino momentum " <<
289  fourMomenta[ip]/GeV <<"(m="<< fourMomenta[ip].m()/ GeV<<") + " <<gluinoMomentum/GeV<<std::endl; ;
290  G4LorentzVector p4_new = gluinoMomentum+fourMomenta[ip];
291  G4ThreeVector momentum = p4_new.vect();
292  double rhMass=newParticlesRHadron[ip]->GetPDGMass() ;
293  // e_kin = sqrt(momentum.mag()*momentum.mag()+rhMass*rhMass)-rhMass;
294  // fourMomenta[ip]=G4LorentzVector(momentum,sqrt(momentum.mag2()+rhMass*rhMass));
295  fourMomenta[ip].setVectM(momentum,rhMass);
296 
297 // double virt=(p4_new-fourMomenta[ip]).m()/MeV;
298 
299  if(m_verboseLevel >= 3)
300  std::cout << " = " << fourMomenta[ip]/GeV <<"(m="<< fourMomenta[ip].m() / GeV<<") vs. "<<rhMass/GeV
301  << std::endl;
302  }
303  m_particleChange.ProposeMomentumDirection(fourMomenta[ip].vect()/fourMomenta[ip].vect().mag());
304  m_particleChange.ProposeEnergy(fourMomenta[ip].e()-fourMomenta[ip].mag());
305  if(m_verboseLevel >= 3) std::cout << "ToyModelHadronicProcess::PostStepDoIt Propose momentum " << fourMomenta[ip]/GeV << std::endl;
306  } else { //this particle is not the incident one
307  //Create new dynamic particle
308  G4DynamicParticle* productDynParticle = new G4DynamicParticle();
309  //Set the pDef to the dynParte
310  productDynParticle->SetDefinition(newParticlesRHadron[ip]);
311  //Set the 4-vector to dynPart
312  if(newParticlesRHadron[ip]!=newParticles[ip] && m_detachCloud ) // check if it is a cloud, second check is useless
313  {
314  G4LorentzVector p4_new;
315  p4_new.setVectM(gluinoMomentum.vect()+fourMomenta[ip].vect(),productDynParticle->GetDefinition()->GetPDGMass());
316  // productDynParticle->SetMomentum(fourMomenta[ip].vect()+gluinoMomentum.vect());
317  productDynParticle->Set4Momentum(p4_new);
318 
319 // double virt=(gluinoMomentum+fourMomenta[ip]-p4_new).m()/MeV;
320 
321  if(m_verboseLevel >= 3)
322  std::cout << "ToyModelHadronicProcess::PostStepDoIt Add gluino momentum " <<
323  fourMomenta[ip]/GeV
324  <<"(m="<< fourMomenta[ip].m()/ GeV<<") + "
325  <<gluinoMomentum/GeV
326  <<" = " << productDynParticle->Get4Momentum()/GeV
327  <<" => "<<productDynParticle->Get4Momentum().m()/GeV
328  <<" vs. "<<productDynParticle->GetDefinition()->GetPDGMass()/GeV
329  << std::endl;
330  }
331  else
332  {
333  productDynParticle->Set4Momentum(fourMomenta[ip]);
334  }
335  //Create a G4Track
336  G4Track* productTrack = new G4Track(productDynParticle,
337  track.GetGlobalTime(),
338  position);
339  productTrack->SetTouchableHandle(thisTouchable);
340  //Append to the result
341  if(m_verboseLevel >= 3) std::cout << "ToyModelHadronicProcess::PostStepDoIt Add secondary with 4-Momentum " << productDynParticle->Get4Momentum()/GeV << std::endl;
342  m_particleChange.AddSecondary(productTrack);
343  }
344  }
345 
346  //clear interaction length
347  ClearNumberOfInteractionLengthLeft();
348  //return the result
349  return &m_particleChange;
350 
351 }
352 
353 const G4DynamicParticle* ToyModelHadronicProcess::FindRhadron(G4ParticleChange* aParticleChange)
354 {
355  G4int nsec = aParticleChange->GetNumberOfSecondaries();
356  if (nsec==0) return 0;
357  int i = 0;
358  G4bool found = false;
359  while (i!=nsec && !found){
360  if (dynamic_cast<CustomParticle*>(aParticleChange->GetSecondary(i)->GetDynamicParticle()->GetDefinition())!=0) found = true;
361  i++;
362  }
363  i--;
364  if(found) return aParticleChange->GetSecondary(i)->GetDynamicParticle();
365  return 0;
366 }
int i
Definition: DBlmapReader.cc:9
void doDecay(const G4LorentzVector &mother, G4LorentzVector &daughter1, G4LorentzVector &daughter2, G4LorentzVector &daughter3)
Definition: Decay3Body.cc:23
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
G4ParticleDefinition * GetCloud()
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
T sqrt(T t)
Definition: SSEVec.h:48
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
G4ParticleDefinition * GetSpectator()
tuple cout
Definition: gather_cfg.py:121
double pi