]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG2/RESONANCES/AliRsnLoopEffPair.cxx
Some bug fixes, removal of some duplicates and clarified the logic of some pieces...
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnLoopEffPair.cxx
CommitLineData
c865cb1d 1//
2// Class AliRsnLoopEffPair
3//
4// Inherits from basic AliRsnLoopEff for efficiency,
5// and computed efficiencies for single-tracks
6//
7// author: Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
8//
9
f34f960b 10#include <Riostream.h>
11
c865cb1d 12#include "AliStack.h"
f34f960b 13#include "AliGenEventHeader.h"
14#include "AliAODMCHeader.h"
c865cb1d 15
e187bd70 16#include "AliRsnEvent.h"
c865cb1d 17#include "AliRsnCutManager.h"
18#include "AliRsnDaughterDef.h"
19#include "AliRsnPairDef.h"
20#include "AliRsnLoopEffPair.h"
21
22ClassImp(AliRsnLoopEffPair)
23
24//_____________________________________________________________________________
25AliRsnLoopEffPair::AliRsnLoopEffPair(const char *name, AliRsnPairDef *def) :
f34f960b 26 AliRsnLoopEff(name, 1),
c865cb1d 27 fDef(def),
28 fMother()
29{
30//
31// Default constructor.
32// Do not repeat 'DefineOutput' since it is done in base class and we don't add new ones.
33//
34}
35
36//_____________________________________________________________________________
37AliRsnLoopEffPair::AliRsnLoopEffPair(const AliRsnLoopEffPair& copy) :
38 AliRsnLoopEff(copy),
39 fDef(copy.fDef),
40 fMother(copy.fMother)
41{
42//
43// Copy constrtuctor.
44//
45}
46
47//_____________________________________________________________________________
48AliRsnLoopEffPair& AliRsnLoopEffPair::operator=(const AliRsnLoopEffPair& copy)
49{
50//
51// Assignment operator.
52// Owned data members are meaningless for this operator.
53//
54
55 AliRsnLoopEff::operator=(copy);
56 fDef = copy.fDef;
57
58 return (*this);
59}
60
f34f960b 61//__________________________________________________________________________________________________
62Bool_t AliRsnLoopEffPair::AssignMotherAndDaughters(AliRsnEvent *rsnEvent, Int_t ipart)
63{
64//
65// Calls the appropriate assignment method
66//
67
68 // setup pointers
69 fMother.SetDaughter(0, &fDaughter[0]);
70 fMother.SetDaughter(1, &fDaughter[1]);
71 fMother.SetRefEvent(rsnEvent);
72 fDaughter[0].SetOwnerEvent(rsnEvent);
73 fDaughter[1].SetOwnerEvent(rsnEvent);
74
75 if (rsnEvent->IsESD())
76 return AssignMotherAndDaughtersESD(rsnEvent, ipart);
77 else if (rsnEvent->IsAOD())
78 return AssignMotherAndDaughtersAOD(rsnEvent, ipart);
79 else {
80 AliError("Unrecognized input event");
81 return kFALSE;
82 }
83}
84
85//__________________________________________________________________________________________________
86Bool_t AliRsnLoopEffPair::AssignMotherAndDaughtersESD(AliRsnEvent *rsnEvent, Int_t ipart)
87{
88//
89// Gets a particle in the MC event and try to assign it to the mother.
90// If it has two daughters, retrieve them and assign also them.
91// NOTE: assignment is done only for MC, since reconstructed match is assigned in the same way
92// for ESD and AOD, if available
93// ---
94// Implementation for ESD inputs
95//
96
97 AliMCEvent *mc = rsnEvent->GetRefMCESD();
98 AliStack *stack = mc->Stack();
99 AliMCParticle *mother = (AliMCParticle*)mc->GetTrack(ipart);
100 TParticle *motherP = mother->Particle();
101 Int_t ntracks = stack->GetNtrack();
102
103 // check PDG code and exit if it is wrong
104 if (TMath::Abs(motherP->GetPdgCode()) != fDef->GetMotherPDG()) return kFALSE;
105
106 // check number of daughters and exit if it is not 2
107 if (motherP->GetNDaughters() < 2) return kFALSE;
108
109 // check distance from primary vertex
110 TLorentzVector vprod;
111 motherP->ProductionVertex(vprod);
112 if (!CheckDistanceFromPV(vprod.X(), vprod.Y(), vprod.Z())) {
113 AliDebugClass(1, "Distant production vertex");
114 return kFALSE;
115 }
116
117 // get the daughters and check their PDG code and charge:
118 // if they match one of the pair daughter definitions,
119 // assign them as MC reference of the 'fDaughter' objects
120 fDaughter[0].Reset();
121 fDaughter[1].Reset();
122 Int_t index[2] = {motherP->GetFirstDaughter(), motherP->GetLastDaughter()};
123 Int_t i, pdg;
124 Short_t charge;
125 AliMCParticle *daughter = 0x0;
126 for (i = 0; i < 2; i++) {
127 // check index for stack
128 if (index[i] < 0 || index[i] > ntracks) {
129 AliError(Form("Index %d overflow: value = %d, max = %d", i, index[i], ntracks));
130 return kFALSE;
131 }
132 // get daughter and its PDG and charge
133 daughter = (AliMCParticle*)mc->GetTrack(index[i]);
134 pdg = TMath::Abs(daughter->Particle()->GetPdgCode());
135 charge = (Short_t)(daughter->Particle()->GetPDG()->Charge() / 3);
136 // check if it matches one definition
137 if (fDef->GetDef1().MatchesPDG(pdg) && fDef->GetDef1().MatchesChargeS(charge)) {
138 fDaughter[0].SetGood();
139 fDaughter[0].SetRefMC(daughter);
140 fDaughter[0].SetLabel(index[i]);
141 } else if (fDef->GetDef2().MatchesPDG(pdg) && fDef->GetDef2().MatchesChargeS(charge)) {
142 fDaughter[1].SetGood();
143 fDaughter[1].SetRefMC(daughter);
144 fDaughter[1].SetLabel(index[i]);
145 }
146 }
147
148 // return success if both daughters were assigned
149 if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
150 return kTRUE;
151 } else {
152 fDaughter[0].Reset();
153 fDaughter[1].Reset();
154 return kFALSE;
155 }
156}
157
158//__________________________________________________________________________________________________
159Bool_t AliRsnLoopEffPair::AssignMotherAndDaughtersAOD(AliRsnEvent *rsnEvent, Int_t ipart)
160{
161 AliAODEvent *aod = rsnEvent->GetRefAOD();
162 TClonesArray *listAOD = (TClonesArray*)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
163 AliAODMCParticle *mother = (AliAODMCParticle*)listAOD->At(ipart);
164 Int_t ntracks = listAOD->GetEntries();
165
166 // check PDG code and exit if it is wrong
167 if (TMath::Abs(mother->GetPdgCode()) != fDef->GetMotherPDG()) return kFALSE;
168
169 // check number of daughters and exit if it is not 2
170 if (mother->GetNDaughters() < 2) return kFALSE;
171
172 // check distance from primary vertex
173 Double_t vprod[3] = {(Double_t)mother->Xv(), (Double_t)mother->Yv(), (Double_t)mother->Zv()};
174 Double_t dv = DistanceFromPV(vprod[0], vprod[1], vprod[2]);
175 if (dv > fMaxDistPV) {
176 AliDebugClass(1, "Distant production vertex");
177 return kFALSE;
178 }
179
180 // get the daughters and check their PDG code and charge:
181 // if they match one of the pair daughter definitions,
182 // assign them as MC reference of the 'fDaughter' objects
183 fDaughter[0].Reset();
184 fDaughter[1].Reset();
185 Int_t index[2] = {(Int_t)mother->GetDaughter(0), (Int_t)mother->GetDaughter(1)};
186 Int_t i, pdg;
187 Short_t charge;
188 AliAODMCParticle *daughter = 0x0;
189 for (i = 0; i < 2; i++) {
190 // check index for stack
191 if (index[i] < 0 || index[i] > ntracks) {
192 AliError(Form("Index %d overflow: value = %d, max = %d", i, index[i], ntracks));
193 return kFALSE;
194 }
195 // get daughter and its PDG and charge
196 daughter = (AliAODMCParticle*)listAOD->At(index[i]);
197 pdg = TMath::Abs(daughter->GetPdgCode());
198 charge = (Short_t)(daughter->Charge() / 3);
199 // check if it matches one definition
200 if (fDef->GetDef1().MatchesPDG(pdg) && fDef->GetDef1().MatchesChargeS(charge)) {
201 fDaughter[0].SetGood();
202 fDaughter[0].SetRefMC(daughter);
203 fDaughter[0].SetLabel(index[i]);
204 } else if (fDef->GetDef2().MatchesPDG(pdg) && fDef->GetDef2().MatchesChargeS(charge)) {
205 fDaughter[1].SetGood();
206 fDaughter[1].SetRefMC(daughter);
207 fDaughter[1].SetLabel(index[i]);
208 }
209 }
210
211 // return success if both daughters were assigned
212 if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
213 return kTRUE;
214 } else {
215 fDaughter[0].Reset();
216 fDaughter[1].Reset();
217 return kFALSE;
218 }
219}
220
c865cb1d 221//_____________________________________________________________________________
222Int_t AliRsnLoopEffPair::DoLoop(AliRsnEvent *rsn, AliRsnDaughterSelector*, AliRsnEvent*, AliRsnDaughterSelector*)
223{
224//
225// Loop on event and fill containers
226//
227
228 // check event cuts
229 if (!OkEvent(rsn)) return 0;
230
f34f960b 231 // retrieve output
232 fOutput = (AliRsnListOutput*)fOutputs[0];
233
c865cb1d 234 // check presence of MC reference
235 if (!rsn->GetRefMC()) {
236 AliError("Need a MC to compute efficiency");
237 return 0;
238 }
239
f34f960b 240 // check presence of event
241 if (!rsn->GetRef()) {
242 AliError("Need an event to compute efficiency");
243 return 0;
244 }
245
c865cb1d 246 // check event type:
247 // must be ESD or AOD, and then use a bool to know in the rest
248 if (!rsn->IsESD() && !rsn->IsAOD()) {
249 AliError("Need to process ESD or AOD input");
250 return 0;
251 }
c865cb1d 252
f34f960b 253 // retrieve the MC primary vertex position
254 // and do some additional coherence checks
255 Int_t i, npart = 0;
e187bd70 256 if (rsn->IsESD()) {
f34f960b 257 TArrayF mcVertex(3);
258 AliGenEventHeader *genEH = rsn->GetRefMCESD()->GenEventHeader();
259 genEH->PrimaryVertex(mcVertex);
260 for (i = 0; i < 3; i++) fVertex[i] = (Double_t)mcVertex[i];
261 npart = rsn->GetRefMCESD()->GetNumberOfTracks();
c865cb1d 262 } else {
f34f960b 263 for (i = 0; i < 3; i++) fVertex[i] = 0.0;
264 AliAODEvent *aod = rsn->GetRefMCAOD();
265 TClonesArray *listAOD = (TClonesArray*)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
266 if (listAOD) npart = listAOD->GetEntries();
267 AliAODMCHeader *mcH = static_cast<AliAODMCHeader*>(aod->FindListObject(AliAODMCHeader::StdBranchName()));
268 if (mcH) mcH->GetVertex(fVertex);
c865cb1d 269 }
270
271 // check number of particles
272 if (!npart) {
273 AliInfo("Empty event");
274 return 0;
275 }
c865cb1d 276
277 // utility variables
f34f960b 278 Int_t ipart, istep, count = 0, nsteps = fSteps.GetEntries();
279 Int_t ntracks = rsn->GetAbsoluteSum();
280 AliRsnDaughter check;
c865cb1d 281
282 // loop over particles
283 for (ipart = 0; ipart < npart; ipart++) {
f34f960b 284 // check i-th particle
285 if (!AssignMotherAndDaughters(rsn, ipart)) continue;
286 // if assignment was successful, for first step, use MC info
287 fDaughter[0].SetRef(fDaughter[0].GetRefMC());
288 fDaughter[1].SetRef(fDaughter[1].GetRefMC());
289 fMother.SetRefEvent(rsn);
290 fMother.ComputeSum(fDef->GetDef1().GetMass(), fDef->GetDef2().GetMass(), fDef->GetMotherMass());
291 fOutput->Fill(&fMother, 0);
c865cb1d 292 count++;
f34f960b 293 // for each further step, try to find two tracks which pass the related cuts
294 for (istep = 0; istep < nsteps; istep++) {
295 AliRsnCutManager *cuts = (AliRsnCutManager*)fSteps[istep];
296 fDaughter[0].SetBad();
297 fDaughter[1].SetBad();
298 for (i = 0; i < ntracks; i++) {
299 rsn->SetDaughter(check, i);
300 if (!cuts->PassCommonDaughterCuts(&check)) continue;
301 if (TMath::Abs(check.GetLabel()) == fDaughter[0].GetLabel()) {
302 if (!cuts->PassDaughter1Cuts(&check)) continue;
303 fDaughter[0].SetRef(check.GetRef());
304 fDaughter[0].SetGood();
305 } else if (TMath::Abs(check.GetLabel()) == fDaughter[1].GetLabel()) {
306 if (!cuts->PassDaughter2Cuts(&check)) continue;
307 fDaughter[1].SetRef(check.GetRef());
308 fDaughter[1].SetGood();
309 }
310 if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
311 fMother.ComputeSum(fDef->GetDef1().GetMass(), fDef->GetDef2().GetMass(), fDef->GetMotherMass());
312 if (cuts->PassMotherCuts(&fMother)) {
313 fOutput->Fill(&fMother, 1 + istep);
314 break;
315 }
316 }
c865cb1d 317 }
318 }
319 }
320
321 return count;
322}