ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4LMsdGenerator.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4LMsdGenerator.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // G4LMsdGenerator
28 //
29 //
30 
31 #include "G4DynamicParticle.hh"
32 #include "G4LMsdGenerator.hh"
34 #include "G4ReactionProduct.hh"
35 #include "G4IonTable.hh"
36 #include "G4NucleiProperties.hh"
37 #include "G4ParticleDefinition.hh"
38 #include "G4HadFinalState.hh"
39 #include "G4KineticTrack.hh"
40 #include "G4DecayKineticTracks.hh"
41 #include "G4KineticTrackVector.hh"
42 #include "G4Log.hh"
43 
44 
46  : G4HadronicInteraction(name)
47 
48 {
49  fPDGencoding = 0;
50 
51  // theParticleChange = new G4HadFinalState;
52 }
53 
55 {
56  // delete theParticleChange;
57 }
58 
59 void G4LMsdGenerator::ModelDescription(std::ostream& outFile) const
60 {
61  outFile << GetModelName() <<" consists of a "
62  << " string model and a stage to de-excite the excited nuclear fragment."
63  << "\n<p>"
64  << "The string model simulates the interaction of\n"
65  << "an incident hadron with a nucleus, forming \n"
66  << "excited strings, decays these strings into hadrons,\n"
67  << "and leaves an excited nucleus. \n"
68  << "<p>The string model:\n";
69 }
70 
72 //
73 // Particle and kinematical limitation od diffraction dissociation
74 
75 G4bool
77  G4Nucleus& targetNucleus )
78 {
79  G4bool applied = false;
80 
81  if( ( aTrack.GetDefinition() == G4Proton::Proton() ||
82  aTrack.GetDefinition() == G4Neutron::Neutron() ) &&
83  targetNucleus.GetA_asInt() >= 1 &&
84  // aTrack.GetKineticEnergy() > 1800*CLHEP::MeV
85  aTrack.GetKineticEnergy() > 300*CLHEP::MeV
86  ) // 750*CLHEP::MeV )
87  {
88  applied = true;
89  }
90  else if( ( aTrack.GetDefinition() == G4PionPlus::PionPlus() ||
91  aTrack.GetDefinition() == G4PionMinus::PionMinus() ) &&
92  targetNucleus.GetA_asInt() >= 1 &&
93  aTrack.GetKineticEnergy() > 2340*CLHEP::MeV )
94  {
95  applied = true;
96  }
97  else if( ( aTrack.GetDefinition() == G4KaonPlus::KaonPlus() ||
98  aTrack.GetDefinition() == G4KaonMinus::KaonMinus() ) &&
99  targetNucleus.GetA_asInt() >= 1 &&
100  aTrack.GetKineticEnergy() > 1980*CLHEP::MeV )
101  {
102  applied = true;
103  }
104  return applied;
105 }
106 
108 //
109 // Return dissociated particle products and recoil nucleus
110 
113  G4Nucleus& targetNucleus )
114 {
116 
117  const G4HadProjectile* aParticle = &aTrack;
118  G4double eTkin = aParticle->GetKineticEnergy();
119 
120  if( eTkin <= 1.*CLHEP::GeV && aTrack.GetDefinition() != G4Proton::Proton())
121  {
124  return &theParticleChange;
125  }
126 
127  G4int A = targetNucleus.GetA_asInt();
128  G4int Z = targetNucleus.GetZ_asInt();
129 
130  G4double plab = aParticle->GetTotalMomentum();
131  G4double plab2 = plab*plab;
132 
133  const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
134  G4double partMass = theParticle->GetPDGMass();
135 
136  G4double oldE = partMass + eTkin;
137 
139  G4double targMass2 = targMass*targMass;
140 
141  G4LorentzVector partLV = aParticle->Get4Momentum();
142 
143  G4double sumE = oldE + targMass;
144  G4double sumE2 = sumE*sumE;
145 
146  G4ThreeVector p1 = partLV.vect();
147  // G4cout<<"p1 = "<<p1<<G4endl;
148  G4ParticleMomentum p1unit = p1.unit();
149 
150  G4double Mx = SampleMx(aParticle); // in GeV
151  G4double t = SampleT( aParticle, Mx); // in GeV
152 
153  Mx *= CLHEP::GeV;
154 
155  G4double Mx2 = Mx*Mx;
156 
157  // equation for q|| based on sum-E-P and new invariant mass
158 
159  G4double B = sumE2 + targMass2 - Mx2 - plab2;
160 
161  G4double a = 4*(plab2 - sumE2);
162  G4double b = 4*plab*B;
163  G4double c = B*B - 4*sumE2*targMass2;
164  G4double det2 = b*b - 4*a*c;
165  G4double qLong, det, eRetard; // , x2, x3, e2;
166 
167  if( det2 >= 0.)
168  {
169  det = std::sqrt(det2);
170  qLong = (-b - det)/2./a;
171  eRetard = std::sqrt((plab-qLong)*(plab-qLong)+Mx2);
172  }
173  else
174  {
177  return &theParticleChange;
178  }
180 
181  plab -= qLong;
182 
183  G4ThreeVector pRetard = plab*p1unit;
184 
185  G4ThreeVector pTarg = p1 - pRetard;
186 
187  G4double eTarg = std::sqrt( targMass2 + pTarg.mag2()); // std::sqrt( targMass*targMass + pTarg.mag2() );
188 
189  G4LorentzVector lvRetard(pRetard, eRetard);
190  G4LorentzVector lvTarg(pTarg, eTarg);
191 
192  lvTarg += lvRetard; // sum LV
193 
194  G4ThreeVector bst = lvTarg.boostVector();
195 
196  lvRetard.boost(-bst); // to CNS
197 
198  G4ThreeVector pCMS = lvRetard.vect();
199  G4double momentumCMS = pCMS.mag();
200  G4double tMax = 4.0*momentumCMS*momentumCMS;
201 
202  if( t > tMax ) t = tMax*G4UniformRand();
203 
204  G4double cost = 1. - 2.0*t/tMax;
205 
206 
208  G4double sint;
209 
210  if( cost > 1.0 || cost < -1.0 ) //
211  {
212  cost = 1.0;
213  sint = 0.0;
214  }
215  else // normal situation
216  {
217  sint = std::sqrt( (1.0-cost)*(1.0+cost) );
218  }
219  G4ThreeVector v1( sint*std::cos(phi), sint*std::sin(phi), cost);
220 
221  v1 *= momentumCMS;
222 
223  G4LorentzVector lvRes( v1.x(),v1.y(),v1.z(), std::sqrt( momentumCMS*momentumCMS + Mx2));
224 
225  lvRes.boost(bst); // to LS
226 
227  lvTarg -= lvRes;
228 
229  G4double eRecoil = lvTarg.e() - targMass;
230 
231  if( eRecoil > 100.*CLHEP::MeV ) // add recoil nucleus
232  {
233  G4ParticleDefinition * recoilDef = 0;
234 
235  if ( Z == 1 && A == 1 ) { recoilDef = G4Proton::Proton(); }
236  else if ( Z == 1 && A == 2 ) { recoilDef = G4Deuteron::Deuteron(); }
237  else if ( Z == 1 && A == 3 ) { recoilDef = G4Triton::Triton(); }
238  else if ( Z == 2 && A == 3 ) { recoilDef = G4He3::He3(); }
239  else if ( Z == 2 && A == 4 ) { recoilDef = G4Alpha::Alpha(); }
240  else
241  {
242  recoilDef =
244  }
245  G4DynamicParticle * aSec = new G4DynamicParticle( recoilDef, lvTarg);
247  }
248  else if( eRecoil > 0.0 )
249  {
251  }
252 
254  FindParticle(fPDGencoding);
255 
256  // G4cout<<fPDGencoding<<", "<<ddPart->GetParticleName()<<", "<<ddPart->GetPDGMass()<<" MeV; lvRes = "<<lvRes<<G4endl;
257 
258  // G4DynamicParticle * aRes = new G4DynamicParticle( ddPart, lvRes);
259  // theParticleChange.AddSecondary(aRes); // simply return resonance
260 
261 
262 
263  // Recursive decay using methods of G4KineticTrack
264 
265  G4KineticTrack ddkt( ddPart, 0., G4ThreeVector(0.,0.,0.), lvRes);
266  G4KineticTrackVector* ddktv = ddkt.Decay();
267 
268  G4DecayKineticTracks decay( ddktv );
269 
270  for( unsigned int i = 0; i < ddktv->size(); i++ ) // add products to partchange
271  {
272  G4DynamicParticle * aNew =
273  new G4DynamicParticle( ddktv->operator[](i)->GetDefinition(),
274  ddktv->operator[](i)->Get4Momentum());
275 
276  // G4cout<<" "<<i<<", "<<aNew->GetDefinition()->GetParticleName()<<", "<<aNew->Get4Momentum()<<G4endl;
277 
279  delete ddktv->operator[](i);
280  }
281  delete ddktv;
282 
283  return &theParticleChange;
284 }
285 
287 //
288 // Sample Mx as Roper resonances, set PDG encoding
289 
291 {
292  G4double Mx = 0.;
293  G4int i;
294  G4double rand = G4UniformRand();
295 
296  for( i = 0; i < 60; i++)
297  {
298  if( rand >= fProbMx[i][1] ) break;
299  }
300  if(i <= 0) Mx = fProbMx[0][0];
301  else if(i >= 59) Mx = fProbMx[59][0];
302  else Mx = fProbMx[i][0];
303 
304  fPDGencoding = 0;
305 
306  if ( Mx <= 1.45 )
307  {
308  if( aParticle->GetDefinition() == G4Proton::Proton() )
309  {
310  Mx = 1.44;
311  // fPDGencoding = 12212;
312  fPDGencoding = 2214;
313  }
314  else if( aParticle->GetDefinition() == G4Neutron::Neutron() )
315  {
316  Mx = 1.44;
317  fPDGencoding = 12112;
318  }
319  else if( aParticle->GetDefinition() == G4PionPlus::PionPlus() )
320  {
321  // Mx = 1.3;
322  // fPDGencoding = 100211;
323  Mx = 1.26;
324  fPDGencoding = 20213; // a1(1260)+
325  }
326  else if( aParticle->GetDefinition() == G4PionMinus::PionMinus() )
327  {
328  // Mx = 1.3;
329  // fPDGencoding = -100211;
330  Mx = 1.26;
331  fPDGencoding = -20213; // a1(1260)-
332  }
333  else if( aParticle->GetDefinition() == G4KaonPlus::KaonPlus() )
334  {
335  Mx = 1.27;
336  fPDGencoding = 10323;
337  }
338  else if( aParticle->GetDefinition() == G4KaonMinus::KaonMinus() )
339  {
340  Mx = 1.27;
341  fPDGencoding = -10323;
342  }
343  }
344  else if ( Mx <= 1.55 )
345  {
346  if( aParticle->GetDefinition() == G4Proton::Proton() )
347  {
348  Mx = 1.52;
349  // fPDGencoding = 2124;
350  fPDGencoding = 2214;
351  }
352  else if( aParticle->GetDefinition() == G4Neutron::Neutron() )
353  {
354  Mx = 1.52;
355  fPDGencoding = 1214;
356  }
357  else if( aParticle->GetDefinition() == G4PionPlus::PionPlus() )
358  {
359  // Mx = 1.45;
360  // fPDGencoding = 10211;
361  Mx = 1.32;
362  fPDGencoding = 215; // a2(1320)+
363  }
364  else if( aParticle->GetDefinition() == G4PionMinus::PionMinus() )
365  {
366  // Mx = 1.45;
367  // fPDGencoding = -10211;
368  Mx = 1.32;
369  fPDGencoding = -215; // a2(1320)-
370  }
371  else if( aParticle->GetDefinition() == G4KaonPlus::KaonPlus() )
372  {
373  Mx = 1.46;
374  fPDGencoding = 100321;
375  }
376  else if( aParticle->GetDefinition() == G4KaonMinus::KaonMinus() )
377  {
378  Mx = 1.46;
379  fPDGencoding = -100321;
380  }
381  }
382  else
383  {
384  if( aParticle->GetDefinition() == G4Proton::Proton() )
385  {
386  Mx = 1.68;
387  // fPDGencoding = 12216;
388  fPDGencoding = 2214;
389  }
390  else if( aParticle->GetDefinition() == G4Neutron::Neutron() )
391  {
392  Mx = 1.68;
393  fPDGencoding = 12116;
394  }
395  else if( aParticle->GetDefinition() == G4PionPlus::PionPlus() )
396  {
397  Mx = 1.67;
398  fPDGencoding = 10215; // pi2(1670)+
399  // Mx = 1.45;
400  // fPDGencoding = 10211;
401  }
402  else if( aParticle->GetDefinition() == G4PionMinus::PionMinus() )
403  {
404  Mx = 1.67; // f0 problems->4pi vmg 20.11.14
405  fPDGencoding = -10215; // pi2(1670)-
406  // Mx = 1.45;
407  // fPDGencoding = -10211;
408  }
409  else if( aParticle->GetDefinition() == G4KaonPlus::KaonPlus() )
410  {
411  Mx = 1.68;
412  fPDGencoding = 30323;
413  }
414  else if( aParticle->GetDefinition() == G4KaonMinus::KaonMinus() )
415  {
416  Mx = 1.68;
417  fPDGencoding = -30323;
418  }
419  }
420  if(fPDGencoding == 0)
421  {
422  Mx = 1.44;
423  // fPDGencoding = 12212;
424  fPDGencoding = 2214;
425  }
426  G4ParticleDefinition* myResonance =
428 
429  if ( myResonance ) Mx = myResonance->GetPDGMass();
430 
431  // G4cout<<"PDG-ID = "<<fPDGencoding<<"; with mass = "<<Mx/CLHEP::GeV<<" GeV"<<G4endl;
432 
433  return Mx/CLHEP::GeV;
434 }
435 
437 //
438 // Sample t with kinematic limitations of Mx and Tkin
439 
441 G4double Mx)
442 {
443  G4double t=0., b=0., rTkin = 50.*CLHEP::GeV, eTkin = aParticle->GetKineticEnergy();
444  G4int i;
445 
446  for( i = 0; i < 23; ++i)
447  {
448  if( Mx <= fMxBdata[i][0] ) break;
449  }
450  if( i <= 0 ) b = fMxBdata[0][1];
451  else if( i >= 22 ) b = fMxBdata[22][1];
452  else b = fMxBdata[i][1];
453 
454  if( eTkin > rTkin ) b *= 1. + G4Log(eTkin/rTkin);
455 
456  G4double rand = G4UniformRand();
457 
458  t = -G4Log(rand)/b;
459 
460  t *= (CLHEP::GeV*CLHEP::GeV); // in G4 internal units
461 
462  return t;
463 }
464 
465 
467 //
468 // Integral spectrum of Mx (GeV)
469 
470 const G4double G4LMsdGenerator::fProbMx[60][2] =
471 {
472  {1.000000e+00, 1.000000e+00},
473  {1.025000e+00, 1.000000e+00},
474  {1.050000e+00, 1.000000e+00},
475  {1.075000e+00, 1.000000e+00},
476  {1.100000e+00, 9.975067e-01},
477  {1.125000e+00, 9.934020e-01},
478  {1.150000e+00, 9.878333e-01},
479  {1.175000e+00, 9.805002e-01},
480  {1.200000e+00, 9.716846e-01},
481  {1.225000e+00, 9.604761e-01},
482  {1.250000e+00, 9.452960e-01},
483  {1.275000e+00, 9.265278e-01},
484  {1.300000e+00, 9.053632e-01},
485  {1.325000e+00, 8.775566e-01},
486  {1.350000e+00, 8.441969e-01},
487  {1.375000e+00, 8.076336e-01},
488  {1.400000e+00, 7.682520e-01},
489  {1.425000e+00, 7.238306e-01},
490  {1.450000e+00, 6.769306e-01},
491  {1.475000e+00, 6.303898e-01},
492  {1.500000e+00, 5.824632e-01},
493  {1.525000e+00, 5.340696e-01},
494  {1.550000e+00, 4.873736e-01},
495  {1.575000e+00, 4.422901e-01},
496  {1.600000e+00, 3.988443e-01},
497  {1.625000e+00, 3.583727e-01},
498  {1.650000e+00, 3.205405e-01},
499  {1.675000e+00, 2.856655e-01},
500  {1.700000e+00, 2.537508e-01},
501  {1.725000e+00, 2.247863e-01},
502  {1.750000e+00, 1.985798e-01},
503  {1.775000e+00, 1.750252e-01},
504  {1.800000e+00, 1.539777e-01},
505  {1.825000e+00, 1.352741e-01},
506  {1.850000e+00, 1.187157e-01},
507  {1.875000e+00, 1.040918e-01},
508  {1.900000e+00, 9.118422e-02},
509  {1.925000e+00, 7.980909e-02},
510  {1.950000e+00, 6.979378e-02},
511  {1.975000e+00, 6.097771e-02},
512  {2.000000e+00, 5.322122e-02},
513  {2.025000e+00, 4.639628e-02},
514  {2.050000e+00, 4.039012e-02},
515  {2.075000e+00, 3.510275e-02},
516  {2.100000e+00, 3.044533e-02},
517  {2.125000e+00, 2.633929e-02},
518  {2.150000e+00, 2.271542e-02},
519  {2.175000e+00, 1.951295e-02},
520  {2.200000e+00, 1.667873e-02},
521  {2.225000e+00, 1.416633e-02},
522  {2.250000e+00, 1.193533e-02},
523  {2.275000e+00, 9.950570e-03},
524  {2.300000e+00, 8.181515e-03},
525  {2.325000e+00, 6.601664e-03},
526  {2.350000e+00, 5.188025e-03},
527  {2.375000e+00, 3.920655e-03},
528  {2.400000e+00, 2.782246e-03},
529  {2.425000e+00, 1.757765e-03},
530  {2.450000e+00, 8.341435e-04},
531  {2.475000e+00, 0.000000e+00}
532 };
533 
535 //
536 // Slope b (1/GeV/GeV) vs Mx (GeV) for t-sampling over exp(-b*t)
537 
538 const G4double G4LMsdGenerator::fMxBdata[23][2] =
539 {
540  {1.09014, 17.8620},
541  {1.12590, 19.2831},
542  {1.18549, 17.6907},
543  {1.21693, 16.4760},
544  {1.25194, 15.3867},
545  {1.26932, 14.4236},
546  {1.29019, 13.2931},
547  {1.30755, 12.2882},
548  {1.31790, 11.4509},
549  {1.33888, 10.6969},
550  {1.34911, 9.44130},
551  {1.37711, 8.56148},
552  {1.39101, 7.76593},
553  {1.42608, 6.88582},
554  {1.48593, 6.13019},
555  {1.53179, 5.87723},
556  {1.58111, 5.37308},
557  {1.64105, 4.95217},
558  {1.69037, 4.44803},
559  {1.81742, 3.89879},
560  {1.88096, 3.68693},
561  {1.95509, 3.43278},
562  {2.02219, 3.30445}
563 };
564 
565 
566 
567 //
568 //