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>
18 #include <TStopwatch.h>
21 #include "AliEventplane.h"
22 #include "AliMultiplicity.h"
23 #include "AliTriggerAnalysis.h"
24 #include "AliAnalysisManager.h"
25 #include "AliInputEventHandler.h"
27 #include "AliESDtrackCuts.h"
28 #include "AliESDUtils.h"
30 #include "AliAODEvent.h"
31 #include "AliAODMCParticle.h"
33 #include "AliRsnCutSet.h"
34 #include "AliRsnMiniPair.h"
35 #include "AliRsnMiniEvent.h"
36 #include "AliRsnMiniParticle.h"
38 #include "AliRsnMiniAnalysisTask.h"
41 ClassImp(AliRsnMiniAnalysisTask)
43 //__________________________________________________________________________________________________
44 AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask() :
48 fUseCentrality(kFALSE),
49 fCentralityType("QUALITY"),
50 fUseAOD049CentralityPatch(kFALSE),
51 fContinuousMix(kTRUE),
57 fHistograms("AliRsnMiniOutput", 0),
58 fValues("AliRsnMiniValue", 0),
60 fHAEventsVsMulti(0x0),
72 // Dummy constructor ALWAYS needed for I/O.
76 //__________________________________________________________________________________________________
77 AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const char *name, Bool_t useMC) :
78 AliAnalysisTaskSE(name),
81 fUseCentrality(kFALSE),
82 fCentralityType("QUALITY"),
83 fUseAOD049CentralityPatch(kFALSE),
84 fContinuousMix(kTRUE),
90 fHistograms("AliRsnMiniOutput", 0),
91 fValues("AliRsnMiniValue", 0),
93 fHAEventsVsMulti(0x0),
105 // Default constructor.
106 // Define input and output slots here (never in the dummy constructor)
107 // Input slot #0 works with a TChain - it is connected to the default input container
108 // Output slot #1 writes into a TH1 container
111 DefineOutput(1, TList::Class());
114 //__________________________________________________________________________________________________
115 AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const AliRsnMiniAnalysisTask ©) :
116 AliAnalysisTaskSE(copy),
119 fUseCentrality(copy.fUseCentrality),
120 fCentralityType(copy.fCentralityType),
121 fUseAOD049CentralityPatch(copy.fUseAOD049CentralityPatch),
122 fContinuousMix(copy.fContinuousMix),
124 fMaxDiffMult(copy.fMaxDiffMult),
125 fMaxDiffVz(copy.fMaxDiffVz),
126 fMaxDiffAngle(copy.fMaxDiffAngle),
128 fHistograms(copy.fHistograms),
129 fValues(copy.fValues),
131 fHAEventsVsMulti(0x0),
132 fEventCuts(copy.fEventCuts),
133 fTrackCuts(copy.fTrackCuts),
136 fTriggerAna(copy.fTriggerAna),
137 fESDtrackCuts(copy.fESDtrackCuts),
139 fBigOutput(copy.fBigOutput),
140 fMixPrintRefresh(copy.fMixPrintRefresh)
144 // Implemented as requested by C++ standards.
145 // Can be used in PROOF and by plugins.
149 //__________________________________________________________________________________________________
150 AliRsnMiniAnalysisTask &AliRsnMiniAnalysisTask::operator=(const AliRsnMiniAnalysisTask ©)
153 // Assignment operator.
154 // Implemented as requested by C++ standards.
155 // Can be used in PROOF and by plugins.
158 AliAnalysisTaskSE::operator=(copy);
161 fUseMC = copy.fUseMC;
162 fUseCentrality = copy.fUseCentrality;
163 fCentralityType = copy.fCentralityType;
164 fUseAOD049CentralityPatch = copy.fUseAOD049CentralityPatch;
165 fContinuousMix = copy.fContinuousMix;
167 fMaxDiffMult = copy.fMaxDiffMult;
168 fMaxDiffVz = copy.fMaxDiffVz;
169 fMaxDiffAngle = copy.fMaxDiffAngle;
170 fHistograms = copy.fHistograms;
171 fValues = copy.fValues;
172 fHEventStat = copy.fHEventStat;
173 fHAEventsVsMulti = copy.fHAEventsVsMulti;
174 fEventCuts = copy.fEventCuts;
175 fTrackCuts = copy.fTrackCuts;
176 fTriggerAna = copy.fTriggerAna;
177 fESDtrackCuts = copy.fESDtrackCuts;
178 fBigOutput = copy.fBigOutput;
179 fMixPrintRefresh = copy.fMixPrintRefresh;
183 //__________________________________________________________________________________________________
184 AliRsnMiniAnalysisTask::~AliRsnMiniAnalysisTask()
188 // Clean-up the output list, but not the histograms that are put inside
189 // (the list is owner and will clean-up these histograms). Protect in PROOF case.
193 if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
199 //__________________________________________________________________________________________________
200 Int_t AliRsnMiniAnalysisTask::AddTrackCuts(AliRsnCutSet *cuts)
203 // Add a new cut set for a new criterion for track selection.
204 // A user can add as many as he wants, and each one corresponds
205 // to one of the available bits in the AliRsnMiniParticle mask.
206 // The only check is the following: if a cut set with the same name
207 // as the argument is there, this is not added.
208 // Return value is the array position of this set.
211 TObject *obj = fTrackCuts.FindObject(cuts->GetName());
214 AliInfo(Form("A cut set named '%s' already exists", cuts->GetName()));
215 return fTrackCuts.IndexOf(obj);
217 fTrackCuts.AddLast(cuts);
218 return fTrackCuts.IndexOf(cuts);
222 //__________________________________________________________________________________________________
223 void AliRsnMiniAnalysisTask::UserCreateOutputObjects()
226 // Initialization of outputs.
227 // This is called once per worker node.
234 AliInfo(Form("Selected event characterization: %s (%s)", (fUseCentrality ? "centrality" : "multiplicity"), fCentralityType.Data()));
236 // initialize trigger analysis
237 if (fTriggerAna) delete fTriggerAna;
238 fTriggerAna = new AliTriggerAnalysis;
240 // initialize ESD quality cuts
241 if (fESDtrackCuts) delete fESDtrackCuts;
242 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010();
244 // create list and set it as owner of its content (MANDATORY)
245 if (fBigOutput) OpenFile(1);
246 fOutput = new TList();
249 // initialize event statistics counter
250 fHEventStat = new TH1F("hEventStat", "Event statistics", 4, 0.0, 4.0);
251 fHEventStat->GetXaxis()->SetBinLabel(1, "CINT1B");
252 fHEventStat->GetXaxis()->SetBinLabel(2, "V0AND");
253 fHEventStat->GetXaxis()->SetBinLabel(3, "Candle");
254 fHEventStat->GetXaxis()->SetBinLabel(4, "Accepted");
255 fOutput->Add(fHEventStat);
258 fHAEventsVsMulti = new TH1F("hAEventsVsMulti", "Accepted events vs Centrality", 100, 0, 100.0);
260 fHAEventsVsMulti = new TH1F("hAEventsVsMulti", "Accepted events vs Multiplicity",1000, 0, 1000.0);
262 fOutput->Add(fHAEventsVsMulti);
264 TIter next(&fTrackCuts);
266 while ((cs = (AliRsnCutSet *) next())) {
270 // create temporary tree for filtered events
271 if (fMiniEvent) delete fMiniEvent;
272 fEvBuffer = new TTree("EventBuffer", "Temporary buffer for mini events");
273 fEvBuffer->Branch("events", "AliRsnMiniEvent", &fMiniEvent);
275 // create one histogram per each stored definition (event histograms)
276 Int_t i, ndef = fHistograms.GetEntries();
277 AliRsnMiniOutput *def = 0x0;
278 for (i = 0; i < ndef; i++) {
279 def = (AliRsnMiniOutput *)fHistograms[i];
281 if (!def->Init(GetName(), fOutput)) {
282 AliError(Form("Def '%s': failed initialization", def->GetName()));
287 // post data for ALL output slots >0 here, to get at least an empty histogram
288 PostData(1, fOutput);
291 //__________________________________________________________________________________________________
292 void AliRsnMiniAnalysisTask::UserExec(Option_t *)
296 // In this case, it checks if the event is acceptable, and eventually
297 // creates the corresponding mini-event and stores it in the buffer.
298 // The real histogram filling is done at the end, in "FinishTaskOutput".
301 // increment event counter
304 // check current event
305 Char_t check = CheckCurrentEvent();
308 // setup PID response
309 AliAnalysisManager *man = AliAnalysisManager::GetAnalysisManager();
310 AliInputEventHandler *inputHandler = (AliInputEventHandler *)man->GetInputEventHandler();
311 fRsnEvent.SetPIDResponse(inputHandler->GetPIDResponse());
313 // fill a mini-event from current
314 // and skip this event if no tracks were accepted
315 FillMiniEvent(check);
317 // fill MC based histograms on mothers,
318 // which do need the original event
320 if (fRsnEvent.IsESD() && fMCEvent)
321 FillTrueMotherESD(fMiniEvent);
322 else if (fRsnEvent.IsAOD() && fRsnEvent.GetAODList())
323 FillTrueMotherAOD(fMiniEvent);
326 // if the event is not empty, store it
327 if (fMiniEvent->IsEmpty()) {
328 AliDebugClass(2, Form("Rejecting empty event #%d", fEvNum));
330 Int_t id = fEvBuffer->GetEntries();
331 AliDebugClass(2, Form("Adding event #%d with ID = %d", fEvNum, id));
332 fMiniEvent->ID() = id;
336 // post data for computed stuff
337 PostData(1, fOutput);
340 //__________________________________________________________________________________________________
341 void AliRsnMiniAnalysisTask::FinishTaskOutput()
344 // This function is called at the end of the loop on available events,
345 // and then the buffer will be full with all the corresponding mini-events,
346 // each one containing all tracks selected by each of the available track cuts.
347 // Here a loop is done on each of these events, and both single-event and mixing are computed
350 // security code: reassign the buffer to the mini-event cursor
351 fEvBuffer->SetBranchAddress("events", &fMiniEvent);
354 Int_t ievt, nEvents = (Int_t)fEvBuffer->GetEntries();
355 Int_t idef, nDefs = fHistograms.GetEntries();
356 Int_t imix, iloop, ifill;
357 AliRsnMiniOutput *def = 0x0;
358 AliRsnMiniOutput::EComputation compType;
360 Int_t printNum = fMixPrintRefresh;
362 if (nEvents>1e5) printNum=nEvents/100;
363 else if (nEvents>1e4) printNum=nEvents/10;
367 // loop on events, and for each one fill all outputs
368 // using the appropriate procedure depending on its type
369 // only mother-related histograms are filled in UserExec,
370 // since they require direct access to MC event
372 for (ievt = 0; ievt < nEvents; ievt++) {
374 fEvBuffer->GetEntry(ievt);
375 if (printNum&&(ievt%printNum==0)) {
376 AliInfo(Form("[%s] Std.Event %d/%d",GetName(), ievt,nEvents));
377 timer.Stop(); timer.Print(); fflush(stdout); timer.Start(kFALSE);
380 for (idef = 0; idef < nDefs; idef++) {
381 def = (AliRsnMiniOutput *)fHistograms[idef];
383 compType = def->GetComputation();
384 // execute computation in the appropriate way
386 case AliRsnMiniOutput::kEventOnly:
387 //AliDebugClass(1, Form("Event %d, def '%s': event-value histogram filling", ievt, def->GetName()));
389 def->FillEvent(fMiniEvent, &fValues);
391 case AliRsnMiniOutput::kTruePair:
392 //AliDebugClass(1, Form("Event %d, def '%s': true-pair histogram filling", ievt, def->GetName()));
393 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
395 case AliRsnMiniOutput::kTrackPair:
396 //AliDebugClass(1, Form("Event %d, def '%s': pair-value histogram filling", ievt, def->GetName()));
397 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
399 case AliRsnMiniOutput::kTrackPairRotated1:
400 //AliDebugClass(1, Form("Event %d, def '%s': rotated (1) background histogram filling", ievt, def->GetName()));
401 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
403 case AliRsnMiniOutput::kTrackPairRotated2:
404 //AliDebugClass(1, Form("Event %d, def '%s': rotated (2) background histogram filling", ievt, def->GetName()));
405 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
408 // other kinds are processed elsewhere
410 AliDebugClass(2, Form("Computation = %d", (Int_t)compType));
413 AliDebugClass(1, Form("Event %6d: def = '%15s' -- fills = %5d", ievt, def->GetName(), ifill));
417 // if no mixing is required, stop here and post the output
419 AliDebugClass(2, "Stopping here, since no mixing is required");
420 PostData(1, fOutput);
424 // initialize mixing counter
425 Int_t nmatched[nEvents];
426 TString *smatched = new TString[nEvents];
427 for (ievt = 0; ievt < nEvents; ievt++) {
428 smatched[ievt] = "|";
433 AliInfo(Form("[%s] Std.Event %d/%d",GetName(), nEvents,nEvents));
434 timer.Stop(); timer.Print(); timer.Start(); fflush(stdout);
436 // search for good matchings
437 for (ievt = 0; ievt < nEvents; ievt++) {
438 if (printNum&&(ievt%printNum==0)) {
439 AliInfo(Form("[%s] EventMixing searching %d/%d",GetName(),ievt,nEvents));
440 timer.Stop(); timer.Print(); timer.Start(kFALSE); fflush(stdout);
442 if (nmatched[ievt] >= fNMix) continue;
443 fEvBuffer->GetEntry(ievt);
444 AliRsnMiniEvent evMain(*fMiniEvent);
445 for (iloop = 1; iloop < nEvents; iloop++) {
447 if (imix >= nEvents) imix -= nEvents;
448 if (imix == ievt) continue;
450 fEvBuffer->GetEntry(imix);
451 // skip if events are not matched
452 if (!EventsMatch(&evMain, fMiniEvent)) continue;
453 // check that the array of good matches for mixed does not already contain main event
454 if (smatched[imix].Contains(Form("|%d|", ievt))) continue;
455 // check that the found good events has not enough matches already
456 if (nmatched[imix] >= fNMix) continue;
457 // add new mixing candidate
458 smatched[ievt].Append(Form("%d|", imix));
461 if (nmatched[ievt] >= fNMix) break;
463 AliDebugClass(1, Form("Matches for event %5d = %d [%s] (missing are declared above)", evMain.ID(), nmatched[ievt], smatched[ievt].Data()));
466 AliInfo(Form("[%s] EventMixing searching %d/%d",GetName(),nEvents,nEvents));
467 timer.Stop(); timer.Print(); fflush(stdout); timer.Start();
470 TObjArray *list = 0x0;
471 TObjString *os = 0x0;
472 for (ievt = 0; ievt < nEvents; ievt++) {
473 if (printNum&&(ievt%printNum==0)) {
474 AliInfo(Form("[%s] EventMixing %d/%d",GetName(),ievt,nEvents));
475 timer.Stop(); timer.Print(); timer.Start(kFALSE); fflush(stdout);
478 fEvBuffer->GetEntry(ievt);
479 AliRsnMiniEvent evMain(*fMiniEvent);
480 list = smatched[ievt].Tokenize("|");
481 TObjArrayIter next(list);
482 while ( (os = (TObjString *)next()) ) {
483 imix = os->GetString().Atoi();
484 fEvBuffer->GetEntry(imix);
485 for (idef = 0; idef < nDefs; idef++) {
486 def = (AliRsnMiniOutput *)fHistograms[idef];
488 if (!def->IsTrackPairMix()) continue;
489 ifill += def->FillPair(&evMain, fMiniEvent, &fValues, kTRUE);
490 if (!def->IsSymmetric()) {
491 AliDebugClass(2, "Reflecting non symmetric pair");
492 ifill += def->FillPair(fMiniEvent, &evMain, &fValues, kFALSE);
501 AliInfo(Form("[%s] EventMixing %d/%d",GetName(),nEvents,nEvents));
502 timer.Stop(); timer.Print(); fflush(stdout);
507 for (iloop = 1; iloop < nEvents; iloop++) {
509 // restart from beginning if reached last event
510 if (imix >= nEvents) imix -= nEvents;
511 // avoid to mix an event with itself
512 if (imix == ievt) continue;
513 // skip all events already mixed enough times
514 if (fNMixed[ievt] >= fNMix) break;
515 if (fNMixed[imix] >= fNMix) continue;
516 fEvBuffer->GetEntry(imix);
517 // skip if events are not matched
518 if (TMath::Abs(evMain.Vz() - fMiniEvent->Vz() ) > fMaxDiffVz ) continue;
519 if (TMath::Abs(evMain.Mult() - fMiniEvent->Mult() ) > fMaxDiffMult ) continue;
520 if (TMath::Abs(evMain.Angle() - fMiniEvent->Angle()) > fMaxDiffAngle) continue;
521 // found a match: increment counter for both events
522 AliDebugClass(1, Form("Event %d, def '%s': event mixing (%d with %d)", ievt, def->GetName(), ievt, imix));
526 ifill += def->FillPair(&evMain, fMiniEvent, &fValues);
527 // stop if mixed enough times
528 if (fNMixed[ievt] >= fNMix) break;
531 // print number of mixings done with each event
532 for (ievt = 0; ievt < nEvents; ievt++) {
533 AliDebugClass(2, Form("Event %6d: mixed %2d times", ievt, fNMixed[ievt]));
537 // post computed data
538 PostData(1, fOutput);
541 //__________________________________________________________________________________________________
542 void AliRsnMiniAnalysisTask::Terminate(Option_t *)
545 // Draw result to screen, or perform fitting, normalizations
546 // Called once at the end of the query
549 fOutput = dynamic_cast<TList *>(GetOutputData(1));
551 AliError("Could not retrieve TList fOutput");
556 //__________________________________________________________________________________________________
557 Char_t AliRsnMiniAnalysisTask::CheckCurrentEvent()
560 // This method checks if current event is OK for analysis.
561 // In case it is, the pointers of the local AliRsnEvent data member
562 // will point to it, in order to allow cut checking, otherwise the
563 // function exits with a failure message.
565 // ESD events must pass the physics selection, AOD are supposed to do.
567 // While checking the event, a histogram is filled to count the number
568 // of CINT1B, V0AND and CANDLE events, which are needed for normalization
570 // Return values can be:
571 // -- 'E' if the event is accepted and is ESD
572 // -- 'A' if the event is accepted and is AOD
573 // -- 0 if the event is not accepted
576 // string to sum messages
580 // exit points are provided in all cases an event is bad
581 // if this block is passed, an event can be rejected only
582 // if it does not pass the set of event cuts defined in the task
585 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
588 // ESD specific check: Physics Selection
589 // --> if this is failed, the event is rejected
590 isSelected = (((AliInputEventHandler *)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kMB);
592 AliDebugClass(2, "Event does not pass physics selections");
593 fRsnEvent.SetRef(0x0);
594 fRsnEvent.SetRefMC(0x0);
597 // set reference to input
598 fRsnEvent.SetRef(fInputEvent);
599 // add MC if requested and available
602 fRsnEvent.SetRefMC(fMCEvent);
604 AliWarning("MC event requested but not available");
605 fRsnEvent.SetRefMC(0x0);
608 } else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
611 // set reference to input
612 fRsnEvent.SetRef(fInputEvent);
613 // add MC if requested and available (it is in the same object)
615 fRsnEvent.SetRefMC(fInputEvent);
616 if (!fRsnEvent.GetAODList()) {
617 AliWarning("MC event requested but not available");
618 fRsnEvent.SetRefMC(0x0);
622 AliError(Form("Bad input event class: %s", fInputEvent->ClassName()));
623 // reset pointers in local AliRsnEvent object
624 fRsnEvent.SetRef(0x0);
625 fRsnEvent.SetRefMC(0x0);
629 // fill counter of accepted events
630 fHEventStat->Fill(0.1);
632 // check if it is V0AND
633 // --> uses a cast to AliESDEvent even if the input is an AliAODEvent
634 Bool_t v0A = fTriggerAna->IsOfflineTriggerFired((AliESDEvent *)fInputEvent, AliTriggerAnalysis::kV0A);
635 Bool_t v0C = fTriggerAna->IsOfflineTriggerFired((AliESDEvent *)fInputEvent, AliTriggerAnalysis::kV0C);
637 msg += " -- VOAND = YES";
638 fHEventStat->Fill(1.1);
640 msg += " -- VOAND = NO ";
644 // --> requires at least one good quality track with Pt > 0.5 and |eta| <= 0.8
645 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
646 Bool_t candle = kFALSE;
647 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
648 AliVTrack *track = (AliVTrack *)fInputEvent->GetTrack(iTrack);
649 AliESDtrack *esdt = dynamic_cast<AliESDtrack *>(track);
650 AliAODTrack *aodt = dynamic_cast<AliAODTrack *>(track);
651 if (track->Pt() < 0.5) continue;
652 if(TMath::Abs(track->Eta()) > 0.8) continue;
653 if (esdt) if (!fESDtrackCuts->AcceptTrack(esdt)) continue;
654 if (aodt) if (!aodt->TestFilterBit(5)) continue;
659 msg += " -- CANDLE = YES";
660 fHEventStat->Fill(2.1);
662 msg += " -- CANDLE = NO ";
665 // if event cuts are defined, they are checked here
666 // final decision on the event depends on this
669 if (!fEventCuts->IsSelected(&fRsnEvent)) {
670 msg += " -- Local cuts = REJECTED";
673 msg += " -- Local cuts = ACCEPTED";
677 msg += " -- Local cuts = NONE";
681 // if the above exit point is not taken, the event is accepted
682 AliDebugClass(2, Form("Stats: %s", msg.Data()));
684 fHEventStat->Fill(3.1);
685 Double_t multi = ComputeCentrality((output == 'E'));
686 fHAEventsVsMulti->Fill(multi);
693 //__________________________________________________________________________________________________
694 void AliRsnMiniAnalysisTask::FillMiniEvent(Char_t evType)
697 // Refresh cursor mini-event data member to fill with current event.
698 // Returns the total number of tracks selected.
701 // assign event-related values
702 if (fMiniEvent) delete fMiniEvent;
703 fMiniEvent = new AliRsnMiniEvent;
704 fMiniEvent->Vz() = fInputEvent->GetPrimaryVertex()->GetZ();
705 fMiniEvent->Angle() = ComputeAngle();
706 fMiniEvent->Mult() = ComputeCentrality((evType == 'E'));
707 AliDebugClass(2, Form("Event %d: type = %c -- vz = %f -- mult = %f -- angle = %f", fEvNum, evType, fMiniEvent->Vz(), fMiniEvent->Mult(), fMiniEvent->Angle()));
709 // loop on daughters and assign track-related values
710 Int_t ic, ncuts = fTrackCuts.GetEntries();
711 Int_t ip, npart = fRsnEvent.GetAbsoluteSum();
712 Int_t npos = 0, nneg = 0, nneu = 0;
713 AliRsnDaughter cursor;
714 AliRsnMiniParticle miniParticle;
715 for (ip = 0; ip < npart; ip++) {
716 // point cursor to next particle
717 fRsnEvent.SetDaughter(cursor, ip);
718 // copy momentum and MC info if present
719 miniParticle.CopyDaughter(&cursor);
720 miniParticle.Index() = ip;
721 // switch on the bits corresponding to passed cuts
722 for (ic = 0; ic < ncuts; ic++) {
723 AliRsnCutSet *cuts = (AliRsnCutSet *)fTrackCuts[ic];
724 if (cuts->IsSelected(&cursor)) miniParticle.SetCutBit(ic);
726 // if a track passes at least one track cut, it is added to the pool
727 if (miniParticle.CutBits()) {
728 fMiniEvent->AddParticle(miniParticle);
729 if (miniParticle.Charge() == '+') npos++;
730 else if (miniParticle.Charge() == '-') nneg++;
735 // get number of accepted tracks
736 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));
739 //__________________________________________________________________________________________________
740 Double_t AliRsnMiniAnalysisTask::ComputeAngle()
743 // Get the plane angle
746 AliEventplane *plane = 0x0;
748 if (fInputEvent->InheritsFrom(AliESDEvent::Class()))
749 plane = fInputEvent->GetEventplane();
750 else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
751 AliAODEvent *aodEvent = (AliAODEvent *)fInputEvent;
752 plane = aodEvent->GetHeader()->GetEventplaneP();
756 return plane->GetEventplane("Q");
758 AliWarning("No event plane defined");
763 //__________________________________________________________________________________________________
764 Double_t AliRsnMiniAnalysisTask::ComputeCentrality(Bool_t isESD)
767 // Computes event centrality/multiplicity according to the criterion defined
768 // by two elements: (1) choice between multiplicity and centrality and
769 // (2) the string defining what criterion must be used for specific computation.
772 if (fUseCentrality) {
774 if ((!fUseMC) && (!isESD) && (fUseAOD049CentralityPatch)) {
775 return ApplyCentralityPatchAOD049();
777 AliCentrality *centrality = fInputEvent->GetCentrality();
779 AliError("Cannot compute centrality!");
782 return centrality->GetCentralityPercentile(fCentralityType.Data());
785 if (!fCentralityType.CompareTo("TRACKS"))
786 return fInputEvent->GetNumberOfTracks();
787 else if (!fCentralityType.CompareTo("QUALITY"))
789 return AliESDtrackCuts::GetReferenceMultiplicity((AliESDEvent *)fInputEvent, kTRUE);
792 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
793 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
794 AliVTrack *track = (AliVTrack *)fInputEvent->GetTrack(iTrack);
795 AliAODTrack *aodt = dynamic_cast<AliAODTrack *>(track);
797 if (!aodt->TestFilterBit(5)) continue;
802 else if (!fCentralityType.CompareTo("TRACKLETS")) {
804 const AliMultiplicity *mult = ((AliESDEvent *)fInputEvent)->GetMultiplicity();
805 Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
806 for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
807 return AliESDUtils::GetCorrSPD2(nClusters[1], fInputEvent->GetPrimaryVertex()->GetZ());
809 AliWarning("Cannot compute multiplicity with SPD tracklets from AOD");
813 AliError(Form("String '%s' does not define a possible multiplicity/centrality computation", fCentralityType.Data()));
819 //__________________________________________________________________________________________________
820 void AliRsnMiniAnalysisTask::FillTrueMotherESD(AliRsnMiniEvent *miniEvent)
823 // Fills the histograms with true mother (ESD version)
827 Int_t id, ndef = fHistograms.GetEntries();
828 Int_t ip, label1, label2, npart = fMCEvent->GetNumberOfTracks();
829 static AliRsnMiniPair miniPair;
830 AliMCParticle *daughter1, *daughter2;
831 TLorentzVector p1, p2;
832 AliRsnMiniOutput *def = 0x0;
834 for (id = 0; id < ndef; id++) {
835 def = (AliRsnMiniOutput *)fHistograms[id];
837 if (!def->IsMother()) continue;
838 for (ip = 0; ip < npart; ip++) {
839 AliMCParticle *part = (AliMCParticle *)fMCEvent->GetTrack(ip);
840 if (part->Particle()->GetPdgCode() != def->GetMotherPDG()) continue;
841 // check that daughters match expected species
842 if (part->Particle()->GetNDaughters() < 2) continue;
843 label1 = part->Particle()->GetDaughter(0);
844 label2 = part->Particle()->GetDaughter(1);
845 daughter1 = (AliMCParticle *)fMCEvent->GetTrack(label1);
846 daughter2 = (AliMCParticle *)fMCEvent->GetTrack(label2);
848 if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(1)) {
850 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
851 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
852 } else if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(0)) {
854 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
855 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
857 if (!okMatch) continue;
858 // assign momenta to computation object
859 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
860 miniPair.FillRef(def->GetMotherMass());
862 def->FillMother(&miniPair, miniEvent, &fValues);
867 //__________________________________________________________________________________________________
868 void AliRsnMiniAnalysisTask::FillTrueMotherAOD(AliRsnMiniEvent *miniEvent)
871 // Fills the histograms with true mother (AOD version)
875 TClonesArray *list = fRsnEvent.GetAODList();
876 Int_t id, ndef = fHistograms.GetEntries();
877 Int_t ip, label1, label2, npart = list->GetEntries();
878 static AliRsnMiniPair miniPair;
879 AliAODMCParticle *daughter1, *daughter2;
880 TLorentzVector p1, p2;
881 AliRsnMiniOutput *def = 0x0;
883 for (id = 0; id < ndef; id++) {
884 def = (AliRsnMiniOutput *)fHistograms[id];
886 if (!def->IsMother()) continue;
887 for (ip = 0; ip < npart; ip++) {
888 AliAODMCParticle *part = (AliAODMCParticle *)list->At(ip);
889 if (part->GetPdgCode() != def->GetMotherPDG()) continue;
890 // check that daughters match expected species
891 if (part->GetNDaughters() < 2) continue;
892 label1 = part->GetDaughter(0);
893 label2 = part->GetDaughter(1);
894 daughter1 = (AliAODMCParticle *)list->At(label1);
895 daughter2 = (AliAODMCParticle *)list->At(label2);
897 if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(1)) {
899 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
900 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
901 } else if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(0)) {
903 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
904 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
906 if (!okMatch) continue;
907 // assign momenta to computation object
908 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
909 miniPair.FillRef(def->GetMotherMass());
911 def->FillMother(&miniPair, miniEvent, &fValues);
916 //__________________________________________________________________________________________________
917 Bool_t AliRsnMiniAnalysisTask::EventsMatch(AliRsnMiniEvent *event1, AliRsnMiniEvent *event2)
920 // Check if two events are compatible.
921 // If the mixing is continuous, this is true if differences in vz, mult and angle are smaller than
922 // the specified values.
923 // If the mixing is binned, this is true if the events are in the same bin.
926 if (!event1 || !event2) return kFALSE;
927 Int_t ivz1, ivz2, imult1, imult2, iangle1, iangle2;
930 if (fContinuousMix) {
931 dv = TMath::Abs(event1->Vz() - event2->Vz() );
932 dm = TMath::Abs(event1->Mult() - event2->Mult() );
933 da = TMath::Abs(event1->Angle() - event2->Angle());
934 if (dv > fMaxDiffVz) {
935 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Vz = %f", event1->ID(), event2->ID(), dv));
938 if (dm > fMaxDiffMult ) {
939 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Mult = %f", event1->ID(), event2->ID(), dm));
942 if (da > fMaxDiffAngle) {
943 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Angle = %f", event1->ID(), event2->ID(), da));
948 ivz1 = (Int_t)(event1->Vz() / fMaxDiffVz);
949 ivz2 = (Int_t)(event2->Vz() / fMaxDiffVz);
950 imult1 = (Int_t)(event1->Mult() / fMaxDiffMult);
951 imult2 = (Int_t)(event2->Mult() / fMaxDiffMult);
952 iangle1 = (Int_t)(event1->Angle() / fMaxDiffAngle);
953 iangle2 = (Int_t)(event2->Angle() / fMaxDiffAngle);
954 if (ivz1 != ivz2) return kFALSE;
955 if (imult1 != imult2) return kFALSE;
956 if (iangle1 != iangle2) return kFALSE;
962 //---------------------------------------------------------------------
963 Double_t AliRsnMiniAnalysisTask::ApplyCentralityPatchAOD049()
966 //Apply centrality patch for AOD049 outliers
968 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
969 AliWarning("Requested patch for AOD049 for ESD. ");
973 if (fCentralityType!="V0M") {
974 AliWarning("Requested patch forAOD049 for wrong value (not centrality from V0).");
978 AliCentrality *centrality = fInputEvent->GetCentrality();
980 AliWarning("Cannot get centrality from AOD event.");
984 Float_t cent = (Float_t)(centrality->GetCentralityPercentile("V0M"));
986 Bool_t isSelRun = kFALSE;
987 Int_t selRun[5] = {138364, 138826, 138828, 138836, 138871};
989 Int_t quality = centrality->GetQuality();
991 cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
993 Int_t runnum=aodEvent->GetRunNumber();
994 for(Int_t ir=0;ir<5;ir++){
995 if(runnum==selRun[ir]){
1000 if((quality==8||quality==9)&&isSelRun) cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
1007 AliAODEvent *aodEvent = (AliAODEvent *)fInputEvent;
1008 AliAODVZERO *aodV0 = (AliAODVZERO *) aodEvent->GetVZEROData();
1009 v0+=aodV0->GetMTotV0A();
1010 v0+=aodV0->GetMTotV0C();
1011 if ( (cent==0) && (v0<19500) ) {
1012 AliDebug(3, Form("Filtering issue in centrality -> cent = %5.2f",cent));
1015 Float_t tkl = (Float_t)(aodEvent->GetTracklets()->GetNumberOfTracklets());
1016 Float_t val = 1.30552 + 0.147931 * v0;
1018 Float_t tklSigma[101] = {176.644, 156.401, 153.789, 153.015, 142.476, 137.951, 136.127, 129.852, 127.436, 124.86,
1019 120.788, 115.611, 113.172, 110.496, 109.127, 104.421, 102.479, 99.9766, 97.5152, 94.0654,
1020 92.4602, 89.3364, 87.1342, 83.3497, 82.6216, 81.1084, 78.0793, 76.1234, 72.9434, 72.1334,
1021 68.0056, 68.2755, 66.0376, 62.9666, 62.4274, 59.65, 58.3776, 56.6361, 54.5184, 53.4224,
1022 51.932, 50.8922, 48.2848, 47.912, 46.5717, 43.4114, 43.2083, 41.3065, 40.1863, 38.5255,
1023 37.2851, 37.5396, 34.4949, 33.8366, 31.8043, 31.7412, 30.8392, 30.0274, 28.8793, 27.6398,
1024 26.6488, 25.0183, 25.1489, 24.4185, 22.9107, 21.2002, 21.6977, 20.1242, 20.4963, 19.0235,
1025 19.298, 17.4103, 16.868, 15.2939, 15.2939, 16.0295, 14.186, 14.186, 15.2173, 12.9504, 12.9504,
1026 12.9504, 15.264, 12.3674, 12.3674, 12.3674, 12.3674, 12.3674, 18.3811, 13.7544, 13.7544,
1027 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544
1030 if ( TMath::Abs(tkl-val) > 6.*tklSigma[(Int_t)cent] ) {
1031 AliDebug(3, Form("Outlier event in centrality -> cent = %5.2f",cent));
1035 //force it to be -999. whatever the negative value was