ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4INCLParticle.hh
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4INCLParticle.hh
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 // INCL++ intra-nuclear cascade model
27 // Alain Boudard, CEA-Saclay, France
28 // Joseph Cugnon, University of Liege, Belgium
29 // Jean-Christophe David, CEA-Saclay, France
30 // Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
31 // Sylvie Leray, CEA-Saclay, France
32 // Davide Mancusi, CEA-Saclay, France
33 //
34 #define INCLXX_IN_GEANT4_MODE 1
35 
36 #include "globals.hh"
37 
38 /*
39  * G4INCLParticle.hh
40  *
41  * \date Jun 5, 2009
42  * \author Pekka Kaitaniemi
43  */
44 
45 #ifndef PARTICLE_HH_
46 #define PARTICLE_HH_
47 
48 #include "G4INCLThreeVector.hh"
49 #include "G4INCLParticleTable.hh"
50 #include "G4INCLParticleType.hh"
51 #include "G4INCLParticleSpecies.hh"
52 #include "G4INCLLogger.hh"
53 #include "G4INCLUnorderedVector.hh"
54 #include "G4INCLAllocationPool.hh"
55 #include <sstream>
56 #include <string>
57 
58 namespace G4INCL {
59 
60  class Particle;
61 
62  class ParticleList : public UnorderedVector<Particle*> {
63  public:
64  void rotatePositionAndMomentum(const G4double angle, const ThreeVector &axis) const;
65  void rotatePosition(const G4double angle, const ThreeVector &axis) const;
66  void rotateMomentum(const G4double angle, const ThreeVector &axis) const;
67  void boost(const ThreeVector &b) const;
69  std::vector<G4int> getParticleListBiasVector() const;
70  };
71 
72  typedef ParticleList::const_iterator ParticleIter;
73  typedef ParticleList::iterator ParticleMutableIter;
74 
75  class Particle {
76  public:
77  Particle();
79  Particle(ParticleType t, ThreeVector const &momentum, ThreeVector const &position);
80  virtual ~Particle() {}
81 
86  Particle(const Particle &rhs) :
87  theZ(rhs.theZ),
88  theA(rhs.theA),
89  theS(rhs.theS),
91  theType(rhs.theType),
92  theEnergy(rhs.theEnergy),
98  nDecays(rhs.nDecays),
103  theNKaon(rhs.theNKaon),
106  outOfWell(rhs.outOfWell),
107  theMass(rhs.theMass)
108  {
109  if(rhs.thePropagationEnergy == &(rhs.theFrozenEnergy))
111  else
113  if(rhs.thePropagationMomentum == &(rhs.theFrozenMomentum))
115  else
117  // ID intentionally not copied
118  ID = nextID++;
119 
121  }
122 
123  protected:
125  void swap(Particle &rhs) {
126  std::swap(theZ, rhs.theZ);
127  std::swap(theA, rhs.theA);
128  std::swap(theS, rhs.theS);
130  std::swap(theType, rhs.theType);
131  if(rhs.thePropagationEnergy == &(rhs.theFrozenEnergy))
133  else
137  if(rhs.thePropagationMomentum == &(rhs.theFrozenMomentum))
139  else
145  std::swap(nDecays, rhs.nDecays);
147  // ID intentionally not swapped
148 
152 
153  std::swap(theMass, rhs.theMass);
156 
159 
160  }
161 
162  public:
163 
168  Particle &operator=(const Particle &rhs) {
169  Particle temporaryParticle(rhs);
170  swap(temporaryParticle);
171  return *this;
172  }
173 
179  return theType;
180  };
181 
184  return ParticleSpecies(theType);
185  };
186 
188  theType = t;
189  switch(theType)
190  {
191  case DeltaPlusPlus:
192  theA = 1;
193  theZ = 2;
194  theS = 0;
195  break;
196  case Proton:
197  case DeltaPlus:
198  theA = 1;
199  theZ = 1;
200  theS = 0;
201  break;
202  case Neutron:
203  case DeltaZero:
204  theA = 1;
205  theZ = 0;
206  theS = 0;
207  break;
208  case DeltaMinus:
209  theA = 1;
210  theZ = -1;
211  theS = 0;
212  break;
213  case PiPlus:
214  theA = 0;
215  theZ = 1;
216  theS = 0;
217  break;
218  case PiZero:
219  case Eta:
220  case Omega:
221  case EtaPrime:
222  case Photon:
223  theA = 0;
224  theZ = 0;
225  theS = 0;
226  break;
227  case PiMinus:
228  theA = 0;
229  theZ = -1;
230  theS = 0;
231  break;
232  case Lambda:
233  theA = 1;
234  theZ = 0;
235  theS = -1;
236  break;
237  case SigmaPlus:
238  theA = 1;
239  theZ = 1;
240  theS = -1;
241  break;
242  case SigmaZero:
243  theA = 1;
244  theZ = 0;
245  theS = -1;
246  break;
247  case SigmaMinus:
248  theA = 1;
249  theZ = -1;
250  theS = -1;
251  break;
252  case KPlus:
253  theA = 0;
254  theZ = 1;
255  theS = 1;
256  break;
257  case KZero:
258  theA = 0;
259  theZ = 0;
260  theS = 1;
261  break;
262  case KZeroBar:
263  theA = 0;
264  theZ = 0;
265  theS = -1;
266  break;
267  case KShort:
268  theA = 0;
269  theZ = 0;
270 // theS should not be defined
271  break;
272  case KLong:
273  theA = 0;
274  theZ = 0;
275 // theS should not be defined
276  break;
277  case KMinus:
278  theA = 0;
279  theZ = -1;
280  theS = -1;
281  break;
282  case Composite:
283  // INCL_ERROR("Trying to set particle type to Composite! Construct a Cluster object instead" << '\n');
284  theA = 0;
285  theZ = 0;
286  theS = 0;
287  break;
288  case UnknownParticle:
289  theA = 0;
290  theZ = 0;
291  theS = 0;
292  INCL_ERROR("Trying to set particle type to Unknown!" << '\n');
293  break;
294  }
295 
296  if( !isResonance() && t!=Composite )
297  setINCLMass();
298  }
299 
303  G4bool isNucleon() const {
305  return true;
306  else
307  return false;
308  };
309 
311  return theParticipantType;
312  }
313 
316  }
317 
320  }
321 
324  }
325 
328  }
329 
330  virtual void makeParticipant() {
332  }
333 
334  virtual void makeTargetSpectator() {
336  }
337 
338  virtual void makeProjectileSpectator() {
340  }
341 
343  G4bool isPion() const { return (theType == PiPlus || theType == PiZero || theType == PiMinus); }
344 
346  G4bool isEta() const { return (theType == Eta); }
347 
349  G4bool isOmega() const { return (theType == Omega); }
350 
352  G4bool isEtaPrime() const { return (theType == EtaPrime); }
353 
355  G4bool isPhoton() const { return (theType == Photon); }
356 
358  inline G4bool isResonance() const { return isDelta(); }
359 
361  inline G4bool isDelta() const {
362  return (theType==DeltaPlusPlus || theType==DeltaPlus ||
364 
366  G4bool isSigma() const { return (theType == SigmaPlus || theType == SigmaZero || theType == SigmaMinus); }
367 
369  G4bool isKaon() const { return (theType == KPlus || theType == KZero); }
370 
372  G4bool isAntiKaon() const { return (theType == KZeroBar || theType == KMinus); }
373 
375  G4bool isLambda() const { return (theType == Lambda); }
376 
378  G4bool isNucleonorLambda() const { return (isNucleon() || isLambda()); }
379 
381  G4bool isHyperon() const { return (isLambda() || isSigma()); }
382 
384  G4bool isMeson() const { return (isPion() || isKaon() || isAntiKaon() || isEta() || isEtaPrime() || isOmega()); }
385 
387  G4bool isBaryon() const { return (isNucleon() || isResonance() || isHyperon()); }
388 
390  G4bool isStrange() const { return (isKaon() || isAntiKaon() || isHyperon()); }
391 
393  G4int getA() const { return theA; }
394 
396  G4int getZ() const { return theZ; }
397 
399  G4int getS() const { return theS; }
400 
401  G4double getBeta() const {
402  const G4double P = theMomentum.mag();
403  return P/theEnergy;
404  }
405 
413  return theMomentum / theEnergy;
414  }
415 
422  void boost(const ThreeVector &aBoostVector) {
423  const G4double beta2 = aBoostVector.mag2();
424  const G4double gamma = 1.0 / std::sqrt(1.0 - beta2);
425  const G4double bp = theMomentum.dot(aBoostVector);
426  const G4double alpha = (gamma*gamma)/(1.0 + gamma);
427 
428  theMomentum = theMomentum + aBoostVector * (alpha * bp - gamma * theEnergy);
429  theEnergy = gamma * (theEnergy - bp);
430  }
431 
440  void lorentzContract(const ThreeVector &aBoostVector, const ThreeVector &refPos) {
441  const G4double beta2 = aBoostVector.mag2();
442  const G4double gamma = 1.0 / std::sqrt(1.0 - beta2);
443  const ThreeVector theRelativePosition = thePosition - refPos;
444  const ThreeVector transversePosition = theRelativePosition - aBoostVector * (theRelativePosition.dot(aBoostVector) / aBoostVector.mag2());
445  const ThreeVector longitudinalPosition = theRelativePosition - transversePosition;
446 
447  thePosition = refPos + transversePosition + longitudinalPosition / gamma;
448  }
449 
451  inline G4double getMass() const { return theMass; }
452 
454  inline G4double getINCLMass() const {
455  switch(theType) {
456  case Proton:
457  case Neutron:
458  case PiPlus:
459  case PiMinus:
460  case PiZero:
461  case Lambda:
462  case SigmaPlus:
463  case SigmaZero:
464  case SigmaMinus:
465  case KPlus:
466  case KZero:
467  case KZeroBar:
468  case KShort:
469  case KLong:
470  case KMinus:
471  case Eta:
472  case Omega:
473  case EtaPrime:
474  case Photon:
476  break;
477 
478  case DeltaPlusPlus:
479  case DeltaPlus:
480  case DeltaZero:
481  case DeltaMinus:
482  return theMass;
483  break;
484 
485  case Composite:
487  break;
488 
489  default:
490  INCL_ERROR("Particle::getINCLMass: Unknown particle type." << '\n');
491  return 0.0;
492  break;
493  }
494  }
495 
497  inline virtual G4double getTableMass() const {
498  switch(theType) {
499  case Proton:
500  case Neutron:
501  case PiPlus:
502  case PiMinus:
503  case PiZero:
504  case Lambda:
505  case SigmaPlus:
506  case SigmaZero:
507  case SigmaMinus:
508  case KPlus:
509  case KZero:
510  case KZeroBar:
511  case KShort:
512  case KLong:
513  case KMinus:
514  case Eta:
515  case Omega:
516  case EtaPrime:
517  case Photon:
519  break;
520 
521  case DeltaPlusPlus:
522  case DeltaPlus:
523  case DeltaZero:
524  case DeltaMinus:
525  return theMass;
526  break;
527 
528  case Composite:
530  break;
531 
532  default:
533  INCL_ERROR("Particle::getTableMass: Unknown particle type." << '\n');
534  return 0.0;
535  break;
536  }
537  }
538 
540  inline G4double getRealMass() const {
541  switch(theType) {
542  case Proton:
543  case Neutron:
544  case PiPlus:
545  case PiMinus:
546  case PiZero:
547  case Lambda:
548  case SigmaPlus:
549  case SigmaZero:
550  case SigmaMinus:
551  case KPlus:
552  case KZero:
553  case KZeroBar:
554  case KShort:
555  case KLong:
556  case KMinus:
557  case Eta:
558  case Omega:
559  case EtaPrime:
560  case Photon:
562  break;
563 
564  case DeltaPlusPlus:
565  case DeltaPlus:
566  case DeltaZero:
567  case DeltaMinus:
568  return theMass;
569  break;
570 
571  case Composite:
573  break;
574 
575  default:
576  INCL_ERROR("Particle::getRealMass: Unknown particle type." << '\n');
577  return 0.0;
578  break;
579  }
580  }
581 
584 
587 
590 
602  G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent) const {
603  const G4int SParent = 0;
604  const G4int ADaughter = AParent - theA;
605  const G4int ZDaughter = ZParent - theZ;
606  const G4int SDaughter = 0;
607 
608  // Note the minus sign here
609  G4double theQValue;
610  if(isCluster())
611  theQValue = -ParticleTable::getTableQValue(theA, theZ, theS, ADaughter, ZDaughter, SDaughter);
612  else {
613  const G4double massTableParent = ParticleTable::getTableMass(AParent,ZParent,SParent);
614  const G4double massTableDaughter = ParticleTable::getTableMass(ADaughter,ZDaughter,SDaughter);
615  const G4double massTableParticle = getTableMass();
616  theQValue = massTableParent - massTableDaughter - massTableParticle;
617  }
618 
619  const G4double massINCLParent = ParticleTable::getINCLMass(AParent,ZParent,SParent);
620  const G4double massINCLDaughter = ParticleTable::getINCLMass(ADaughter,ZDaughter,SDaughter);
621  const G4double massINCLParticle = getINCLMass();
622 
623  // The rhs corresponds to the INCL Q-value
624  return theQValue - (massINCLParent-massINCLDaughter-massINCLParticle);
625  }
626 
642  G4double getTransferQValueCorrection(const G4int AFrom, const G4int ZFrom, const G4int ATo, const G4int ZTo) const {
643  const G4int SFrom = 0;
644  const G4int STo = 0;
645  const G4int AFromDaughter = AFrom - theA;
646  const G4int ZFromDaughter = ZFrom - theZ;
647  const G4int SFromDaughter = 0;
648  const G4int AToDaughter = ATo + theA;
649  const G4int ZToDaughter = ZTo + theZ;
650  const G4int SToDaughter = 0;
651  const G4double theQValue = ParticleTable::getTableQValue(AToDaughter,ZToDaughter,SToDaughter,AFromDaughter,ZFromDaughter,SFromDaughter,AFrom,ZFrom,SFrom);
652 
653  const G4double massINCLTo = ParticleTable::getINCLMass(ATo,ZTo,STo);
654  const G4double massINCLToDaughter = ParticleTable::getINCLMass(AToDaughter,ZToDaughter,SToDaughter);
655  /* Note that here we have to use the table mass in the INCL Q-value. We
656  * cannot use theMass, because at this stage the particle is probably
657  * still off-shell; and we cannot use getINCLMass(), because it leads to
658  * violations of global energy conservation.
659  */
660  const G4double massINCLParticle = getTableMass();
661 
662  // The rhs corresponds to the INCL Q-value for particle absorption
663  return theQValue - (massINCLToDaughter-massINCLTo-massINCLParticle);
664  }
665 
678  G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent, const G4int SParent) const {
679  const G4int ADaughter = AParent - theA;
680  const G4int ZDaughter = ZParent - theZ;
681  const G4int SDaughter = SParent - theS;
682 
683  // Note the minus sign here
684  G4double theQValue;
685  if(isCluster())
686  theQValue = -ParticleTable::getTableQValue(theA, theZ, theS, ADaughter, ZDaughter, SDaughter);
687  else {
688  const G4double massTableParent = ParticleTable::getTableMass(AParent,ZParent,SParent);
689  const G4double massTableDaughter = ParticleTable::getTableMass(ADaughter,ZDaughter,SDaughter);
690  const G4double massTableParticle = getTableMass();
691  theQValue = massTableParent - massTableDaughter - massTableParticle;
692  }
693 
694  const G4double massINCLParent = ParticleTable::getINCLMass(AParent,ZParent,SParent);
695  const G4double massINCLDaughter = ParticleTable::getINCLMass(ADaughter,ZDaughter,SDaughter);
696  const G4double massINCLParticle = getINCLMass();
697 
698  // The rhs corresponds to the INCL Q-value
699  return theQValue - (massINCLParent-massINCLDaughter-massINCLParticle);
700  }
701 
719  G4double getTransferQValueCorrection(const G4int AFrom, const G4int ZFrom, const G4int SFrom, const G4int ATo, const G4int ZTo , const G4int STo) const {
720  const G4int AFromDaughter = AFrom - theA;
721  const G4int ZFromDaughter = ZFrom - theZ;
722  const G4int SFromDaughter = SFrom - theS;
723  const G4int AToDaughter = ATo + theA;
724  const G4int ZToDaughter = ZTo + theZ;
725  const G4int SToDaughter = STo + theS;
726  const G4double theQValue = ParticleTable::getTableQValue(AToDaughter,ZToDaughter,SFromDaughter,AFromDaughter,ZFromDaughter,SToDaughter,AFrom,ZFrom,SFrom);
727 
728  const G4double massINCLTo = ParticleTable::getINCLMass(ATo,ZTo,STo);
729  const G4double massINCLToDaughter = ParticleTable::getINCLMass(AToDaughter,ZToDaughter,SToDaughter);
730  /* Note that here we have to use the table mass in the INCL Q-value. We
731  * cannot use theMass, because at this stage the particle is probably
732  * still off-shell; and we cannot use getINCLMass(), because it leads to
733  * violations of global energy conservation.
734  */
735  const G4double massINCLParticle = getTableMass();
736 
737  // The rhs corresponds to the INCL Q-value for particle absorption
738  return theQValue - (massINCLToDaughter-massINCLTo-massINCLParticle);
739  }
740 
741 
742 
749  const G4double mass = std::pow(theEnergy, 2) - theMomentum.dot(theMomentum);
750  if(mass < 0.0) {
751  INCL_ERROR("E*E - p*p is negative." << '\n');
752  return 0.0;
753  } else {
754  return std::sqrt(mass);
755  }
756  };
757 
759  inline G4double getKineticEnergy() const { return theEnergy - theMass; }
760 
762  inline G4double getPotentialEnergy() const { return thePotentialEnergy; }
763 
766 
771  {
772  return theEnergy;
773  };
774 
779  {
780  this->theMass = mass;
781  }
782 
786  void setEnergy(G4double energy)
787  {
788  this->theEnergy = energy;
789  };
790 
795  {
796  return theMomentum;
797  };
798 
801  {
803  };
804 
808  virtual void setMomentum(const G4INCL::ThreeVector &momentum)
809  {
810  this->theMomentum = momentum;
811  };
812 
817  {
818  return thePosition;
819  };
820 
821  virtual void setPosition(const G4INCL::ThreeVector &position)
822  {
823  this->thePosition = position;
824  };
825 
828 
830  thePosition += ((*thePropagationMomentum)*(step/(*thePropagationEnergy)));
831  };
832 
835 
838 
841 
843  G4int getNumberOfDecays() const { return nDecays; }
844 
847 
850 
859  void setOutOfWell() { outOfWell = true; }
860 
862  G4bool isOutOfWell() const { return outOfWell; }
863 
866 
870  }
871 
875  }
876 
879 
882 
883  G4bool isCluster() const {
884  return (theType == Composite);
885  }
886 
889 
891  void setFrozenEnergy(const G4double energy) { theFrozenEnergy = energy; }
892 
895 
898 
900  ThreeVector getPropagationVelocity() const { return (*thePropagationMomentum)/(*thePropagationEnergy); }
901 
911  }
912 
922  }
923 
929  virtual void rotatePositionAndMomentum(const G4double angle, const ThreeVector &axis) {
930  rotatePosition(angle, axis);
931  rotateMomentum(angle, axis);
932  }
933 
939  virtual void rotatePosition(const G4double angle, const ThreeVector &axis) {
940  thePosition.rotate(angle, axis);
941  }
942 
948  virtual void rotateMomentum(const G4double angle, const ThreeVector &axis) {
949  theMomentum.rotate(angle, axis);
950  theFrozenMomentum.rotate(angle, axis);
951  }
952 
953  std::string print() const {
954  std::stringstream ss;
955  ss << "Particle (ID = " << ID << ") type = ";
957  ss << '\n'
958  << " energy = " << theEnergy << '\n'
959  << " momentum = "
960  << theMomentum.print()
961  << '\n'
962  << " position = "
963  << thePosition.print()
964  << '\n';
965  return ss.str();
966  };
967 
968  std::string dump() const {
969  std::stringstream ss;
970  ss << "(particle " << ID << " ";
972  ss << '\n'
973  << thePosition.dump()
974  << '\n'
975  << theMomentum.dump()
976  << '\n'
977  << theEnergy << ")" << '\n';
978  return ss.str();
979  };
980 
981  long getID() const { return ID; };
982 
986  ParticleList const *getParticles() const {
987  INCL_WARN("Particle::getParticles() method was called on a Particle object" << '\n');
988  return 0;
989  }
990 
998  if(rpCorrelated)
999  return theMomentum.mag();
1000  else
1001  return uncorrelatedMomentum;
1002  }
1003 
1006 
1008  void rpCorrelate() { rpCorrelated = true; }
1009 
1011  void rpDecorrelate() { rpCorrelated = false; }
1012 
1016  if(norm>0.)
1017  return thePosition.dot(*thePropagationMomentum) / std::sqrt(norm);
1018  else
1019  return 1.;
1020  }
1021 
1023  static G4double getTotalBias();
1024  static void setINCLBiasVector(std::vector<G4double> NewVector);
1025  static void FillINCLBiasVector(G4double newBias);
1026  static G4double getBiasFromVector(std::vector<G4int> VectorBias);
1027 
1028  static std::vector<G4int> MergeVectorBias(Particle const * const p1, Particle const * const p2);
1029  static std::vector<G4int> MergeVectorBias(std::vector<G4int> p1, Particle const * const p2);
1030 
1033 
1035  void setParticleBias(G4double ParticleBias) { this->theParticleBias = ParticleBias; }
1036 
1038  std::vector<G4int> getBiasCollisionVector() const { return theBiasCollisionVector; }
1039 
1041  void setBiasCollisionVector(std::vector<G4int> BiasCollisionVector) {
1042  this->theBiasCollisionVector = BiasCollisionVector;
1043  this->setParticleBias(Particle::getBiasFromVector(BiasCollisionVector));
1044  }
1045 
1053  G4int getNumberOfKaon() const { return theNKaon; };
1054  void setNumberOfKaon(const G4int NK) { theNKaon = NK; }
1055 
1056  public:
1070 #ifdef INCLXX_IN_GEANT4_MODE
1071  static std::vector<G4double> INCLBiasVector;
1072  //static G4VectorCache<G4double> INCLBiasVector;
1073 #else
1074  static G4ThreadLocal std::vector<G4double> INCLBiasVector;
1075  //static G4VectorCache<G4double> INCLBiasVector;
1076 #endif
1078 
1079  protected:
1093  long ID;
1094 
1097 
1101 
1102  private:
1106 
1108  std::vector<G4int> theBiasCollisionVector;
1109 
1111  static G4ThreadLocal long nextID;
1112 
1114  };
1115 }
1116 
1117 #endif /* PARTICLE_HH_ */