4 // Implementation of a pair of tracks, for several purposes
5 // - computing the total 4-momentum & inv. mass for output histos filling
6 // - evaluating cut checks on the pair of particles
7 // - evaluating any kind of kinematic value over their sum
9 // authors: Martin Vala (martin.vala@cern.ch)
10 // Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
12 #include <Riostream.h>
14 #include "AliAODMCParticle.h"
15 #include "AliMCParticle.h"
16 #include "AliRsnDaughter.h"
17 #include "AliRsnPairDef.h"
18 #include "AliRsnMother.h"
20 ClassImp(AliRsnMother)
22 //_____________________________________________________________________________
23 AliRsnMother::AliRsnMother() :
33 // Initializes all variables to meaningless values.
37 for (i = 0; i < 2; i++) fDaughter[i] = 0x0;
40 //_____________________________________________________________________________
41 AliRsnMother::AliRsnMother(const AliRsnMother &obj) :
44 fDefaultMass(obj.fDefaultMass),
52 // Initializes all variables to copy values.
53 // Does not duplicate pointers.
57 for (i = 0; i < 2; i++) fDaughter[i] = obj.fDaughter[i];
60 //_____________________________________________________________________________
61 AliRsnMother& AliRsnMother::operator=(const AliRsnMother &obj)
64 // Assignment operator.
65 // Initializes all variables to copy values.
66 // Does not duplicate pointers.
71 fDefaultMass = obj.fDefaultMass;
77 for (i = 0; i < 2; i++) fDaughter[i] = obj.fDaughter[i];
82 //_____________________________________________________________________________
83 AliRsnMother::~AliRsnMother()
87 // Does nothing, since pointers are not created in this class.
91 //_____________________________________________________________________________
92 Int_t AliRsnMother::CommonMother(Int_t &m0, Int_t &m1) const
95 // Checks if the two tracks in the pair have the same mother.
96 // This can be known if MC info is present.
97 // If the mother label is the same, rhe PDG code of the mother is returned,
98 // otherwise the method returns 0.
99 // In the two arguments passed by reference, the mothers of the two daghters are stored
102 // if MC info is not available, the pairs is not true by default
103 if (!fDaughter[0]->GetRefMC() || !fDaughter[1]->GetRefMC())
105 AliInfo("Cannot know if the pairs is true or not because MC Info is not present");
109 // check that labels are the same
112 if (fDaughter[0]->IsESD() && fDaughter[1]->IsESD() )
114 if (fDaughter[0]->GetRefMCESD() && fDaughter[1]->GetRefMCESD())
116 m0 = fDaughter[0]->GetRefMCESD()->Particle()->GetFirstMother();
117 m1 = fDaughter[1]->GetRefMCESD()->Particle()->GetFirstMother();
120 if (fDaughter[0]->IsAOD() && fDaughter[1]->IsAOD())
122 if (fDaughter[0]->GetRefMCAOD() && fDaughter[1]->GetRefMCAOD())
124 m0 = fDaughter[0]->GetRefMCAOD()->GetMother();
125 m1 = fDaughter[1]->GetRefMCAOD()->GetMother();
128 if (m0 != m1) return 0;
130 // if we reach this point, the two tracks have the same mother
131 // let's check now the PDG code of this common mother
132 return TMath::Abs(fDaughter[0]->GetMotherPDG());
135 //_____________________________________________________________________________
136 void AliRsnMother::SetDaughters
137 (AliRsnDaughter *d0, Double_t mass0, AliRsnDaughter *d1, Double_t mass1)
140 // Sets the pair defined in this usind tso passed daughters and two masses
141 // which will be assigned to them, in order to recompute their 4-momenta
142 // and sum them into the datamembers of this object.
145 if (d0) fDaughter[0] = d0;
146 if (d1) fDaughter[1] = d1;
148 if (!d0 || !d1) return;
150 fDaughter[0]->SetMass(mass0);
151 fDaughter[1]->SetMass(mass1);
153 fSum = fDaughter[0]->P(kFALSE) + fDaughter[1]->P(kFALSE);
154 fSumMC = fDaughter[0]->P(kTRUE) + fDaughter[1]->P(kTRUE);
156 fRef .SetXYZM(fSum .X(), fSum .Y(), fSum .Z(), fDefaultMass);
157 fRefMC.SetXYZM(fSumMC.X(), fSumMC.Y(), fSumMC.Z(), fDefaultMass);
160 //_____________________________________________________________________________
161 void AliRsnMother::ResetPair()
164 // Resets the mother, nullifying all data members
168 for (i = 0; i < 2; i++) fDaughter[i] = 0x0;
170 fSum .SetXYZM(0.0, 0.0, 0.0, 0.0);
171 fRef .SetXYZM(0.0, 0.0, 0.0, 0.0);
172 fSumMC.SetXYZM(0.0, 0.0, 0.0, 0.0);
173 fRefMC.SetXYZM(0.0, 0.0, 0.0, 0.0);
176 //_____________________________________________________________________________
177 Double_t AliRsnMother::CosThetaStar(Bool_t first, Bool_t useMC)
179 TLorentzVector mother = (useMC ? fSumMC : fSum);
180 TLorentzVector daughter0 = (first ? fDaughter[0]->P() : fDaughter[1]->P());
181 TLorentzVector daughter1 = (first ? fDaughter[1]->P() : fDaughter[0]->P());
182 TVector3 momentumM (mother.Vect());
183 //cout << mother.Vect().X() << ' ' << mother.Vect().Y() << ' ' << mother.Vect().Z() << endl;
184 TVector3 normal (mother.Y()/momentumM.Mag(), -mother.X()/momentumM.Mag(), 0.0);
185 //cout << momentumM.Mag() << ' ' << normal.X() << ' ' << normal.Y() << ' ' << normal.Z() << endl;
187 // Computes first the invariant mass of the mother
189 Double_t mass0 = fDaughter[0]->P().M();
190 Double_t mass1 = fDaughter[1]->P().M();
191 Double_t p0 = daughter0.Vect().Mag();
192 Double_t p1 = daughter1.Vect().Mag();
193 Double_t E0 = TMath::Sqrt(mass0*mass0+p0*p0);
194 Double_t E1 = TMath::Sqrt(mass1*mass1+p1*p1);
195 Double_t MotherMass = TMath::Sqrt((E0+E1)*(E0+E1)-(p0*p0+2.0*daughter0.Vect().Dot(daughter1.Vect())+p1*p1));
196 MotherMass = fSum.M();
198 // Computes components of beta
200 Double_t betaX = -mother.X()/mother.E(); //TMath::Sqrt(momentumM.Mag()*momentumM.Mag()+MotherMass*MotherMass);
201 Double_t betaY = -mother.Y()/mother.E(); //TMath::Sqrt(momentumM.Mag()*momentumM.Mag()+MotherMass*MotherMass);
202 Double_t betaZ = -mother.Z()/mother.E(); //TMath::Sqrt(momentumM.Mag()*momentumM.Mag()+MotherMass*MotherMass);
204 // Computes Lorentz transformation of the momentum of the first daughter
205 // into the rest frame of the mother and theta*
206 //cout << "Beta = " << betaX << ' ' << betaY << ' ' << betaZ << endl;
208 daughter0.Boost(betaX,betaY,betaZ);
209 TVector3 momentumD = daughter0.Vect();
211 Double_t cosThetaStar = normal.Dot(momentumD)/momentumD.Mag();
217 //_____________________________________________________________________________
218 void AliRsnMother::PrintInfo(const Option_t * /*option*/) const
221 // Print some info of the pair.
222 // The options are passed to the AliRsnDaughter::Print() method
225 AliInfo("======== BEGIN PAIR INFO ===========");
227 fDaughter[0]->Print();
229 fDaughter[1]->Print();
230 AliInfo("========= END PAIR INFO ===========");
233 //_____________________________________________________________________________
234 Bool_t AliRsnMother::CheckPair() const
237 // Checks that the pair is well initialized:
238 // - both daughters are good pointers
239 // - if MC is required, both daughters have a MC reference
242 if (!fDaughter[0] || !fDaughter[1])
244 AliError("One of the two tracks is NULL in this pair!");
250 if (fDaughter[0]->GetRefMC() == 0x0 || fDaughter[1]->GetRefMC() == 0x0)
252 AliError("Required MC info but not all MC refs are available");
260 //_____________________________________________________________________________
261 Bool_t AliRsnMother::MatchesDef(AliRsnPairDef *def)
264 // Checks if the daughters, in any order, do match a given decay channel,
265 // using the specified identification method, which can be the 'true' one
266 // or the 'realistic' one only.
269 if (!def) return kFALSE;
270 if (!fDaughter[0]->GetRefMC()) return kFALSE;
271 if (!fDaughter[1]->GetRefMC()) return kFALSE;
273 Bool_t decayMatch = kFALSE;
274 Int_t pdg[2], ref[2];
275 pdg[0] = fDaughter[0]->GetPDG();
276 pdg[1] = fDaughter[1]->GetPDG();
277 ref[0] = TMath::Abs(AliPID::ParticleCode(def->GetPID(0)));
278 ref[1] = TMath::Abs(AliPID::ParticleCode(def->GetPID(1)));
281 // if first member of pairDef has same sign as first member of this,
282 // daughter[0] perfect PID must match first member of pairDef
283 // daughter[1] perfect PID must march second member of pairDef
284 if (fDaughter[0]->IsSign(def->GetCharge(0)) && fDaughter[1]->IsSign(def->GetCharge(1)))
286 decayMatch = (pdg[0] == ref[0] && pdg[1] == ref[1]);
290 // if first member of pairDef has same sign as second member of this,
291 // daughter[0] perfect PID must match second member of pairDef
292 // daughter[1] perfect PID must march first member of pairDef
293 if (fDaughter[1]->IsSign(def->GetCharge(0)) && fDaughter[0]->IsSign(def->GetCharge(1)))
295 decayMatch = (pdg[0] == ref[1] && pdg[1] == ref[0]);
298 return (decayMatch && (CommonMother() == def->GetMotherPDG()));