CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FullModelHadronicProcess.cc
Go to the documentation of this file.
1 #include "G4HadReentrentException.hh"
2 #include "G4ProcessManager.hh"
3 #include "G4ParticleTable.hh"
4 
5 #include "SimG4Core/CustomPhysics/interface/FullModelHadronicProcess.hh"
6 #include "SimG4Core/CustomPhysics/interface/G4ProcessHelper.hh"
10 
11 using namespace CLHEP;
12 
13 FullModelHadronicProcess::FullModelHadronicProcess(G4ProcessHelper * aHelper,
14  const G4String& processName) :
15  G4VDiscreteProcess(processName), theHelper(aHelper)
16 {}
17 
18 FullModelHadronicProcess::~FullModelHadronicProcess()
19 {}
20 
21 G4bool FullModelHadronicProcess::IsApplicable(const G4ParticleDefinition& aP)
22 {
23  return theHelper->ApplicabilityTester(aP);
24 }
25 
26 G4double FullModelHadronicProcess::GetMicroscopicCrossSection(const G4DynamicParticle *aParticle,
27  const G4Element *anElement,
28  G4double aTemp)
29 {
30  //Get the cross section for this particle/element combination from the ProcessHelper
31  G4double InclXsec = theHelper->GetInclusiveCrossSection(aParticle,anElement);
32  // G4cout<<"Returned cross section from helper was: "<<InclXsec/millibarn<<" millibarn"<<G4endl;
33  return InclXsec;
34 }
35 
36 G4double FullModelHadronicProcess::GetMeanFreePath(const G4Track& aTrack, G4double,
37  G4ForceCondition*)
38 {
39  G4Material *aMaterial = aTrack.GetMaterial();
40  const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
41  G4double sigma = 0.0;
42 
43  G4int nElements = aMaterial->GetNumberOfElements();
44 
45  const G4double *theAtomicNumDensityVector =
46  aMaterial->GetAtomicNumDensityVector();
47  G4double aTemp = aMaterial->GetTemperature();
48 
49  for( G4int i=0; i<nElements; ++i )
50  {
51  G4double xSection =
52  GetMicroscopicCrossSection( aParticle, (*aMaterial->GetElementVector())[i], aTemp);
53  sigma += theAtomicNumDensityVector[i] * xSection;
54  }
55  G4double res = DBL_MAX;
56  if(sigma > 0.0) { res = 1./sigma; }
57  return res;
58 }
59 
60 G4VParticleChange* FullModelHadronicProcess::PostStepDoIt(const G4Track& aTrack,
61  const G4Step& aStep)
62 {
63  // G4cout<<"**** Entering FullModelHadronicProcess::PostStepDoIt ******"<<G4endl;
64  const G4TouchableHandle thisTouchable(aTrack.GetTouchableHandle());
65 
66  // A little setting up
67  aParticleChange.Initialize(aTrack);
68  const G4DynamicParticle* IncidentRhadron = aTrack.GetDynamicParticle();
69  CustomParticle* CustomIncident = static_cast<CustomParticle*>(IncidentRhadron->GetDefinition());
70  const G4ThreeVector aPosition = aTrack.GetPosition();
71  // G4cout<<"G: "<<aStep.GetStepLength()/cm<<G4endl;
72  const G4int theIncidentPDG = IncidentRhadron->GetDefinition()->GetPDGEncoding();
73  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
74  std::vector<G4ParticleDefinition*> theParticleDefinitions;
75  G4bool IncidentSurvives = false;
76  G4bool TargetSurvives = false;
77  G4Nucleus targetNucleus(aTrack.GetMaterial());
78  G4ParticleDefinition* outgoingRhadron=0;
79  G4ParticleDefinition* outgoingCloud=0;
80  G4ParticleDefinition* outgoingTarget=0;
81 
82  G4ThreeVector p_0 = IncidentRhadron->GetMomentum();
83  G4double e_kin_0 = IncidentRhadron->GetKineticEnergy();
84  // G4cout<<e_kin_0/GeV<<G4endl;
85 
86  G4DynamicParticle* cloudParticle = new G4DynamicParticle();
87  /*
88  if(CustomPDGParser::s_isRMeson(theIncidentPDG))
89  G4cout<<"Rmeson"<<G4endl;
90  if(CustomPDGParser::s_isRBaryon(theIncidentPDG))
91  G4cout<<"Rbaryon"<<G4endl;
92  */
93  cloudParticle->SetDefinition(CustomIncident->GetCloud());
94 
95  if(cloudParticle->GetDefinition() == 0)
96  {
97  G4cout << "FullModelHadronicProcess::PostStepDoIt Definition of particle cloud not available!!" << G4endl;
98  }
99  /*
100  G4cout<<"Incoming particle was "<<IncidentRhadron->GetDefinition()->GetParticleName()
101  <<". Corresponding cloud is "<<cloudParticle->GetDefinition()->GetParticleName()<<G4endl;
102  G4cout<<"Kinetic energy was: "<<IncidentRhadron->GetKineticEnergy()/GeV<<" GeV"<<G4endl;
103  */
104  double scale=cloudParticle->GetDefinition()->GetPDGMass()
105  /IncidentRhadron->GetDefinition()->GetPDGMass();
106  // G4cout<<"Mass ratio: "<<scale<<G4endl;
107  G4LorentzVector cloudMomentum(IncidentRhadron->GetMomentum()*scale,
108  cloudParticle->GetDefinition()->GetPDGMass());
109  G4LorentzVector gluinoMomentum(IncidentRhadron->GetMomentum()*(1.-scale),
110  CustomIncident->GetSpectator()->GetPDGMass());
111 
112  //These two for getting CMS transforms later (histogramming purposes...)
113  G4LorentzVector FullRhadron4Momentum = IncidentRhadron->Get4Momentum();
114  G4LorentzVector Cloud4Momentum = cloudMomentum;
115 
116  cloudParticle->Set4Momentum(cloudMomentum);
117 
118  G4DynamicParticle* OrgPart = cloudParticle;
119 
120  /*
121  G4cout<<"Original momentum: "<<IncidentRhadron->Get4Momentum().v().mag()/GeV
122  <<" GeV, corresponding to gamma: "
123  <<IncidentRhadron->GetTotalEnergy()/IncidentRhadron->GetDefinition()->GetPDGMass()<<G4endl;
124 
125  G4cout<<"Cloud momentum: "<<cloudParticle->Get4Momentum().v().mag()/GeV
126  <<" GeV, corresponding to gamma: "
127  <<cloudParticle->GetTotalEnergy()/cloudParticle->GetDefinition()->GetPDGMass()<<G4endl;
128  */
129 
130  double E_0 = IncidentRhadron->GetKineticEnergy();
131  G4double ek = OrgPart->GetKineticEnergy();
132  G4double amas = OrgPart->GetDefinition()->GetPDGMass();
133  G4ThreeVector dir = (OrgPart->GetMomentum()).unit();
134  G4double tkin = targetNucleus.Cinema( ek );
135  ek += tkin;
136 
137  // calculate black track energies
138  tkin = targetNucleus.EvaporationEffects( ek );
139  ek -= tkin;
140 
141  if(ek+gluinoMomentum.e()-gluinoMomentum.m()<=0.1*MeV||ek<=0.) {
142  //Very rare event...
143  G4cout<<"Kinetic energy is sick"<<G4endl;
144  G4cout<<"Full R-hadron: "<<(ek+gluinoMomentum.e()-gluinoMomentum.m())/MeV<<" MeV" <<G4endl;
145  G4cout<<"Quark system: "<<ek/MeV<<" MeV"<<G4endl;
146  aParticleChange.ProposeTrackStatus( fStopButAlive ); // AR_NEWCODE_IMPORT
147  return &aParticleChange;
148  }
149  OrgPart->SetKineticEnergy( ek );
150  G4double p = std::sqrt(ek*(ek + 2*amas));
151  OrgPart->SetMomentum(dir * p);
152 
153  //Get the final state particles
154  G4ParticleDefinition* aTarget;
155  ReactionProduct rp = theHelper->GetFinalState(aTrack,aTarget);
156  G4bool force2to2 = false;
157  // G4cout<<"Trying to get final state..."<<G4endl;
158  while(rp.size()!=2 && force2to2){
159  rp = theHelper->GetFinalState(aTrack,aTarget);
160  }
161  G4int NumberOfSecondaries = rp.size();
162  // G4cout<<"Multiplicity of selected final state: "<<rp.size()<<G4endl;
163 
164  //Getting CMS transforms. Boosting is done at histogram filling
165  G4LorentzVector Target4Momentum(0.,0.,0.,aTarget->GetPDGMass());
166 
167  G4LorentzVector psum_full = FullRhadron4Momentum + Target4Momentum;
168  G4LorentzVector psum_cloud = Cloud4Momentum + Target4Momentum;
169  G4ThreeVector trafo_full_cms = (-1)*psum_full.boostVector();
170  G4ThreeVector trafo_cloud_cms = (-1)*psum_cloud.boostVector();
171 
172  // OK Let's make some particles :-)
173  // We're not using them for anything yet, I know, but let's make sure the machinery is there
174  for(ReactionProduct::iterator it = rp.begin();
175  it != rp.end(); ++it) {
176  G4ParticleDefinition* tempDef = theParticleTable->FindParticle(*it);
177  CustomParticle* tempCust = dynamic_cast<CustomParticle*>(tempDef);
178  if (tempDef==aTarget) TargetSurvives = true;
179 
180  // if (tempDef->GetParticleType()=="rhadron")
181  if (tempCust!=0) {
182  outgoingRhadron = tempDef;
183  //Setting outgoing cloud definition
184  outgoingCloud=tempCust->GetCloud();
185  if(outgoingCloud == 0) {
186  G4cout << "FullModelHadronicProcess::PostStepDoIt Definition of outgoing particle cloud not available!" << G4endl;
187  }
188  /*
189  G4cout<<"Outgoing Rhadron is: "<<outgoingRhadron->GetParticleName()<<G4endl;
190  G4cout<<"Outgoing cloud is: "<<outgoingCloud->GetParticleName()<<G4endl;
191  */
192  }
193 
194  if (tempDef==G4Proton::Proton()||tempDef==G4Neutron::Neutron()) outgoingTarget = tempDef;
195  if (tempCust==0&&rp.size()==2) outgoingTarget = tempDef;
196  if (tempDef->GetPDGEncoding()==theIncidentPDG) {
197  IncidentSurvives = true;
198  } else {
199  theParticleDefinitions.push_back(tempDef);
200  }
201  }
202 
203  if (outgoingTarget==0) outgoingTarget = theParticleTable->FindParticle(rp[1]);
204 
205  // A little debug information
206  /*
207  G4cout<<"The particles coming out of this reaction will be: ";
208  for (std::vector<G4DynamicParticle*>::iterator it = theDynamicParticles.begin();
209  it != theDynamicParticles.end();
210  it++){
211  G4cout<< (*it)->GetDefinition()->GetParticleName()<<" ";
212  }
213  G4cout<<G4endl;
214  */
215  // If the incident particle survives it is not a "secondary", although
216  // it would probably be easier to fStopAndKill the track every time.
217  if(IncidentSurvives) NumberOfSecondaries--;
218  aParticleChange.SetNumberOfSecondaries(NumberOfSecondaries);
219 
220  // ADAPTED FROM G4LEPionMinusInelastic::ApplyYourself
221  // It is bloody ugly, but such is the way of cut 'n' paste
222 
223  // Set up the incident
224  // This is where rotation to z-axis is done
225  const G4HadProjectile* originalIncident = new G4HadProjectile(*OrgPart);
226 
227  //Maybe I need to calculate trafo from R-hadron... Bollocks! Labframe does not move. CMS does.
228  G4HadProjectile* org2 = new G4HadProjectile(*OrgPart);
229  G4LorentzRotation trans = org2->GetTrafoToLab();
230  delete org2;
231 
232 
233  /*
234  G4cout<<"Kinetic energies: "<<G4endl;
235  G4cout<<"True kinetic energy: "<<originalIncident->GetKineticEnergy()/GeV<<" GeV"<<G4endl;
236  G4cout<<"Mass: "<<originalIncident->GetDefinition()->GetPDGMass()/GeV<<" GeV"<<G4endl;
237 
238  G4double e_kin_rescaled = targetNucleus.EvaporationEffects(originalIncident->GetTotalEnergy()-originalIncident->GetDefinition()->GetPDGMass());
239 
240  G4cout<<"Rescaled kinetic energy: "<<e_kin_rescaled<<G4endl;
241 
242  const G4double cutOff = 0.1*MeV;
243 
244  if ( e_kin_rescaled < cutOff )
245  {
246  aParticleChange.ProposeTrackStatus( fStopAndKill );//If the dice decides not to cascade I stop the particle
247  return &aParticleChange;
248  }
249  */
250  // create the target particle
251 
252  G4DynamicParticle *originalTarget = new G4DynamicParticle;
253  originalTarget->SetDefinition(aTarget);
254 
255  G4ReactionProduct targetParticle(aTarget);
256 
257  G4ReactionProduct currentParticle(const_cast<G4ParticleDefinition *>(originalIncident->GetDefinition() ) );
258  currentParticle.SetMomentum( originalIncident->Get4Momentum().vect() );
259  currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() );
260 
261  /*
262  G4cout<<"After creation:"<<G4endl;
263  G4cout<<"currentParticle: "<<currentParticle.GetMomentum()/GeV<<" GeV vs. "<<OrgPart->Get4Momentum()/GeV<<" GeV"<<G4endl;
264  G4cout<<"targetParticle: "<<targetParticle.GetMomentum()/GeV<<" GeV"<<G4endl;
265  G4cout<<"Fourmomentum from originalIncident: "<<originalIncident->Get4Momentum()<<" vs "<<OrgPart->Get4Momentum()<<G4endl;
266  */
267 
268  G4ReactionProduct modifiedOriginal = currentParticle;
269 
270  currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
271  targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
272  G4bool incidentHasChanged = false;
273  if (!IncidentSurvives) incidentHasChanged = true; //I wonder if I am supposed to do this...
274  G4bool targetHasChanged = false;
275  if (!TargetSurvives) targetHasChanged = true; //Ditto here
276  G4bool quasiElastic = false;
277  if (rp.size()==2) quasiElastic = true; //Oh well...
278  G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> vec; // vec will contain the secondary particles
279  G4int vecLen = 0;
280  vec.Initialize( 0 );
281 
282  // I hope my understanding of "secondary" is correct here
283  // I think that it entails only what is not a surviving incident of target
284 
285  for (G4int i = 0; i!=NumberOfSecondaries;i++){
286  if(theParticleDefinitions[i]!=aTarget
287  && theParticleDefinitions[i]!=originalIncident->GetDefinition()
288  && theParticleDefinitions[i]!=outgoingRhadron
289  && theParticleDefinitions[i]!=outgoingTarget)
290  {
291  G4ReactionProduct* pa = new G4ReactionProduct;
292  pa->SetDefinition( theParticleDefinitions[i] );
293  (G4UniformRand() < 0.5) ? pa->SetSide( -1 ) : pa->SetSide( 1 );
294  vec.SetElement( vecLen++, pa );
295  }
296  }
297 
298  if (incidentHasChanged) currentParticle.SetDefinitionAndUpdateE( outgoingCloud );
299  if (incidentHasChanged) modifiedOriginal.SetDefinition( outgoingCloud );//Is this correct? It solves the "free energy" checking in ReactionDynamics
300  if (targetHasChanged) targetParticle.SetDefinitionAndUpdateE( outgoingTarget );
301 
302  // G4cout<<"Calling CalculateMomenta... "<<G4endl;
303  /*
304  G4cout<<"Current particle starts as: "<<currentParticle.GetDefinition()->GetParticleName()<<G4endl;
305  G4cout<<"with momentum: "<<currentParticle.GetMomentum()/GeV<<" GeV"<<G4endl;
306  G4cout<<"May be killed?: "<<currentParticle.GetMayBeKilled()<<G4endl;
307  */
308 
309  CalculateMomenta( vec, vecLen,
310  originalIncident, originalTarget, modifiedOriginal,
311  targetNucleus, currentParticle, targetParticle,
312  incidentHasChanged, targetHasChanged, quasiElastic );
313 
314  // G4cout <<"Cloud loss: "<<(e_temp-currentParticle.GetKineticEnergy())/GeV<<" GeV"<<G4endl;
315 
316  G4String cPname = currentParticle.GetDefinition()->GetParticleName();
317 
318  // if(cPname!="rhadronmesoncloud"&&cPname!="rhadronbaryoncloud")
319  // {
320  /*
321  G4cout<<"Current particle is now: "<<cPname <<G4endl;
322  G4cout<<"with momentum: "<<currentParticle.GetMomentum()/GeV<<" GeV"<<G4endl;
323  G4cout<<"and kinetic energy: "<<currentParticle.GetKineticEnergy()/GeV<<" GeV"<<G4endl;
324  G4cout<<"May be killed?: "<<currentParticle.GetMayBeKilled()<<G4endl;
325  G4cout<<"Modified original is: "<<modifiedOriginal.GetDefinition()->GetParticleName()<<G4endl;
326  G4cout<<"with momentum: "<<modifiedOriginal.GetMomentum()/GeV<<" GeV"<<G4endl;
327  G4cout<<"and kinetic energy: "<<modifiedOriginal.GetKineticEnergy()/GeV<<" GeV"<<G4endl;
328  G4cout<<"May be killed?: "<<modifiedOriginal.GetMayBeKilled()<<G4endl;
329  G4cout<<"Target particle is: "<<targetParticle.GetDefinition()->GetParticleName()<<G4endl;
330  G4cout<<"with momentum: "<<targetParticle.GetMomentum()/GeV<<" GeV"<<G4endl;
331  G4cout<<"and kinetic energy: "<<targetParticle.GetKineticEnergy()/GeV<<" GeV"<<G4endl;
332  G4cout<<"May be killed?: "<<targetParticle.GetMayBeKilled()<<G4endl;
333  G4cout<<"incidentHasChanged: "<<incidentHasChanged<<G4endl;
334  G4cout<<"targetHasChanged: "<<targetHasChanged<<G4endl;
335  G4cout<<"Particles in vec:"<<G4endl;
336  for(int i=0; i<vecLen; ++i )
337  {
338  G4cout<< vec[i]->GetDefinition()->GetParticleName()<<G4endl;
339  }
340  */
341  // G4cout<<"Done!"<<G4endl;
342  // const G4LorentzRotation& trans(originalIncident->GetTrafoToLab());
343 
344  aParticleChange.SetNumberOfSecondaries(vecLen+NumberOfSecondaries);
345  G4double e_kin=0;
346  G4LorentzVector cloud_p4_new; //Cloud 4-momentum in lab after collision
347  // n++;
348  // G4cout << n << G4endl;
349  /*
350  if(cPname!="rhadronmesoncloud"&&cPname!="rhadronbaryoncloud") {
351  G4cout<<"Cloud deleted!!! AAARRRRGGGHHH!!!"<<G4endl;
352  G4cout<<"Cloud name: "<<cPname<<G4endl;
353  G4cout<<"E_kin_0: "<<e_kin_0/GeV<<" GeV"<<G4endl;
354  // G4cout<<"n: "<<n<<G4endl;
355  // n=0;
356  }
357  */
358  cloud_p4_new.setVectM(currentParticle.GetMomentum(),currentParticle.GetMass());
359  cloud_p4_new *= trans;
360 
361  G4LorentzVector cloud_p4_old_full = Cloud4Momentum; //quark system in CMS BEFORE collision
362  cloud_p4_old_full.boost(trafo_full_cms);
363  G4LorentzVector cloud_p4_old_cloud = Cloud4Momentum; //quark system in cloud CMS BEFORE collision
364  cloud_p4_old_cloud.boost(trafo_cloud_cms);
365  G4LorentzVector cloud_p4_full = cloud_p4_new; //quark system in CMS AFTER collision
366  cloud_p4_full.boost(trafo_full_cms);
367  G4LorentzVector cloud_p4_cloud = cloud_p4_new; //quark system in cloud CMS AFTER collision
368  cloud_p4_cloud.boost(trafo_cloud_cms);
369 
370  G4LorentzVector p_g_cms = gluinoMomentum; //gluino in CMS BEFORE collision
371  p_g_cms.boost(trafo_full_cms);
372 
373  double e = cloud_p4_new.e() + gluinoMomentum.e();
374  if(outgoingRhadron) e += outgoingRhadron->GetPDGMass();
375  G4LorentzVector p4_new( cloud_p4_new.v() + gluinoMomentum.v(), e );
376  // G4cout<<"P4-diff: "<<(p4_new-cloud_p4_new-gluinoMomentum)/GeV<<", magnitude: "
377  // <<(p4_new-cloud_p4_new-gluinoMomentum).m()/MeV<<" MeV" <<G4endl;
378 
379  G4ThreeVector p_new = p4_new.vect();
380 
381  aParticleChange.ProposeLocalEnergyDeposit((p4_new-cloud_p4_new-gluinoMomentum).m());
382 
383  if( incidentHasChanged )
384  {
385  G4DynamicParticle* p0 = new G4DynamicParticle;
386  p0->SetDefinition( outgoingRhadron );
387  p0->SetMomentum( p_new );
388 
389  // May need to run SetDefinitionAndUpdateE here...
390  G4Track* Track0 = new G4Track(p0,
391  aTrack.GetGlobalTime(),
392  aPosition);
393  Track0->SetTouchableHandle(thisTouchable);
394  aParticleChange.AddSecondary(Track0);
395  /*
396  G4cout<<"Adding a particle "<<p0->GetDefinition()->GetParticleName()<<G4endl;
397  G4cout<<"with momentum: "<<p0->GetMomentum()/GeV<<" GeV"<<G4endl;
398  G4cout<<"and kinetic energy: "<<p0->GetKineticEnergy()/GeV<<" GeV"<<G4endl;
399  */
400  if(p0->GetKineticEnergy()>e_kin_0) {
401  G4cout<<"ALAAAAARM!!! (incident changed from "
402  <<IncidentRhadron->GetDefinition()->GetParticleName()
403  <<" to "<<p0->GetDefinition()->GetParticleName()<<")"<<G4endl;
404  G4cout<<"Energy loss: "<<(e_kin_0-p0->GetKineticEnergy())/GeV
405  <<" GeV (should be positive)"<<G4endl;
406  //Turns out problem is only in 2 -> 3 (Won't fix 2 -> 2 energy deposition)
407  if(rp.size()!=3) G4cout<<"DOUBLE ALAAAAARM!!!"<<G4endl;
408  } /*else {
409  G4cout<<"NO ALAAAAARM!!!"<<G4endl;
410  }*/
411  if(std::abs(p0->GetKineticEnergy()-e_kin_0)>100*GeV) {
412  G4cout<<"Diff. too big"<<G4endl;
413  }
414  aParticleChange.ProposeTrackStatus( fStopAndKill );
415  }
416  else
417  {
418  G4double p = p_new.mag();
419  if( p > DBL_MIN )
420  aParticleChange.ProposeMomentumDirection( p_new.x()/p, p_new.y()/p, p_new.z()/p );
421  else
422  aParticleChange.ProposeMomentumDirection( 1.0, 0.0, 0.0 );
423 
424  G4double aE = sqrt(p*p+(outgoingRhadron->GetPDGMass()*outgoingRhadron->GetPDGMass()) );
425  e_kin = aE - outgoingRhadron->GetPDGMass();
426  }
427 
428  // return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
429  if( targetParticle.GetMass() > 0.0 ) // targetParticle can be eliminated in TwoBody
430  {
431  G4DynamicParticle *p1 = new G4DynamicParticle;
432  p1->SetDefinition( targetParticle.GetDefinition() );
433  //G4cout<<"Target secondary: "<<targetParticle.GetDefinition()->GetParticleName()<<G4endl;
434  G4ThreeVector momentum = targetParticle.GetMomentum();
435  momentum = momentum.rotate(cache,what);
436  p1->SetMomentum( momentum );
437  p1->SetMomentum( (trans*p1->Get4Momentum()).vect());
438  G4Track* Track1 = new G4Track(p1,
439  aTrack.GetGlobalTime(),
440  aPosition);
441  Track1->SetTouchableHandle(thisTouchable);
442  aParticleChange.AddSecondary(Track1);
443  }
444  G4DynamicParticle *pa;
445  /*
446  G4cout<<"vecLen: "<<vecLen<<G4endl;
447  G4cout<<"#sec's: "<<aParticleChange.GetNumberOfSecondaries()<<G4endl;
448  */
449 
450  for(int i=0; i<vecLen; ++i )
451  {
452  pa = new G4DynamicParticle();
453  pa->SetDefinition( vec[i]->GetDefinition() );
454  pa->SetMomentum( vec[i]->GetMomentum() );
455  pa->Set4Momentum(trans*(pa->Get4Momentum()));
456  G4ThreeVector pvec = pa->GetMomentum();
457  G4Track* Trackn = new G4Track(pa,
458  aTrack.GetGlobalTime(),
459  aPosition);
460  Trackn->SetTouchableHandle(thisTouchable);
461  aParticleChange.AddSecondary(Trackn);
462 
463  delete vec[i];
464  }
465 
466  // Histogram filling
467  const G4DynamicParticle* theRhadron = FindRhadron(&aParticleChange);
468 
469  if (theRhadron!=NULL||IncidentSurvives) {
470  double E_new;
471  if(IncidentSurvives) {
472  E_new = e_kin;
473  } else {
474  E_new = theRhadron->GetKineticEnergy();
475  if(CustomPDGParser::s_isRMeson(theRhadron->GetDefinition()->GetPDGEncoding())
476  !=CustomPDGParser::s_isRMeson(theIncidentPDG)
477  ||
478  CustomPDGParser::s_isMesonino(theRhadron->GetDefinition()->GetPDGEncoding())
479  !=CustomPDGParser::s_isMesonino(theIncidentPDG)
480  ) {
481  G4cout<<"Rm: "<<CustomPDGParser::s_isRMeson(theRhadron->GetDefinition()->GetPDGEncoding())
482  <<" vs: "<<CustomPDGParser::s_isRMeson(theIncidentPDG)<<G4endl;
483  G4cout<<"Sm: "<<CustomPDGParser::s_isMesonino(theRhadron->GetDefinition()->GetPDGEncoding())
484  <<" vs: "<<CustomPDGParser::s_isMesonino(theIncidentPDG)<<G4endl;
485 
486  }
487  }
488 
489  //Calculating relevant scattering angles.
490  G4LorentzVector p4_old_full = FullRhadron4Momentum; //R-hadron in CMS BEFORE collision
491  p4_old_full.boost(trafo_full_cms);
492  G4LorentzVector p4_old_cloud = FullRhadron4Momentum; //R-hadron in cloud CMS BEFORE collision
493  p4_old_cloud.boost(trafo_cloud_cms);
494  G4LorentzVector p4_full = p4_new; //R-hadron in CMS AFTER collision
495  // G4cout<<p4_full.v()/GeV<<G4endl;
496  p4_full=p4_full.boost(trafo_full_cms);
497  // G4cout<<p4_full.m()<<" / "<<(cloud_p4_new+gluinoMomentum).boost(trafo_full_cms).m()<<G4endl;
498  G4LorentzVector p4_cloud = p4_new; //R-hadron in cloud CMS AFTER collision
499  p4_cloud.boost(trafo_cloud_cms);
500 
501  G4double AbsDeltaE = E_0-E_new;
502  // G4cout <<"Energy loss: "<<AbsDeltaE/GeV<<G4endl;
503  if (AbsDeltaE > 10*GeV) {
504  G4cout<<"Energy loss larger than 10 GeV..."<<G4endl;
505  G4cout<<"E_0: "<<E_0/GeV<<" GeV"<<G4endl;
506  G4cout<<"E_new: "<<E_new/GeV<<" GeV"<<G4endl;
507  G4cout<<"Gamma: "<<IncidentRhadron->GetTotalEnergy()/IncidentRhadron->GetDefinition()->GetPDGMass()<<G4endl;
508  G4cout<<"x: "<<aPosition.x()/cm<<" cm"<<G4endl;
509  }
510  }
511  delete originalIncident;
512  delete originalTarget;
513  // aParticleChange.DumpInfo();
514  // G4cout << "Exiting FullModelHadronicProcess::PostStepDoIt"<<G4endl;
515 
516  //clear interaction length
517  ClearNumberOfInteractionLengthLeft();
518 
519  return &aParticleChange;
520 }
521 
522 
523 void FullModelHadronicProcess::CalculateMomenta(
524  G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
525  G4int &vecLen,
526  const G4HadProjectile *originalIncident, // the original incident particle
527  const G4DynamicParticle *originalTarget,
528  G4ReactionProduct &modifiedOriginal, // Fermi motion and evap. effects included
529  G4Nucleus &targetNucleus,
530  G4ReactionProduct &currentParticle,
531  G4ReactionProduct &targetParticle,
532  G4bool &incidentHasChanged,
533  G4bool &targetHasChanged,
534  G4bool quasiElastic )
535 {
536  FullModelReactionDynamics theReactionDynamics;
537 
538  cache = 0;
539  what = originalIncident->Get4Momentum().vect();
540 
541  if( quasiElastic )
542  {
543  // G4cout<<"We are calling TwoBody..."<<G4endl;
544  theReactionDynamics.TwoBody( vec, vecLen,
545  modifiedOriginal, originalTarget,
546  currentParticle, targetParticle,
547  targetNucleus, targetHasChanged );
548 
549  return;
550  }
551 
552  //If ProduceStrangeParticlePairs is commented out, let's cut this one as well
553  G4ReactionProduct leadingStrangeParticle;
554  G4bool leadFlag = MarkLeadingStrangeParticle( currentParticle,
555  targetParticle,
556  leadingStrangeParticle );
557 
558  //
559  // Note: the number of secondaries can be reduced in GenerateXandPt and TwoCluster
560  //
561  G4bool finishedGenXPt = false;
562  G4bool annihilation = false;
563  if( originalIncident->GetDefinition()->GetPDGEncoding() < 0 &&
564  currentParticle.GetMass() == 0.0 && targetParticle.GetMass() == 0.0 )
565  {
566  // original was an anti-particle and annihilation has taken place
567  annihilation = true;
568  G4double ekcor = 1.0;
569  G4double ek = originalIncident->GetKineticEnergy();
570  G4double ekOrg = ek;
571 
572  const G4double tarmas = originalTarget->GetDefinition()->GetPDGMass();
573  if( ek > 1.0*GeV )ekcor = 1./(ek/GeV);
574  const G4double atomicWeight = G4double(targetNucleus.GetN_asInt());
575  ek = 2*tarmas + ek*(1.+ekcor/atomicWeight);
576 
577  G4double tkin = targetNucleus.Cinema( ek );
578  ek += tkin;
579  ekOrg += tkin;
580  modifiedOriginal.SetKineticEnergy( ekOrg );
581  }
582 
583  const G4double twsup[] = { 1.0, 0.7, 0.5, 0.3, 0.2, 0.1 };
584  G4double rand1 = G4UniformRand();
585  G4double rand2 = G4UniformRand();
586  if( (annihilation || (vecLen >= 6) || (modifiedOriginal.GetKineticEnergy()/GeV >= 1.0)) &&
587  (((originalIncident->GetDefinition() == G4KaonPlus::KaonPlus()) ||
588  (originalIncident->GetDefinition() == G4KaonMinus::KaonMinus()) ||
589  (originalIncident->GetDefinition() == G4KaonZeroLong::KaonZeroLong()) ||
590  (originalIncident->GetDefinition() == G4KaonZeroShort::KaonZeroShort())) &&
591  ((rand1 < 0.5) || (rand2 > twsup[vecLen]))))
592  finishedGenXPt =
593  theReactionDynamics.GenerateXandPt( vec, vecLen,
594  modifiedOriginal, originalIncident,
595  currentParticle, targetParticle,
596  targetNucleus, incidentHasChanged,
597  targetHasChanged, leadFlag,
598  leadingStrangeParticle );
599  if( finishedGenXPt )
600  {
601  Rotate(vec, vecLen);
602  return;
603  }
604 
605  G4bool finishedTwoClu = false;
606  if( modifiedOriginal.GetTotalMomentum()/MeV < 1.0 )
607  {
608 
609  for(G4int i=0; i<vecLen; i++) delete vec[i];
610  vecLen = 0;
611  }
612  else
613  {
614 
615  theReactionDynamics.SuppressChargedPions( vec, vecLen,
616  modifiedOriginal, currentParticle,
617  targetParticle, targetNucleus,
618  incidentHasChanged, targetHasChanged );
619 
620  try
621  {
622  finishedTwoClu = theReactionDynamics.TwoCluster( vec, vecLen,
623  modifiedOriginal, originalIncident,
624  currentParticle, targetParticle,
625  targetNucleus, incidentHasChanged,
626  targetHasChanged, leadFlag,
627  leadingStrangeParticle );
628  }
629  catch(G4HadReentrentException aC)
630  {
631  aC.Report(G4cout);
632  throw G4HadReentrentException(__FILE__, __LINE__, "Failing to calculate momenta");
633  }
634  }
635  if( finishedTwoClu )
636  {
637  Rotate(vec, vecLen);
638  return;
639  }
640 
641  //
642  // PNBlackTrackEnergy is the kinetic energy available for
643  // proton/neutron black track particles [was enp(1) in fortran code]
644  // DTABlackTrackEnergy is the kinetic energy available for
645  // deuteron/triton/alpha particles [was enp(3) in fortran code]
646  // the atomic weight of the target nucleus is >= 1.5 AND
647  // neither the incident nor the target particles have changed AND
648  // there is no kinetic energy available for either proton/neutron
649  // or for deuteron/triton/alpha black track particles
650  // For diffraction scattering on heavy nuclei use elastic routines instead
651 
652  theReactionDynamics.TwoBody( vec, vecLen,
653  modifiedOriginal, originalTarget,
654  currentParticle, targetParticle,
655  targetNucleus, targetHasChanged );
656 }
657 
658 G4bool FullModelHadronicProcess::MarkLeadingStrangeParticle(
659  const G4ReactionProduct &currentParticle,
660  const G4ReactionProduct &targetParticle,
661  G4ReactionProduct &leadParticle )
662 {
663  // the following was in GenerateXandPt and TwoCluster
664  // add a parameter to the GenerateXandPt function telling it about the strange particle
665  //
666  // assumes that the original particle was a strange particle
667  //
668  G4bool lead = false;
669  if( (currentParticle.GetMass() >= G4KaonPlus::KaonPlus()->GetPDGMass()) &&
670  (currentParticle.GetDefinition() != G4Proton::Proton()) &&
671  (currentParticle.GetDefinition() != G4Neutron::Neutron()) )
672  {
673  lead = true;
674  leadParticle = currentParticle; // set lead to the incident particle
675  }
676  else if( (targetParticle.GetMass() >= G4KaonPlus::KaonPlus()->GetPDGMass()) &&
677  (targetParticle.GetDefinition() != G4Proton::Proton()) &&
678  (targetParticle.GetDefinition() != G4Neutron::Neutron()) )
679  {
680  lead = true;
681  leadParticle = targetParticle; // set lead to the target particle
682  }
683  return lead;
684 }
685 
686 void FullModelHadronicProcess::Rotate(G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
687  G4int &vecLen)
688 {
689  G4double rotation = 2.*pi*G4UniformRand();
690  cache = rotation;
691  G4int i;
692  for( i=0; i<vecLen; ++i )
693  {
694  G4ThreeVector momentum = vec[i]->GetMomentum();
695  momentum = momentum.rotate(rotation, what);
696  vec[i]->SetMomentum(momentum);
697  }
698 }
699 
700 const G4DynamicParticle* FullModelHadronicProcess::FindRhadron(G4ParticleChange* aParticleChange)
701 {
702  G4int nsec = aParticleChange->GetNumberOfSecondaries();
703  if (nsec==0) return 0;
704  int i = 0;
705  G4bool found = false;
706  while (i!=nsec && !found){
707  // G4cout<<"Checking "<<aParticleChange->GetSecondary(i)->GetDynamicParticle()->GetDefinition()->GetParticleName()<<G4endl;
708  // if (aParticleChange->GetSecondary(i)->GetDynamicParticle()->GetDefinition()->GetParticleType()=="rhadron") found = true;
709  if (dynamic_cast<CustomParticle*>(aParticleChange->GetSecondary(i)->GetDynamicParticle()->GetDefinition())!=0) found = true;
710  i++;
711  }
712  i--;
713  if(found) return aParticleChange->GetSecondary(i)->GetDynamicParticle();
714  return 0;
715 }
716 
int i
Definition: DBlmapReader.cc:9
const double GeV
Definition: MathUtil.h:16
G4ParticleDefinition * GetCloud()
#define NULL
Definition: scimark2.h:8
susybsm::HSCParticle pa
Definition: classes.h:8
static bool s_isRMeson(int pdg)
const Double_t pi
const double MeV
static bool s_isMesonino(int pdg)
string unit
Definition: csvLumiCalc.py:46
T sqrt(T t)
Definition: SSEVec.h:48
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
G4ParticleDefinition * GetSpectator()
double p1[4]
Definition: TauolaWrapper.h:89
dbl *** dir
Definition: mlp_gen.cc:35