2 // Analysis task for 'mini' sub-package
3 // Contains all definitions needed for running an analysis:
5 // -- a list of track cuts (any number)
6 // -- definitions of output histograms
7 // -- values to be computed.
8 // Each one must be defined using the "CREATE" methods, which
9 // add directly a new element in the task collections, and don't
10 // need an external object to be passed to the task itself.
13 #include <Riostream.h>
20 #include "AliEventplane.h"
21 #include "AliMultiplicity.h"
22 #include "AliTriggerAnalysis.h"
23 #include "AliAnalysisManager.h"
24 #include "AliInputEventHandler.h"
26 #include "AliESDtrackCuts.h"
27 #include "AliESDUtils.h"
29 #include "AliAODEvent.h"
30 #include "AliAODMCParticle.h"
32 #include "AliRsnCutSet.h"
33 #include "AliRsnMiniPair.h"
34 #include "AliRsnMiniEvent.h"
35 #include "AliRsnMiniParticle.h"
37 #include "AliRsnMiniAnalysisTask.h"
39 ClassImp(AliRsnMiniAnalysisTask)
41 //__________________________________________________________________________________________________
42 AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask() :
46 fUseCentrality(kFALSE),
47 fCentralityType("QUALITY"),
53 fHistograms("AliRsnMiniOutput", 0),
54 fValues("AliRsnMiniValue", 0),
65 // Dummy constructor ALWAYS needed for I/O.
69 //__________________________________________________________________________________________________
70 AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const char *name, Bool_t useMC) :
71 AliAnalysisTaskSE(name),
74 fUseCentrality(kFALSE),
75 fCentralityType("QUALITY"),
81 fHistograms("AliRsnMiniOutput", 0),
82 fValues("AliRsnMiniValue", 0),
93 // Default constructor.
94 // Define input and output slots here (never in the dummy constructor)
95 // Input slot #0 works with a TChain - it is connected to the default input container
96 // Output slot #1 writes into a TH1 container
99 DefineOutput(1, TList::Class());
102 //__________________________________________________________________________________________________
103 AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const AliRsnMiniAnalysisTask& copy) :
104 AliAnalysisTaskSE(copy),
107 fUseCentrality(copy.fUseCentrality),
108 fCentralityType(copy.fCentralityType),
110 fMaxDiffMult(copy.fMaxDiffMult),
111 fMaxDiffVz(copy.fMaxDiffVz),
112 fMaxDiffAngle(copy.fMaxDiffAngle),
114 fHistograms(copy.fHistograms),
115 fValues(copy.fValues),
117 fEventCuts(copy.fEventCuts),
118 fTrackCuts(copy.fTrackCuts),
121 fTriggerAna(copy.fTriggerAna),
122 fESDtrackCuts(copy.fESDtrackCuts),
127 // Implemented as requested by C++ standards.
128 // Can be used in PROOF and by plugins.
132 //__________________________________________________________________________________________________
133 AliRsnMiniAnalysisTask& AliRsnMiniAnalysisTask::operator=(const AliRsnMiniAnalysisTask& copy)
136 // Assignment operator.
137 // Implemented as requested by C++ standards.
138 // Can be used in PROOF and by plugins.
141 AliAnalysisTaskSE::operator=(copy);
143 fUseMC = copy.fUseMC;
144 fUseCentrality = copy.fUseCentrality;
145 fCentralityType = copy.fCentralityType;
147 fMaxDiffMult = copy.fMaxDiffMult;
148 fMaxDiffVz = copy.fMaxDiffVz;
149 fMaxDiffAngle = copy.fMaxDiffAngle;
150 fHistograms = copy.fHistograms;
151 fValues = copy.fValues;
152 fEventCuts = copy.fEventCuts;
153 fTrackCuts = copy.fTrackCuts;
154 fTriggerAna = copy.fTriggerAna;
155 fESDtrackCuts = copy.fESDtrackCuts;
160 //__________________________________________________________________________________________________
161 AliRsnMiniAnalysisTask::~AliRsnMiniAnalysisTask()
165 // Clean-up the output list, but not the histograms that are put inside
166 // (the list is owner and will clean-up these histograms). Protect in PROOF case.
169 cout << "CIAO" << endl;
170 if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
175 //__________________________________________________________________________________________________
176 Int_t AliRsnMiniAnalysisTask::AddTrackCuts(AliRsnCutSet *cuts)
179 // Add a new cut set for a new criterion for track selection.
180 // A user can add as many as he wants, and each one corresponds
181 // to one of the available bits in the AliRsnMiniParticle mask.
182 // The only check is the following: if a cut set with the same name
183 // as the argument is there, this is not added.
184 // Return value is the array position of this set.
187 TObject *obj = fTrackCuts.FindObject(cuts->GetName());
190 AliInfo(Form("A cut set named '%s' already exists", cuts->GetName()));
191 return fTrackCuts.IndexOf(obj);
193 fTrackCuts.AddLast(cuts);
194 return fTrackCuts.IndexOf(cuts);
198 //__________________________________________________________________________________________________
199 void AliRsnMiniAnalysisTask::UserCreateOutputObjects()
202 // Initialization of outputs.
203 // This is called once per worker node.
209 // initialize trigger analysis
210 if (fTriggerAna) delete fTriggerAna;
211 fTriggerAna = new AliTriggerAnalysis;
213 // initialize ESD quality cuts
214 if (fESDtrackCuts) delete fESDtrackCuts;
215 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010();
217 // create list and set it as owner of its content (MANDATORY)
218 fOutput = new TList();
221 // initialize event statistics counter
222 fHEventStat = new TH1F("hEventStat", "Event statistics", 4, 0.0, 4.0);
223 fHEventStat->GetXaxis()->SetBinLabel(1, "CINT1B");
224 fHEventStat->GetXaxis()->SetBinLabel(2, "V0AND");
225 fHEventStat->GetXaxis()->SetBinLabel(3, "Candle");
226 fHEventStat->GetXaxis()->SetBinLabel(4, "Accepted");
227 fOutput->Add(fHEventStat);
229 // create temporary tree for filtered events
230 if (fMiniEvent) delete fMiniEvent;
231 fEvBuffer = new TTree("EventBuffer", "Temporary buffer for mini events");
232 fEvBuffer->Branch("events", "AliRsnMiniEvent", &fMiniEvent);
234 // create one histogram per each stored definition (event histograms)
235 Int_t i, ndef = fHistograms.GetEntries();
236 AliRsnMiniOutput *def = 0x0;
237 for (i = 0; i < ndef; i++) {
238 def = (AliRsnMiniOutput*)fHistograms[i];
240 if (!def->Init(GetName(), fOutput)) {
241 AliError(Form("Def '%s': failed initialization", def->GetName()));
246 // setup PID response
247 AliAnalysisManager *man = AliAnalysisManager::GetAnalysisManager();
248 AliInputEventHandler *inputHandler = (AliInputEventHandler*)man->GetInputEventHandler();
249 fRsnEvent.SetPIDResponse(inputHandler->GetPIDResponse());
251 // post data for ALL output slots >0 here, to get at least an empty histogram
252 PostData(1, fOutput);
255 //__________________________________________________________________________________________________
256 void AliRsnMiniAnalysisTask::UserExec(Option_t *)
260 // In this case, it checks if the event is acceptable, and eventually
261 // creates the corresponding mini-event and stores it in the buffer.
262 // The real histogram filling is done at the end, in "FinishTaskOutput".
268 // check current event
269 Char_t check = CheckCurrentEvent();
272 // fill a mini-event from current
273 // and skip this event if no tracks were accepted
274 FillMiniEvent(check);
276 // fill MC based histograms on mothers,
277 // which do need the original event
279 if (fRsnEvent.IsESD() && fMCEvent)
280 FillTrueMotherESD(fMiniEvent);
281 else if (fRsnEvent.IsAOD() && fRsnEvent.GetAODList())
282 FillTrueMotherAOD(fMiniEvent);
288 // post data for computed stuff
289 PostData(1, fOutput);
292 //__________________________________________________________________________________________________
293 void AliRsnMiniAnalysisTask::FinishTaskOutput()
296 // This function is called at the end of the loop on available events,
297 // and then the buffer will be full with all the corresponding mini-events,
298 // each one containing all tracks selected by each of the available track cuts.
299 // Here a loop is done on each of these events, and both single-event and mixing are computed
302 // security code: reassign the buffer to the mini-event cursor
303 fEvBuffer->SetBranchAddress("events", &fMiniEvent);
306 Int_t ievt, nEvents = (Int_t)fEvBuffer->GetEntries();
307 Int_t idef, nDefs = fHistograms.GetEntries();
308 Int_t imix, iloop, ifill;
309 AliRsnMiniOutput *def = 0x0;
310 AliRsnMiniOutput::EComputation compType;
312 // loop on events, and for each one fill all outputs
313 // using the appropriate procedure depending on its type
314 // only mother-related histograms are filled in UserExec,
315 // since they require direct access to MC event
316 for (ievt = 0; ievt < nEvents; ievt++) {
318 fEvBuffer->GetEntry(ievt);
320 for (idef = 0; idef < nDefs; idef++) {
321 def = (AliRsnMiniOutput*)fHistograms[idef];
323 compType = def->GetComputation();
324 // execute computation in the appropriate way
326 case AliRsnMiniOutput::kEventOnly:
327 AliDebugClass(1, Form("Event %d, def '%s': event-value histogram filling", ievt, def->GetName()));
329 def->FillEvent(fMiniEvent, &fValues);
331 case AliRsnMiniOutput::kTruePair:
332 AliDebugClass(1, Form("Event %d, def '%s': true-pair histogram filling", ievt, def->GetName()));
333 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
335 case AliRsnMiniOutput::kTrackPair:
336 AliDebugClass(1, Form("Event %d, def '%s': pair-value histogram filling", ievt, def->GetName()));
337 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
339 case AliRsnMiniOutput::kTrackPairRotated1:
340 AliDebugClass(1, Form("Event %d, def '%s': rotated (1) background histogram filling", ievt, def->GetName()));
341 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
343 case AliRsnMiniOutput::kTrackPairRotated2:
344 AliDebugClass(1, Form("Event %d, def '%s': rotated (2) background histogram filling", ievt, def->GetName()));
345 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
348 // other kinds are processed elsewhere
350 AliDebugClass(2, Form("Computation = %d", (Int_t)compType));
353 AliDebugClass(1, Form("Event %6d: def = '%15s' -- fills = %5d", ievt, def->GetName(), ifill));
357 // if no mixing is required, stop here and post the output
359 AliDebugClass(2, "Stopping here, since no mixing is required");
360 PostData(1, fOutput);
364 // initialize mixing counter
365 TString *matched = new TString[nEvents];
366 for (ievt = 0; ievt < nEvents; ievt++) {
370 // search for good matchings
371 for (ievt = 0; ievt < nEvents; ievt++) {
373 fEvBuffer->GetEntry(ievt);
374 AliRsnMiniEvent evMain(*fMiniEvent);
375 for (iloop = 1; iloop < nEvents; iloop++) {
377 if (imix >= nEvents) imix -= nEvents;
378 if (imix == ievt) continue;
380 fEvBuffer->GetEntry(imix);
381 // skip if events are not matched
382 if (TMath::Abs(evMain.Vz() - fMiniEvent->Vz() ) > fMaxDiffVz ) continue;
383 if (TMath::Abs(evMain.Mult() - fMiniEvent->Mult() ) > fMaxDiffMult ) continue;
384 if (TMath::Abs(evMain.Angle() - fMiniEvent->Angle()) > fMaxDiffAngle) continue;
385 // check that the array of good matches for mixed does not already contain main event
386 if (matched[imix].Contains(Form("|%d|", ievt))) continue;
387 // add new mixing candidate
388 matched[ievt].Append(Form("%d|", imix));
390 if (ifill >= fNMix) break;
392 //cout << "Matches for event " << Form("%5d", ievt) << ": " << matched[ievt].Data() << " (" << ifill << ")" << endl;
396 TObjArray *list = 0x0;
397 TObjString *os = 0x0;
398 for (ievt = 0; ievt < nEvents; ievt++) {
400 fEvBuffer->GetEntry(ievt);
401 AliRsnMiniEvent evMain(*fMiniEvent);
402 list = matched[ievt].Tokenize("|");
403 TObjArrayIter next(list);
404 while ( (os = (TObjString*)next()) ) {
405 imix = os->GetString().Atoi();
406 //cout << "Mixing " << ievt << " with " << imix << endl;
407 fEvBuffer->GetEntry(imix);
408 for (idef = 0; idef < nDefs; idef++) {
409 def = (AliRsnMiniOutput*)fHistograms[idef];
411 if (!def->IsTrackPairMix()) continue;
412 ifill += def->FillPair(&evMain, fMiniEvent, &fValues);
423 for (iloop = 1; iloop < nEvents; iloop++) {
425 // restart from beginning if reached last event
426 if (imix >= nEvents) imix -= nEvents;
427 // avoid to mix an event with itself
428 if (imix == ievt) continue;
429 // skip all events already mixed enough times
430 if (fNMixed[ievt] >= fNMix) break;
431 if (fNMixed[imix] >= fNMix) continue;
432 fEvBuffer->GetEntry(imix);
433 // skip if events are not matched
434 if (TMath::Abs(evMain.Vz() - fMiniEvent->Vz() ) > fMaxDiffVz ) continue;
435 if (TMath::Abs(evMain.Mult() - fMiniEvent->Mult() ) > fMaxDiffMult ) continue;
436 if (TMath::Abs(evMain.Angle() - fMiniEvent->Angle()) > fMaxDiffAngle) continue;
437 // found a match: increment counter for both events
438 AliDebugClass(1, Form("Event %d, def '%s': event mixing (%d with %d)", ievt, def->GetName(), ievt, imix));
442 ifill += def->FillPair(&evMain, fMiniEvent, &fValues);
443 // stop if mixed enough times
444 if (fNMixed[ievt] >= fNMix) break;
447 // print number of mixings done with each event
448 for (ievt = 0; ievt < nEvents; ievt++) {
449 AliDebugClass(2, Form("Event %6d: mixed %2d times", ievt, fNMixed[ievt]));
453 // post computed data
454 PostData(1, fOutput);
457 //__________________________________________________________________________________________________
458 void AliRsnMiniAnalysisTask::Terminate(Option_t *)
461 // Draw result to screen, or perform fitting, normalizations
462 // Called once at the end of the query
465 fOutput = dynamic_cast<TList*>(GetOutputData(1));
467 AliError("Could not retrieve TList fOutput");
472 //__________________________________________________________________________________________________
473 Char_t AliRsnMiniAnalysisTask::CheckCurrentEvent()
476 // This method checks if current event is OK for analysis.
477 // In case it is, the pointers of the local AliRsnEvent data member
478 // will point to it, in order to allow cut checking, otherwise the
479 // function exits with a failure message.
481 // ESD events must pass the physics selection, AOD are supposed to do.
483 // While checking the event, a histogram is filled to count the number
484 // of CINT1B, V0AND and CANDLE events, which are needed for normalization
486 // Return values can be:
487 // -- 'E' if the event is accepted and is ESD
488 // -- 'A' if the event is accepted and is AOD
489 // -- 0 if the event is not accepted
492 // string to sum messages
496 // exit points are provided in all cases an event is bad
497 // if this block is passed, an event can be rejected only
498 // if it does not pass the set of event cuts defined in the task
501 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
504 // ESD specific check: Physics Selection
505 // --> if this is failed, the event is rejected
506 isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kMB);
508 AliDebugClass(2, "Event does not pass physics selections");
509 fRsnEvent.SetRef(0x0);
510 fRsnEvent.SetRefMC(0x0);
513 // set reference to input
514 fRsnEvent.SetRef(fInputEvent);
515 // add MC if requested and available
518 fRsnEvent.SetRefMC(fMCEvent);
520 AliWarning("MC event requested but not available");
521 fRsnEvent.SetRefMC(0x0);
524 } else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
527 // set reference to input
528 fRsnEvent.SetRef(fInputEvent);
529 // add MC if requested and available (it is in the same object)
531 fRsnEvent.SetRefMC(fInputEvent);
532 if (!fRsnEvent.GetAODList()) {
533 AliWarning("MC event requested but not available");
534 fRsnEvent.SetRefMC(0x0);
538 AliError(Form("Bad input event class: %s", fInputEvent->ClassName()));
539 // reset pointers in local AliRsnEvent object
540 fRsnEvent.SetRef(0x0);
541 fRsnEvent.SetRefMC(0x0);
545 // fill counter of accepted events
546 fHEventStat->Fill(0.1);
548 // check if it is V0AND
549 // --> uses a cast to AliESDEvent even if the input is an AliAODEvent
550 Bool_t v0A = fTriggerAna->IsOfflineTriggerFired((AliESDEvent*)fInputEvent, AliTriggerAnalysis::kV0A);
551 Bool_t v0C = fTriggerAna->IsOfflineTriggerFired((AliESDEvent*)fInputEvent, AliTriggerAnalysis::kV0C);
553 msg += " -- VOAND = YES";
554 fHEventStat->Fill(1.1);
556 msg += " -- VOAND = NO ";
560 // --> requires at least one good quality track with Pt > 0.5 and |eta| <= 0.8
561 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
562 Bool_t candle = kFALSE;
563 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
564 AliVTrack *track = (AliVTrack*)fInputEvent->GetTrack(iTrack);
565 AliESDtrack *esdt = dynamic_cast<AliESDtrack*>(track);
566 AliAODTrack *aodt = dynamic_cast<AliAODTrack*>(track);
567 if (track->Pt() < 0.5) continue;
568 if(TMath::Abs(track->Eta()) > 0.8) continue;
569 if (esdt) if (!fESDtrackCuts->AcceptTrack(esdt)) continue;
570 if (aodt) if (!aodt->TestFilterBit(5)) continue;
575 msg += " -- CANDLE = YES";
576 fHEventStat->Fill(2.1);
578 msg += " -- CANDLE = NO ";
581 // if event cuts are defined, they are checked here
582 // final decision on the event depends on this
585 if (!fEventCuts->IsSelected(&fRsnEvent)) {
586 msg += " -- Local cuts = REJECTED";
589 msg += " -- Local cuts = ACCEPTED";
593 msg += " -- Local cuts = NONE";
597 // if the above exit point is not taken, the event is accepted
598 AliDebugClass(2, Form("Stats for event %d: %s", fEvNum, msg.Data()));
600 fHEventStat->Fill(3.1);
607 //__________________________________________________________________________________________________
608 void AliRsnMiniAnalysisTask::FillMiniEvent(Char_t evType)
611 // Refresh cursor mini-event data member to fill with current event.
612 // Returns the total number of tracks selected.
615 // assign event-related values
616 if (fMiniEvent) delete fMiniEvent;
617 fMiniEvent = new AliRsnMiniEvent;
618 fMiniEvent->ID() = fEvNum;
619 fMiniEvent->Vz() = fInputEvent->GetPrimaryVertex()->GetZ();
620 fMiniEvent->Angle() = ComputeAngle();
621 fMiniEvent->Mult() = ComputeCentrality((evType == 'E'));
622 AliDebugClass(2, Form("Event %d: type = %c -- vz = %f -- mult = %f -- angle = %f", fEvNum, evType, fMiniEvent->Vz(), fMiniEvent->Mult(), fMiniEvent->Angle()));
624 // loop on daughters and assign track-related values
625 Int_t ic, ncuts = fTrackCuts.GetEntries();
626 Int_t ip, npart = fRsnEvent.GetAbsoluteSum();
627 Int_t npos = 0, nneg = 0, nneu = 0;
628 AliRsnDaughter cursor;
629 AliRsnMiniParticle miniParticle;
630 for (ip = 0; ip < npart; ip++) {
631 // point cursor to next particle
632 fRsnEvent.SetDaughter(cursor, ip);
633 // copy momentum and MC info if present
634 miniParticle.CopyDaughter(&cursor);
635 miniParticle.Index() = ip;
636 // switch on the bits corresponding to passed cuts
637 for (ic = 0; ic < ncuts; ic++) {
638 AliRsnCutSet *cuts = (AliRsnCutSet*)fTrackCuts[ic];
639 if (cuts->IsSelected(&cursor)) miniParticle.SetCutBit(ic);
641 // if a track passes at least one track cut, it is added to the pool
642 if (miniParticle.CutBits()) {
643 fMiniEvent->AddParticle(miniParticle);
644 if (miniParticle.Charge() == '+') npos++;
645 else if (miniParticle.Charge() == '-') nneg++;
650 // get number of accepted tracks
651 AliDebugClass(1, Form("Event %6d: total = %5d, accepted = %4d (pos %4d, neg %4d, neu %4d)", fEvNum, npart, (Int_t)fMiniEvent->Particles().GetEntriesFast(), npos, nneg, nneu));
654 //__________________________________________________________________________________________________
655 Double_t AliRsnMiniAnalysisTask::ComputeAngle()
658 // Get the plane angle
661 AliEventplane *plane = fInputEvent->GetEventplane();
663 return plane->GetEventplane("Q");
665 AliWarning("No event plane defined");
670 //__________________________________________________________________________________________________
671 Double_t AliRsnMiniAnalysisTask::ComputeCentrality(Bool_t isESD)
674 // Computes event centrality/multiplicity according to the criterion defined
675 // by two elements: (1) choice between multiplicity and centrality and
676 // (2) the string defining what criterion must be used for specific computation.
679 if (fUseCentrality) {
680 AliCentrality *centrality = fInputEvent->GetCentrality();
682 AliError("Cannot compute centrality!");
685 return centrality->GetCentralityPercentile(fCentralityType.Data());
687 if (!fCentralityType.CompareTo("TRACKS"))
688 return fInputEvent->GetNumberOfTracks();
689 else if (!fCentralityType.CompareTo("QUALITY"))
691 return AliESDtrackCuts::GetReferenceMultiplicity((AliESDEvent*)fInputEvent, kTRUE);
694 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
695 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
696 AliVTrack *track = (AliVTrack*)fInputEvent->GetTrack(iTrack);
697 AliAODTrack *aodt = dynamic_cast<AliAODTrack*>(track);
699 if (!aodt->TestFilterBit(5)) continue;
704 else if (!fCentralityType.CompareTo("TRACKLETS")) {
706 const AliMultiplicity *mult = ((AliESDEvent*)fInputEvent)->GetMultiplicity();
707 Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
708 for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
709 return AliESDUtils::GetCorrSPD2(nClusters[1], fInputEvent->GetPrimaryVertex()->GetZ());
711 AliWarning("Cannot compute multiplicity with SPD tracklets from AOD");
715 AliError(Form("String '%s' does not define a possible multiplicity/centrality computation", fCentralityType.Data()));
721 //__________________________________________________________________________________________________
722 void AliRsnMiniAnalysisTask::FillTrueMotherESD(AliRsnMiniEvent *miniEvent)
725 // Fills the histograms with true mother (ESD version)
729 Int_t id, ndef = fHistograms.GetEntries();
730 Int_t ip, label1, label2, npart = fMCEvent->GetNumberOfTracks();
731 static AliRsnMiniPair miniPair;
732 AliMCParticle *daughter1, *daughter2;
733 TLorentzVector p1, p2;
734 AliRsnMiniOutput *def = 0x0;
736 for (id = 0; id < ndef; id++) {
737 def = (AliRsnMiniOutput*)fHistograms[id];
739 if (!def->IsMother()) continue;
740 for (ip = 0; ip < npart; ip++) {
741 AliMCParticle *part = (AliMCParticle*)fMCEvent->GetTrack(ip);
742 if (TMath::Abs(part->Particle()->GetPdgCode()) != def->GetMotherPDG()) continue;
743 // check that daughters match expected species
744 if (part->Particle()->GetNDaughters() < 2) continue;
745 label1 = part->Particle()->GetDaughter(0);
746 label2 = part->Particle()->GetDaughter(1);
747 daughter1 = (AliMCParticle*)fMCEvent->GetTrack(label1);
748 daughter2 = (AliMCParticle*)fMCEvent->GetTrack(label2);
750 if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(1)) {
752 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
753 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
754 } else if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(0)) {
756 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
757 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
759 if (!okMatch) continue;
760 // assign momenta to computation object
761 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
762 miniPair.FillRef(def->GetMotherMass());
764 def->FillMother(&miniPair, miniEvent, &fValues);
769 //__________________________________________________________________________________________________
770 void AliRsnMiniAnalysisTask::FillTrueMotherAOD(AliRsnMiniEvent *miniEvent)
773 // Fills the histograms with true mother (AOD version)
777 TClonesArray *list = fRsnEvent.GetAODList();
778 Int_t id, ndef = fHistograms.GetEntries();
779 Int_t ip, label1, label2, npart = list->GetEntries();
780 static AliRsnMiniPair miniPair;
781 AliAODMCParticle *daughter1, *daughter2;
782 TLorentzVector p1, p2;
783 AliRsnMiniOutput *def = 0x0;
785 for (id = 0; id < ndef; id++) {
786 def = (AliRsnMiniOutput*)fHistograms[id];
788 if (!def->IsMother()) continue;
789 for (ip = 0; ip < npart; ip++) {
790 AliAODMCParticle *part = (AliAODMCParticle*)list->At(ip);
791 if (TMath::Abs(part->GetPdgCode()) != def->GetMotherPDG()) continue;
792 // check that daughters match expected species
793 if (part->GetNDaughters() < 2) continue;
794 label1 = part->GetDaughter(0);
795 label2 = part->GetDaughter(1);
796 daughter1 = (AliAODMCParticle*)list->At(label1);
797 daughter2 = (AliAODMCParticle*)list->At(label2);
799 if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(1)) {
801 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
802 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
803 } else if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(0)) {
805 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
806 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
808 if (!okMatch) continue;
809 // assign momenta to computation object
810 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
811 miniPair.FillRef(def->GetMotherMass());
813 def->FillMother(&miniPair, miniEvent, &fValues);