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),
66 // Dummy constructor ALWAYS needed for I/O.
70 //__________________________________________________________________________________________________
71 AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const char *name, Bool_t useMC) :
72 AliAnalysisTaskSE(name),
75 fUseCentrality(kFALSE),
76 fCentralityType("QUALITY"),
82 fHistograms("AliRsnMiniOutput", 0),
83 fValues("AliRsnMiniValue", 0),
95 // Default constructor.
96 // Define input and output slots here (never in the dummy constructor)
97 // Input slot #0 works with a TChain - it is connected to the default input container
98 // Output slot #1 writes into a TH1 container
101 DefineOutput(1, TList::Class());
104 //__________________________________________________________________________________________________
105 AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const AliRsnMiniAnalysisTask& copy) :
106 AliAnalysisTaskSE(copy),
109 fUseCentrality(copy.fUseCentrality),
110 fCentralityType(copy.fCentralityType),
112 fMaxDiffMult(copy.fMaxDiffMult),
113 fMaxDiffVz(copy.fMaxDiffVz),
114 fMaxDiffAngle(copy.fMaxDiffAngle),
116 fHistograms(copy.fHistograms),
117 fValues(copy.fValues),
119 fEventCuts(copy.fEventCuts),
120 fTrackCuts(copy.fTrackCuts),
124 fTriggerAna(copy.fTriggerAna),
125 fESDtrackCuts(copy.fESDtrackCuts),
130 // Implemented as requested by C++ standards.
131 // Can be used in PROOF and by plugins.
135 //__________________________________________________________________________________________________
136 AliRsnMiniAnalysisTask& AliRsnMiniAnalysisTask::operator=(const AliRsnMiniAnalysisTask& copy)
139 // Assignment operator.
140 // Implemented as requested by C++ standards.
141 // Can be used in PROOF and by plugins.
144 AliAnalysisTaskSE::operator=(copy);
146 fUseMC = copy.fUseMC;
147 fUseCentrality = copy.fUseCentrality;
148 fCentralityType = copy.fCentralityType;
150 fMaxDiffMult = copy.fMaxDiffMult;
151 fMaxDiffVz = copy.fMaxDiffVz;
152 fMaxDiffAngle = copy.fMaxDiffAngle;
153 fHistograms = copy.fHistograms;
154 fValues = copy.fValues;
155 fEventCuts = copy.fEventCuts;
156 fTrackCuts = copy.fTrackCuts;
157 fTriggerAna = copy.fTriggerAna;
158 fESDtrackCuts = copy.fESDtrackCuts;
163 //__________________________________________________________________________________________________
164 AliRsnMiniAnalysisTask::~AliRsnMiniAnalysisTask()
168 // Clean-up the output list, but not the histograms that are put inside
169 // (the list is owner and will clean-up these histograms). Protect in PROOF case.
172 if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
177 //__________________________________________________________________________________________________
178 Int_t AliRsnMiniAnalysisTask::AddTrackCuts(AliRsnCutSet *cuts)
181 // Add a new cut set for a new criterion for track selection.
182 // A user can add as many as he wants, and each one corresponds
183 // to one of the available bits in the AliRsnMiniParticle mask.
184 // The only check is the following: if a cut set with the same name
185 // as the argument is there, this is not added.
186 // Return value is the array position of this set.
189 TObject *obj = fTrackCuts.FindObject(cuts->GetName());
192 AliInfo(Form("A cut set named '%s' already exists", cuts->GetName()));
193 return fTrackCuts.IndexOf(obj);
195 fTrackCuts.AddLast(cuts);
196 return fTrackCuts.IndexOf(cuts);
200 //__________________________________________________________________________________________________
201 void AliRsnMiniAnalysisTask::UserCreateOutputObjects()
204 // Initialization of outputs.
205 // This is called once per worker node.
211 // initialize trigger analysis
212 if (fTriggerAna) delete fTriggerAna;
213 fTriggerAna = new AliTriggerAnalysis;
215 // initialize ESD quality cuts
216 if (fESDtrackCuts) delete fESDtrackCuts;
217 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010();
219 // create list and set it as owner of its content (MANDATORY)
220 fOutput = new TList();
223 // initialize event statistics counter
224 fHEventStat = new TH1F("hEventStat", "Event statistics", 4, 0.0, 4.0);
225 fHEventStat->GetXaxis()->SetBinLabel(1, "CINT1B");
226 fHEventStat->GetXaxis()->SetBinLabel(2, "V0AND");
227 fHEventStat->GetXaxis()->SetBinLabel(3, "Candle");
228 fHEventStat->GetXaxis()->SetBinLabel(4, "Accepted");
229 fOutput->Add(fHEventStat);
231 // create temporary tree for filtered events
232 if (fMiniEvent) delete fMiniEvent;
233 fEvBuffer = new TTree("EventBuffer", "Temporary buffer for mini events");
234 fEvBuffer->Branch("events", "AliRsnMiniEvent", &fMiniEvent);
236 // create one histogram per each stored definition (event histograms)
237 Int_t i, ndef = fHistograms.GetEntries();
238 AliRsnMiniOutput *def = 0x0;
239 for (i = 0; i < ndef; i++) {
240 def = (AliRsnMiniOutput*)fHistograms[i];
242 if (!def->Init(GetName(), fOutput)) {
243 AliError(Form("Def '%s': failed initialization", def->GetName()));
248 // setup PID response
249 AliAnalysisManager *man = AliAnalysisManager::GetAnalysisManager();
250 AliInputEventHandler *inputHandler = (AliInputEventHandler*)man->GetInputEventHandler();
251 fRsnEvent.SetPIDResponse(inputHandler->GetPIDResponse());
253 // post data for ALL output slots >0 here, to get at least an empty histogram
254 PostData(1, fOutput);
257 //__________________________________________________________________________________________________
258 void AliRsnMiniAnalysisTask::UserExec(Option_t *)
262 // In this case, it checks if the event is acceptable, and eventually
263 // creates the corresponding mini-event and stores it in the buffer.
264 // The real histogram filling is done at the end, in "FinishTaskOutput".
270 // check current event
271 Char_t check = CheckCurrentEvent();
274 // fill a mini-event from current
275 // and skip this event if no tracks were accepted
276 Int_t nacc = FillMiniEvent(check);
278 AliDebugClass(1, Form("Event %d: skipping event with no tracks accepted", fEvNum));
282 // fill MC based histograms on mothers,
283 // which do need the original event
285 if (fRsnEvent.IsESD() && fMCEvent)
286 FillTrueMotherESD(fMiniEvent);
287 else if (fRsnEvent.IsAOD() && fRsnEvent.GetAODList())
288 FillTrueMotherAOD(fMiniEvent);
294 // post data for computed stuff
295 PostData(1, fOutput);
298 //__________________________________________________________________________________________________
299 void AliRsnMiniAnalysisTask::FinishTaskOutput()
302 // This function is called at the end of the loop on available events,
303 // and then the buffer will be full with all the corresponding mini-events,
304 // each one containing all tracks selected by each of the available track cuts.
305 // Here a loop is done on each of these events, and both single-event and mixing are computed
308 // security code: reassign the buffer to the mini-event cursor
309 fEvBuffer->SetBranchAddress("events", &fMiniEvent);
311 Int_t ievt, nEvents = (Int_t)fEvBuffer->GetEntries();
312 Int_t idef, nDefs = fHistograms.GetEntries();
314 AliRsnMiniOutput *def = 0x0;
315 AliRsnMiniOutput::EComputation compType;
316 AliRsnMiniEvent evMain;
318 // initialize mixing counter
319 fNMixed.Set(nEvents);
320 for (ievt = 0; ievt < nEvents; ievt++) fNMixed[ievt] = 0;
322 // loop on events, and for each one fill all outputs
323 // using the appropriate procedure depending on its type
324 // only mother-related histograms are filled in UserExec,
325 // since they require direct access to MC event
326 for (ievt = 0; ievt < nEvents; ievt++) {
328 fEvBuffer->GetEntry(ievt);
329 // store in temp variable
330 evMain = (*fMiniEvent);
331 // fill non-mixed histograms
332 for (idef = 0; idef < nDefs; idef++) {
333 def = (AliRsnMiniOutput*)fHistograms[idef];
335 compType = def->GetComputation();
336 // execute computation in the appropriate way
338 case AliRsnMiniOutput::kEventOnly:
339 AliDebugClass(1, Form("Event %d, def %d: event-value histogram filling", ievt, idef));
340 def->Fill(&evMain, &fValues);
342 case AliRsnMiniOutput::kTruePair:
343 AliDebugClass(1, Form("Event %d, def %d: true-pair histogram filling", ievt, idef));
344 ProcessEvents(&evMain, 0x0);
346 case AliRsnMiniOutput::kTrackPair:
347 AliDebugClass(1, Form("Event %d, def %d: pair-value histogram filling", ievt, idef));
348 ProcessEvents(&evMain, 0x0);
350 case AliRsnMiniOutput::kTrackPairRotated1:
351 AliDebugClass(1, Form("Event %d, def %d: rotated (1) background histogram filling", ievt, idef));
352 ProcessEvents(&evMain, 0x0);
354 case AliRsnMiniOutput::kTrackPairRotated2:
355 AliDebugClass(1, Form("Event %d, def %d: rotated (2) background histogram filling", ievt, idef));
356 ProcessEvents(&evMain, 0x0);
358 case AliRsnMiniOutput::kTrackPairMix:
359 for (iloop = 1; iloop < nEvents; iloop++) {
361 AliDebugClass(1, Form("Event %d, def %d: event mixing (%d with %d)", ievt, idef, ievt, imix));
362 // restart from beginning if reached last event
363 if (imix >= nEvents) imix -= nEvents;
364 // avoid to mix an event with itself
365 if (imix == ievt) continue;
366 // skip all events already mixed enough times
367 if (fNMixed[ievt] >= fNMix) break;
368 if (fNMixed[imix] >= fNMix) continue;
369 fEvBuffer->GetEntry(imix);
370 // skip if events are not matched
371 if (TMath::Abs(evMain.Vz() - fMiniEvent->Vz() ) > fMaxDiffVz ) continue;
372 if (TMath::Abs(evMain.Mult() - fMiniEvent->Mult() ) > fMaxDiffMult ) continue;
373 if (TMath::Abs(evMain.Angle() - fMiniEvent->Angle()) > fMaxDiffAngle) continue;
374 // found a match: increment counter for both events
378 ProcessEvents(&evMain, fMiniEvent);
382 // other kinds are processed elsewhere
383 AliDebugClass(2, Form("Computation = %d", (Int_t)compType));
388 // print number of mixings done with each event
389 for (ievt = 0; ievt < nEvents; ievt++) cout << Form("Event #%6d mixed %3d times", ievt, fNMixed[ievt]) << endl;
391 // post computed data
392 PostData(1, fOutput);
395 //__________________________________________________________________________________________________
396 void AliRsnMiniAnalysisTask::Terminate(Option_t *)
399 // Draw result to screen, or perform fitting, normalizations
400 // Called once at the end of the query
403 fOutput = dynamic_cast<TList*>(GetOutputData(1));
405 AliError("Could not retrieve TList fOutput");
410 //__________________________________________________________________________________________________
411 Char_t AliRsnMiniAnalysisTask::CheckCurrentEvent()
414 // This method checks if current event is OK for analysis.
415 // In case it is, the pointers of the local AliRsnEvent data member
416 // will point to it, in order to allow cut checking, otherwise the
417 // function exits with a failure message.
419 // ESD events must pass the physics selection, AOD are supposed to do.
421 // While checking the event, a histogram is filled to count the number
422 // of CINT1B, V0AND and CANDLE events, which are needed for normalization
424 // Return values can be:
425 // -- 'E' if the event is accepted and is ESD
426 // -- 'A' if the event is accepted and is AOD
427 // -- 0 if the event is not accepted
430 // string to sum messages
434 // exit points are provided in all cases an event is bad
435 // if this block is passed, an event can be rejected only
436 // if it does not pass the set of event cuts defined in the task
439 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
442 // ESD specific check: Physics Selection
443 // --> if this is failed, the event is rejected
444 isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kMB);
446 AliDebugClass(1, "Event does not pass physics selections");
447 fRsnEvent.SetRef(0x0);
448 fRsnEvent.SetRefMC(0x0);
451 // set reference to input
452 fRsnEvent.SetRef(fInputEvent);
453 // add MC if requested and available
456 fRsnEvent.SetRefMC(fMCEvent);
458 AliWarning("MC event requested but not available");
459 fRsnEvent.SetRefMC(0x0);
462 } else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
465 // set reference to input
466 fRsnEvent.SetRef(fInputEvent);
467 // add MC if requested and available (it is in the same object)
469 fRsnEvent.SetRefMC(fInputEvent);
470 if (!fRsnEvent.GetAODList()) {
471 AliWarning("MC event requested but not available");
472 fRsnEvent.SetRefMC(0x0);
476 AliError(Form("Bad input event class: %s", fInputEvent->ClassName()));
477 // reset pointers in local AliRsnEvent object
478 fRsnEvent.SetRef(0x0);
479 fRsnEvent.SetRefMC(0x0);
483 // fill counter of accepted events
484 fHEventStat->Fill(0.1);
486 // check if it is V0AND
487 // --> uses a cast to AliESDEvent even if the input is an AliAODEvent
488 Bool_t v0A = fTriggerAna->IsOfflineTriggerFired((AliESDEvent*)fInputEvent, AliTriggerAnalysis::kV0A);
489 Bool_t v0C = fTriggerAna->IsOfflineTriggerFired((AliESDEvent*)fInputEvent, AliTriggerAnalysis::kV0C);
491 msg += " -- VOAND = YES";
492 fHEventStat->Fill(1.1);
494 msg += " -- VOAND = NO ";
498 // --> requires at least one good quality track with Pt > 0.5 and |eta| <= 0.8
499 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
500 Bool_t candle = kFALSE;
501 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
502 AliVTrack *track = (AliVTrack*)fInputEvent->GetTrack(iTrack);
503 AliESDtrack *esdt = dynamic_cast<AliESDtrack*>(track);
504 AliAODTrack *aodt = dynamic_cast<AliAODTrack*>(track);
505 if (track->Pt() < 0.5) continue;
506 if(TMath::Abs(track->Eta()) > 0.8) continue;
507 if (esdt) if (!fESDtrackCuts->AcceptTrack(esdt)) continue;
508 if (aodt) if (!aodt->TestFilterBit(5)) continue;
513 msg += " -- CANDLE = YES";
514 fHEventStat->Fill(2.1);
516 msg += " -- CANDLE = NO ";
519 // if event cuts are defined, they are checked here
520 // final decision on the event depends on this
523 if (!fEventCuts->IsSelected(&fRsnEvent)) {
524 msg += " -- Local cuts = REJECTED";
527 msg += " -- Local cuts = ACCEPTED";
531 msg += " -- Local cuts = NONE";
535 // if the above exit point is not taken, the event is accepted
536 AliDebugClass(1, Form("Stats for event %d: %s", fEvNum, msg.Data()));
538 fHEventStat->Fill(3.1);
545 //__________________________________________________________________________________________________
546 Int_t AliRsnMiniAnalysisTask::FillMiniEvent(Char_t evType)
549 // Refresh cursor mini-event data member to fill with current event.
550 // Returns the total number of tracks selected.
553 // assign event-related values
554 fMiniEvent = new AliRsnMiniEvent;
555 fMiniEvent->Vz() = fInputEvent->GetPrimaryVertex()->GetZ();
556 fMiniEvent->Angle() = ComputeAngle();
557 fMiniEvent->Mult() = ComputeCentrality((evType == 'E'));
558 AliDebugClass(1, Form("Event %d: type = %c -- vz = %f -- mult = %f -- angle = %f", fEvNum, evType, fMiniEvent->Vz(), fMiniEvent->Mult(), fMiniEvent->Angle()));
560 // loop on daughters and assign track-related values
561 Int_t ic, ncuts = fTrackCuts.GetEntries();
562 Int_t ip, npart = fRsnEvent.GetAbsoluteSum();
563 AliRsnDaughter cursor;
564 AliRsnMiniParticle miniParticle;
565 for (ip = 0; ip < npart; ip++) {
566 // point cursor to next particle
567 fRsnEvent.SetDaughter(cursor, ip);
568 // copy momentum and MC info if present
569 miniParticle.CopyDaughter(&cursor);
570 // switch on the bits corresponding to passed cuts
571 for (ic = 0; ic < ncuts; ic++) {
572 AliRsnCutSet *cuts = (AliRsnCutSet*)fTrackCuts[ic];
573 if (cuts->IsSelected(&cursor)) miniParticle.SetCutBit(ic);
575 // if a track passes at least one track cut, it is added to the pool
576 if (miniParticle.CutBits()) fMiniEvent->AddParticle(miniParticle);
579 // get number of accepted tracks
580 Int_t nacc = (Int_t)fMiniEvent->Particles().GetEntriesFast();
581 AliDebugClass(1, Form("Event %d: total = %d, accepted = %d", fEvNum, npart, nacc));
585 //__________________________________________________________________________________________________
586 Double_t AliRsnMiniAnalysisTask::ComputeAngle()
589 // Get the plane angle
592 AliEventplane *plane = fInputEvent->GetEventplane();
594 return plane->GetEventplane("Q");
596 AliWarning("No event plane defined");
601 //__________________________________________________________________________________________________
602 Double_t AliRsnMiniAnalysisTask::ComputeCentrality(Bool_t isESD)
605 // Computes event centrality/multiplicity according to the criterion defined
606 // by two elements: (1) choice between multiplicity and centrality and
607 // (2) the string defining what criterion must be used for specific computation.
610 if (fUseCentrality) {
611 AliCentrality *centrality = fInputEvent->GetCentrality();
613 AliError("Cannot compute centrality!");
616 return centrality->GetCentralityPercentile(fCentralityType.Data());
618 if (!fCentralityType.CompareTo("TRACKS"))
619 return fInputEvent->GetNumberOfTracks();
620 else if (!fCentralityType.CompareTo("QUALITY"))
622 return AliESDtrackCuts::GetReferenceMultiplicity((AliESDEvent*)fInputEvent, kTRUE);
625 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
626 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
627 AliVTrack *track = (AliVTrack*)fInputEvent->GetTrack(iTrack);
628 AliAODTrack *aodt = dynamic_cast<AliAODTrack*>(track);
630 if (!aodt->TestFilterBit(5)) continue;
635 else if (!fCentralityType.CompareTo("TRACKLETS")) {
637 const AliMultiplicity *mult = ((AliESDEvent*)fInputEvent)->GetMultiplicity();
638 Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
639 for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
640 return AliESDUtils::GetCorrSPD2(nClusters[1], fInputEvent->GetPrimaryVertex()->GetZ());
642 AliWarning("Cannot compute multiplicity with SPD tracklets from AOD");
646 AliError(Form("String '%s' does not define a possible multiplicity/centrality computation", fCentralityType.Data()));
652 //__________________________________________________________________________________________________
653 void AliRsnMiniAnalysisTask::FillTrueMotherESD(AliRsnMiniEvent *miniEvent)
656 // Fills the histograms with true mother (ESD version)
660 Int_t id, ndef = fHistograms.GetEntries();
661 Int_t ip, label1, label2, npart = fMCEvent->GetNumberOfTracks();
662 static AliRsnMiniPair miniPair;
663 AliMCParticle *daughter1, *daughter2;
664 TLorentzVector p1, p2;
665 AliRsnMiniOutput *def = 0x0;
667 for (id = 0; id < ndef; id++) {
668 def = (AliRsnMiniOutput*)fHistograms[id];
670 if (!def->IsMother()) continue;
671 for (ip = 0; ip < npart; ip++) {
672 AliMCParticle *part = (AliMCParticle*)fMCEvent->GetTrack(ip);
673 if (TMath::Abs(part->Particle()->GetPdgCode()) != def->GetMotherPDG()) continue;
674 // check that daughters match expected species
675 if (part->Particle()->GetNDaughters() < 2) continue;
676 label1 = part->Particle()->GetDaughter(0);
677 label2 = part->Particle()->GetDaughter(1);
678 daughter1 = (AliMCParticle*)fMCEvent->GetTrack(label1);
679 daughter2 = (AliMCParticle*)fMCEvent->GetTrack(label2);
681 if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(1)) {
683 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
684 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
685 } else if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(0)) {
687 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
688 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
690 if (!okMatch) continue;
691 // assign momenta to computation object
692 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
693 miniPair.FillRef(def->GetMotherMass());
695 def->Fill(&miniPair, miniEvent, &fValues);
700 //__________________________________________________________________________________________________
701 void AliRsnMiniAnalysisTask::FillTrueMotherAOD(AliRsnMiniEvent *miniEvent)
704 // Fills the histograms with true mother (AOD version)
708 TClonesArray *list = fRsnEvent.GetAODList();
709 Int_t id, ndef = fHistograms.GetEntries();
710 Int_t ip, label1, label2, npart = list->GetEntries();
711 static AliRsnMiniPair miniPair;
712 AliAODMCParticle *daughter1, *daughter2;
713 TLorentzVector p1, p2;
714 AliRsnMiniOutput *def = 0x0;
716 for (id = 0; id < ndef; id++) {
717 def = (AliRsnMiniOutput*)fHistograms[id];
719 if (!def->IsMother()) continue;
720 for (ip = 0; ip < npart; ip++) {
721 AliAODMCParticle *part = (AliAODMCParticle*)list->At(ip);
722 if (TMath::Abs(part->GetPdgCode()) != def->GetMotherPDG()) continue;
723 // check that daughters match expected species
724 if (part->GetNDaughters() < 2) continue;
725 label1 = part->GetDaughter(0);
726 label2 = part->GetDaughter(1);
727 daughter1 = (AliAODMCParticle*)list->At(label1);
728 daughter2 = (AliAODMCParticle*)list->At(label2);
730 if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(1)) {
732 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
733 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
734 } else if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(0)) {
736 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
737 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
739 if (!okMatch) continue;
740 // assign momenta to computation object
741 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
742 miniPair.FillRef(def->GetMotherMass());
744 def->Fill(&miniPair, miniEvent, &fValues);
749 //________________________________________________________________________
750 void AliRsnMiniAnalysisTask::ProcessEvents(AliRsnMiniEvent *evMain, AliRsnMiniEvent *evMix)
753 // This function processes all single tracks.
754 // Loops on the daughters defined in current event
755 // and on all of them which pass the single-track cuts defined, computes what needed
758 // check if it is mixed
767 // 2 nested loops on tracks
768 // inner starts from next track or from first, depending if is mixing or not
769 Int_t i1, i2, idef, start;
770 Int_t n1 = evMain->Particles().GetEntries();
771 Int_t n2 = evMix ->Particles().GetEntries();
772 Int_t ndef = fHistograms.GetEntries();
773 AliRsnMiniParticle *daughter1 = 0x0, *daughter2 = 0x0;
774 AliRsnMiniOutput *def = 0x0;
775 for (i1 = 0; i1 < n1; i1++) {
776 daughter1 = (AliRsnMiniParticle*)evMain->Particles()[i1];
777 if (!daughter1) continue;
778 if (isMix) start = 0; else start = i1 + 1;
779 for (i2 = start; i2 < n2; i2++) {
780 daughter2 = (AliRsnMiniParticle*)evMix->Particles()[i2];
781 if (!daughter2) continue;
782 // loop on definitions
783 for (idef = 0; idef < ndef; idef++) {
784 def = (AliRsnMiniOutput*)fHistograms[idef];
786 if (def->IsEventOnly()) continue;
787 if (def->IsMother()) continue;
788 if (isMix && !def->IsTrackPairMix()) continue;
789 if (!isMix && def->IsTrackPairMix()) continue;
790 // check if definitions here match the current pair
791 def->Fill(daughter1, daughter2, evMain, &fValues);
792 } // end loop on definitions
793 } // end loop on daughter #2
794 } // end loop on daughter #1