Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/inclxx/utils/include/G4INCLParticle.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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;
 68       G4double getParticleListBias() 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();
 78     Particle(ParticleType t, G4double energy, ThreeVector const &momentum, ThreeVector const &position);
 79     Particle(ParticleType t, ThreeVector const &momentum, ThreeVector const &position);
 80     virtual ~Particle() {}
 81 
 82     /** \brief Copy constructor
 83      *
 84      * Does not copy the particle ID.
 85      */
 86     Particle(const Particle &rhs) :
 87       theZ(rhs.theZ),
 88       theA(rhs.theA),
 89       theS(rhs.theS),
 90       theParticipantType(rhs.theParticipantType),
 91       theType(rhs.theType),
 92       theEnergy(rhs.theEnergy),
 93       theFrozenEnergy(rhs.theFrozenEnergy),
 94       theMomentum(rhs.theMomentum),
 95       theFrozenMomentum(rhs.theFrozenMomentum),
 96       thePosition(rhs.thePosition),
 97       nCollisions(rhs.nCollisions),
 98       nDecays(rhs.nDecays),
 99       thePotentialEnergy(rhs.thePotentialEnergy),
100       rpCorrelated(rhs.rpCorrelated),
101       uncorrelatedMomentum(rhs.uncorrelatedMomentum),
102       theParticleBias(rhs.theParticleBias),
103       theNKaon(rhs.theNKaon),
104 #ifdef INCLXX_IN_GEANT4_MODE
105       theParentResonancePDGCode(rhs.theParentResonancePDGCode),
106       theParentResonanceID(rhs.theParentResonanceID),
107 #endif
108       theHelicity(rhs.theHelicity),
109       emissionTime(rhs.emissionTime),
110       outOfWell(rhs.outOfWell),
111       theMass(rhs.theMass)
112       {
113         if(rhs.thePropagationEnergy == &(rhs.theFrozenEnergy))
114           thePropagationEnergy = &theFrozenEnergy;
115         else
116           thePropagationEnergy = &theEnergy;
117         if(rhs.thePropagationMomentum == &(rhs.theFrozenMomentum))
118           thePropagationMomentum = &theFrozenMomentum;
119         else
120           thePropagationMomentum = &theMomentum;
121         // ID intentionally not copied
122         ID = nextID++;
123         
124         theBiasCollisionVector = rhs.theBiasCollisionVector;
125       }
126 
127   protected:
128     /// \brief Helper method for the assignment operator
129     void swap(Particle &rhs) {
130       std::swap(theZ, rhs.theZ);
131       std::swap(theA, rhs.theA);
132       std::swap(theS, rhs.theS);
133       std::swap(theParticipantType, rhs.theParticipantType);
134       std::swap(theType, rhs.theType);
135       if(rhs.thePropagationEnergy == &(rhs.theFrozenEnergy))
136         thePropagationEnergy = &theFrozenEnergy;
137       else
138         thePropagationEnergy = &theEnergy;
139       std::swap(theEnergy, rhs.theEnergy);
140       std::swap(theFrozenEnergy, rhs.theFrozenEnergy);
141       if(rhs.thePropagationMomentum == &(rhs.theFrozenMomentum))
142         thePropagationMomentum = &theFrozenMomentum;
143       else
144         thePropagationMomentum = &theMomentum;
145       std::swap(theMomentum, rhs.theMomentum);
146       std::swap(theFrozenMomentum, rhs.theFrozenMomentum);
147       std::swap(thePosition, rhs.thePosition);
148       std::swap(nCollisions, rhs.nCollisions);
149       std::swap(nDecays, rhs.nDecays);
150       std::swap(thePotentialEnergy, rhs.thePotentialEnergy);
151       // ID intentionally not swapped
152 
153 #ifdef INCLXX_IN_GEANT4_MODE
154       std::swap(theParentResonancePDGCode, rhs.theParentResonancePDGCode);
155       std::swap(theParentResonanceID, rhs.theParentResonanceID);
156 #endif
157 
158       std::swap(theHelicity, rhs.theHelicity);
159       std::swap(emissionTime, rhs.emissionTime);
160       std::swap(outOfWell, rhs.outOfWell);
161 
162       std::swap(theMass, rhs.theMass);
163       std::swap(rpCorrelated, rhs.rpCorrelated);
164       std::swap(uncorrelatedMomentum, rhs.uncorrelatedMomentum);
165       
166       std::swap(theParticleBias, rhs.theParticleBias);
167       std::swap(theBiasCollisionVector, rhs.theBiasCollisionVector);
168 
169     }
170 
171   public:
172 
173     /** \brief Assignment operator
174      *
175      * Does not copy the particle ID.
176      */
177     Particle &operator=(const Particle &rhs) {
178       Particle temporaryParticle(rhs);
179       swap(temporaryParticle);
180       return *this;
181     }
182 
183     /**
184      * Get the particle type.
185      * @see G4INCL::ParticleType
186      */
187     G4INCL::ParticleType getType() const {
188       return theType;
189     };
190 
191     /// \brief Get the particle species
192     virtual G4INCL::ParticleSpecies getSpecies() const {
193       return ParticleSpecies(theType);
194     };
195 
196     void setType(ParticleType t) {
197       theType = t;
198       switch(theType)
199       {
200         case DeltaPlusPlus:
201           theA = 1;
202           theZ = 2;
203           theS = 0;
204           break;
205         case Proton:
206         case DeltaPlus:
207           theA = 1;
208           theZ = 1;
209           theS = 0;
210           break;
211         case Neutron:
212         case DeltaZero:
213           theA = 1;
214           theZ = 0;
215           theS = 0;
216           break;
217         case DeltaMinus:
218           theA = 1;
219           theZ = -1;
220           theS = 0;
221           break;
222         case PiPlus:
223           theA = 0;
224           theZ = 1;
225           theS = 0;
226           break;
227         case PiZero:
228         case Eta:
229         case Omega:
230         case EtaPrime:
231         case Photon:
232           theA = 0;
233           theZ = 0;
234           theS = 0;
235           break;
236         case PiMinus:
237           theA = 0;
238           theZ = -1;
239           theS = 0;
240           break;
241         case Lambda:
242           theA = 1;
243           theZ = 0;
244           theS = -1;
245           break;
246         case SigmaPlus:
247           theA = 1;
248           theZ = 1;
249           theS = -1;
250           break;
251         case SigmaZero:
252           theA = 1;
253           theZ = 0;
254           theS = -1;
255           break;
256         case SigmaMinus:
257           theA = 1;
258           theZ = -1;
259           theS = -1;
260           break;         
261         case antiProton:
262           theA = -1;
263           theZ = -1;
264           theS = 0;
265           break;         
266         case XiMinus:
267           theA = 1;
268           theZ = -1;
269           theS = -2;
270           break;
271         case XiZero:
272           theA = 1;
273           theZ = 0;
274           theS = -2;
275           break;      
276         case antiNeutron:
277           theA = -1;
278           theZ = 0;
279           theS = 0;
280           break;
281         case antiLambda:
282           theA = -1;
283           theZ = 0;
284           theS = 1;
285           break;
286         case antiSigmaMinus:
287           theA = -1;
288           theZ = 1;
289           theS = 1;
290           break;
291         case antiSigmaPlus:
292           theA = -1;
293           theZ = -1;
294           theS = 1;
295           break;
296         case antiSigmaZero:
297           theA = -1;
298           theZ = 0;
299           theS = 1;
300           break;
301         case antiXiMinus:
302           theA = -1;
303           theZ = 1;
304           theS = 2;
305           break;
306         case antiXiZero:
307           theA = -1;
308           theZ = 0;
309           theS = 2;
310           break;         
311         case KPlus:
312           theA = 0;
313           theZ = 1;
314           theS = 1;
315           break;
316         case KZero:
317           theA = 0;
318           theZ = 0;
319           theS = 1;
320           break;
321         case KZeroBar:
322           theA = 0;
323           theZ = 0;
324           theS = -1;
325           break;
326         case KShort:
327           theA = 0;
328           theZ = 0;
329 //        theS should not be defined
330           break;
331         case KLong:
332           theA = 0;
333           theZ = 0;
334 //        theS should not be defined
335           break;
336         case KMinus:
337           theA = 0;
338           theZ = -1;
339           theS = -1;
340           break;
341         case Composite:
342          // INCL_ERROR("Trying to set particle type to Composite! Construct a Cluster object instead" << '\n');
343           theA = 0;
344           theZ = 0;
345           theS = 0;
346           break;       
347         case UnknownParticle:
348           theA = 0;
349           theZ = 0;
350           theS = 0;
351           INCL_ERROR("Trying to set particle type to Unknown!" << '\n');
352           break;
353       }
354 
355       if( !isResonance() && t!=Composite )
356         setINCLMass();
357     }
358 
359     /**
360      * Is this a nucleon?
361      */
362     G4bool isNucleon() const {
363       if(theType == G4INCL::Proton || theType == G4INCL::Neutron)
364     return true;
365       else
366     return false;
367     };
368 
369     ParticipantType getParticipantType() const {
370       return theParticipantType;
371     }
372 
373     void setParticipantType(ParticipantType const p) {
374       theParticipantType = p;
375     }
376 
377     G4bool isParticipant() const {
378       return (theParticipantType==Participant);
379     }
380 
381     G4bool isTargetSpectator() const {
382       return (theParticipantType==TargetSpectator);
383     }
384 
385     G4bool isProjectileSpectator() const {
386       return (theParticipantType==ProjectileSpectator);
387     }
388 
389     virtual void makeParticipant() {
390       theParticipantType = Participant;
391     }
392 
393     virtual void makeTargetSpectator() {
394       theParticipantType = TargetSpectator;
395     }
396 
397     virtual void makeProjectileSpectator() {
398       theParticipantType = ProjectileSpectator;
399     }
400 
401     /** \brief Is this a pion? */
402     G4bool isPion() const { return (theType == PiPlus || theType == PiZero || theType == PiMinus); }
403 
404     /** \brief Is this an eta? */
405     G4bool isEta() const { return (theType == Eta); }
406 
407     /** \brief Is this an omega? */
408     G4bool isOmega() const { return (theType == Omega); }
409 
410     /** \brief Is this an etaprime? */
411     G4bool isEtaPrime() const { return (theType == EtaPrime); }
412 
413     /** \brief Is this a photon? */
414     G4bool isPhoton() const { return (theType == Photon); }
415 
416     /** \brief Is it a resonance? */
417     inline G4bool isResonance() const { return isDelta(); }
418 
419     /** \brief Is it a Delta? */
420     inline G4bool isDelta() const {
421       return (theType==DeltaPlusPlus || theType==DeltaPlus ||
422           theType==DeltaZero || theType==DeltaMinus); }
423     
424     /** \brief Is this a Sigma? */
425     G4bool isSigma() const { return (theType == SigmaPlus || theType == SigmaZero || theType == SigmaMinus); }     
426     
427     /** \brief Is this a Kaon? */
428     G4bool isKaon() const { return (theType == KPlus || theType == KZero); } 
429     
430     /** \brief Is this an antiKaon? */
431     G4bool isAntiKaon() const { return (theType == KZeroBar || theType == KMinus); }
432     
433     /** \brief Is this a Lambda? */
434     G4bool isLambda() const { return (theType == Lambda); }
435 
436     /** \brief Is this a Nucleon or a Lambda? */
437     G4bool isNucleonorLambda() const { return (isNucleon() || isLambda()); }
438     
439     /** \brief Is this an Hyperon? */
440     G4bool isHyperon() const { return (isLambda() || isSigma() ); } //|| isXi()
441     
442     /** \brief Is this a Meson? */
443     G4bool isMeson() const { return (isPion() || isKaon() || isAntiKaon() || isEta() || isEtaPrime() || isOmega()); }
444     
445     /** \brief Is this a Baryon? */
446     G4bool isBaryon() const { return (isNucleon() || isResonance() || isHyperon()); }
447     
448     /** \brief Is this a Strange? */
449     G4bool isStrange() const { return (isKaon() || isAntiKaon() || isHyperon()); }
450     
451     /** \brief Is this a Xi? */
452     G4bool isXi() const { return (theType == XiZero || theType == XiMinus); } 
453     
454     /** \brief Is this an antinucleon? */
455     G4bool isAntiNucleon() const { return (theType == antiProton || theType == antiNeutron); } 
456      
457     /** \brief Is this an antiSigma? */
458     G4bool isAntiSigma() const { return (theType == antiSigmaPlus || theType == antiSigmaZero || theType == antiSigmaMinus); }     
459     
460     /** \brief Is this an antiXi? */
461     G4bool isAntiXi() const { return (theType == antiXiZero || theType == antiXiMinus); } 
462     
463     /** \brief Is this an antiLambda? */
464     G4bool isAntiLambda() const { return (theType == antiLambda); }
465     
466     /** \brief Is this an antiHyperon? */
467     G4bool isAntiHyperon() const { return (isAntiLambda() || isAntiSigma() || isAntiXi()); }
468     
469     /** \brief Is this an antiBaryon? */
470     G4bool isAntiBaryon() const { return (isAntiNucleon() || isAntiHyperon()); }
471     
472     /** \brief Is this an antiNucleon or an antiLambda? */
473     G4bool isAntiNucleonorAntiLambda() const { return (isAntiNucleon() || isAntiLambda()); }
474 
475     /** \brief Returns the baryon number. */
476     G4int getA() const { return theA; }
477 
478     /** \brief Returns the charge number. */
479     G4int getZ() const { return theZ; }
480     
481     /** \brief Returns the strangeness number. */
482     G4int getS() const { return theS; }
483 
484     G4double getBeta() const {
485       const G4double P = theMomentum.mag();
486       return P/theEnergy;
487     }
488 
489     /**
490      * Returns a three vector we can give to the boost() -method.
491      *
492      * In order to go to the particle rest frame you need to multiply
493      * the boost vector by -1.0.
494      */
495     ThreeVector boostVector() const {
496       return theMomentum / theEnergy;
497     }
498 
499     /**
500      * Boost the particle using a boost vector.
501      *
502      * Example (go to the particle rest frame):
503      * particle->boost(particle->boostVector());
504      */
505     void boost(const ThreeVector &aBoostVector) {
506       const G4double beta2 = aBoostVector.mag2();
507       const G4double gamma = 1.0 / std::sqrt(1.0 - beta2);
508       const G4double bp = theMomentum.dot(aBoostVector);
509       const G4double alpha = (gamma*gamma)/(1.0 + gamma);
510 
511       theMomentum = theMomentum + aBoostVector * (alpha * bp - gamma * theEnergy);
512       theEnergy = gamma * (theEnergy - bp);
513     }
514 
515     /** \brief Lorentz-contract the particle position around some center
516      *
517      * Apply Lorentz contraction to the position component along the
518      * direction of the boost vector.
519      *
520      * \param aBoostVector the boost vector (velocity) [c]
521      * \param refPos the reference position
522      */
523     void lorentzContract(const ThreeVector &aBoostVector, const ThreeVector &refPos) {
524       const G4double beta2 = aBoostVector.mag2();
525       const G4double gamma = 1.0 / std::sqrt(1.0 - beta2);
526       const ThreeVector theRelativePosition = thePosition - refPos;
527       const ThreeVector transversePosition = theRelativePosition - aBoostVector * (theRelativePosition.dot(aBoostVector) / aBoostVector.mag2());
528       const ThreeVector longitudinalPosition = theRelativePosition - transversePosition;
529 
530       thePosition = refPos + transversePosition + longitudinalPosition / gamma;
531     }
532 
533     /** \brief Get the cached particle mass. */
534     inline G4double getMass() const { return theMass; }
535 
536     /** \brief Get the INCL particle mass. */
537     inline G4double getINCLMass() const {
538       switch(theType) {
539         case Proton:
540         case Neutron:
541         case PiPlus:
542         case PiMinus:
543         case PiZero:
544         case Lambda:
545         case SigmaPlus:
546         case SigmaZero:
547         case SigmaMinus:       
548         case antiProton: 
549         case XiZero:
550         case XiMinus:
551         case antiNeutron:
552         case antiLambda:
553         case antiSigmaPlus:
554         case antiSigmaZero:
555         case antiSigmaMinus:
556         case antiXiZero:
557         case antiXiMinus:     
558         case KPlus:
559         case KZero:
560         case KZeroBar:
561         case KShort:
562         case KLong:
563         case KMinus:
564         case Eta:
565         case Omega:
566         case EtaPrime:
567         case Photon:                       
568           return ParticleTable::getINCLMass(theType);
569           break;
570 
571         case DeltaPlusPlus:
572         case DeltaPlus:
573         case DeltaZero:
574         case DeltaMinus:
575           return theMass;
576           break;
577 
578         case Composite:
579           return ParticleTable::getINCLMass(theA,theZ,theS);
580           break;
581 
582         default:
583           INCL_ERROR("Particle::getINCLMass: Unknown particle type." << '\n');
584           return 0.0;
585           break;
586       }
587     }
588 
589     /** \brief Get the tabulated particle mass. */
590     inline virtual G4double getTableMass() const {
591       switch(theType) {
592         case Proton:
593         case Neutron:
594         case PiPlus:
595         case PiMinus:
596         case PiZero:
597         case Lambda:
598         case SigmaPlus:
599         case SigmaZero:
600         case SigmaMinus:       
601         case antiProton:      
602         case XiZero:
603         case XiMinus:  
604         case antiNeutron:
605         case antiLambda:
606         case antiSigmaPlus:
607         case antiSigmaZero:
608         case antiSigmaMinus:
609         case antiXiZero:
610         case antiXiMinus:  
611         case KPlus:
612         case KZero:
613         case KZeroBar:
614         case KShort:
615         case KLong:
616         case KMinus:
617         case Eta:
618         case Omega:
619         case EtaPrime:
620         case Photon:  
621           return ParticleTable::getTableParticleMass(theType);
622           break;
623 
624         case DeltaPlusPlus:
625         case DeltaPlus:
626         case DeltaZero:
627         case DeltaMinus:
628           return theMass;
629           break;
630 
631         case Composite:
632           return ParticleTable::getTableMass(theA,theZ,theS);
633           break;
634 
635         default:
636           INCL_ERROR("Particle::getTableMass: Unknown particle type." << '\n');
637           return 0.0;
638           break;
639       }
640     }
641 
642     /** \brief Get the real particle mass. */
643     inline G4double getRealMass() const {
644       switch(theType) {
645         case Proton:
646         case Neutron:
647         case PiPlus:
648         case PiMinus:
649         case PiZero:
650         case Lambda:
651         case SigmaPlus:
652         case SigmaZero:
653         case SigmaMinus:       
654         case antiProton: 
655         case XiZero:
656         case XiMinus: 
657         case antiNeutron:
658         case antiLambda:
659         case antiSigmaPlus:
660         case antiSigmaZero:
661         case antiSigmaMinus:
662         case antiXiZero:
663         case antiXiMinus:    
664         case KPlus:
665         case KZero:
666         case KZeroBar:
667         case KShort:
668         case KLong:
669         case KMinus:
670         case Eta:
671         case Omega:
672         case EtaPrime:
673         case Photon:    
674           return ParticleTable::getRealMass(theType);
675           break;
676 
677         case DeltaPlusPlus:
678         case DeltaPlus:
679         case DeltaZero:
680         case DeltaMinus:
681           return theMass;
682           break;
683 
684         case Composite:
685           return ParticleTable::getRealMass(theA,theZ,theS);
686           break;
687 
688         default:
689           INCL_ERROR("Particle::getRealMass: Unknown particle type." << '\n');
690           return 0.0;
691           break;
692       }
693     }
694 
695     /// \brief Set the mass of the Particle to its real mass
696     void setRealMass() { setMass(getRealMass()); }
697 
698     /// \brief Set the mass of the Particle to its table mass
699     void setTableMass() { setMass(getTableMass()); }
700 
701     /// \brief Set the mass of the Particle to its table mass
702     void setINCLMass() { setMass(getINCLMass()); }
703 
704     /**\brief Computes correction on the emission Q-value
705      *
706      * Computes the correction that must be applied to INCL particles in
707      * order to obtain the correct Q-value for particle emission from a given
708      * nucleus. For absorption, the correction is obviously equal to minus
709      * the value returned by this function.
710      *
711      * \param AParent the mass number of the emitting nucleus
712      * \param ZParent the charge number of the emitting nucleus
713      * \return the correction
714      */
715     G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent) const {
716       const G4int SParent = 0;
717       const G4int ADaughter = AParent - theA;
718       const G4int ZDaughter = ZParent - theZ;
719       const G4int SDaughter = 0;
720 
721       // Note the minus sign here
722       G4double theQValue;
723       if(isCluster())
724         theQValue = -ParticleTable::getTableQValue(theA, theZ, theS, ADaughter, ZDaughter, SDaughter);
725       else {
726         const G4double massTableParent = ParticleTable::getTableMass(AParent,ZParent,SParent);
727         const G4double massTableDaughter = ParticleTable::getTableMass(ADaughter,ZDaughter,SDaughter);
728         const G4double massTableParticle = getTableMass();
729         theQValue = massTableParent - massTableDaughter - massTableParticle;
730       }
731 
732       const G4double massINCLParent = ParticleTable::getINCLMass(AParent,ZParent,SParent);
733       const G4double massINCLDaughter = ParticleTable::getINCLMass(ADaughter,ZDaughter,SDaughter);
734       const G4double massINCLParticle = getINCLMass();
735 
736       // The rhs corresponds to the INCL Q-value
737       return theQValue - (massINCLParent-massINCLDaughter-massINCLParticle);
738     }
739 
740     G4double getEmissionPbarQvalueCorrection(const G4int AParent, const G4int ZParent, const G4bool Victim) const {
741       G4int SParent = 0;
742       G4int SDaughter = 0;
743       G4int ADaughter = AParent - 1;
744       G4int ZDaughter; 
745       G4bool isProton = Victim;
746       if(isProton){     //proton is annihilated
747         ZDaughter = ZParent - 1;
748       }
749       else {       //neutron is annihilated
750         ZDaughter = ZParent;
751       }
752       
753       G4double theQValue; //same procedure as for normal case
754       
755       const G4double massTableParent = ParticleTable::getTableMass(AParent,ZParent,SParent);
756       const G4double massTableDaughter = ParticleTable::getTableMass(ADaughter,ZDaughter,SDaughter);
757       const G4double massTableParticle = getTableMass();
758       theQValue = massTableParent - massTableDaughter - massTableParticle;
759       
760       const G4double massINCLParent = ParticleTable::getINCLMass(AParent,ZParent,SParent);
761       const G4double massINCLDaughter = ParticleTable::getINCLMass(ADaughter,ZDaughter,SDaughter);
762       const G4double massINCLParticle = getINCLMass();
763 
764       return theQValue - (massINCLParent-massINCLDaughter-massINCLParticle);
765     }
766 
767     /**\brief Computes correction on the transfer Q-value
768      *
769      * Computes the correction that must be applied to INCL particles in
770      * order to obtain the correct Q-value for particle transfer from a given
771      * nucleus to another.
772      *
773      * Assumes that the receving nucleus is INCL's target nucleus, with the
774      * INCL separation energy.
775      *
776      * \param AFrom the mass number of the donating nucleus
777      * \param ZFrom the charge number of the donating nucleus
778      * \param ATo the mass number of the receiving nucleus
779      * \param ZTo the charge number of the receiving nucleus
780      * \return the correction
781      */
782     G4double getTransferQValueCorrection(const G4int AFrom, const G4int ZFrom, const G4int ATo, const G4int ZTo) const {
783       const G4int SFrom = 0;
784       const G4int STo = 0;
785       const G4int AFromDaughter = AFrom - theA;
786       const G4int ZFromDaughter = ZFrom - theZ;
787       const G4int SFromDaughter = 0;
788       const G4int AToDaughter = ATo + theA;
789       const G4int ZToDaughter = ZTo + theZ;
790       const G4int SToDaughter = 0;
791       const G4double theQValue = ParticleTable::getTableQValue(AToDaughter,ZToDaughter,SToDaughter,AFromDaughter,ZFromDaughter,SFromDaughter,AFrom,ZFrom,SFrom);
792 
793       const G4double massINCLTo = ParticleTable::getINCLMass(ATo,ZTo,STo);
794       const G4double massINCLToDaughter = ParticleTable::getINCLMass(AToDaughter,ZToDaughter,SToDaughter);
795       /* Note that here we have to use the table mass in the INCL Q-value. We
796        * cannot use theMass, because at this stage the particle is probably
797        * still off-shell; and we cannot use getINCLMass(), because it leads to
798        * violations of global energy conservation.
799        */
800       const G4double massINCLParticle = getTableMass();
801 
802       // The rhs corresponds to the INCL Q-value for particle absorption
803       return theQValue - (massINCLToDaughter-massINCLTo-massINCLParticle);
804     }
805 
806     /**\brief Computes correction on the emission Q-value for hypernuclei
807      *
808      * Computes the correction that must be applied to INCL particles in
809      * order to obtain the correct Q-value for particle emission from a given
810      * nucleus. For absorption, the correction is obviously equal to minus
811      * the value returned by this function.
812      *
813      * \param AParent the mass number of the emitting nucleus
814      * \param ZParent the charge number of the emitting nucleus
815      * \param SParent the strangess number of the emitting nucleus
816      * \return the correction
817      */
818     G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent, const G4int SParent) const {
819       const G4int ADaughter = AParent - theA;
820       const G4int ZDaughter = ZParent - theZ;
821       const G4int SDaughter = SParent - theS;
822 
823       // Note the minus sign here
824       G4double theQValue;
825       if(isCluster())
826         theQValue = -ParticleTable::getTableQValue(theA, theZ, theS, ADaughter, ZDaughter, SDaughter);
827       else {
828         const G4double massTableParent = ParticleTable::getTableMass(AParent,ZParent,SParent);
829         const G4double massTableDaughter = ParticleTable::getTableMass(ADaughter,ZDaughter,SDaughter);
830         const G4double massTableParticle = getTableMass();
831         theQValue = massTableParent - massTableDaughter - massTableParticle;
832       }
833 
834       const G4double massINCLParent = ParticleTable::getINCLMass(AParent,ZParent,SParent);
835       const G4double massINCLDaughter = ParticleTable::getINCLMass(ADaughter,ZDaughter,SDaughter);
836       const G4double massINCLParticle = getINCLMass();
837 
838       // The rhs corresponds to the INCL Q-value
839       return theQValue - (massINCLParent-massINCLDaughter-massINCLParticle);
840     }
841 
842     /**\brief Computes correction on the transfer Q-value for hypernuclei
843      *
844      * Computes the correction that must be applied to INCL particles in
845      * order to obtain the correct Q-value for particle transfer from a given
846      * nucleus to another.
847      *
848      * Assumes that the receving nucleus is INCL's target nucleus, with the
849      * INCL separation energy.
850      *
851      * \param AFrom the mass number of the donating nucleus
852      * \param ZFrom the charge number of the donating nucleus
853      * \param SFrom the strangess number of the donating nucleus
854      * \param ATo the mass number of the receiving nucleus
855      * \param ZTo the charge number of the receiving nucleus
856      * \param STo the strangess number of the receiving nucleus
857      * \return the correction
858      */
859     G4double getTransferQValueCorrection(const G4int AFrom, const G4int ZFrom, const G4int SFrom, const G4int ATo, const G4int ZTo , const G4int STo) const {
860       const G4int AFromDaughter = AFrom - theA;
861       const G4int ZFromDaughter = ZFrom - theZ;
862       const G4int SFromDaughter = SFrom - theS;
863       const G4int AToDaughter = ATo + theA;
864       const G4int ZToDaughter = ZTo + theZ;
865       const G4int SToDaughter = STo + theS;
866       const G4double theQValue = ParticleTable::getTableQValue(AToDaughter,ZToDaughter,SFromDaughter,AFromDaughter,ZFromDaughter,SToDaughter,AFrom,ZFrom,SFrom);
867 
868       const G4double massINCLTo = ParticleTable::getINCLMass(ATo,ZTo,STo);
869       const G4double massINCLToDaughter = ParticleTable::getINCLMass(AToDaughter,ZToDaughter,SToDaughter);
870       /* Note that here we have to use the table mass in the INCL Q-value. We
871        * cannot use theMass, because at this stage the particle is probably
872        * still off-shell; and we cannot use getINCLMass(), because it leads to
873        * violations of global energy conservation.
874        */
875       const G4double massINCLParticle = getTableMass();
876 
877       // The rhs corresponds to the INCL Q-value for particle absorption
878       return theQValue - (massINCLToDaughter-massINCLTo-massINCLParticle);
879     }
880 
881 
882 
883     /** \brief Get the the particle invariant mass.
884      *
885      * Uses the relativistic invariant
886      * \f[ m = \sqrt{E^2 - {\vec p}^2}\f]
887      **/
888     G4double getInvariantMass() const {
889       const G4double mass = std::pow(theEnergy, 2) - theMomentum.dot(theMomentum);
890       if(mass < 0.0) {
891         INCL_ERROR("E*E - p*p is negative." << '\n');
892         return 0.0;
893       } else {
894         return std::sqrt(mass);
895       }
896     };
897 
898     /// \brief Get the particle kinetic energy.
899     inline G4double getKineticEnergy() const { return theEnergy - theMass; }
900 
901     /// \brief Get the particle potential energy.
902     inline G4double getPotentialEnergy() const { return thePotentialEnergy; }
903 
904     /// \brief Set the particle potential energy.
905     inline void setPotentialEnergy(G4double v) { thePotentialEnergy = v; }
906 
907     /**
908      * Get the energy of the particle in MeV.
909      */
910     G4double getEnergy() const
911     {
912       return theEnergy;
913     };
914 
915     /**
916      * Set the mass of the particle in MeV/c^2.
917      */
918     void setMass(G4double mass)
919     {
920       this->theMass = mass;
921     }
922 
923     /**
924      * Set the energy of the particle in MeV.
925      */
926     void setEnergy(G4double energy)
927     {
928       this->theEnergy = energy;
929     };
930 
931     /**
932      * Get the momentum vector.
933      */
934     const G4INCL::ThreeVector &getMomentum() const
935     {
936       return theMomentum;
937     };
938 
939     /** Get the angular momentum w.r.t. the origin */
940     virtual G4INCL::ThreeVector getAngularMomentum() const
941     {
942       return thePosition.vector(theMomentum);
943     };
944 
945     /**
946      * Set the momentum vector.
947      */
948     virtual void setMomentum(const G4INCL::ThreeVector &momentum)
949     {
950       this->theMomentum = momentum;
951     };
952 
953     /**
954      * Set the position vector.
955      */
956     const G4INCL::ThreeVector &getPosition() const
957     {
958       return thePosition;
959     };
960 
961     virtual void setPosition(const G4INCL::ThreeVector &position)
962     {
963       this->thePosition = position;
964     };
965 
966     G4double getHelicity() { return theHelicity; };
967     void setHelicity(G4double h) { theHelicity = h; };
968 
969     void propagate(G4double step) {
970       thePosition += ((*thePropagationMomentum)*(step/(*thePropagationEnergy)));
971     };
972 
973     /** \brief Return the number of collisions undergone by the particle. **/
974     G4int getNumberOfCollisions() const { return nCollisions; }
975 
976     /** \brief Set the number of collisions undergone by the particle. **/
977     void setNumberOfCollisions(G4int n) { nCollisions = n; }
978 
979     /** \brief Increment the number of collisions undergone by the particle. **/
980     void incrementNumberOfCollisions() { nCollisions++; }
981 
982     /** \brief Return the number of decays undergone by the particle. **/
983     G4int getNumberOfDecays() const { return nDecays; }
984 
985     /** \brief Set the number of decays undergone by the particle. **/
986     void setNumberOfDecays(G4int n) { nDecays = n; }
987 
988     /** \brief Increment the number of decays undergone by the particle. **/
989     void incrementNumberOfDecays() { nDecays++; }
990 
991     /** \brief Mark the particle as out of its potential well
992      *
993      * This flag is used to control pions created outside their potential well
994      * in delta decay. The pion potential checks it and returns zero if it is
995      * true (necessary in order to correctly enforce energy conservation). The
996      * Nucleus::applyFinalState() method uses it to determine whether new
997      * avatars should be generated for the particle.
998      */
999     void setOutOfWell() { outOfWell = true; }
1000 
1001     /// \brief Check if the particle is out of its potential well
1002     G4bool isOutOfWell() const { return outOfWell; }
1003 
1004     void setEmissionTime(G4double t) { emissionTime = t; }
1005     G4double getEmissionTime() { return emissionTime; };
1006 
1007     /** \brief Transverse component of the position w.r.t. the momentum. */
1008     ThreeVector getTransversePosition() const {
1009       return thePosition - getLongitudinalPosition();
1010     }
1011 
1012     /** \brief Longitudinal component of the position w.r.t. the momentum. */
1013     ThreeVector getLongitudinalPosition() const {
1014       return *thePropagationMomentum * (thePosition.dot(*thePropagationMomentum)/thePropagationMomentum->mag2());
1015     }
1016 
1017     /** \brief Rescale the momentum to match the total energy. */
1018     const ThreeVector &adjustMomentumFromEnergy();
1019 
1020     /** \brief Recompute the energy to match the momentum. */
1021     G4double adjustEnergyFromMomentum();
1022 
1023     G4bool isCluster() const {
1024       return (theType == Composite);
1025     }
1026 
1027     /// \brief Set the frozen particle momentum
1028     void setFrozenMomentum(const ThreeVector &momentum) { theFrozenMomentum = momentum; }
1029 
1030     /// \brief Set the frozen particle momentum
1031     void setFrozenEnergy(const G4double energy) { theFrozenEnergy = energy; }
1032 
1033     /// \brief Get the frozen particle momentum
1034     ThreeVector getFrozenMomentum() const { return theFrozenMomentum; }
1035 
1036     /// \brief Get the frozen particle momentum
1037     G4double getFrozenEnergy() const { return theFrozenEnergy; }
1038 
1039     /// \brief Get the propagation velocity of the particle
1040     ThreeVector getPropagationVelocity() const { return (*thePropagationMomentum)/(*thePropagationEnergy); }
1041 
1042     /** \brief Freeze particle propagation
1043      *
1044      * Make the particle use theFrozenMomentum and theFrozenEnergy for
1045      * propagation. The normal state can be restored by calling the
1046      * thawPropagation() method.
1047      */
1048     void freezePropagation() {
1049       thePropagationMomentum = &theFrozenMomentum;
1050       thePropagationEnergy = &theFrozenEnergy;
1051     }
1052 
1053     /** \brief Unfreeze particle propagation
1054      *
1055      * Make the particle use theMomentum and theEnergy for propagation. Call
1056      * this method to restore the normal propagation if the
1057      * freezePropagation() method has been called.
1058      */
1059     void thawPropagation() {
1060       thePropagationMomentum = &theMomentum;
1061       thePropagationEnergy = &theEnergy;
1062     }
1063 
1064     /** \brief Rotate the particle position and momentum
1065      *
1066      * \param angle the rotation angle
1067      * \param axis a unit vector representing the rotation axis
1068      */
1069     virtual void rotatePositionAndMomentum(const G4double angle, const ThreeVector &axis) {
1070       rotatePosition(angle, axis);
1071       rotateMomentum(angle, axis);
1072     }
1073 
1074     /** \brief Rotate the particle position
1075      *
1076      * \param angle the rotation angle
1077      * \param axis a unit vector representing the rotation axis
1078      */
1079     virtual void rotatePosition(const G4double angle, const ThreeVector &axis) {
1080       thePosition.rotate(angle, axis);
1081     }
1082 
1083     /** \brief Rotate the particle momentum
1084      *
1085      * \param angle the rotation angle
1086      * \param axis a unit vector representing the rotation axis
1087      */
1088     virtual void rotateMomentum(const G4double angle, const ThreeVector &axis) {
1089       theMomentum.rotate(angle, axis);
1090       theFrozenMomentum.rotate(angle, axis);
1091     }
1092 
1093     std::string print() const {
1094       std::stringstream ss;
1095       ss << "Particle (ID = " << ID << ") type = ";
1096       ss << ParticleTable::getName(theType);
1097       ss << '\n'
1098         << "   energy = " << theEnergy << '\n'
1099         << "   momentum = "
1100         << theMomentum.print()
1101         << '\n'
1102         << "   position = "
1103         << thePosition.print()
1104         << '\n';
1105       return ss.str();
1106     };
1107 
1108     std::string dump() const {
1109       std::stringstream ss;
1110       ss << "(particle " << ID << " ";
1111       ss << ParticleTable::getName(theType);
1112       ss << '\n'
1113         << thePosition.dump()
1114         << '\n'
1115         << theMomentum.dump()
1116         << '\n'
1117         << theEnergy << ")" << '\n';
1118       return ss.str();
1119     };
1120 
1121     long getID() const { return ID; };
1122 
1123     /**
1124      * Return a NULL pointer
1125      */
1126     ParticleList const *getParticles() const {
1127       INCL_WARN("Particle::getParticles() method was called on a Particle object" << '\n');
1128       return 0;
1129     }
1130 
1131     /** \brief Return the reflection momentum
1132      *
1133      * The reflection momentum is used by calls to getSurfaceRadius to compute
1134      * the radius of the sphere where the nucleon moves. It is necessary to
1135      * introduce fuzzy r-p correlations.
1136      */
1137     G4double getReflectionMomentum() const {
1138       if(rpCorrelated)
1139         return theMomentum.mag();
1140       else
1141         return uncorrelatedMomentum;
1142     }
1143 
1144     /// \brief Set the uncorrelated momentum
1145     void setUncorrelatedMomentum(const G4double p) { uncorrelatedMomentum = p; }
1146 
1147     /// \brief Make the particle follow a strict r-p correlation
1148     void rpCorrelate() { rpCorrelated = true; }
1149 
1150     /// \brief Make the particle not follow a strict r-p correlation
1151     void rpDecorrelate() { rpCorrelated = false; }
1152 
1153     /// \brief Get the cosine of the angle between position and momentum
1154     G4double getCosRPAngle() const {
1155       const G4double norm = thePosition.mag2()*thePropagationMomentum->mag2();
1156       if(norm>0.)
1157         return thePosition.dot(*thePropagationMomentum) / std::sqrt(norm);
1158       else
1159         return 1.;
1160     }
1161 
1162     /// \brief General bias vector function
1163     static G4double getTotalBias();
1164     static void setINCLBiasVector(std::vector<G4double> NewVector);
1165     static void FillINCLBiasVector(G4double newBias);
1166     static G4double getBiasFromVector(std::vector<G4int> VectorBias);
1167 
1168     static std::vector<G4int> MergeVectorBias(Particle const * const p1, Particle const * const p2);
1169     static std::vector<G4int> MergeVectorBias(std::vector<G4int> p1, Particle const * const p2);
1170 
1171     /// \brief Get the particle bias.
1172     G4double getParticleBias() const { return theParticleBias; };
1173 
1174     /// \brief Set the particle bias.
1175     void setParticleBias(G4double ParticleBias) { this->theParticleBias = ParticleBias; }
1176 
1177     /// \brief Get the vector list of biased vertices on the particle path.
1178     std::vector<G4int> getBiasCollisionVector() const { return theBiasCollisionVector; }
1179 
1180     /// \brief Set the vector list of biased vertices on the particle path.
1181     void setBiasCollisionVector(std::vector<G4int> BiasCollisionVector) {
1182     this->theBiasCollisionVector = BiasCollisionVector;
1183     this->setParticleBias(Particle::getBiasFromVector(std::move(BiasCollisionVector)));
1184     }
1185     
1186     /** \brief Number of Kaon inside de nucleus
1187      * 
1188      * Put in the Particle class in order to calculate the
1189      * "correct" mass of composit particle.
1190      * 
1191      */
1192      
1193     G4int getNumberOfKaon() const { return theNKaon; };
1194     void setNumberOfKaon(const G4int NK) { theNKaon = NK; }
1195 
1196 #ifdef INCLXX_IN_GEANT4_MODE
1197     G4int getParentResonancePDGCode() const { return theParentResonancePDGCode; };
1198     void setParentResonancePDGCode(const G4int parentPDGCode) { theParentResonancePDGCode = parentPDGCode; };    
1199     G4int getParentResonanceID() const { return theParentResonanceID; };
1200     void setParentResonanceID(const G4int parentID) { theParentResonanceID = parentID; };
1201 #endif
1202   
1203   public:
1204     /** \brief Time ordered vector of all bias applied
1205      * 
1206      * /!\ Caution /!\
1207      * methods Assotiated to G4VectorCache<T> are:
1208      * Push_back(…),
1209      * operator[],
1210      * Begin(),
1211      * End(),
1212      * Clear(),
1213      * Size() and 
1214      * Pop_back()
1215      * 
1216      */
1217 #ifdef INCLXX_IN_GEANT4_MODE
1218       static std::vector<G4double> INCLBiasVector;
1219       //static G4VectorCache<G4double> INCLBiasVector;
1220 #else
1221       static G4ThreadLocal std::vector<G4double> INCLBiasVector;
1222       //static G4VectorCache<G4double> INCLBiasVector;
1223 #endif
1224     static G4ThreadLocal G4int nextBiasedCollisionID;
1225     
1226   protected:
1227     G4int theZ, theA, theS;
1228     ParticipantType theParticipantType;
1229     G4INCL::ParticleType theType;
1230     G4double theEnergy;
1231     G4double *thePropagationEnergy;
1232     G4double theFrozenEnergy;
1233     G4INCL::ThreeVector theMomentum;
1234     G4INCL::ThreeVector *thePropagationMomentum;
1235     G4INCL::ThreeVector theFrozenMomentum;
1236     G4INCL::ThreeVector thePosition;
1237     G4int nCollisions;
1238     G4int nDecays;
1239     G4double thePotentialEnergy;
1240     long ID;
1241 
1242     G4bool rpCorrelated;
1243     G4double uncorrelatedMomentum;
1244     
1245     G4double theParticleBias;
1246     /// \brief The number of Kaons inside the nucleus (update during the cascade)
1247     G4int theNKaon;
1248 
1249 #ifdef INCLXX_IN_GEANT4_MODE
1250     G4int theParentResonancePDGCode;
1251     G4int theParentResonanceID;
1252 #endif
1253 
1254   private:
1255     G4double theHelicity;
1256     G4double emissionTime;
1257     G4bool outOfWell;
1258     
1259     /// \brief Time ordered vector of all biased vertices on the particle path
1260     std::vector<G4int> theBiasCollisionVector;
1261 
1262     G4double theMass;
1263     static G4ThreadLocal long nextID;
1264 
1265     INCL_DECLARE_ALLOCATION_POOL(Particle)
1266   };
1267 }
1268 
1269 #endif /* PARTICLE_HH_ */
1270