Some bug fixes, removal of some duplicates and clarified the logic of some pieces...
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnMother.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 ////////////////////////////////////////////////////////////////////////////////
17 //
18 //  This class implements a candidate resonance. It has two pointers to its
19 //  two candidate daughters, whose 4-momenta are combined to obtain the mother
20 //  invariant mass and other kinematical quantities.
21 //  This class contains also some methods used to compute kinematical relations
22 //  between the candidate resonance and other particles.
23 //
24 //  authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
25 //           M. Vala (martin.vala@cern.ch)
26 //
27 ////////////////////////////////////////////////////////////////////////////////
28
29 #include <Riostream.h>
30 #include <TVector3.h>
31
32 #include "AliAODMCParticle.h"
33 #include "AliMCParticle.h"
34 #include "AliRsnDaughter.h"
35 #include "AliRsnEvent.h"
36
37 #include "AliRsnMother.h"
38
39 ClassImp(AliRsnMother)
40
41 //__________________________________________________________________________________________________
42 AliRsnMother::AliRsnMother(const AliRsnMother &obj) :
43    TObject(obj),
44    fRefEvent(obj.fRefEvent),
45    fSum(obj.fSum),
46    fRef(obj.fRef)
47 {
48 //
49 // Copy constructor.
50 // Does not duplicate pointers.
51 //
52
53    Int_t i;
54    for (i = 0; i < 2; i++) fDaughter[i] = obj.fDaughter[i];
55 }
56
57 //__________________________________________________________________________________________________
58 AliRsnMother& AliRsnMother::operator=(const AliRsnMother &obj)
59 {
60 //
61 // Assignment operator.
62 // Does not duplicate pointers.
63 //
64
65    fSum = obj.fSum;
66    fRef = obj.fRef;
67    fRefEvent = obj.fRefEvent;
68    fDaughter[0] = obj.fDaughter[0];
69    fDaughter[1] = obj.fDaughter[1];
70    
71    return (*this);
72 }
73
74 //__________________________________________________________________________________________________
75 AliRsnMother::~AliRsnMother()
76 {
77 //
78 // Desctructor.
79 // Does nothing, since pointers are not created in this class.
80 //
81 }
82
83 //_______________________________________________________________________________________________________________________
84 void AliRsnMother::Reset()
85 {
86 //
87 // Resets the mother, zeroing all data members.
88 //
89
90    Int_t i;
91    for (i = 0; i < 2; i++) fDaughter[i] = 0x0;
92    fRefEvent = 0x0;
93    fSum.SetXYZM(0.0, 0.0, 0.0, 0.0);
94    fRef.SetXYZM(0.0, 0.0, 0.0, 0.0);
95 }
96
97 //__________________________________________________________________________________________________
98 Int_t AliRsnMother::CommonMother() const
99 {
100 //
101 // If MC info is available, checks if the two tracks in the pair have the same mother.
102 // If the mother label is the same, the function returns the PDG code of mother,
103 // otherwise it returns 0.
104 // The two arguments passed by reference contain the GEANT labels of the mother
105 // of the two particles to which the two daughters point. This is for being able 
106 // to check if they are really coming from a resonance (indexes >= 0) or not.
107 //
108
109    Int_t m1  = fDaughter[0]->GetMother();
110    Int_t m2  = fDaughter[1]->GetMother();
111    Int_t out = 0;
112    
113    // a true mother makes sense only if both mothers
114    // are not-negative and equal
115    if (m1 >= 0 && m2 >= 0 && m1 == m2) {
116       out = TMath::Abs(fDaughter[0]->GetMotherPDG());
117       AliDebugClass(1, Form("Mothers are: %d %d --> EQUAL (PDG = %d)", m1, m2, out));
118    } 
119    
120    return out;
121 }
122
123 //__________________________________________________________________________________________________
124 Double_t AliRsnMother::AngleToLeading(Bool_t &success)
125 {
126 //
127 // Compute the angle betwee this and the leading particls
128 // of the reference event (if this was set properly).
129 // In case one of the two daughters is the leading, return
130 // a meaningless value, in order to skip this pair.
131 // if second argument is kTRUE, use MC values.
132 //
133
134    if (!fRefEvent) {
135       success = kFALSE;
136       return -99.0;
137    }
138    
139    Int_t id1 = fDaughter[0]->GetID();
140    Int_t id2 = fDaughter[1]->GetID();
141    Int_t idL = fRefEvent->GetLeadingIndex();
142    
143    if (id1 == idL || id2 == idL) {
144       success = kFALSE;
145       return -99.0;
146    }
147    
148    AliRsnDaughter leading = fRefEvent->GetDaughter(idL, kFALSE);
149    AliVParticle  *ref     = leading.GetRef();
150    Double_t       angle   = ref->Phi() - fSum.Phi();
151    
152    //return angle w.r.t. leading particle in the range -pi/2, 3/2pi
153    while (angle >= 1.5 * TMath::Pi()) angle -= 2 * TMath::Pi();
154    while (angle < -0.5 * TMath::Pi()) angle += 2 * TMath::Pi();
155    success = kTRUE;
156    
157    return angle;
158 }
159
160 //__________________________________________________________________________________________________
161 void AliRsnMother::ComputeSum(Double_t mass0, Double_t mass1, Double_t motherMass)
162 {
163 //
164 // Sets the masses for the 4-momenta of the daughters and then
165 // sums them, taking into account that the space part is set to
166 // each of them when the reference object is set (see AliRsnDaughter::SetRef)
167 //
168
169    fDaughter[0]->FillP(mass0);
170    fDaughter[1]->FillP(mass1);
171
172    // sum
173    fSum   = fDaughter[0]->Prec() + fDaughter[1]->Prec();
174    fSumMC = fDaughter[0]->Psim() + fDaughter[1]->Psim();
175    
176    // reference
177    fRef.SetXYZM(fSum.X(), fSum.Y(), fSum.Z(), motherMass);
178    fRefMC.SetXYZM(fSumMC.X(), fSumMC.Y(), fSumMC.Z(), motherMass);
179 }
180
181 //__________________________________________________________________________________________________
182 Double_t AliRsnMother::CosThetaStar(Bool_t first, Bool_t useMC)
183 {
184 //
185 // Computes the cosine of theta*, which is the angle of one of the daughters
186 // with respect to the total momentum of the resonance, in its rest frame.
187 // The arguments are needed to choose which of the daughters one want to use
188 // and if reconstructed or MC momentum must be used.
189 // [Contribution from Z. Feckova]
190 //
191
192    TLorentzVector &mother    = Sum(useMC);
193    TLorentzVector &daughter0 = (first ? fDaughter[0]->P(useMC) : fDaughter[1]->P(useMC));
194    TLorentzVector &daughter1 = (first ? fDaughter[1]->P(useMC) : fDaughter[0]->P(useMC));
195    TVector3 momentumM(mother.Vect());
196    TVector3 normal(mother.Y() / momentumM.Mag(), -mother.X() / momentumM.Mag(), 0.0);
197
198    // Computes first the invariant mass of the mother
199    Double_t mass0      = fDaughter[0]->P(useMC).M();
200    Double_t mass1      = fDaughter[1]->P(useMC).M();
201    Double_t p0         = daughter0.Vect().Mag();
202    Double_t p1         = daughter1.Vect().Mag();
203    Double_t E0         = TMath::Sqrt(mass0 * mass0 + p0 * p0);
204    Double_t E1         = TMath::Sqrt(mass1 * mass1 + p1 * p1);
205    Double_t MotherMass = TMath::Sqrt((E0 + E1) * (E0 + E1) - (p0 * p0 + 2.0 * daughter0.Vect().Dot(daughter1.Vect()) + p1 * p1));
206    MotherMass = fSum.M();
207
208    // Computes components of beta
209    Double_t betaX = -mother.X() / mother.E();
210    Double_t betaY = -mother.Y() / mother.E();
211    Double_t betaZ = -mother.Z() / mother.E();
212
213    // Computes Lorentz transformation of the momentum of the first daughter
214    // into the rest frame of the mother and theta*
215    daughter0.Boost(betaX, betaY, betaZ);
216    TVector3 momentumD = daughter0.Vect();
217
218    Double_t cosThetaStar = normal.Dot(momentumD) / momentumD.Mag();
219
220    return cosThetaStar;
221 }
222
223 //__________________________________________________________________________________________________
224 void AliRsnMother::PrintInfo(const Option_t * /*option*/) const
225 {
226 //
227 // Print some info of the pair.
228 // The options are passed to the AliRsnDaughter::Print() method
229 //
230
231    AliInfo("======== BEGIN PAIR INFO ===========");
232    AliInfo("Track #1");
233    fDaughter[0]->Print();
234    AliInfo("Track #2");
235    fDaughter[1]->Print();
236    AliInfo("========= END PAIR INFO ===========");
237 }
238
239 //__________________________________________________________________________________________________
240 Bool_t AliRsnMother::CheckPair(Bool_t checkMC) const
241 {
242 //
243 // Checks that the pair is well initialized:
244 // - both daughters are good pointers
245 // - if MC is required, both daughters have a MC reference
246 //
247
248    if (!fDaughter[0] || !fDaughter[1]) {
249       AliError("One of the two tracks is NULL in this pair!");
250       return kFALSE;
251    }
252
253    if (checkMC) {
254       if (fDaughter[0]->GetRefMC() == 0x0 || fDaughter[1]->GetRefMC() == 0x0) {
255          AliError("Required MC info but not all MC refs are available");
256          return kFALSE;
257       }
258    }
259
260    return kTRUE;
261 }