// Author: Marios A. Kagarlis
// Written: 15.11.98
// Revised: 20.07.99
// Revised: 30.08.00  R. Holzmann
// Revised: 07.09.00  J. Ritman (added parent-,siblings-,daughter- index
//                    and decayTime)
// Revised: 15.12.00  R. Holzmann  (creation time added)
// Revised: 22.03.05  R. Holzmann  (get/setParent() added)
// Revised: 23.07.07  IF (new framework) 

// PParticle Class Header
 
#ifndef _PPARTICLE_H_
#define _PPARTICLE_H_

#include "TLorentzVector.h"
#include "PData.h"
#include "PValues.h"
#include "PUtils.h"

#include "TMath.h"



class PParticle: public TLorentzVector {
    
 public:
    PParticle(Int_t id=0, Double_t T=0., Double_t w=1.);
    // id, lab kinetic energy (GeV), weight
    
    PParticle(const char *, Double_t T=0., Double_t w=1.);
    // name, lab kinetic energy (GeV), weight
    
    PParticle(Int_t, Double_t, Double_t, Double_t, Double_t m=0., Double_t w=1.);
    // id, Px, Py, Pz (GeV/c), mass (GeV/c**2) overrides default, weight
    
    PParticle(const char *, Double_t, Double_t, Double_t,Double_t m=0., Double_t w=1.);
    // name, Px, Py, Pz (GeV/c), mass (GeV/c**2) overrides default, weight
    
    PParticle(Int_t, const TVector3 &, Double_t m=0., Double_t w=1.);
    // id, 3-momentum vector (GeV/c), mass (GeV/c**2) overrides default, weight

    PParticle(Int_t, Double_t *, Double_t w=1.);
    // id, pointer to 4-dim array (Px, Py, Pz, E) (GeV/c, GeV), weight
  
    PParticle(Int_t, float *, Double_t w=1.);
    // id, pointer to 4-dim array (Px, Py, Pz, E) (GeV/c, GeV), weight

    PParticle(const PParticle &);
    // copy constructor

    PParticle(const PParticle *);
    // copy constructor

    virtual ~PParticle() {
	if (qParticle1) delete qParticle1;
	if (qParticle2) delete qParticle2;
	if (values)  delete values;
    }

    Int_t Is(const char * id) { 
	return (pid==makeStaticData()->GetParticleID(id)); 
    }
    Int_t is(const char * id) { 
	//kept for compatibility only
	return Is(id); 
    }
    Int_t HasID(const Int_t id) { 
	return (pid==id); 
    }
    Int_t HasNotID(const Int_t id) { 
	return (pid!=id); 
    }

    Int_t size()      { return (pid<1000)?1:2; }
    Int_t IsNucleon() { return (Is("p") || Is("n")); }
    Int_t IsDelta()   { return (Is("D0") || Is("D-") || Is("D+") || Is("D++")); }
    Int_t IsPi()      { return (Is("pi0") || Is("pi+") || Is("pi-")); }
    Int_t IsRho()     { return (Is("rho0") || Is("rho+") || Is("rho-")); }
    Int_t ID() const  { return pid; }

    const char *Name() { 
	return makeStaticData()->GetParticleName(pid); 
    }

    void SetSpectator(Int_t s) {spectator=s;};
    //=0 don't care; =-1 never; =1 force

    Int_t  IsSpectator() {return spectator;};

    void SetID(const Int_t id) { pid=id; }
    Double_t W() const         { return wt; }
    void SetW(Double_t w=1.)   { wt=w; }
    void SetMultiplicity(Double_t w=1.) { mult=w; }
    Double_t GetMultiplicity() {return mult;};
    Double_t GenW() const      { return genwt; }
    void SetGenW(Double_t w=1.) { genwt=w; }
    Double_t InvGenW() const    { return invgenwt; }
    void SetInvGenW(Double_t w=1.) { invgenwt=w; }


    virtual Double_t KE() const { return E()-M(); } // kinetic energy
    void SetKE(Double_t T=0.);    // reset by kinetic energy
    void SetM(Double_t m=0.);     // reset by mass
    void SetMom(Double_t mom=0.); // reset by momentum

    void ResetE() {             // reset E to be consistent with mass(ID)
	if (makeStaticData()->GetParticleTotalWidth(pid) > 1.e-3) 
	    return;      // broad particle
	Double_t m = makeStaticData()->GetParticleMass(pid);            // get tabulated mass
	Double_t px = Px(), py = Py(), pz = Pz();
	Double_t lE = sqrt(m*m + px*px + py*py + pz*pz);
	SetPxPyPzE(px, py, pz, lE);
    }

    Double_t Life(Double_t m=0., Int_t idx=-1); // lifetime in lab frame
    TLorentzVector Vect4() const { return TLorentzVector(Vect(),E()); }
    void SetVect4(const TLorentzVector & v) { SetPxPyPzE(v[0],v[1],v[2],v[3]); }
    Int_t IsMeson() const  { return makeStaticData()->IsParticleMeson(pid); }
    Int_t IsHadron() const { return makeStaticData()->IsParticleHadron(pid); }
    Int_t BaryonN() const  { return makeStaticData()->GetParticleBaryon(pid); }
    Int_t LeptonN() const  { return makeStaticData()->GetParticleLepton(pid); }
    Int_t Charge() const   { return makeStaticData()->GetParticleCharge(pid); }
    Int_t Key() const      { return makeStaticData()->GetParticleKey(pid); }
    void Reset(const Int_t id, const TLorentzVector & v, const Double_t w=1.) { 
	pid = id;
	wt  = w;
	SetVect4(v);
    }
    virtual Int_t IsFireball()  { return 0; }
    virtual Int_t IsDilepton()  { return 0; }
    virtual Int_t IsFileInput() { return 0; }
    void Reset(const Int_t id=0, const Double_t px=0., const Double_t py=0.,
	       const Double_t pz=0., const Double_t e=0., const Double_t w=1.) {
	SetPxPyPzE(px,py,pz,e);
	pid = id;
	wt  = w;
    };
    void Reset(const PParticle & p) {
	*this = p;
    };

    PParticle* Clone(const char*delme = NULL) const;

    bool SetValue(Int_t id , Double_t val) {
	if (!values) values=new PValues();
	return values->SetValue(id, val);
    };

    bool SetValue(Int_t id)  {
	return SetValue(id, 1.);
    };

    bool GetValue(Int_t id, Double_t *val) {
	if (!values) return kFALSE;
	return values->GetValue(id, val);
    };
   

    Int_t GetDBInt(char *name) {
	Int_t param = makeDataBase()->GetParamInt(name);
	if (param < 0) return -1;
	Int_t pkey = makeStaticData()->GetParticleKey(pid);
	if (pkey < 0) return -1;
	Int_t *result;
	if (!makeDataBase()->GetParamInt(pkey, param, &result)) return -1;
	return *result;
    };
    Double_t GetDBDouble(char *name) {
	Int_t param = makeDataBase()->GetParamDouble(name);
	if (param < 0) return -1;
	Int_t pkey = makeStaticData()->GetParticleKey(pid);
	if (pkey < 0) return -1;
	Double_t *result;
	if (!makeDataBase()->GetParamDouble(pkey, param, &result)) return -1;
	return *result;
    };
    char GetDBString(char *name) const {
	Int_t param = makeDataBase()->GetParamString(name);
	if (param < 0) return -1;
	Int_t pkey = makeStaticData()->GetParticleKey(pid);
	if (pkey < 0) return -1;
	const char *result;
	if (!makeDataBase()->GetParamString(pkey, param, &result)) return -1;
	return *result;
    };

    void SetStatus(Int_t st){
	status=st;
    };
  
    Int_t GetStatus(){
	return status;
    };

    Double_t InvariantT(Double_t m3, Double_t m4, Double_t cos_th_cm);
    // The Mandelstam invariant t in 1 + 2 --> 3 + 4 scattering
  
    PParticle operator + (const PParticle & b) const {
	// "addition" for composite quasi-particles
	PParticle v( *this );
	return v += b;
    }
    void Scatter(PParticle *p1, PParticle *p2);

    PParticle operator - (const PParticle & b) const {
	// "addition" for composite quasi-particles
	PParticle v( *this );
	return v -= b;
    }
    void Reconstruct(void);

    PParticle & operator += ( const PParticle & );
    PParticle & operator -= ( const PParticle & );
    PParticle & operator =  ( const PParticle & );
    PParticle & operator *= ( const TRotation & );
    PParticle & operator *= ( const TLorentzRotation & );
    PParticle & Transform( const TRotation & );
    PParticle & Transform( const TLorentzRotation & );

    PParticle & AddTmp( const PParticle & p);
    PParticle & SubTmp( const PParticle & p);

    void Print(const Option_t* delme= NULL) const;
  

    inline void SetParentId(Int_t pId) {parentId = pId;}
    inline void SetSourceId(Int_t sId) {sourceId = sId;}
    inline Int_t GetParentId() const {return parentId;}
    inline Int_t GetSourceId() const {return sourceId;}

    inline Int_t getSourceId() const {return sourceId;} //kept for backw. comp.

    inline void  SetParentIndex(Int_t pInd) {parentIndex = pInd;}
    inline Int_t GetParentIndex() const {return parentIndex;}
    inline void  SetDecayModeIndex(Int_t pInd, Int_t i=0) {
	if (i) {
	    decayModeIndex = -1;
	    destroyDecayModeIndex = pInd;	  
	} else {
	    decayModeIndex = pInd;
	    destroyDecayModeIndex = -1;
	}
    }
  
    //Internal models should use opt=1, they will not get the "wrong" getDecayModeIndex
    inline Int_t GetDecayModeIndex(Int_t opt=0) const {
	if ((opt ==0) && (decayModeIndex<0) && (destroyDecayModeIndex>0))
	    return destroyDecayModeIndex;      
	return decayModeIndex;
    }
    inline void  SetDaughterIndex(Int_t dInd) {daughterIndex = dInd;}
    inline Int_t GetDaughterIndex() const {return daughterIndex;}
    inline void  SetSiblingIndex(Int_t sInd) {siblingIndex = sInd;}
    inline Int_t GetSiblingIndex() const {return siblingIndex;}
    inline void SetIndex(Int_t Ind) {index = Ind;}
    inline Int_t GetIndex() const {return index;}

    inline Bool_t IsActive() const {return active;}
    inline void SetActive() {active = kTRUE;}
    inline void SetInActive() {active = kFALSE;}

    void SetProperTime();     // sample time until decay in proper time (sec)
    void SetProperTime(Double_t t) {decayTime = t;}
    inline Double_t GetProperTime() const {return decayTime;}  

    void SetVertex(Double_t x, Double_t y, Double_t z, Double_t t) {
	fV.SetXYZ(x, y, z); 
	fT = t;
    }
    void SetVertex(Double_t x, Double_t y, Double_t z) {
	fV.SetXYZ(x, y, z);
    }
    inline void SetVertex(TVector3& v, Double_t t) {fV = v; fT=t;}
    inline TVector3& GetVertex() {return fV;}
    inline TVector3& getVertex() {return fV;}
    inline Double_t X() const {return fV.X();}
    inline Double_t Y() const {return fV.Y();}
    inline Double_t Z() const {return fV.Z();}
    inline Double_t R() const {return fV.Mag();}
    inline Double_t T() const {return fT;}
    inline void SetT(Double_t time) {fT = time;}
    inline void SetInput(PParticle *p) {pParticle = p;}
    inline PParticle* GetInput() {return pParticle;}
    inline void SetParent(PParticle *p) {pParticle = p;}
    inline PParticle* GetParent() {return pParticle;}
    inline void SetSibling(PParticle *p) {sParticle = p;}
    inline PParticle* GetSibling() {
	if (sParticle) 
	    return sParticle;
	else 
	    return this;
    };

    inline void ResetDaughters(void) {
	for (int i=0; i<(MAX_DAUGHTERS+1); i++)
	    daughters[i] = NULL;
    };

    inline void SetDaughter(PParticle *d) {
	for (int i=0; i<MAX_DAUGHTERS; i++) {
	    if (daughters[i] == NULL) {
		daughters[i] = d;
		return;
	    }
	}
	Error("SetDaughter","MAX_DAUGHTERS reached");
    };

    inline PParticle *GetDaughter(int i) { 
	return daughters[i];
    }

    inline PParticle *GetScattering(Int_t i) {
	if (i == 0) 
	    return qParticle1; 
	else 
	    return qParticle2;
    };

    inline PParticle *GetBeam(void){
	return qParticle1;
    };
    inline PParticle *GetTarget(void){
	return qParticle2;
    };

    void addDebugString(char * s) {
	debug.Append(s);  
	debug.Append(":");  
    }
    void clearDebugString() {
	debug = "";  //BUGBUG memory leak?
    }
    TString *GetDebugString(){
	return &debug;
    }

    Int_t GetScatterClone(void) {return make_new_qParticle;};
    void  SetScatterClone(Int_t t) {make_new_qParticle=t;};

    Double_t weight_divisor; //!Helper for PReaction

    //Something for PBatch:
    Double_t Sample() {return PUtils::sampleFlat();};

 protected:

    void defaults(void);

    Int_t pid;           //  particle code  (partially conforms with Geant 3)
    Int_t sourceId;      //  Source ID
    Int_t parentId;      //  parent ID
    Int_t parentIndex;   //  parent index in particle array
    Int_t decayModeIndex;//  decay Mode index (for decayAll option)
    Int_t destroyDecayModeIndex;// save only for data file
    Int_t daughterIndex; //  daughter index
    Int_t siblingIndex;  //  sibling index
    Int_t spectator;     //! flag that forces particle to be treated as spectator

    Double_t decayTime;  //  proper time until decay  (in mm/c)
    Double_t wt;         //  weight
    Double_t genwt;      //! generator weight
    Double_t invgenwt;   //! inverted generator weight
    Double_t mult;       //! multiplicity

    TVector3 fV;         //  creation vertex (in mm)
    Double_t fT;         //  creation time (in mm/c)
    Bool_t active;       //! internal activity flag
    Int_t index;         //! index in particle array
    PParticle* pParticle;//! pointer to particle object
    PParticle* qParticle1;//!
    PParticle* qParticle2;//!
    PParticle* sParticle; //! pointer to particle object
    PParticle* daughters[MAX_DAUGHTERS+1]; //!pointer to daughter array 
    TString debug;        //! debug string

    PValues * values;   //!pointer to value container
    Int_t status;       //! status of parent particle in PChannel::Decay

    Bool_t make_new_qParticle; //! Workaround

    ClassDef(PParticle,4)  // Pluto Particle Class
	};
#endif // _PPARTICLE_H_













 PParticle.h:1
 PParticle.h:2
 PParticle.h:3
 PParticle.h:4
 PParticle.h:5
 PParticle.h:6
 PParticle.h:7
 PParticle.h:8
 PParticle.h:9
 PParticle.h:10
 PParticle.h:11
 PParticle.h:12
 PParticle.h:13
 PParticle.h:14
 PParticle.h:15
 PParticle.h:16
 PParticle.h:17
 PParticle.h:18
 PParticle.h:19
 PParticle.h:20
 PParticle.h:21
 PParticle.h:22
 PParticle.h:23
 PParticle.h:24
 PParticle.h:25
 PParticle.h:26
 PParticle.h:27
 PParticle.h:28
 PParticle.h:29
 PParticle.h:30
 PParticle.h:31
 PParticle.h:32
 PParticle.h:33
 PParticle.h:34
 PParticle.h:35
 PParticle.h:36
 PParticle.h:37
 PParticle.h:38
 PParticle.h:39
 PParticle.h:40
 PParticle.h:41
 PParticle.h:42
 PParticle.h:43
 PParticle.h:44
 PParticle.h:45
 PParticle.h:46
 PParticle.h:47
 PParticle.h:48
 PParticle.h:49
 PParticle.h:50
 PParticle.h:51
 PParticle.h:52
 PParticle.h:53
 PParticle.h:54
 PParticle.h:55
 PParticle.h:56
 PParticle.h:57
 PParticle.h:58
 PParticle.h:59
 PParticle.h:60
 PParticle.h:61
 PParticle.h:62
 PParticle.h:63
 PParticle.h:64
 PParticle.h:65
 PParticle.h:66
 PParticle.h:67
 PParticle.h:68
 PParticle.h:69
 PParticle.h:70
 PParticle.h:71
 PParticle.h:72
 PParticle.h:73
 PParticle.h:74
 PParticle.h:75
 PParticle.h:76
 PParticle.h:77
 PParticle.h:78
 PParticle.h:79
 PParticle.h:80
 PParticle.h:81
 PParticle.h:82
 PParticle.h:83
 PParticle.h:84
 PParticle.h:85
 PParticle.h:86
 PParticle.h:87
 PParticle.h:88
 PParticle.h:89
 PParticle.h:90
 PParticle.h:91
 PParticle.h:92
 PParticle.h:93
 PParticle.h:94
 PParticle.h:95
 PParticle.h:96
 PParticle.h:97
 PParticle.h:98
 PParticle.h:99
 PParticle.h:100
 PParticle.h:101
 PParticle.h:102
 PParticle.h:103
 PParticle.h:104
 PParticle.h:105
 PParticle.h:106
 PParticle.h:107
 PParticle.h:108
 PParticle.h:109
 PParticle.h:110
 PParticle.h:111
 PParticle.h:112
 PParticle.h:113
 PParticle.h:114
 PParticle.h:115
 PParticle.h:116
 PParticle.h:117
 PParticle.h:118
 PParticle.h:119
 PParticle.h:120
 PParticle.h:121
 PParticle.h:122
 PParticle.h:123
 PParticle.h:124
 PParticle.h:125
 PParticle.h:126
 PParticle.h:127
 PParticle.h:128
 PParticle.h:129
 PParticle.h:130
 PParticle.h:131
 PParticle.h:132
 PParticle.h:133
 PParticle.h:134
 PParticle.h:135
 PParticle.h:136
 PParticle.h:137
 PParticle.h:138
 PParticle.h:139
 PParticle.h:140
 PParticle.h:141
 PParticle.h:142
 PParticle.h:143
 PParticle.h:144
 PParticle.h:145
 PParticle.h:146
 PParticle.h:147
 PParticle.h:148
 PParticle.h:149
 PParticle.h:150
 PParticle.h:151
 PParticle.h:152
 PParticle.h:153
 PParticle.h:154
 PParticle.h:155
 PParticle.h:156
 PParticle.h:157
 PParticle.h:158
 PParticle.h:159
 PParticle.h:160
 PParticle.h:161
 PParticle.h:162
 PParticle.h:163
 PParticle.h:164
 PParticle.h:165
 PParticle.h:166
 PParticle.h:167
 PParticle.h:168
 PParticle.h:169
 PParticle.h:170
 PParticle.h:171
 PParticle.h:172
 PParticle.h:173
 PParticle.h:174
 PParticle.h:175
 PParticle.h:176
 PParticle.h:177
 PParticle.h:178
 PParticle.h:179
 PParticle.h:180
 PParticle.h:181
 PParticle.h:182
 PParticle.h:183
 PParticle.h:184
 PParticle.h:185
 PParticle.h:186
 PParticle.h:187
 PParticle.h:188
 PParticle.h:189
 PParticle.h:190
 PParticle.h:191
 PParticle.h:192
 PParticle.h:193
 PParticle.h:194
 PParticle.h:195
 PParticle.h:196
 PParticle.h:197
 PParticle.h:198
 PParticle.h:199
 PParticle.h:200
 PParticle.h:201
 PParticle.h:202
 PParticle.h:203
 PParticle.h:204
 PParticle.h:205
 PParticle.h:206
 PParticle.h:207
 PParticle.h:208
 PParticle.h:209
 PParticle.h:210
 PParticle.h:211
 PParticle.h:212
 PParticle.h:213
 PParticle.h:214
 PParticle.h:215
 PParticle.h:216
 PParticle.h:217
 PParticle.h:218
 PParticle.h:219
 PParticle.h:220
 PParticle.h:221
 PParticle.h:222
 PParticle.h:223
 PParticle.h:224
 PParticle.h:225
 PParticle.h:226
 PParticle.h:227
 PParticle.h:228
 PParticle.h:229
 PParticle.h:230
 PParticle.h:231
 PParticle.h:232
 PParticle.h:233
 PParticle.h:234
 PParticle.h:235
 PParticle.h:236
 PParticle.h:237
 PParticle.h:238
 PParticle.h:239
 PParticle.h:240
 PParticle.h:241
 PParticle.h:242
 PParticle.h:243
 PParticle.h:244
 PParticle.h:245
 PParticle.h:246
 PParticle.h:247
 PParticle.h:248
 PParticle.h:249
 PParticle.h:250
 PParticle.h:251
 PParticle.h:252
 PParticle.h:253
 PParticle.h:254
 PParticle.h:255
 PParticle.h:256
 PParticle.h:257
 PParticle.h:258
 PParticle.h:259
 PParticle.h:260
 PParticle.h:261
 PParticle.h:262
 PParticle.h:263
 PParticle.h:264
 PParticle.h:265
 PParticle.h:266
 PParticle.h:267
 PParticle.h:268
 PParticle.h:269
 PParticle.h:270
 PParticle.h:271
 PParticle.h:272
 PParticle.h:273
 PParticle.h:274
 PParticle.h:275
 PParticle.h:276
 PParticle.h:277
 PParticle.h:278
 PParticle.h:279
 PParticle.h:280
 PParticle.h:281
 PParticle.h:282
 PParticle.h:283
 PParticle.h:284
 PParticle.h:285
 PParticle.h:286
 PParticle.h:287
 PParticle.h:288
 PParticle.h:289
 PParticle.h:290
 PParticle.h:291
 PParticle.h:292
 PParticle.h:293
 PParticle.h:294
 PParticle.h:295
 PParticle.h:296
 PParticle.h:297
 PParticle.h:298
 PParticle.h:299
 PParticle.h:300
 PParticle.h:301
 PParticle.h:302
 PParticle.h:303
 PParticle.h:304
 PParticle.h:305
 PParticle.h:306
 PParticle.h:307
 PParticle.h:308
 PParticle.h:309
 PParticle.h:310
 PParticle.h:311
 PParticle.h:312
 PParticle.h:313
 PParticle.h:314
 PParticle.h:315
 PParticle.h:316
 PParticle.h:317
 PParticle.h:318
 PParticle.h:319
 PParticle.h:320
 PParticle.h:321
 PParticle.h:322
 PParticle.h:323
 PParticle.h:324
 PParticle.h:325
 PParticle.h:326
 PParticle.h:327
 PParticle.h:328
 PParticle.h:329
 PParticle.h:330
 PParticle.h:331
 PParticle.h:332
 PParticle.h:333
 PParticle.h:334
 PParticle.h:335
 PParticle.h:336
 PParticle.h:337
 PParticle.h:338
 PParticle.h:339
 PParticle.h:340
 PParticle.h:341
 PParticle.h:342
 PParticle.h:343
 PParticle.h:344
 PParticle.h:345
 PParticle.h:346
 PParticle.h:347
 PParticle.h:348
 PParticle.h:349
 PParticle.h:350
 PParticle.h:351
 PParticle.h:352
 PParticle.h:353
 PParticle.h:354
 PParticle.h:355
 PParticle.h:356
 PParticle.h:357
 PParticle.h:358
 PParticle.h:359
 PParticle.h:360
 PParticle.h:361
 PParticle.h:362
 PParticle.h:363
 PParticle.h:364
 PParticle.h:365
 PParticle.h:366
 PParticle.h:367
 PParticle.h:368
 PParticle.h:369
 PParticle.h:370
 PParticle.h:371
 PParticle.h:372
 PParticle.h:373
 PParticle.h:374
 PParticle.h:375
 PParticle.h:376
 PParticle.h:377
 PParticle.h:378
 PParticle.h:379
 PParticle.h:380
 PParticle.h:381
 PParticle.h:382
 PParticle.h:383
 PParticle.h:384
 PParticle.h:385
 PParticle.h:386
 PParticle.h:387
 PParticle.h:388
 PParticle.h:389
 PParticle.h:390
 PParticle.h:391
 PParticle.h:392
 PParticle.h:393
 PParticle.h:394
 PParticle.h:395
 PParticle.h:396
 PParticle.h:397
 PParticle.h:398