2 // Class AliRsnPairParticle
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)
13 #include "AliRsnPairDef.h"
14 #include "AliRsnPairParticle.h"
16 ClassImp(AliRsnPairParticle)
18 //_____________________________________________________________________________
19 AliRsnPairParticle::AliRsnPairParticle()
23 // Initializes all variables to meaningless values.
28 for (i = 0; i < 3; i++) {
36 for (j = 0; j < 2; j++) {
38 fPTrackMC[j][i] = 0.0;
43 //_____________________________________________________________________________
44 AliRsnPairParticle::AliRsnPairParticle(const AliRsnPairParticle &obj) :
49 // Initializes all variables to copy values.
50 // Does not duplicate pointers.
54 for (i = 0; i < 3; i++) {
55 fPTot[i] = obj.fPTot[i];
56 fPTotMC[i] = obj.fPTotMC[i];
58 fMotherLabel[i] = obj.fMotherLabel[i];
59 fMotherPDG[i] = obj.fMotherPDG[i];
60 fDaughter[i] = obj.fDaughter[i];
62 for (j = 0; j < 2; j++) {
63 fPTrack[j][i] = obj.fPTrack[j][i];
64 fPTrackMC[j][i] = obj.fPTrackMC[j][i];
69 //_____________________________________________________________________________
70 AliRsnPairParticle& AliRsnPairParticle::operator=(const AliRsnPairParticle &obj)
73 // Assignment operator.
74 // Initializes all variables to copy values.
75 // Does not duplicate pointers.
79 for (i = 0; i < 3; i++) {
80 fPTot[i] = obj.fPTot[i];
81 fPTotMC[i] = obj.fPTotMC[i];
83 fMotherLabel[i] = obj.fMotherLabel[i];
84 fMotherPDG[i] = obj.fMotherPDG[i];
85 fDaughter[i] = obj.fDaughter[i];
87 for (j = 0; j < 2; j++) {
88 fPTrack[j][i] = obj.fPTrack[j][i];
89 fPTrackMC[j][i] = obj.fPTrackMC[j][i];
96 //_____________________________________________________________________________
97 AliRsnPairParticle::~AliRsnPairParticle()
105 //_____________________________________________________________________________
106 Double_t AliRsnPairParticle::GetInvMass(Double_t mass0, Double_t mass1)
109 // Compute invariant mass using reconstructed values.
110 // Mass in argument #1 is assigned to first track in the pair (fDaughter[0]),
111 // mass in argument #2 is assigned to second track in the pair (fDaughter[1]).
112 // If the third argument is not zero, a rotation of that angle is applied to XY momentum of track #2
113 // before computing invariant mass.
114 // Then, the invariant mass of the pair is computed by using their total momentum
115 // and the sum of their energies computed after assigned masses.
118 if (!fDaughter[0] || !fDaughter[1]) {
119 AliError("One of the two tracks is NULL in this pair!");
123 // compute track energies using the shortcut method defined in AliRsnDaughter
125 etot += fDaughter[0]->E(mass0);
126 etot += fDaughter[1]->E(mass1);
128 // compute & return invariant mass
129 return TMath::Sqrt(etot * etot - GetP2());
132 //_____________________________________________________________________________
133 Double_t AliRsnPairParticle::GetInvMassMC(Double_t mass0, Double_t mass1)
136 // Compute invariant mass using MC values.
137 // Mass in argument #1 is assigned to first track in the pair (fDaughter[0]),
138 // mass in argument #2 is assigned to second track in the pair (fDaughter[1])
139 // Then, the invariant mass of the pair is computed by using their total momentum
140 // and the sum of their energies.
143 if (!fDaughter[0] || !fDaughter[1]) {
144 AliError("One of the two tracks is NULL in this pair!");
147 if (!fDaughter[0]->GetParticle() || !fDaughter[1]->GetParticle()) {
148 AliError("One of the two tracks has a NULL MCInfo in this pair!");
152 // compute track energies using the shortcut method defined in AliRsnDaughter
154 etot += fDaughter[0]->GetMCEnergy(mass0);
155 etot += fDaughter[1]->GetMCEnergy(mass1);
157 // compute & return invariant mass
158 return TMath::Sqrt(etot * etot - GetP2MC());
161 //_____________________________________________________________________________
162 Double_t AliRsnPairParticle::GetEtot(Double_t mass0, Double_t mass1) const
165 // Compute total pair energy from the sum of single track energies
166 // with a necessary mass hypothesis (rec. values).
170 etot += fDaughter[0]->E(mass0);
171 etot += fDaughter[1]->E(mass1);
176 //_____________________________________________________________________________
177 Double_t AliRsnPairParticle::GetEtotMC(Double_t mass0, Double_t mass1) const
180 // Compute total pair energy from the sum of single track energies
181 // with a necessary mass hypothesis (MC values).
184 etot += fDaughter[0]->GetMCEnergy(mass0);
185 etot += fDaughter[1]->GetMCEnergy(mass1);
190 //_____________________________________________________________________________
191 Double_t AliRsnPairParticle::GetAngle() const
194 // Returns the relative angle between the vector momenta of the tracks
195 // Return value is in DEGREES.
198 Double_t dotProd = 0.0;
199 dotProd += fDaughter[0]->Px() * fDaughter[1]->Px();
200 dotProd += fDaughter[0]->Py() * fDaughter[1]->Py();
201 dotProd += fDaughter[0]->Pz() * fDaughter[1]->Pz();
203 Double_t cosAngle = dotProd / (fDaughter[0]->P() * fDaughter[1]->P());
205 return TMath::ACos(cosAngle) * TMath::RadToDeg();
208 //_____________________________________________________________________________
209 Bool_t AliRsnPairParticle::IsTruePair(Int_t refPDG)
212 // Checks if the two tracks in the pair come from the same resonance.
213 // This can be known if MC info is present, looking at the GEANT label of mother
214 // (which should be the same).
215 // If the argument is 0, the answer is kTRUE whenever the labels of mothers of the
216 // two tracks is the same. When the argument is not zero, the answer is kTRUE only
217 // if the mother is the same and its PDG code is equal to the argument.
220 // if MC info is not available, the pairs is not true by default
221 if (!fDaughter[0]->GetParticle() || !fDaughter[1]->GetParticle()) {
222 AliInfo("Cannot know if the pairs is true or not because MC Info is not present");
226 // check that labels are the same
227 if (fDaughter[0]->GetParticle()->GetFirstMother() != fDaughter[1]->GetParticle()->GetFirstMother()) {
231 // if we reach this point, the two tracks have the same mother
232 // let's check now the PDG code of this common mother
233 Int_t motherPDG = TMath::Abs(fDaughter[0]->GetMotherPDG());
234 if (refPDG == 0) return kTRUE;
235 else return (motherPDG == refPDG);
238 //_____________________________________________________________________________
239 Int_t AliRsnPairParticle::CommonMother()
242 // Checks if the two tracks in the pair have the same mother.
243 // This can be known if MC info is present.
244 // If the mother label is the same, rhe PDG code of the mother is returned,
245 // otherwise the method returns 0.
248 // if MC info is not available, the pairs is not true by default
249 if (!fDaughter[0]->GetParticle() || !fDaughter[1]->GetParticle()) {
250 AliInfo("Cannot know if the pairs is true or not because MC Info is not present");
254 // check that labels are the same
255 if (fDaughter[0]->GetParticle()->GetFirstMother() != fDaughter[1]->GetParticle()->GetFirstMother()) {
259 // if we reach this point, the two tracks have the same mother
260 // let's check now the PDG code of this common mother
261 return TMath::Abs(fDaughter[0]->GetMotherPDG());
264 //_____________________________________________________________________________
265 void AliRsnPairParticle::SetPair(AliRsnDaughter * const daughter1, AliRsnDaughter * const daughter2)
268 // Accepts two AliRsnDaughter's which are the two tracks in the pair,
269 // fills all data-members which contain their momenta & info,
270 // and computes the total momentum for REC data and MC if available
275 fDaughter[0] = daughter1;
276 fDaughter[1] = daughter2;
278 // copy MC info (if available)
279 if (fDaughter[0]->GetParticle() && fDaughter[1]->GetParticle()) {
280 for (i = 0; i < 2; i++) {
281 fPTrackMC[i][0] = fDaughter[i]->GetParticle()->Px();
282 fPTrackMC[i][1] = fDaughter[i]->GetParticle()->Py();
283 fPTrackMC[i][2] = fDaughter[i]->GetParticle()->Pz();
284 fMotherPDG[i] = fDaughter[i]->GetMotherPDG();
286 for (i = 0; i < 3; i++) fPTotMC[i] = fPTrackMC[0][i] + fPTrackMC[1][i];
289 // copy reconstructed info (always available)
290 for (i = 0; i < 2; i++) {
291 fPTrack[i][0] = fDaughter[i]->Px();
292 fPTrack[i][1] = fDaughter[i]->Py();
293 fPTrack[i][2] = fDaughter[i]->Pz();
295 for (i = 0; i < 3; i++) fPTot[i] = fPTrack[0][i] + fPTrack[1][i];
298 //_____________________________________________________________________________
299 void AliRsnPairParticle::ResetPair()
302 // Computes the total momentum for REC data and MC if available
307 // copy MC info (if available)
308 if (fDaughter[0]->GetParticle() && fDaughter[1]->GetParticle()) {
309 for (i = 0; i < 2; i++) {
310 fPTrackMC[i][0] = fDaughter[i]->GetParticle()->Px();
311 fPTrackMC[i][1] = fDaughter[i]->GetParticle()->Py();
312 fPTrackMC[i][2] = fDaughter[i]->GetParticle()->Pz();
313 fMotherPDG[i] = fDaughter[i]->GetMotherPDG();
315 for (i = 0; i < 3; i++) fPTotMC[i] = fPTrackMC[0][i] + fPTrackMC[1][i];
318 // copy reconstructed info (always available)
319 for (i = 0; i < 2; i++) {
320 fPTrack[i][0] = fDaughter[i]->Px();
321 fPTrack[i][1] = fDaughter[i]->Py();
322 fPTrack[i][2] = fDaughter[i]->Pz();
324 for (i = 0; i < 3; i++) fPTot[i] = fPTrack[0][i] + fPTrack[1][i];
327 //_____________________________________________________________________________
328 void AliRsnPairParticle::RotateTrack(Int_t idx, Double_t angle, Bool_t isDegrees)
331 // Computes the total momentum for REC data and MC if available
334 if (idx < 0 || idx > 1) return;
338 // copy MC info (if available)
339 if (fDaughter[0]->GetParticle() && fDaughter[1]->GetParticle()) {
340 for (i = 0; i < 2; i++) {
342 fDaughter[i]->RotateP(angle, fPTrackMC[i][0], fPTrackMC[i][1], isDegrees);
344 fPTrackMC[i][0] = fDaughter[i]->GetParticle()->Px();
345 fPTrackMC[i][1] = fDaughter[i]->GetParticle()->Py();
347 fPTrackMC[i][2] = fDaughter[i]->GetParticle()->Pz();
349 for (i = 0; i < 3; i++) fPTotMC[i] = fPTrackMC[0][i] + fPTrackMC[1][i];
352 for (i = 0; i < 2; i++) {
354 fDaughter[i]->RotateP(angle, fPTrack[i][0], fPTrack[i][1], isDegrees);
356 fPTrack[i][0] = fDaughter[i]->GetParticle()->Px();
357 fPTrack[i][1] = fDaughter[i]->GetParticle()->Py();
359 fPTrack[i][2] = fDaughter[i]->GetParticle()->Pz();
361 for (i = 0; i < 3; i++) fPTot[i] = fPTrack[0][i] + fPTrack[1][i];
365 //_____________________________________________________________________________
366 void AliRsnPairParticle::PrintInfo(const Option_t *option)
369 // Print some info of the pair.
370 // The options are passed to the AliRsnDaughter::Print() method
373 AliInfo("======== BEGIN PAIR INFO ===========");
375 fDaughter[0]->Print(option);
377 fDaughter[1]->Print(option);
378 AliInfo("========= END PAIR INFO ===========");
381 //_____________________________________________________________________________
382 Bool_t AliRsnPairParticle::MatchesDef(AliRsnPairDef *def)
385 // Checks if the daughters, in any order, do match a given decay channel,
386 // using the specified identification method, which can be the 'true' one
387 // or the 'realistic' one only.
390 if (!def) return kFALSE;
392 Bool_t decayMatch = kFALSE;
395 // daughter[0] matches first member of pairDef
396 // daughter[1] matches second member of pairDef
397 if (fDaughter[0]->IsSign(def->GetCharge(0)) && fDaughter[1]->IsSign(def->GetCharge(1))) {
398 decayMatch = (fDaughter[0]->IsPerfectPID(def->GetType(0)) && fDaughter[1]->IsPerfectPID(def->GetType(1)));
399 fDaughter[0]->SetRequiredPID(def->GetType(0));
400 fDaughter[1]->SetRequiredPID(def->GetType(1));
404 // daughter[1] matches first member of pairDef
405 // daughter[0] matches second member of pairDef
406 if (fDaughter[1]->IsSign(def->GetCharge(0)) && fDaughter[0]->IsSign(def->GetCharge(1))) {
407 decayMatch = (fDaughter[1]->IsPerfectPID(def->GetType(0)) && fDaughter[0]->IsPerfectPID(def->GetType(1)));
408 fDaughter[1]->SetRequiredPID(def->GetType(0));
409 fDaughter[0]->SetRequiredPID(def->GetType(1));
412 return (decayMatch && (CommonMother() == def->GetMotherPDG()));