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