]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG2/RESONANCES/AliRsnLoopPair.cxx
Added first version of cut monitoring + style format applied
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnLoopPair.cxx
CommitLineData
c865cb1d 1//
2// *** Class AliRsnLoopPair ***
3//
4// "Core" method for defining the work on a pari of particles.
5// For one analysis, one must setup one of this for each pair he wants to analyze,
6// adding to it all analysis which he desires to do.
7// Here he defines the cuts, and the particle types and charges, and can add
8// functions which do different operations on the same pair, and some binning
9// with respect to some kinematic variables (eta, momentum)
10//
11// authors: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it)
12// M. Vala (email: martin.vala@cern.ch)
13//
14
f34f960b 15#include <Riostream.h>
c865cb1d 16#include <TList.h>
17#include <TEntryList.h>
18
19#include "AliLog.h"
20
b63357a0 21#include "AliRsnEvent.h"
22#include "AliRsnPairDef.h"
c865cb1d 23#include "AliRsnMother.h"
24#include "AliRsnCutSet.h"
25#include "AliRsnDaughterSelector.h"
26
27#include "AliRsnLoopPair.h"
28
29ClassImp(AliRsnLoopPair)
30
31//_____________________________________________________________________________
32AliRsnLoopPair::AliRsnLoopPair(const char *name, AliRsnPairDef *def, Bool_t isMixed) :
33 AliRsnLoop(name, isMixed),
b63357a0 34 fTrueMC(kFALSE),
c865cb1d 35 fOnlyTrue(kFALSE),
52e6652d 36 fUseMCRef(kFALSE),
c865cb1d 37 fCheckDecay(kFALSE),
b63357a0 38 fRangeY(1E20),
c865cb1d 39 fPairDef(def),
40 fPairCuts(0x0),
41 fMother()
42{
43//
44// Default constructor
45//
46
47 fListID[0] = -1;
48 fListID[1] = -1;
49}
50
51//_____________________________________________________________________________
52e6652d 52AliRsnLoopPair::AliRsnLoopPair(const AliRsnLoopPair &copy) :
c865cb1d 53 AliRsnLoop(copy),
b63357a0 54 fTrueMC(copy.fTrueMC),
c865cb1d 55 fOnlyTrue(copy.fOnlyTrue),
52e6652d 56 fUseMCRef(copy.fUseMCRef),
c865cb1d 57 fCheckDecay(copy.fCheckDecay),
b63357a0 58 fRangeY(copy.fRangeY),
c865cb1d 59 fPairDef(copy.fPairDef),
60 fPairCuts(copy.fPairCuts),
61 fMother(copy.fMother)
62{
63//
64// Copy constructor
65//
66
67 fListID[0] = copy.fListID[0];
68 fListID[1] = copy.fListID[1];
69}
70
71//_____________________________________________________________________________
52e6652d 72AliRsnLoopPair &AliRsnLoopPair::operator=(const AliRsnLoopPair &copy)
c865cb1d 73{
b63357a0 74//
75// Assignment operator
76//
77
c865cb1d 78 AliRsnLoop::operator=(copy);
e6f3a909 79 if (this == &copy)
61f275d1 80 return *this;
b63357a0 81 fTrueMC = copy.fTrueMC;
c865cb1d 82 fOnlyTrue = copy.fOnlyTrue;
52e6652d 83 fUseMCRef = copy.fUseMCRef;
c865cb1d 84 fCheckDecay = copy.fCheckDecay;
b63357a0 85 fRangeY = copy.fRangeY;
c865cb1d 86 fPairDef = copy.fPairDef;
87 fPairCuts = copy.fPairCuts;
88 fMother = copy.fMother;
89 fListID[0] = copy.fListID[0];
90 fListID[1] = copy.fListID[1];
91
92 return (*this);
93}
94
95//_____________________________________________________________________________
96AliRsnLoopPair::~AliRsnLoopPair()
97{
98//
99// Destructor
100//
101}
102
103//_____________________________________________________________________________
104void AliRsnLoopPair::Print(Option_t* /*option*/) const
105{
106//
107// Prints info about pair
108//
109
110 AliRsnLoop::Print();
111}
112
113//_____________________________________________________________________________
114Bool_t AliRsnLoopPair::Init(const char *prefix, TList *list)
115{
116//
117// Initialization function.
118// Loops on all functions and eventual the ntuple, to initialize output objects.
119//
120
121 // assign data members relations
122 fMother.SetDaughter(0, &fDaughter[0]);
123 fMother.SetDaughter(1, &fDaughter[1]);
124 AliInfo(Form("[%s] Initialization", GetName()));
52e6652d 125
c865cb1d 126 TString name(prefix);
127 name += '_';
128 name += GetName();
52e6652d 129// if (IsMixed()) name.Prepend("mix_");
130 if (IsMixed()) name.Append("_mix");
131
c865cb1d 132 return AliRsnLoop::Init(name.Data(), list);
133}
134
135//_____________________________________________________________________________
136Int_t AliRsnLoopPair::DoLoop
137(AliRsnEvent *evMain, AliRsnDaughterSelector *selMain, AliRsnEvent *evMix, AliRsnDaughterSelector *selMix)
138{
139//
140// Loop function.
141// Computes what is needed from passed events.
142// Returns the number of pairs successfully processed.
143//
144
145 if (fIsMixed) {
b63357a0 146 AliDebugClass(3, Form("[%s]: event-mixing loop", GetName()));
c865cb1d 147 if (!evMix || !selMix) {
148 AliError(Form("[%s] NULL mixed event when mixing is required: cannot process", GetName()));
149 return 0;
150 }
151 } else {
b63357a0 152 AliDebugClass(3, Form("[%s]: single-event loop", GetName()));
c865cb1d 153 evMix = evMain;
154 selMix = selMain;
155 }
156 fMother.SetRefEvent(evMain);
52e6652d 157
c865cb1d 158 // check cuts
159 if (!OkEvent(evMain)) {
b63357a0 160 AliDebugClass(3, Form("[%s]: main event not accepted", GetName()));
c865cb1d 161 return 0;
162 }
163 if (!OkEvent(evMix)) {
b63357a0 164 AliDebugClass(3, Form("[%s]: mixed event not accepted", GetName()));
c865cb1d 165 return 0;
166 }
52e6652d 167
b63357a0 168 // if it is required to loop over True MC, do this here and skip the rest of the method
169 if (fTrueMC) return LoopTrueMC(evMain);
52e6652d 170
c865cb1d 171 Int_t i0, i1, start, npairs = 0;
52e6652d 172
c865cb1d 173 TEntryList *list0 = selMain->GetSelected(fListID[0], fPairDef->GetDef1().GetChargeC());
174 TEntryList *list1 = selMix ->GetSelected(fListID[1], fPairDef->GetDef2().GetChargeC());
175 if (!list0 || !list1) {
176 AliError("Can't process NULL lists");
177 return 0;
178 }
52e6652d 179 AliDebugClass(3, Form("[%s]: list counts: %lld, %lld", GetName(), list0->GetN(), list1->GetN()));
c865cb1d 180 if (!list0->GetN() || !list1->GetN()) {
b63357a0 181 AliDebugClass(3, Form("[%s]: at least one list is empty", GetName()));
c865cb1d 182 return 0;
183 }
52e6652d 184
c865cb1d 185 TObjArrayIter next(&fOutputs);
186 AliRsnListOutput *out = 0x0;
52e6652d 187 Long64_t iEntry1,iEntry2;
c865cb1d 188 for (i0 = 0; i0 < list0->GetN(); i0++) {
52e6652d 189 iEntry1 = list0->GetEntry(i0);
190 evMain->SetDaughter(fDaughter[0], iEntry1,fUseMCRef);
f34f960b 191 fDaughter[0].FillP(fPairDef->GetDef1().GetMass());
c865cb1d 192 start = 0;
c865cb1d 193 if (!fIsMixed && list0 == list1) start = i0 + 1;
194 for (i1 = start; i1 < list1->GetN(); i1++) {
52e6652d 195 iEntry2 = list1->GetEntry(i1);
61f275d1 196 if (iEntry1 == iEntry2) continue;
52e6652d 197 AliDebugClass(4, Form("Checking entries pair: %d (%lld) with %d (%lld)", i0, iEntry1, i1, iEntry2));
198 evMix->SetDaughter(fDaughter[1], iEntry2,fUseMCRef);
f34f960b 199 fDaughter[1].FillP(fPairDef->GetDef2().GetMass());
200 fMother.Sum(0) = fDaughter[0].Prec() + fDaughter[1].Prec();
201 fMother.Sum(1) = fDaughter[0].Psim() + fDaughter[1].Psim();
202 fMother.Ref(0).SetXYZM(fMother.Sum(0).X(), fMother.Sum(0).Y(), fMother.Sum(0).Z(), fPairDef->GetMotherMass());
203 fMother.Ref(1).SetXYZM(fMother.Sum(1).X(), fMother.Sum(1).Y(), fMother.Sum(1).Z(), fPairDef->GetMotherMass());
b63357a0 204 // check rapidity range
205 if (TMath::Abs(fMother.Rapidity(0)) > fRangeY) {
206 AliDebugClass(2, Form("[%s]: Outside rapidity range", GetName()));
207 continue;
c865cb1d 208 }
209 // check mother
f34f960b 210 if (fOnlyTrue) {
211 if (!IsTrueMother()) {
212 AliDebugClass(2, Form("[%s]: candidate mother is not true", GetName()));
213 continue;
214 }
c865cb1d 215 }
b63357a0 216 // check cuts
217 if (fPairCuts) {
218 if (!fPairCuts->IsSelected(&fMother)) {
219 AliDebugClass(2, Form("[%s]: candidate mother didn't pass the cuts", GetName()));
220 continue;
221 }
222 }
c865cb1d 223 // fill outputs
224 next.Reset();
52e6652d 225 while ( (out = (AliRsnListOutput *)next()) ) {
c865cb1d 226 if (out->Fill(&fMother)) npairs++;
227 else AliDebugClass(3, Form("[%s]: failed computation", GetName()));
228 }
229 }
230 }
f34f960b 231
c865cb1d 232 return npairs;
233}
234
235//_____________________________________________________________________________
f34f960b 236Bool_t AliRsnLoopPair::IsTrueMother()
c865cb1d 237{
238//
f34f960b 239// Checks to see if the mother comes from a true resonance.
240// It is triggered by the 'SetOnlyTrue()' function
c865cb1d 241//
52e6652d 242
f34f960b 243 // check #1:
244 // daughters have same mother with the right PDG code
245 Int_t commonPDG = fMother.CommonMother();
246 if (commonPDG != fPairDef->GetMotherPDG()) return kFALSE;
b63357a0 247 AliDebugClass(1, "Found a true mother");
52e6652d 248
f34f960b 249 // check #2:
250 // checks if daughter have the right particle type
251 // (activated by fCheckDecay)
252 if (fCheckDecay) {
253 AliRsnDaughterDef &def1 = fPairDef->GetDef1();
254 AliRsnDaughterDef &def2 = fPairDef->GetDef2();
255 if (!def1.MatchesPID(&fDaughter[0])) return kFALSE;
256 if (!def2.MatchesPID(&fDaughter[1])) return kFALSE;
c865cb1d 257 }
b63357a0 258 AliDebugClass(1, "Decay products match");
52e6652d 259
f34f960b 260 return kTRUE;
c865cb1d 261}
b63357a0 262
263//__________________________________________________________________________________________________
264Bool_t AliRsnLoopPair::AssignMotherAndDaughters(AliRsnEvent *rsnEvent, Int_t ipart)
265{
266//
267// Calls the appropriate assignment method
268//
269
270 // setup pointers
271 fMother.SetDaughter(0, &fDaughter[0]);
272 fMother.SetDaughter(1, &fDaughter[1]);
273 fMother.SetRefEvent(rsnEvent);
274 fDaughter[0].SetOwnerEvent(rsnEvent);
275 fDaughter[1].SetOwnerEvent(rsnEvent);
276
277 if (rsnEvent->IsESD())
278 return AssignMotherAndDaughtersESD(rsnEvent, ipart);
279 else if (rsnEvent->IsAOD())
280 return AssignMotherAndDaughtersAOD(rsnEvent, ipart);
281 else {
282 AliError("Unrecognized input event");
283 return kFALSE;
284 }
285}
286
287//__________________________________________________________________________________________________
288Bool_t AliRsnLoopPair::AssignMotherAndDaughtersESD(AliRsnEvent *rsnEvent, Int_t ipart)
289{
290//
291// Gets a particle in the MC event and try to assign it to the mother.
292// If it has two daughters, retrieve them and assign also them.
293// NOTE: assignment is done only for MC, since reconstructed match is assigned in the same way
294// for ESD and AOD, if available
295// ---
296// Implementation for ESD inputs
297//
298
299 AliMCEvent *mc = rsnEvent->GetRefMCESD();
300 AliStack *stack = mc->Stack();
52e6652d 301 AliMCParticle *mother = (AliMCParticle *)mc->GetTrack(ipart);
b63357a0 302 TParticle *motherP = mother->Particle();
303 Int_t ntracks = stack->GetNtrack();
52e6652d 304
b63357a0 305 // check PDG code and exit if it is wrong
306 if (TMath::Abs(motherP->GetPdgCode()) != fPairDef->GetMotherPDG()) return kFALSE;
52e6652d 307
b63357a0 308 // check number of daughters and exit if it is not 2
309 if (motherP->GetNDaughters() < 2) return kFALSE;
310 //if (!stack->IsPhysicalPrimary(ipart)) return kFALSE;
52e6652d 311
b63357a0 312 /*
313 // check distance from primary vertex
314 TLorentzVector vprod;
315 motherP->ProductionVertex(vprod);
316 if (!CheckDistanceFromPV(vprod.X(), vprod.Y(), vprod.Z())) {
317 AliDebugClass(1, "Distant production vertex");
318 return kFALSE;
319 }
320 */
52e6652d 321
b63357a0 322 // get the daughters and check their PDG code and charge:
52e6652d 323 // if they match one of the pair daughter definitions,
b63357a0 324 // assign them as MC reference of the 'fDaughter' objects
325 fDaughter[0].Reset();
326 fDaughter[1].Reset();
327 Int_t index[2] = {motherP->GetDaughter(0), motherP->GetDaughter(1)};
328 Int_t i, pdg;
329 Short_t charge;
330 AliMCParticle *daughter = 0x0;
331 for (i = 0; i < 2; i++) {
332 // check index for stack
333 if (index[i] < 0 || index[i] > ntracks) {
334 AliError(Form("Index %d overflow: value = %d, max = %d", i, index[i], ntracks));
335 return kFALSE;
336 }
337 // get daughter and its PDG and charge
52e6652d 338 daughter = (AliMCParticle *)mc->GetTrack(index[i]);
b63357a0 339 pdg = TMath::Abs(daughter->Particle()->GetPdgCode());
340 charge = (Short_t)(daughter->Particle()->GetPDG()->Charge() / 3);
341 // check if it matches one definition
342 if (fPairDef->GetDef1().MatchesPDG(pdg) && fPairDef->GetDef1().MatchesChargeS(charge)) {
343 fDaughter[0].SetGood();
344 fDaughter[0].SetRefMC(daughter);
345 fDaughter[0].SetLabel(index[i]);
346 } else if (fPairDef->GetDef2().MatchesPDG(pdg) && fPairDef->GetDef2().MatchesChargeS(charge)) {
347 fDaughter[1].SetGood();
348 fDaughter[1].SetRefMC(daughter);
349 fDaughter[1].SetLabel(index[i]);
350 }
351 }
52e6652d 352
b63357a0 353 // return success if both daughters were assigned
354 if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
355 return kTRUE;
356 } else {
357 fDaughter[0].Reset();
358 fDaughter[1].Reset();
359 return kFALSE;
360 }
361}
362
363//__________________________________________________________________________________________________
364Bool_t AliRsnLoopPair::AssignMotherAndDaughtersAOD(AliRsnEvent *rsnEvent, Int_t ipart)
365{
366//
367// Gets a particle in the MC event and try to assign it to the mother.
368// If it has two daughters, retrieve them and assign also them.
369// NOTE: assignment is done only for MC, since reconstructed match is assigned in the same way
370// for ESD and AOD, if available
371// ---
372// Implementation for AOD inputs
373//
374
375 AliAODEvent *aod = rsnEvent->GetRefAOD();
52e6652d 376 TClonesArray *listAOD = (TClonesArray *)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
377 AliAODMCParticle *mother = (AliAODMCParticle *)listAOD->At(ipart);
378
b63357a0 379 // check PDG code and exit if it is wrong
380 if (TMath::Abs(mother->GetPdgCode()) != fPairDef->GetMotherPDG()) return kFALSE;
52e6652d 381
b63357a0 382 // check number of daughters and exit if it is not 2
383 if (mother->GetNDaughters() < 2) return kFALSE;
384 if (!mother->IsPrimary()) return kFALSE;
52e6652d 385
b63357a0 386 /*
387 // check distance from primary vertex
388 Double_t vprod[3] = {(Double_t)mother->Xv(), (Double_t)mother->Yv(), (Double_t)mother->Zv()};
389 Double_t dv = DistanceFromPV(vprod[0], vprod[1], vprod[2]);
390 if (dv > fMaxDistPV) {
391 AliDebugClass(1, "Distant production vertex");
392 return kFALSE;
393 }
394 */
52e6652d 395
b63357a0 396 // get the daughters and check their PDG code and charge:
52e6652d 397 // if they match one of the pair daughter definitions,
b63357a0 398 // assign them as MC reference of the 'fDaughter' objects
399 fDaughter[0].Reset();
400 fDaughter[1].Reset();
401 Int_t index[2] = {(Int_t)mother->GetDaughter(0), (Int_t)mother->GetDaughter(1)};
402 Int_t ntracks = listAOD->GetEntriesFast();
403 Int_t i, pdg;
404 Short_t charge;
405 AliAODMCParticle *daughter = 0x0;
406 for (i = 0; i < 2; i++) {
407 // check index for stack
408 if (index[i] < 0 || index[i] > ntracks) {
409 AliError(Form("Index %d overflow: value = %d, max = %d", i, index[i], ntracks));
410 return kFALSE;
411 }
412 // get daughter and its PDG and charge
52e6652d 413 daughter = (AliAODMCParticle *)listAOD->At(index[i]);
b63357a0 414 pdg = TMath::Abs(daughter->GetPdgCode());
415 charge = (Short_t)(daughter->Charge() / 3);
416 // check if it matches one definition
417 if (fPairDef->GetDef1().MatchesPDG(pdg) && fPairDef->GetDef1().MatchesChargeS(charge)) {
418 fDaughter[0].SetGood();
419 fDaughter[0].SetRefMC(daughter);
420 fDaughter[0].SetLabel(index[i]);
421 } else if (fPairDef->GetDef2().MatchesPDG(pdg) && fPairDef->GetDef2().MatchesChargeS(charge)) {
422 fDaughter[1].SetGood();
423 fDaughter[1].SetRefMC(daughter);
424 fDaughter[1].SetLabel(index[i]);
425 }
426 }
52e6652d 427
b63357a0 428 // return success if both daughters were assigned
429 if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
430 return kTRUE;
431 } else {
432 fDaughter[0].Reset();
433 fDaughter[1].Reset();
434 return kFALSE;
435 }
436}
437
438//_____________________________________________________________________________
439Int_t AliRsnLoopPair::LoopTrueMC(AliRsnEvent *rsn)
440{
441//
442// Loop on event and fill containers
443//
444
445 // check presence of MC reference
446 if (!rsn->GetRefMC()) {
447 AliError("Need a MC to compute efficiency");
448 return 0;
449 }
52e6652d 450
b63357a0 451 // check event type:
452 // must be ESD or AOD, and then use a bool to know in the rest
453 if (!rsn->IsESD() && !rsn->IsAOD()) {
454 AliError("Need to process ESD or AOD input");
455 return 0;
456 }
52e6652d 457
b63357a0 458 // retrieve the MC primary vertex position
459 // and do some additional coherence checks
460 //Double_t fVertex[3] = {0.0, 0.0, 0.0};
461 Int_t npart = 0;
462 if (rsn->IsESD()) {
463 //TArrayF mcVertex(3);
464 //AliGenEventHeader *genEH = rsn->GetRefMCESD()->GenEventHeader();
465 //genEH->PrimaryVertex(mcVertex);
466 //for (i = 0; i < 3; i++) fVertex[i] = (Double_t)mcVertex[i];
467 npart = rsn->GetRefMCESD()->GetNumberOfTracks();
468 } else {
469 //for (i = 0; i < 3; i++) fVertex[i] = 0.0;
470 AliAODEvent *aod = rsn->GetRefMCAOD();
52e6652d 471 TClonesArray *listAOD = (TClonesArray *)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
b63357a0 472 if (listAOD) npart = listAOD->GetEntries();
473 //AliAODMCHeader *mcH = static_cast<AliAODMCHeader*>(aod->FindListObject(AliAODMCHeader::StdBranchName()));
474 //if (mcH) mcH->GetVertex(fVertex);
475 }
52e6652d 476
b63357a0 477 // check number of particles
478 if (!npart) {
479 AliInfo("Empty event");
480 return 0;
481 }
52e6652d 482
b63357a0 483 // utility variables
484 Int_t ipart, count = 0;
485 AliRsnDaughter check;
52e6652d 486
b63357a0 487 TObjArrayIter next(&fOutputs);
488 AliRsnListOutput *out = 0x0;
52e6652d 489
b63357a0 490 // loop over particles
491 for (ipart = 0; ipart < npart; ipart++) {
492 // check i-th particle
493 if (!AssignMotherAndDaughters(rsn, ipart)) continue;
494 // if assignment was successful, for first step, use MC info
495 fDaughter[0].SetRef(fDaughter[0].GetRefMC());
496 fDaughter[1].SetRef(fDaughter[1].GetRefMC());
497 fMother.SetRefEvent(rsn);
498 fMother.ComputeSum(fPairDef->GetDef1().GetMass(), fPairDef->GetDef2().GetMass(), fPairDef->GetMotherMass());
499 // check rapidity range
500 if (TMath::Abs(fMother.Rapidity(0)) > fRangeY) {
501 AliDebugClass(2, Form("[%s]: Outside rapidity range", GetName()));
502 continue;
503 }
504 // fill outputs
505 next.Reset();
52e6652d 506 while ( (out = (AliRsnListOutput *)next()) ) {
b63357a0 507 if (out->Fill(&fMother)) count++;
508 else AliDebugClass(3, Form("[%s]: failed computation", GetName()));
509 }
510 }
52e6652d 511
b63357a0 512 return count;
513}
52e6652d 514