]>
Commit | Line | Data |
---|---|---|
06351446 | 1 | // |
2 | // Class AliRsnPairParticle | |
3 | // | |
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 | |
e0baff8c | 7 | // - evaluating any kind of kinematic value over their sum |
06351446 | 8 | // |
e0baff8c | 9 | // authors: Martin Vala (martin.vala@cern.ch) |
10 | // Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it) | |
06351446 | 11 | // |
12 | ||
4fbb2459 | 13 | #include "AliRsnPairDef.h" |
06351446 | 14 | #include "AliRsnPairParticle.h" |
15 | ||
aec0ec32 | 16 | ClassImp(AliRsnPairParticle) |
06351446 | 17 | |
18 | //_____________________________________________________________________________ | |
e2bafbbc | 19 | AliRsnPairParticle::AliRsnPairParticle() |
06351446 | 20 | { |
21 | // | |
22 | // Constructor. | |
23 | // Initializes all variables to meaningless values. | |
24 | // | |
e2bafbbc | 25 | |
aec0ec32 | 26 | Int_t i, j; |
27 | ||
5eb970a4 | 28 | for (i = 0; i < 3; i++) { |
aec0ec32 | 29 | fPTot[i] = 0.0; |
30 | fPTotMC[i] = 0.0; | |
5eb970a4 | 31 | if (i < 2) { |
aec0ec32 | 32 | fMotherLabel[i] = -1; |
33 | fMotherPDG[i] = 0; | |
34 | fDaughter[i] = 0x0; | |
06351446 | 35 | } |
5eb970a4 | 36 | for (j = 0; j < 2; j++) { |
aec0ec32 | 37 | fPTrack[j][i] = 0.0; |
38 | fPTrackMC[j][i] = 0.0; | |
39 | } | |
40 | } | |
06351446 | 41 | } |
42 | ||
43 | //_____________________________________________________________________________ | |
44 | AliRsnPairParticle::AliRsnPairParticle(const AliRsnPairParticle &obj) : | |
aec0ec32 | 45 | TObject(obj) |
06351446 | 46 | { |
47 | // | |
48 | // Copy constructor. | |
49 | // Initializes all variables to copy values. | |
50 | // Does not duplicate pointers. | |
51 | // | |
e2bafbbc | 52 | |
aec0ec32 | 53 | Int_t i, j; |
5eb970a4 | 54 | for (i = 0; i < 3; i++) { |
aec0ec32 | 55 | fPTot[i] = obj.fPTot[i]; |
56 | fPTotMC[i] = obj.fPTotMC[i]; | |
5eb970a4 | 57 | if (i < 2) { |
aec0ec32 | 58 | fMotherLabel[i] = obj.fMotherLabel[i]; |
59 | fMotherPDG[i] = obj.fMotherPDG[i]; | |
60 | fDaughter[i] = obj.fDaughter[i]; | |
61 | } | |
5eb970a4 | 62 | for (j = 0; j < 2; j++) { |
aec0ec32 | 63 | fPTrack[j][i] = obj.fPTrack[j][i]; |
64 | fPTrackMC[j][i] = obj.fPTrackMC[j][i]; | |
06351446 | 65 | } |
aec0ec32 | 66 | } |
06351446 | 67 | } |
68 | ||
69 | //_____________________________________________________________________________ | |
70 | AliRsnPairParticle& AliRsnPairParticle::operator=(const AliRsnPairParticle &obj) | |
71 | { | |
72 | // | |
73 | // Assignment operator. | |
74 | // Initializes all variables to copy values. | |
75 | // Does not duplicate pointers. | |
76 | // | |
77 | ||
aec0ec32 | 78 | Int_t i, j; |
5eb970a4 | 79 | for (i = 0; i < 3; i++) { |
aec0ec32 | 80 | fPTot[i] = obj.fPTot[i]; |
81 | fPTotMC[i] = obj.fPTotMC[i]; | |
5eb970a4 | 82 | if (i < 2) { |
aec0ec32 | 83 | fMotherLabel[i] = obj.fMotherLabel[i]; |
84 | fMotherPDG[i] = obj.fMotherPDG[i]; | |
85 | fDaughter[i] = obj.fDaughter[i]; | |
86 | } | |
5eb970a4 | 87 | for (j = 0; j < 2; j++) { |
aec0ec32 | 88 | fPTrack[j][i] = obj.fPTrack[j][i]; |
89 | fPTrackMC[j][i] = obj.fPTrackMC[j][i]; | |
06351446 | 90 | } |
aec0ec32 | 91 | } |
06351446 | 92 | |
aec0ec32 | 93 | return (*this); |
06351446 | 94 | } |
95 | ||
96 | //_____________________________________________________________________________ | |
97 | AliRsnPairParticle::~AliRsnPairParticle() | |
98 | { | |
99 | // | |
100 | // Desctructor. | |
101 | // Does nothing. | |
102 | // | |
103 | } | |
104 | ||
105 | //_____________________________________________________________________________ | |
e2bafbbc | 106 | Double_t AliRsnPairParticle::GetInvMass(Double_t mass0, Double_t mass1) |
06351446 | 107 | { |
108 | // | |
e2bafbbc | 109 | // Compute invariant mass using reconstructed values. |
110 | // Mass in argument #1 is assigned to first track in the pair (fDaughter[0]), | |
5eb970a4 | 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. | |
e2bafbbc | 114 | // Then, the invariant mass of the pair is computed by using their total momentum |
e0baff8c | 115 | // and the sum of their energies computed after assigned masses. |
06351446 | 116 | // |
06351446 | 117 | |
5eb970a4 | 118 | if (!fDaughter[0] || !fDaughter[1]) { |
aec0ec32 | 119 | AliError("One of the two tracks is NULL in this pair!"); |
120 | return -1000.0; | |
121 | } | |
06351446 | 122 | |
aec0ec32 | 123 | // compute track energies using the shortcut method defined in AliRsnDaughter |
124 | Double_t etot = 0.0; | |
125 | etot += fDaughter[0]->E(mass0); | |
126 | etot += fDaughter[1]->E(mass1); | |
06351446 | 127 | |
aec0ec32 | 128 | // compute & return invariant mass |
129 | return TMath::Sqrt(etot * etot - GetP2()); | |
06351446 | 130 | } |
131 | ||
132 | //_____________________________________________________________________________ | |
e2bafbbc | 133 | Double_t AliRsnPairParticle::GetInvMassMC(Double_t mass0, Double_t mass1) |
06351446 | 134 | { |
135 | // | |
e2bafbbc | 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 | |
e0baff8c | 140 | // and the sum of their energies. |
06351446 | 141 | // |
142 | ||
5eb970a4 | 143 | if (!fDaughter[0] || !fDaughter[1]) { |
aec0ec32 | 144 | AliError("One of the two tracks is NULL in this pair!"); |
145 | return -1000.0; | |
146 | } | |
5eb970a4 | 147 | if (!fDaughter[0]->GetParticle() || !fDaughter[1]->GetParticle()) { |
aec0ec32 | 148 | AliError("One of the two tracks has a NULL MCInfo in this pair!"); |
149 | return -1000.0; | |
150 | } | |
151 | ||
152 | // compute track energies using the shortcut method defined in AliRsnDaughter | |
153 | Double_t etot = 0.0; | |
5eb970a4 | 154 | etot += fDaughter[0]->GetMCEnergy(mass0); |
155 | etot += fDaughter[1]->GetMCEnergy(mass1); | |
aec0ec32 | 156 | |
157 | // compute & return invariant mass | |
e0baff8c | 158 | return TMath::Sqrt(etot * etot - GetP2MC()); |
aec0ec32 | 159 | } |
160 | ||
161 | //_____________________________________________________________________________ | |
162 | Double_t AliRsnPairParticle::GetEtot(Double_t mass0, Double_t mass1) const | |
163 | { | |
164 | // | |
165 | // Compute total pair energy from the sum of single track energies | |
166 | // with a necessary mass hypothesis (rec. values). | |
167 | // | |
e0baff8c | 168 | |
169 | Double_t etot = 0.0; | |
170 | etot += fDaughter[0]->E(mass0); | |
171 | etot += fDaughter[1]->E(mass1); | |
172 | ||
173 | return etot; | |
aec0ec32 | 174 | } |
06351446 | 175 | |
aec0ec32 | 176 | //_____________________________________________________________________________ |
177 | Double_t AliRsnPairParticle::GetEtotMC(Double_t mass0, Double_t mass1) const | |
178 | { | |
179 | // | |
180 | // Compute total pair energy from the sum of single track energies | |
181 | // with a necessary mass hypothesis (MC values). | |
182 | // | |
e0baff8c | 183 | Double_t etot = 0.0; |
5eb970a4 | 184 | etot += fDaughter[0]->GetMCEnergy(mass0); |
185 | etot += fDaughter[1]->GetMCEnergy(mass1); | |
e0baff8c | 186 | |
187 | return etot; | |
06351446 | 188 | } |
189 | ||
190 | //_____________________________________________________________________________ | |
e2bafbbc | 191 | Double_t AliRsnPairParticle::GetAngle() const |
06351446 | 192 | { |
193 | // | |
e2bafbbc | 194 | // Returns the relative angle between the vector momenta of the tracks |
195 | // Return value is in DEGREES. | |
06351446 | 196 | // |
197 | ||
aec0ec32 | 198 | Double_t dotProd = 0.0; |
199 | dotProd += fDaughter[0]->Px() * fDaughter[1]->Px(); | |
5acd0c9b | 200 | dotProd += fDaughter[0]->Py() * fDaughter[1]->Py(); |
aec0ec32 | 201 | dotProd += fDaughter[0]->Pz() * fDaughter[1]->Pz(); |
202 | ||
203 | Double_t cosAngle = dotProd / (fDaughter[0]->P() * fDaughter[1]->P()); | |
204 | ||
78b94cbd | 205 | return TMath::ACos(cosAngle) * TMath::RadToDeg(); |
06351446 | 206 | } |
207 | ||
208 | //_____________________________________________________________________________ | |
209 | Bool_t AliRsnPairParticle::IsTruePair(Int_t refPDG) | |
210 | { | |
211 | // | |
e2bafbbc | 212 | // Checks if the two tracks in the pair come from the same resonance. |
06351446 | 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. | |
e2bafbbc | 218 | // |
06351446 | 219 | |
aec0ec32 | 220 | // if MC info is not available, the pairs is not true by default |
5eb970a4 | 221 | if (!fDaughter[0]->GetParticle() || !fDaughter[1]->GetParticle()) { |
aec0ec32 | 222 | AliInfo("Cannot know if the pairs is true or not because MC Info is not present"); |
223 | return kFALSE; | |
224 | } | |
225 | ||
226 | // check that labels are the same | |
5eb970a4 | 227 | if (fDaughter[0]->GetParticle()->GetFirstMother() != fDaughter[1]->GetParticle()->GetFirstMother()) { |
aec0ec32 | 228 | return kFALSE; |
229 | } | |
230 | ||
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 | |
5eb970a4 | 233 | Int_t motherPDG = TMath::Abs(fDaughter[0]->GetMotherPDG()); |
aec0ec32 | 234 | if (refPDG == 0) return kTRUE; |
235 | else return (motherPDG == refPDG); | |
06351446 | 236 | } |
237 | ||
5eb970a4 | 238 | //_____________________________________________________________________________ |
239 | Int_t AliRsnPairParticle::CommonMother() | |
240 | { | |
241 | // | |
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. | |
246 | // | |
247 | ||
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"); | |
251 | return 0; | |
252 | } | |
253 | ||
254 | // check that labels are the same | |
255 | if (fDaughter[0]->GetParticle()->GetFirstMother() != fDaughter[1]->GetParticle()->GetFirstMother()) { | |
256 | return 0; | |
257 | } | |
258 | ||
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()); | |
262 | } | |
263 | ||
06351446 | 264 | //_____________________________________________________________________________ |
4fbb2459 | 265 | void AliRsnPairParticle::SetPair(AliRsnDaughter * const daughter1, AliRsnDaughter * const daughter2) |
06351446 | 266 | { |
267 | // | |
06351446 | 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 | |
271 | // | |
272 | ||
aec0ec32 | 273 | Int_t i; |
06351446 | 274 | |
aec0ec32 | 275 | fDaughter[0] = daughter1; |
276 | fDaughter[1] = daughter2; | |
06351446 | 277 | |
e0baff8c | 278 | // copy MC info (if available) |
5eb970a4 | 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(); | |
e0baff8c | 285 | } |
286 | for (i = 0; i < 3; i++) fPTotMC[i] = fPTrackMC[0][i] + fPTrackMC[1][i]; | |
287 | } | |
288 | ||
289 | // copy reconstructed info (always available) | |
5eb970a4 | 290 | for (i = 0; i < 2; i++) { |
e0baff8c | 291 | fPTrack[i][0] = fDaughter[i]->Px(); |
292 | fPTrack[i][1] = fDaughter[i]->Py(); | |
293 | fPTrack[i][2] = fDaughter[i]->Pz(); | |
294 | } | |
295 | for (i = 0; i < 3; i++) fPTot[i] = fPTrack[0][i] + fPTrack[1][i]; | |
296 | } | |
297 | ||
298 | //_____________________________________________________________________________ | |
299 | void AliRsnPairParticle::ResetPair() | |
300 | { | |
301 | // | |
302 | // Computes the total momentum for REC data and MC if available | |
303 | // | |
304 | ||
305 | Int_t i; | |
306 | ||
aec0ec32 | 307 | // copy MC info (if available) |
5eb970a4 | 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(); | |
06351446 | 314 | } |
aec0ec32 | 315 | for (i = 0; i < 3; i++) fPTotMC[i] = fPTrackMC[0][i] + fPTrackMC[1][i]; |
316 | } | |
317 | ||
318 | // copy reconstructed info (always available) | |
5eb970a4 | 319 | for (i = 0; i < 2; i++) { |
aec0ec32 | 320 | fPTrack[i][0] = fDaughter[i]->Px(); |
321 | fPTrack[i][1] = fDaughter[i]->Py(); | |
322 | fPTrack[i][2] = fDaughter[i]->Pz(); | |
323 | } | |
324 | for (i = 0; i < 3; i++) fPTot[i] = fPTrack[0][i] + fPTrack[1][i]; | |
06351446 | 325 | } |
326 | ||
5eb970a4 | 327 | //_____________________________________________________________________________ |
328 | void AliRsnPairParticle::RotateTrack(Int_t idx, Double_t angle, Bool_t isDegrees) | |
329 | { | |
330 | // | |
331 | // Computes the total momentum for REC data and MC if available | |
332 | // | |
333 | ||
334 | if (idx < 0 || idx > 1) return; | |
335 | ||
336 | Int_t i; | |
337 | ||
338 | // copy MC info (if available) | |
339 | if (fDaughter[0]->GetParticle() && fDaughter[1]->GetParticle()) { | |
340 | for (i = 0; i < 2; i++) { | |
341 | if (i == idx) { | |
342 | fDaughter[i]->RotateP(angle, fPTrackMC[i][0], fPTrackMC[i][1], isDegrees); | |
343 | } else { | |
344 | fPTrackMC[i][0] = fDaughter[i]->GetParticle()->Px(); | |
345 | fPTrackMC[i][1] = fDaughter[i]->GetParticle()->Py(); | |
346 | } | |
347 | fPTrackMC[i][2] = fDaughter[i]->GetParticle()->Pz(); | |
348 | } | |
349 | for (i = 0; i < 3; i++) fPTotMC[i] = fPTrackMC[0][i] + fPTrackMC[1][i]; | |
350 | } | |
351 | ||
352 | for (i = 0; i < 2; i++) { | |
353 | if (i == idx) { | |
354 | fDaughter[i]->RotateP(angle, fPTrack[i][0], fPTrack[i][1], isDegrees); | |
355 | } else { | |
356 | fPTrack[i][0] = fDaughter[i]->GetParticle()->Px(); | |
357 | fPTrack[i][1] = fDaughter[i]->GetParticle()->Py(); | |
358 | } | |
359 | fPTrack[i][2] = fDaughter[i]->GetParticle()->Pz(); | |
360 | } | |
361 | for (i = 0; i < 3; i++) fPTot[i] = fPTrack[0][i] + fPTrack[1][i]; | |
362 | ||
363 | } | |
364 | ||
06351446 | 365 | //_____________________________________________________________________________ |
aec0ec32 | 366 | void AliRsnPairParticle::PrintInfo(const Option_t *option) |
06351446 | 367 | { |
368 | // | |
aec0ec32 | 369 | // Print some info of the pair. |
e2bafbbc | 370 | // The options are passed to the AliRsnDaughter::Print() method |
06351446 | 371 | // |
5eb970a4 | 372 | option = "ALL"; |
aec0ec32 | 373 | AliInfo("======== BEGIN PAIR INFO ==========="); |
374 | AliInfo("Track #1"); | |
375 | fDaughter[0]->Print(option); | |
376 | AliInfo("Track #2"); | |
377 | fDaughter[1]->Print(option); | |
378 | AliInfo("========= END PAIR INFO ==========="); | |
06351446 | 379 | } |
4fbb2459 | 380 | |
381 | //_____________________________________________________________________________ | |
382 | Bool_t AliRsnPairParticle::MatchesDef(AliRsnPairDef *def) | |
383 | { | |
384 | // | |
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. | |
388 | // | |
389 | ||
390 | if (!def) return kFALSE; | |
391 | ||
392 | Bool_t decayMatch = kFALSE; | |
393 | ||
394 | // check #1: | |
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)); | |
401 | } | |
402 | ||
403 | // check #2: | |
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)); | |
410 | } | |
411 | ||
412 | return (decayMatch && (CommonMother() == def->GetMotherPDG())); | |
413 | } |