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, const G4String& processName) :
14  G4VDiscreteProcess(processName), theHelper(aHelper)
15 {}
16 
17 
18 FullModelHadronicProcess::~FullModelHadronicProcess(){}
19 
20 G4bool FullModelHadronicProcess::IsApplicable(const G4ParticleDefinition& aP)
21 {
22  return theHelper->ApplicabilityTester(aP);
23 }
24 
25 G4double FullModelHadronicProcess::GetMicroscopicCrossSection(const G4DynamicParticle *aParticle,
26  const G4Element *anElement,
27  G4double aTemp)
28 {
29  //Get the cross section for this particle/element combination from the ProcessHelper
30  G4double InclXsec = theHelper->GetInclusiveCrossSection(aParticle,anElement);
31  // G4cout<<"Returned cross section from helper was: "<<InclXsec/millibarn<<" millibarn"<<G4endl;
32 
33  // Need to provide Set-methods for these in time
34  G4double HighestEnergyLimit = 10 * TeV ;
35  G4double LowestEnergyLimit = 1 * eV;
36 
37  G4double ParticleEnergy = aParticle->GetKineticEnergy();
38 
39 
40  if (ParticleEnergy > HighestEnergyLimit || ParticleEnergy < LowestEnergyLimit){
41  return 0;
42  } else {
43  // G4cout << "Microscopic Cross Section: "<<InclXsec / millibarn<<" millibarn"<<G4endl;
44  return InclXsec;
45  }
46 
47 }
48 
49 G4double FullModelHadronicProcess::GetMeanFreePath(const G4Track& aTrack, G4double, G4ForceCondition*)
50 {
51  G4Material *aMaterial = aTrack.GetMaterial();
52  const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
53  G4double sigma = 0.0;
54 
55  G4int nElements = aMaterial->GetNumberOfElements();
56 
57  const G4double *theAtomicNumDensityVector =
58  aMaterial->GetAtomicNumDensityVector();
59  G4double aTemp = aMaterial->GetTemperature();
60 
61  for( G4int i=0; i<nElements; ++i )
62  {
63  G4double xSection =
64  GetMicroscopicCrossSection( aParticle, (*aMaterial->GetElementVector())[i], aTemp);
65  sigma += theAtomicNumDensityVector[i] * xSection;
66  }
67 
68  return 1.0/sigma;
69 
70 }
71 
72 G4VParticleChange* FullModelHadronicProcess::PostStepDoIt(const G4Track& aTrack,
73  const G4Step& aStep)
74 {
75  // G4cout<<"***************** Entering FullModelHadronicProcess::PostStepDoIt **********************"<<G4endl;
76 
77  const G4TouchableHandle thisTouchable(aTrack.GetTouchableHandle());
78 
79  // A little setting up
80  aParticleChange.Initialize(aTrack);
81  // G4DynamicParticle* OrgPart = const_cast<G4DynamicParticle*>(aTrack.GetDynamicParticle());
82  G4DynamicParticle* IncidentRhadron = const_cast<G4DynamicParticle*>(aTrack.GetDynamicParticle());
83  CustomParticle* CustomIncident = static_cast<CustomParticle*>(IncidentRhadron->GetDefinition());
84  const G4ThreeVector aPosition = aTrack.GetPosition();
85  // std::cout<<"G: "<<aStep.GetStepLength()/cm<<std::endl;
86  const G4int theIncidentPDG = IncidentRhadron->GetDefinition()->GetPDGEncoding();
87  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
88  std::vector<G4ParticleDefinition*> theParticleDefinitions;
89  // std::vector<G4DynamicParticle*> *theDynamicParticles;//These are probably redundant, but they can easily be removed :-)
90  G4bool IncidentSurvives = false;
91  G4bool TargetSurvives = false;
92  G4Nucleus targetNucleus(aTrack.GetMaterial());
93  G4ParticleDefinition* outgoingRhadron=0;
94  G4ParticleDefinition* outgoingCloud=0;
95  G4ParticleDefinition* outgoingTarget=0;
96 // double gamma = IncidentRhadron->GetTotalEnergy()/IncidentRhadron->GetDefinition()->GetPDGMass();
97 
98 
99  G4ThreeVector p_0 = IncidentRhadron->GetMomentum();
100 
101  // static int n=0;
102 
103  G4double e_kin_0 = IncidentRhadron->GetKineticEnergy();
104  // G4cout<<e_kin_0/GeV<<G4endl;
105 
106  G4DynamicParticle* cloudParticle = new G4DynamicParticle();
107  /*
108  if(CustomPDGParser::s_isRMeson(theIncidentPDG))
109  std::cout<<"Rmeson"<<std::endl;
110  if(CustomPDGParser::s_isRBaryon(theIncidentPDG))
111  std::cout<<"Rbaryon"<<std::endl;
112  */
113  /*
114  if(CustomPDGParser::s_isRBaryon(theIncidentPDG))
115  cloudParticle->SetDefinition(theParticleTable->FindParticle("rhadronbaryoncloud"));
116  if(CustomPDGParser::s_isRMeson(theIncidentPDG) || CustomPDGParser::s_isRGlueball(theIncidentPDG) )
117  cloudParticle->SetDefinition(theParticleTable->FindParticle("rhadronmesoncloud"));
118  */
119  cloudParticle->SetDefinition(CustomIncident->GetCloud());
120 
121  if(cloudParticle->GetDefinition() == 0)
122  {
123  std::cout << "FullModelHadronicProcess::PostStepDoIt Definition of particle cloud not available!!" << std::endl;
124  }
125  /*
126  std::cout<<"Incoming particle was "<<IncidentRhadron->GetDefinition()->GetParticleName()<<". Corresponding cloud is "<<cloudParticle->GetDefinition()->GetParticleName()<<std::endl;
127  G4cout<<"Kinetic energy was: "<<IncidentRhadron->GetKineticEnergy()/GeV<<" GeV"<<G4endl;
128  */
129  double scale=cloudParticle->GetDefinition()->GetPDGMass()/IncidentRhadron->GetDefinition()->GetPDGMass();
130  // std::cout<<"Mass ratio: "<<scale<<std::endl;
131  G4LorentzVector cloudMomentum;
132  cloudMomentum.setVectM(IncidentRhadron->GetMomentum()*scale,cloudParticle->GetDefinition()->GetPDGMass());
133  G4LorentzVector gluinoMomentum;
134  // gluinoMomentum.setVectM(IncidentRhadron->GetMomentum()*(1.-scale),theParticleTable->FindParticle("~g")->GetPDGMass());
135  gluinoMomentum.setVectM(IncidentRhadron->GetMomentum()*(1.-scale),CustomIncident->GetSpectator()->GetPDGMass());
136  /*
137  G4cout <<"Are these the same?"<<G4endl;
138  G4cout<<gluinoMomentum<<G4endl;
139  G4cout<<(1.-scale) * IncidentRhadron->Get4Momentum()<<G4endl;
140  */
141  //These two for getting CMS transforms later (histogramming purposes...)
142  G4LorentzVector FullRhadron4Momentum = IncidentRhadron->Get4Momentum();
143  G4LorentzVector Cloud4Momentum = cloudMomentum;
144 
145  cloudParticle->Set4Momentum(cloudMomentum);
146 
147  G4DynamicParticle* OrgPart = cloudParticle;
148 
149  /*
150  std::cout<<"Original momentum: "<<IncidentRhadron->Get4Momentum().v().mag()/GeV<<" GeV, corresponding to gamma: "
151  <<IncidentRhadron->GetTotalEnergy()/IncidentRhadron->GetDefinition()->GetPDGMass()<<std::endl;
152 
153  std::cout<<"Cloud momentum: "<<cloudParticle->Get4Momentum().v().mag()/GeV<<" GeV, corresponding to gamma: "
154  <<cloudParticle->GetTotalEnergy()/cloudParticle->GetDefinition()->GetPDGMass()<<std::endl;
155  */
156 
157  double E_0 = IncidentRhadron->GetKineticEnergy();
158 
159 
160  G4double ek = OrgPart->GetKineticEnergy();
161  G4double amas = OrgPart->GetDefinition()->GetPDGMass();
162 
163  G4double tkin = targetNucleus.Cinema( ek );
164  ek += tkin;
165  OrgPart->SetKineticEnergy( ek );
166  G4double et = ek + amas;
167  G4double p = std::sqrt( std::abs((et-amas)*(et+amas)) );
168  G4double pp = OrgPart->GetMomentum().mag();
169  if( pp > 0.0 )
170  {
171  G4ThreeVector momentum = OrgPart->GetMomentum();
172  OrgPart->SetMomentum( momentum * (p/pp) );
173  }
174 
175  // calculate black track energies
176  if(ek > 0.) { tkin = targetNucleus.EvaporationEffects( ek ); ek -= tkin; } // AR_NEWCODE_IMPORT
177  if(ek+gluinoMomentum.e()-gluinoMomentum.m()<=0.1*MeV||ek<=0.) {
178  //Very rare event...
179  G4cout<<"Kinetic energy is sick"<<G4endl;
180  G4cout<<"Full R-hadron: "<<(ek+gluinoMomentum.e()-gluinoMomentum.m())/MeV<<" MeV" <<G4endl;
181  G4cout<<"Quark system: "<<ek/MeV<<" MeV"<<G4endl;
182 // aParticleChange.ProposeTrackStatus( fStopAndKill ); // AR_NEWCODE_IMPORT
183  aParticleChange.ProposeTrackStatus( fStopButAlive ); // AR_NEWCODE_IMPORT
184  return &aParticleChange;
185  }
186  OrgPart->SetKineticEnergy( ek );
187  et = ek + amas;
188  p = std::sqrt( std::abs((et-amas)*(et+amas)) );
189  pp = OrgPart->GetMomentum().mag();
190 
191  if( pp > 0.0 )
192  {
193  G4ThreeVector momentum = OrgPart->GetMomentum();
194  OrgPart->SetMomentum( momentum * (p/pp) );
195  }
196 
197 
198 
199  //Get the final state particles
200 
201  G4ParticleDefinition* aTarget;
202  ReactionProduct rp = theHelper->GetFinalState(aTrack,aTarget);
203  G4bool force2to2 = false;
204  // G4cout<<"Trying to get final state..."<<G4endl;
205  while(rp.size()!=2 && force2to2){
206  rp = theHelper->GetFinalState(aTrack,aTarget);
207  }
208  G4int NumberOfSecondaries = rp.size();
209  // G4cout<<"Multiplicity of selected final state: "<<rp.size()<<G4endl;
210 
211  //Getting CMS transforms. Boosting is done at histogram filling
212  G4LorentzVector Target4Momentum;
213  Target4Momentum.set(0.,0.,0.,aTarget->GetPDGMass());
214  // Target4Momentum.setVectM(0.,targetNucleus.GetN()*GeV);
215  G4LorentzVector psum_full,psum_cloud;
216  psum_full = FullRhadron4Momentum + Target4Momentum;
217  psum_cloud = Cloud4Momentum + Target4Momentum;
218  G4ThreeVector trafo_full_cms = (-1)*psum_full.boostVector();
219  G4ThreeVector trafo_cloud_cms = (-1)*psum_cloud.boostVector();
220  /*
221  psum_full.boost(trafo_full_cms);
222  psum_cloud.boost(trafo_cloud_cms);
223  std::cout<<"Checking that the momenta are in deed zero:"<<psum_full.vect()<<std::endl;
224  */
225 
226  // OK Let's make some particles :-)
227  // We're not using them for anything yet, I know, but let's make sure the machinery is there
228 
229  for(ReactionProduct::iterator it = rp.begin();
230  it != rp.end();
231  it++)
232  {
233  G4ParticleDefinition* tempDef = theParticleTable->FindParticle(*it);
234  CustomParticle* tempCust = dynamic_cast<CustomParticle*>(tempDef);
235  if (tempDef==aTarget) TargetSurvives = true;
236 
237  // if (tempDef->GetParticleType()=="rhadron")
238  if (tempCust!=0)
239  {
240  outgoingRhadron = tempDef;
241  //Setting outgoing cloud definition
242  /*
243  if(CustomPDGParser::s_isRBaryon(*it))
244  outgoingCloud=theParticleTable->FindParticle("rhadronbaryoncloud");
245  if(CustomPDGParser::s_isRMeson(*it) || CustomPDGParser::s_isRGlueball(*it) )
246  outgoingCloud=theParticleTable->FindParticle("rhadronmesoncloud");
247  */
248  outgoingCloud=tempCust->GetCloud();
249  if(outgoingCloud == 0)
250  {
251  std::cout << "FullModelHadronicProcess::PostStepDoIt Definition of outgoing particle cloud not available!!" << std::endl;
252  }
253  /*
254  std::cout<<"Outgoing Rhadron is: "<<outgoingRhadron->GetParticleName()<<std::endl;
255  std::cout<<"Outgoing cloud is: "<<outgoingCloud->GetParticleName()<<std::endl;
256  */
257  }
258 
259  if (tempDef==G4Proton::Proton()||tempDef==G4Neutron::Neutron()) outgoingTarget = tempDef;
260  // if (tempDef->GetParticleType()!="rhadron"&&rp.size()==2) outgoingTarget = tempDef;
261  if (tempCust==0&&rp.size()==2) outgoingTarget = tempDef;
262  if (tempDef->GetPDGEncoding()==theIncidentPDG) {
263  IncidentSurvives = true;
264  } else {
265  theParticleDefinitions.push_back(tempDef);
266  /*
267  G4DynamicParticle* tempDyn = new G4DynamicParticle();
268  tempDyn->SetDefinition(tempDef);
269  theDynamicParticles->push_back(tempDyn);
270  */
271  }
272  }
273 
274  //Not using this, so...
275  // delete theDynamicParticles;
276 
277  if (outgoingTarget==0) outgoingTarget = theParticleTable->FindParticle(rp[1]);
278 
279  // A little debug information
280  /*
281  G4cout<<"The particles coming out of this reaction will be: ";
282  for (std::vector<G4DynamicParticle*>::iterator it = theDynamicParticles.begin();
283  it != theDynamicParticles.end();
284  it++){
285  G4cout<< (*it)->GetDefinition()->GetParticleName()<<" ";
286  }
287  G4cout<<G4endl;
288  */
289  // If the incident particle survives it is not a "secondary", although
290  // it would probably be easier to fStopAndKill the track every time.
291  if(IncidentSurvives) NumberOfSecondaries--;
292  aParticleChange.SetNumberOfSecondaries(NumberOfSecondaries);
293 
294 
295  // ADAPTED FROM G4LEPionMinusInelastic::ApplyYourself
296  // It is bloody ugly, but such is the way of cut 'n' paste
297 
298 
299  // Set up the incident
300  const G4HadProjectile* originalIncident = new G4HadProjectile(*OrgPart);//This is where rotation to z-axis is done (Aarrggh!)
301 
302 
303  //Maybe I need to calculate trafo from R-hadron... Bollocks! Labframe does not move. CMS does.
304  G4HadProjectile* org2 = new G4HadProjectile(*OrgPart);
305  G4LorentzRotation trans = org2->GetTrafoToLab();
306  delete org2;
307 
308  // if (originalIncident->GetKineticEnergy()<= 0.1*MeV) { //Needs rescaling. The kinetic energy of the quarksystem is the relevant quantity
309 
310  /*
311  G4cout<<"Kinetic energies: "<<G4endl;
312  G4cout<<"True kinetic energy: "<<originalIncident->GetKineticEnergy()/GeV<<" GeV"<<G4endl;
313  G4cout<<"Mass: "<<originalIncident->GetDefinition()->GetPDGMass()/GeV<<" GeV"<<G4endl;
314 
315  G4double e_kin_rescaled = targetNucleus.EvaporationEffects(originalIncident->GetTotalEnergy()-originalIncident->GetDefinition()->GetPDGMass());
316 
317  G4cout<<"Rescaled kinetic energy: "<<e_kin_rescaled<<G4endl;
318 
319  const G4double cutOff = 0.1*MeV;
320 
321  if ( e_kin_rescaled < cutOff )
322  {
323  aParticleChange.ProposeTrackStatus( fStopAndKill );//If the dice decides not to cascade I stop the particle
324  return &aParticleChange;
325  }
326  */
327  // create the target particle
328 
329  G4DynamicParticle *originalTarget = new G4DynamicParticle;
330  originalTarget->SetDefinition(aTarget);
331 
332  G4ReactionProduct targetParticle(aTarget);
333 
334 
335  G4ReactionProduct currentParticle(const_cast<G4ParticleDefinition *>(originalIncident->GetDefinition() ) );
336  currentParticle.SetMomentum( originalIncident->Get4Momentum().vect() );
337  currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() );
338 
339  /*
340  G4cout<<"After creation:"<<G4endl;
341  G4cout<<"currentParticle: "<<currentParticle.GetMomentum()/GeV<<" GeV vs. "<<OrgPart->Get4Momentum()/GeV<<" GeV"<<G4endl;
342  G4cout<<"targetParticle: "<<targetParticle.GetMomentum()/GeV<<" GeV"<<G4endl;
343  G4cout<<"Fourmomentum from originalIncident: "<<originalIncident->Get4Momentum()<<" vs "<<OrgPart->Get4Momentum()<<G4endl;
344  */
345 
346 
347  G4ReactionProduct modifiedOriginal = currentParticle;
348 
349  currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
350  targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
351  G4bool incidentHasChanged = false;
352  if (!IncidentSurvives) incidentHasChanged = true; //I wonder if I am supposed to do this...
353  G4bool targetHasChanged = false;
354  if (!TargetSurvives) targetHasChanged = true; //Ditto here
355  G4bool quasiElastic = false;
356  if (rp.size()==2) quasiElastic = true; //Oh well...
357  G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> vec; // vec will contain the secondary particles
358  G4int vecLen = 0;
359  vec.Initialize( 0 );
360 
361 
362 
363  // I hope my understanding of "secondary" is correct here
364  // I think that it entails only what is not a surviving incident of target
365 
366  for (G4int i = 0; i!=NumberOfSecondaries;i++){
367  if(theParticleDefinitions[i]!=aTarget
368  && theParticleDefinitions[i]!=originalIncident->GetDefinition()
369  && theParticleDefinitions[i]!=outgoingRhadron
370  && theParticleDefinitions[i]!=outgoingTarget)
371  {
372  G4ReactionProduct* pa = new G4ReactionProduct;
373  pa->SetDefinition( theParticleDefinitions[i] );
374  (G4UniformRand() < 0.5) ? pa->SetSide( -1 ) : pa->SetSide( 1 );
375  vec.SetElement( vecLen++, pa );
376  }
377  }
378 
379  // if (incidentHasChanged) currentParticle.SetDefinitionAndUpdateE( outgoingRhadron );
380 
381  if (incidentHasChanged) currentParticle.SetDefinitionAndUpdateE( outgoingCloud );
382  if (incidentHasChanged) modifiedOriginal.SetDefinition( outgoingCloud );//Is this correct? It solves the "free energy" checking in ReactionDynamics
383  if (targetHasChanged) targetParticle.SetDefinitionAndUpdateE( outgoingTarget );
384 
385  // G4cout<<"Calling CalculateMomenta... "<<G4endl;
386  /*
387  G4cout<<"Current particle starts as: "<<currentParticle.GetDefinition()->GetParticleName()<<G4endl;
388  G4cout<<"with momentum: "<<currentParticle.GetMomentum()/GeV<<" GeV"<<G4endl;
389  G4cout<<"May be killed?: "<<currentParticle.GetMayBeKilled()<<G4endl;
390  */
391  // G4double e_temp = currentParticle.GetKineticEnergy();
392 
393  CalculateMomenta( vec, vecLen,
394  originalIncident, originalTarget, modifiedOriginal,
395  targetNucleus, currentParticle, targetParticle,
396  incidentHasChanged, targetHasChanged, quasiElastic );
397 
398  // G4cout <<"Cloud loss: "<<(e_temp-currentParticle.GetKineticEnergy())/GeV<<" GeV"<<G4endl;
399 
400  G4String cPname = currentParticle.GetDefinition()->GetParticleName();
401 
402  // if(cPname!="rhadronmesoncloud"&&cPname!="rhadronbaryoncloud")
403  // {
404  /*
405  G4cout<<"Current particle is now: "<<cPname <<G4endl;
406  G4cout<<"with momentum: "<<currentParticle.GetMomentum()/GeV<<" GeV"<<G4endl;
407  G4cout<<"and kinetic energy: "<<currentParticle.GetKineticEnergy()/GeV<<" GeV"<<G4endl;
408  G4cout<<"May be killed?: "<<currentParticle.GetMayBeKilled()<<G4endl;
409  G4cout<<"Modified original is: "<<modifiedOriginal.GetDefinition()->GetParticleName()<<G4endl;
410  G4cout<<"with momentum: "<<modifiedOriginal.GetMomentum()/GeV<<" GeV"<<G4endl;
411  G4cout<<"and kinetic energy: "<<modifiedOriginal.GetKineticEnergy()/GeV<<" GeV"<<G4endl;
412  G4cout<<"May be killed?: "<<modifiedOriginal.GetMayBeKilled()<<G4endl;
413  G4cout<<"Target particle is: "<<targetParticle.GetDefinition()->GetParticleName()<<G4endl;
414  G4cout<<"with momentum: "<<targetParticle.GetMomentum()/GeV<<" GeV"<<G4endl;
415  G4cout<<"and kinetic energy: "<<targetParticle.GetKineticEnergy()/GeV<<" GeV"<<G4endl;
416  G4cout<<"May be killed?: "<<targetParticle.GetMayBeKilled()<<G4endl;
417  G4cout<<"incidentHasChanged: "<<incidentHasChanged<<G4endl;
418  G4cout<<"targetHasChanged: "<<targetHasChanged<<G4endl;
419  G4cout<<"Particles in vec:"<<G4endl;
420  for(int i=0; i<vecLen; ++i )
421  {
422  G4cout<< vec[i]->GetDefinition()->GetParticleName()<<G4endl;
423  }
424  */
425 
426  // }
427 
428  // G4cout<<"Done!"<<G4endl;
429  // const G4LorentzRotation& trans(originalIncident->GetTrafoToLab());
430  // G4cout<<"Check aParticleChange.GetNumberOfSecondaries(): "<<aParticleChange.GetNumberOfSecondaries()<<G4endl;
431 
432  aParticleChange.SetNumberOfSecondaries(vecLen+NumberOfSecondaries);
433  G4double e_kin=0;
434  G4LorentzVector cloud_p4_new; //Cloud 4-momentum in lab after collision
435  // n++;
436  // G4cout << n << G4endl;
437  /*
438  if(cPname!="rhadronmesoncloud"&&cPname!="rhadronbaryoncloud") {
439  G4cout<<"Cloud deleted!!! AAARRRRGGGHHH!!!"<<G4endl;
440  G4cout<<"Cloud name: "<<cPname<<G4endl;
441  G4cout<<"E_kin_0: "<<e_kin_0/GeV<<" GeV"<<G4endl;
442  // G4cout<<"n: "<<n<<G4endl;
443  // n=0;
444  }
445  */
446  cloud_p4_new.setVectM(currentParticle.GetMomentum(),currentParticle.GetMass());
447  cloud_p4_new *= trans;
448 
449  G4LorentzVector cloud_p4_old_full = Cloud4Momentum; //quark system in CMS BEFORE collision
450  cloud_p4_old_full.boost(trafo_full_cms);
451  G4LorentzVector cloud_p4_old_cloud = Cloud4Momentum; //quark system in cloud CMS BEFORE collision
452  cloud_p4_old_cloud.boost(trafo_cloud_cms);
453  G4LorentzVector cloud_p4_full = cloud_p4_new; //quark system in CMS AFTER collision
454  cloud_p4_full.boost(trafo_full_cms);
455  G4LorentzVector cloud_p4_cloud = cloud_p4_new; //quark system in cloud CMS AFTER collision
456  cloud_p4_cloud.boost(trafo_cloud_cms);
457 
458  G4LorentzVector p_g_cms = gluinoMomentum; //gluino in CMS BEFORE collision
459  p_g_cms.boost(trafo_full_cms);
460 
461  G4LorentzVector p4_new;
462  // p4_new.setVectM(cloud_p4_full.v()+p_g_cms.v(),outgoingRhadron->GetPDGMass());
463  // p4_new.boost(-trafo_full_cms);
464  // p4_new = cloud_p4_new + gluinoMomentum;
465  p4_new.setVectM( cloud_p4_new.v() + gluinoMomentum.v(), outgoingRhadron->GetPDGMass() );
466  // G4cout<<"P4-diff: "<<(p4_new-cloud_p4_new-gluinoMomentum)/GeV<<", magnitude: "<<(p4_new-cloud_p4_new-gluinoMomentum).m()/MeV<<" MeV" <<G4endl;
467 
468  G4ThreeVector p_new;
469  p_new = p4_new.vect();
470 
471  aParticleChange.ProposeLocalEnergyDeposit((p4_new-cloud_p4_new-gluinoMomentum).m());
472 
473  if( incidentHasChanged )
474  {
475  G4DynamicParticle* p0 = new G4DynamicParticle;
476  p0->SetDefinition( outgoingRhadron );
477  p0->SetMomentum( p_new );
478 
479  // May need to run SetDefinitionAndUpdateE here...
480  G4Track* Track0 = new G4Track(p0,
481  aTrack.GetGlobalTime(),
482  aPosition);
483  Track0->SetTouchableHandle(thisTouchable);
484  aParticleChange.AddSecondary(Track0);
485  /*
486  G4cout<<"Adding a particle "<<p0->GetDefinition()->GetParticleName()<<G4endl;
487  G4cout<<"with momentum: "<<p0->GetMomentum()/GeV<<" GeV"<<G4endl;
488  G4cout<<"and kinetic energy: "<<p0->GetKineticEnergy()/GeV<<" GeV"<<G4endl;
489  */
490  if(p0->GetKineticEnergy()>e_kin_0) {
491  G4cout<<"ALAAAAARM!!! (incident changed from "
492  <<IncidentRhadron->GetDefinition()->GetParticleName()
493  <<" to "<<p0->GetDefinition()->GetParticleName()<<")"<<G4endl;
494  G4cout<<"Energy loss: "<<(e_kin_0-p0->GetKineticEnergy())/GeV<<" GeV (should be positive)"<<G4endl;
495  //Turns out problem is only in 2 -> 3 (Won't fix 2 -> 2 energy deposition)
496  if(rp.size()!=3) G4cout<<"DOUBLE ALAAAAARM!!!"<<G4endl;
497  } /*else {
498  G4cout<<"NO ALAAAAARM!!!"<<G4endl;
499  }*/
500  if(std::abs(p0->GetKineticEnergy()-e_kin_0)>100*GeV) {
501  G4cout<<"Diff. too big"<<G4endl;
502  }
503 
504  aParticleChange.ProposeTrackStatus( fStopAndKill );
505  }
506  else
507  {
508 
509  G4double p = p_new.mag();
510  if( p > DBL_MIN )
511  aParticleChange.ProposeMomentumDirection( p_new.x()/p, p_new.y()/p, p_new.z()/p );
512  else
513  aParticleChange.ProposeMomentumDirection( 1.0, 0.0, 0.0 );
514 
515  G4double aE = sqrt(p*p+(outgoingRhadron->GetPDGMass()*outgoingRhadron->GetPDGMass()) );
516  e_kin = aE - outgoingRhadron->GetPDGMass();
517  /* AR_NEWCODE_IMPORT
518  if(e_kin>e_kin_0) {
519  G4cout<<"ALAAAAARM!!!"<<G4endl;
520  G4cout<<"Energy loss: "<<(e_kin_0-e_kin)/GeV<<" GeV (should be positive)"<<G4endl;
521  if(rp.size()!=3) G4cout<<"DOUBLE ALAAAAARM!!!"<<G4endl;
522  }
523  if(std::abs(e_kin-e_kin_0)>100*GeV) {
524  G4cout<<"Diff. too big"<<G4endl;
525  }
526 
527  if (std::fabs(aE)<.1*eV) aE=.1*eV;
528  aParticleChange.ProposeEnergy( aE- outgoingRhadron->GetPDGMass() ); //I do not know if this is correct...
529  if(std::abs(e_kin-e_kin_0)>100*GeV) {
530  G4cout<<"Diff. too big"<<G4endl;
531  }
532  */
533  }
534 
535  // return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
536  if( targetParticle.GetMass() > 0.0 ) // targetParticle can be eliminated in TwoBody
537  {
538  G4DynamicParticle *p1 = new G4DynamicParticle;
539  p1->SetDefinition( targetParticle.GetDefinition() );
540  // G4cout<<"Target secondary: "<<targetParticle.GetDefinition()->GetParticleName()<<G4endl;
541  G4ThreeVector momentum = targetParticle.GetMomentum();
542  momentum = momentum.rotate(cache,what);
543  p1->SetMomentum( momentum );
544  p1->SetMomentum( (trans*p1->Get4Momentum()).vect());
545  G4Track* Track1 = new G4Track(p1,
546  aTrack.GetGlobalTime(),
547  aPosition);
548  Track1->SetTouchableHandle(thisTouchable);
549  aParticleChange.AddSecondary(Track1);
550  }
551  G4DynamicParticle *pa;
552  /*
553  G4cout<<"vecLen: "<<vecLen<<G4endl;
554  G4cout<<"#sec's: "<<aParticleChange.GetNumberOfSecondaries()<<G4endl;
555  */
556 
557 
558 
559  for(int i=0; i<vecLen; ++i )
560  {
561  pa = new G4DynamicParticle();
562  pa->SetDefinition( vec[i]->GetDefinition() );
563  pa->SetMomentum( vec[i]->GetMomentum() );
564  pa->Set4Momentum(trans*(pa->Get4Momentum()));
565  G4ThreeVector pvec = pa->GetMomentum();
566  G4Track* Trackn = new G4Track(pa,
567  aTrack.GetGlobalTime(),
568  aPosition);
569  Trackn->SetTouchableHandle(thisTouchable);
570  aParticleChange.AddSecondary(Trackn);
571 
572  // debug
573 
574 // G4cerr << "FullModelHadronicProcess: New secondary " << i
575 // << " ID " << Trackn->GetTrackID()
576 // << " PDG " << Trackn->GetDefinition()->GetParticleName()
577 // << " position " << Trackn->GetPosition()
578 // << " volume " << Trackn->GetTouchable()
579 // << " handle " << Trackn->GetTouchableHandle() << G4endl;
580 
581  delete vec[i];
582  }
583 
584  // Histogram filling
585  const G4DynamicParticle* theRhadron = FindRhadron(&aParticleChange);
586 
587 
588  if (theRhadron!=NULL||IncidentSurvives)
589  {
590 
591  double E_new;
592  if(IncidentSurvives)
593  {
594  // E_new = currentParticle.GetKineticEnergy();
595  E_new = e_kin;
596  } else {
597  E_new = theRhadron->GetKineticEnergy();
598  if(CustomPDGParser::s_isRMeson(theRhadron->GetDefinition()->GetPDGEncoding())
599  !=CustomPDGParser::s_isRMeson(theIncidentPDG)
600  ||
601  CustomPDGParser::s_isMesonino(theRhadron->GetDefinition()->GetPDGEncoding())
602  !=CustomPDGParser::s_isMesonino(theIncidentPDG)
603  ) {
604 
605  G4cout<<"Rm: "<<CustomPDGParser::s_isRMeson(theRhadron->GetDefinition()->GetPDGEncoding())
606  <<" vs: "<<CustomPDGParser::s_isRMeson(theIncidentPDG)<<G4endl;
607  G4cout<<"Sm: "<<CustomPDGParser::s_isMesonino(theRhadron->GetDefinition()->GetPDGEncoding())
608  <<" vs: "<<CustomPDGParser::s_isMesonino(theIncidentPDG)<<G4endl;
609 
610  }
611  }
612 
613  //Calculating relevant scattering angles.
614  G4LorentzVector p4_old_full = FullRhadron4Momentum; //R-hadron in CMS BEFORE collision
615  p4_old_full.boost(trafo_full_cms);
616  G4LorentzVector p4_old_cloud = FullRhadron4Momentum; //R-hadron in cloud CMS BEFORE collision
617  p4_old_cloud.boost(trafo_cloud_cms);
618  G4LorentzVector p4_full = p4_new; //R-hadron in CMS AFTER collision
619  // G4cout<<p4_full.v()/GeV<<G4endl;
620  p4_full=p4_full.boost(trafo_full_cms);
621  // G4cout<<p4_full.m()<<" / "<<(cloud_p4_new+gluinoMomentum).boost(trafo_full_cms).m()<<G4endl;
622  G4LorentzVector p4_cloud = p4_new; //R-hadron in cloud CMS AFTER collision
623  p4_cloud.boost(trafo_cloud_cms);
624 
625 
626  /*
627  G4double dtheta_fullcms = p4_full.vect().angle(p4_old_full.vect());
628  G4double dtheta_cloudcms = p4_cloud.vect().angle(p4_old_cloud.vect());
629  G4double dtheta_lab = p_new.angle(p_0);//acos(p_0*p_new/(p_0.mag()*p_new.mag()));
630 
631  G4double cloud_dtheta_fullcms = cloud_p4_full.vect().angle(cloud_p4_old_full.vect());
632  G4double cloud_dtheta_cloudcms = cloud_p4_cloud.vect().angle(p4_old_cloud.vect());
633  G4double cloud_dtheta_lab = cloud_p4_new.vect().angle(p_0);
634  //Writing out momenta for manual check of boosts:
635  G4cout<<"******************************************"<<G4endl;
636 
637  G4cout<<"R-hadron, before: "<<G4endl;
638  G4cout<<"Lab: "<<FullRhadron4Momentum.v().mag()/GeV<<" GeV"<<G4endl;
639  G4cout<<"CMS: "<<p4_old_full.v().mag()/GeV<<" GeV"<<G4endl;
640  G4cout<<"after: "<<G4endl;
641  G4cout<<"Lab: "<<p4_new.v().mag()/GeV<<" GeV"<<G4endl;
642  G4cout<<"CMS: "<<p4_full.v().mag()/GeV<<" GeV"<<G4endl;
643  G4cout<<"cos(theta*): "<<cos(dtheta_fullcms)<<G4endl;
644  G4cout<<"Gluino: "<<G4endl;
645  G4cout<<"Lab: "<<gluinoMomentum.v().mag()/GeV<<" GeV"<<G4endl;
646  G4cout<<"CMS: "<<p_g_cms.v().mag()/GeV<<" GeV"<<G4endl;
647 
648  G4cout<<"Cloud, before: "<<G4endl;
649  G4cout<<"Lab: "<<Cloud4Momentum.v().mag()/GeV<<" GeV"<<G4endl;
650  G4cout<<"CMS: "<<cloud_p4_old_full.v().mag()/GeV<<" GeV"<<G4endl;
651  G4cout<<"after: "<<G4endl;
652  G4cout<<"CMS: "<<cloud_p4_full.v().mag()/GeV<<" GeV"<<G4endl;
653  G4cout<<"cloud cos(theta*): "<<cos(cloud_dtheta_fullcms)<<G4endl;
654  G4cout<<"Longitudinal: "<<cos(cloud_dtheta_fullcms)*cloud_p4_full.v().mag()/GeV<<" GeV"<<G4endl;
655  G4cout<<"~Combined longitudinal: "<<(cos(cloud_dtheta_fullcms)*cloud_p4_full.v().mag()+p4_old_full.v().mag())/GeV<<" GeV"<<G4endl;
656  if ((cos(cloud_dtheta_fullcms)*cloud_p4_full.v().mag()+p4_old_full.v().mag())<0.) G4cout<<"ALAAARM"<<G4endl;
657  G4cout<<"Psum cos(theta*): "<<cos((p_g_cms.v()+cloud_p4_full.v()).angle(p4_old_full.v()))<<G4endl;
658  G4cout<<"True R-hadron (CMS): "<<(p_g_cms.v()+cloud_p4_full.v()).mag()/GeV<<" GeV"<<G4endl;
659  G4cout<<"******************************************"<<G4endl;
660  G4cout<<"Fucking manual fucking calculation:"<<G4endl;
661  G4cout<<"Momenta:"<<G4endl;
662  G4cout<<"Cloud, lab: "<<cloud_p4_new.v()/GeV<<" + gluino: "<<gluinoMomentum.v()/GeV
663  <<" = "<<(cloud_p4_new.v()+gluinoMomentum.v())/GeV
664  <<". Boost to CMS: "<<(cloud_p4_new+gluinoMomentum).boost(trafo_full_cms).v()/GeV<<G4endl;
665  G4cout<<"Cloud, CMS: "<<cloud_p4_full.v()/GeV<<" + gluino: "<<p_g_cms.v()/GeV
666  <<" = "<<(cloud_p4_full.v()+p_g_cms.v())/GeV
667  <<". Boost to Lab: "<<(cloud_p4_full+p_g_cms).boost(-trafo_full_cms).v()/GeV<<G4endl;
668  G4cout<<"Ref: "<<p4_new.v()/GeV<<" / "<<p4_full.v()/GeV<<G4endl;
669  G4cout<<"******************************************"<<G4endl;
670  */
671 
672 
673  // std::cout<<"Lab, fullcms, cloudcms: "<<dtheta_lab<<", "<<dtheta_fullcms<<", "<<dtheta_cloudcms<<std::endl;
674  G4double AbsDeltaE = E_0-E_new;
675  // G4cout <<"Energy loss: "<<AbsDeltaE/GeV<<G4endl;
676  if (AbsDeltaE > 10*GeV) {
677  G4cout<<"Energy loss larger than 10 GeV..."<<G4endl;
678  G4cout<<"E_0: "<<E_0/GeV<<" GeV"<<G4endl;
679  G4cout<<"E_new: "<<E_new/GeV<<" GeV"<<G4endl;
680  G4cout<<"Gamma: "<<IncidentRhadron->GetTotalEnergy()/IncidentRhadron->GetDefinition()->GetPDGMass()<<G4endl;
681  G4cout<<"x: "<<aPosition.x()/cm<<" cm"<<G4endl;
682  }
683  }
684  delete originalIncident;
685  delete originalTarget;
686  // aParticleChange.DumpInfo();
687  // G4cout << "Exiting FullModelHadronicProcess::PostStepDoIt"<<G4endl;
688 
689  //clear interaction length
690  ClearNumberOfInteractionLengthLeft();
691 
692 
693  return &aParticleChange;
694 
695 }
696 
697 
698 void FullModelHadronicProcess::CalculateMomenta(
699  G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
700  G4int &vecLen,
701  const G4HadProjectile *originalIncident, // the original incident particle
702  const G4DynamicParticle *originalTarget,
703  G4ReactionProduct &modifiedOriginal, // Fermi motion and evap. effects included
704  G4Nucleus &targetNucleus,
705  G4ReactionProduct &currentParticle,
706  G4ReactionProduct &targetParticle,
707  G4bool &incidentHasChanged,
708  G4bool &targetHasChanged,
709  G4bool quasiElastic )
710 {
711  FullModelReactionDynamics theReactionDynamics;
712 
713  cache = 0;
714  what = originalIncident->Get4Momentum().vect();
715 
716  //Commented out like in casqmesmin.F where CALL STPAIR is commented out
717  /*
718  theReactionDynamics.ProduceStrangeParticlePairs( vec, vecLen,
719  modifiedOriginal, originalTarget,
720  currentParticle, targetParticle,
721  incidentHasChanged, targetHasChanged );
722  */
723 
724  if( quasiElastic )
725  {
726  // G4cout<<"We are calling TwoBody..."<<G4endl;
727  theReactionDynamics.TwoBody( vec, vecLen,
728  modifiedOriginal, originalTarget,
729  currentParticle, targetParticle,
730  targetNucleus, targetHasChanged );
731 
732  return;
733  }
734 
735  //If ProduceStrangeParticlePairs is commented out, let's cut this one as well
736  G4ReactionProduct leadingStrangeParticle;
737  G4bool leadFlag = MarkLeadingStrangeParticle( currentParticle,
738  targetParticle,
739  leadingStrangeParticle );
740 
741 
742 
743  //
744  // Note: the number of secondaries can be reduced in GenerateXandPt and TwoCluster
745  //
746  G4bool finishedGenXPt = false;
747  G4bool annihilation = false;
748  if( originalIncident->GetDefinition()->GetPDGEncoding() < 0 &&
749  currentParticle.GetMass() == 0.0 && targetParticle.GetMass() == 0.0 )
750  {
751  // original was an anti-particle and annihilation has taken place
752  annihilation = true;
753  G4double ekcor = 1.0;
754  G4double ek = originalIncident->GetKineticEnergy();
755  G4double ekOrg = ek;
756 
757  const G4double tarmas = originalTarget->GetDefinition()->GetPDGMass();
758  if( ek > 1.0*GeV )ekcor = 1./(ek/GeV);
759  const G4double atomicWeight = G4double(targetNucleus.GetN_asInt());
760  ek = 2*tarmas + ek*(1.+ekcor/atomicWeight);
761 
762  G4double tkin = targetNucleus.Cinema( ek );
763  ek += tkin;
764  ekOrg += tkin;
765  modifiedOriginal.SetKineticEnergy( ekOrg );
766  }
767 
768  const G4double twsup[] = { 1.0, 0.7, 0.5, 0.3, 0.2, 0.1 };
769  G4double rand1 = G4UniformRand();
770  G4double rand2 = G4UniformRand();
771  if( (annihilation || (vecLen >= 6) || (modifiedOriginal.GetKineticEnergy()/GeV >= 1.0)) &&
772  (((originalIncident->GetDefinition() == G4KaonPlus::KaonPlus()) ||
773  (originalIncident->GetDefinition() == G4KaonMinus::KaonMinus()) ||
774  (originalIncident->GetDefinition() == G4KaonZeroLong::KaonZeroLong()) ||
775  (originalIncident->GetDefinition() == G4KaonZeroShort::KaonZeroShort())) &&
776  ((rand1 < 0.5) || (rand2 > twsup[vecLen]))))
777  finishedGenXPt =
778  theReactionDynamics.GenerateXandPt( vec, vecLen,
779  modifiedOriginal, originalIncident,
780  currentParticle, targetParticle,
781  targetNucleus, incidentHasChanged,
782  targetHasChanged, leadFlag,
783  leadingStrangeParticle );
784  if( finishedGenXPt )
785  {
786  Rotate(vec, vecLen);
787  return;
788  }
789 
790  G4bool finishedTwoClu = false;
791  if( modifiedOriginal.GetTotalMomentum()/MeV < 1.0 )
792  {
793 
794  for(G4int i=0; i<vecLen; i++) delete vec[i];
795  vecLen = 0;
796  }
797  else
798  {
799 
800  theReactionDynamics.SuppressChargedPions( vec, vecLen,
801  modifiedOriginal, currentParticle,
802  targetParticle, targetNucleus,
803  incidentHasChanged, targetHasChanged );
804 
805  try
806  {
807  finishedTwoClu = theReactionDynamics.TwoCluster( vec, vecLen,
808  modifiedOriginal, originalIncident,
809  currentParticle, targetParticle,
810  targetNucleus, incidentHasChanged,
811  targetHasChanged, leadFlag,
812  leadingStrangeParticle );
813  }
814  catch(G4HadReentrentException aC)
815  {
816  aC.Report(G4cout);
817  throw G4HadReentrentException(__FILE__, __LINE__, "Failing to calculate momenta");
818  }
819  }
820  if( finishedTwoClu )
821  {
822  Rotate(vec, vecLen);
823  return;
824  }
825 
826  //
827  // PNBlackTrackEnergy is the kinetic energy available for
828  // proton/neutron black track particles [was enp(1) in fortran code]
829  // DTABlackTrackEnergy is the kinetic energy available for
830  // deuteron/triton/alpha particles [was enp(3) in fortran code]
831  //const G4double pnCutOff = 0.1;
832  //const G4double dtaCutOff = 0.1;
833  //if( (targetNucleus.GetN() >= 1.5)
834  // && !(incidentHasChanged || targetHasChanged)
835  // && (targetNucleus.GetPNBlackTrackEnergy()/MeV <= pnCutOff)
836  // && (targetNucleus.GetDTABlackTrackEnergy()/MeV <= dtaCutOff) )
837  //{
838  // the atomic weight of the target nucleus is >= 1.5 AND
839  // neither the incident nor the target particles have changed AND
840  // there is no kinetic energy available for either proton/neutron
841  // or for deuteron/triton/alpha black track particles
842  // For diffraction scattering on heavy nuclei use elastic routines instead
843  //G4cerr << "*** Error in G4InelasticInteraction::CalculateMomenta" << G4endl;
844  //G4cerr << "*** the elastic scattering would be better here ***" <<G4endl;
845  //}
846  theReactionDynamics.TwoBody( vec, vecLen,
847  modifiedOriginal, originalTarget,
848  currentParticle, targetParticle,
849  targetNucleus, targetHasChanged );
850 }
851 
852 
853 G4bool FullModelHadronicProcess::MarkLeadingStrangeParticle(
854  const G4ReactionProduct &currentParticle,
855  const G4ReactionProduct &targetParticle,
856  G4ReactionProduct &leadParticle )
857 {
858  // the following was in GenerateXandPt and TwoCluster
859  // add a parameter to the GenerateXandPt function telling it about the strange particle
860  //
861  // assumes that the original particle was a strange particle
862  //
863  G4bool lead = false;
864  if( (currentParticle.GetMass() >= G4KaonPlus::KaonPlus()->GetPDGMass()) &&
865  (currentParticle.GetDefinition() != G4Proton::Proton()) &&
866  (currentParticle.GetDefinition() != G4Neutron::Neutron()) )
867  {
868  lead = true;
869  leadParticle = currentParticle; // set lead to the incident particle
870  }
871  else if( (targetParticle.GetMass() >= G4KaonPlus::KaonPlus()->GetPDGMass()) &&
872  (targetParticle.GetDefinition() != G4Proton::Proton()) &&
873  (targetParticle.GetDefinition() != G4Neutron::Neutron()) )
874  {
875  lead = true;
876  leadParticle = targetParticle; // set lead to the target particle
877  }
878  return lead;
879 }
880 
881 void FullModelHadronicProcess::Rotate(G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec, G4int &vecLen)
882 {
883  G4double rotation = 2.*pi*G4UniformRand();
884  cache = rotation;
885  G4int i;
886  for( i=0; i<vecLen; ++i )
887  {
888  G4ThreeVector momentum = vec[i]->GetMomentum();
889  momentum = momentum.rotate(rotation, what);
890  vec[i]->SetMomentum(momentum);
891  }
892 }
893 
894 const G4DynamicParticle* FullModelHadronicProcess::FindRhadron(G4ParticleChange* aParticleChange)
895 {
896  G4int nsec = aParticleChange->GetNumberOfSecondaries();
897  if (nsec==0) return 0;
898  int i = 0;
899  G4bool found = false;
900  while (i!=nsec && !found){
901  // G4cout<<"Checking "<<aParticleChange->GetSecondary(i)->GetDynamicParticle()->GetDefinition()->GetParticleName()<<G4endl;
902  // if (aParticleChange->GetSecondary(i)->GetDynamicParticle()->GetDefinition()->GetParticleType()=="rhadron") found = true;
903  if (dynamic_cast<CustomParticle*>(aParticleChange->GetSecondary(i)->GetDynamicParticle()->GetDefinition())!=0) found = true;
904  i++;
905  }
906  i--;
907  if(found) return aParticleChange->GetSecondary(i)->GetDynamicParticle();
908  return 0;
909 }
910 
int i
Definition: DBlmapReader.cc:9
const double GeV
Definition: MathUtil.h:16
tuple pp
Definition: createTree.py:15
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)
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
tuple cout
Definition: gather_cfg.py:121