]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/RESONANCES/AliRsnMiniAnalysisTask.cxx
Adding macro to plot <Ncoll>
[u/mrichter/AliRoot.git] / PWGLF / RESONANCES / AliRsnMiniAnalysisTask.cxx
CommitLineData
03d23846 1//
2// Analysis task for 'mini' sub-package
3// Contains all definitions needed for running an analysis:
4// -- global event cut
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.
11//
12
13#include <Riostream.h>
14
03d23846 15#include <TH1.h>
6aaeb33c 16#include <TList.h>
17#include <TTree.h>
52e6652d 18#include <TStopwatch.h>
da997f6c 19#include "TRandom.h"
03d23846 20
21#include "AliLog.h"
6aaeb33c 22#include "AliEventplane.h"
23#include "AliMultiplicity.h"
24#include "AliTriggerAnalysis.h"
03d23846 25#include "AliAnalysisManager.h"
6aaeb33c 26#include "AliInputEventHandler.h"
27
03d23846 28#include "AliESDtrackCuts.h"
29#include "AliESDUtils.h"
6aaeb33c 30
03d23846 31#include "AliAODEvent.h"
03d23846 32#include "AliAODMCParticle.h"
33
34#include "AliRsnCutSet.h"
6aaeb33c 35#include "AliRsnMiniPair.h"
03d23846 36#include "AliRsnMiniEvent.h"
37#include "AliRsnMiniParticle.h"
03d23846 38
39#include "AliRsnMiniAnalysisTask.h"
40
52e6652d 41
03d23846 42ClassImp(AliRsnMiniAnalysisTask)
43
44//__________________________________________________________________________________________________
45AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask() :
46 AliAnalysisTaskSE(),
c80938f5 47 fUseMC(kFALSE),
03d23846 48 fEvNum(0),
4fb0dfa3 49 fTriggerMask(0),
03d23846 50 fUseCentrality(kFALSE),
51 fCentralityType("QUALITY"),
1cdc3671 52 fUseAOD049CentralityPatch(kFALSE),
da997f6c 53 fUseCentralityPatchPbPb2011(0),
caef2e3c 54 fContinuousMix(kTRUE),
03d23846 55 fNMix(0),
56 fMaxDiffMult(10),
57 fMaxDiffVz(1.0),
58 fMaxDiffAngle(1E20),
59 fOutput(0x0),
60 fHistograms("AliRsnMiniOutput", 0),
61 fValues("AliRsnMiniValue", 0),
62 fHEventStat(0x0),
955ca046 63 fHAEventsVsMulti(0x0),
5654276f 64 fHAEventVz(0x0),
65 fHAEventMultiCent(0x0),
66 fHAEventPlane(0x0),
03d23846 67 fEventCuts(0x0),
68 fTrackCuts(0),
69 fRsnEvent(),
c80938f5 70 fEvBuffer(0x0),
c80938f5 71 fTriggerAna(0x0),
6aaeb33c 72 fESDtrackCuts(0x0),
caef2e3c 73 fMiniEvent(0x0),
61f275d1 74 fBigOutput(kFALSE),
088ca370 75 fMixPrintRefresh(-1),
76 fMaxNDaughters(-1),
31dbef4e 77 fCheckP(kFALSE),
78 fCheckFeedDown(kFALSE),
79 fOriginDselection(kFALSE),
80 fKeepDfromB(kFALSE),
81 fKeepDfromBOnly(kFALSE),
82 fRejectIfNoQuark(kFALSE)
03d23846 83{
84//
85// Dummy constructor ALWAYS needed for I/O.
86//
87}
88
89//__________________________________________________________________________________________________
c80938f5 90AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const char *name, Bool_t useMC) :
03d23846 91 AliAnalysisTaskSE(name),
c80938f5 92 fUseMC(useMC),
03d23846 93 fEvNum(0),
4fb0dfa3 94 fTriggerMask(AliVEvent::kMB),
03d23846 95 fUseCentrality(kFALSE),
96 fCentralityType("QUALITY"),
1cdc3671 97 fUseAOD049CentralityPatch(kFALSE),
da997f6c 98 fUseCentralityPatchPbPb2011(0),
caef2e3c 99 fContinuousMix(kTRUE),
03d23846 100 fNMix(0),
101 fMaxDiffMult(10),
102 fMaxDiffVz(1.0),
103 fMaxDiffAngle(1E20),
104 fOutput(0x0),
105 fHistograms("AliRsnMiniOutput", 0),
106 fValues("AliRsnMiniValue", 0),
107 fHEventStat(0x0),
955ca046 108 fHAEventsVsMulti(0x0),
5654276f 109 fHAEventVz(0x0),
110 fHAEventMultiCent(0x0),
111 fHAEventPlane(0x0),
03d23846 112 fEventCuts(0x0),
113 fTrackCuts(0),
114 fRsnEvent(),
c80938f5 115 fEvBuffer(0x0),
c80938f5 116 fTriggerAna(0x0),
6aaeb33c 117 fESDtrackCuts(0x0),
caef2e3c 118 fMiniEvent(0x0),
61f275d1 119 fBigOutput(kFALSE),
088ca370 120 fMixPrintRefresh(-1),
121 fMaxNDaughters(-1),
31dbef4e 122 fCheckP(kFALSE),
123 fCheckFeedDown(kFALSE),
124 fOriginDselection(kFALSE),
125 fKeepDfromB(kFALSE),
126 fKeepDfromBOnly(kFALSE),
127 fRejectIfNoQuark(kFALSE)
03d23846 128{
129//
130// Default constructor.
131// Define input and output slots here (never in the dummy constructor)
132// Input slot #0 works with a TChain - it is connected to the default input container
133// Output slot #1 writes into a TH1 container
134//
135
136 DefineOutput(1, TList::Class());
137}
138
139//__________________________________________________________________________________________________
52e6652d 140AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const AliRsnMiniAnalysisTask &copy) :
03d23846 141 AliAnalysisTaskSE(copy),
c80938f5 142 fUseMC(copy.fUseMC),
03d23846 143 fEvNum(0),
4fb0dfa3 144 fTriggerMask(copy.fTriggerMask),
03d23846 145 fUseCentrality(copy.fUseCentrality),
146 fCentralityType(copy.fCentralityType),
1cdc3671 147 fUseAOD049CentralityPatch(copy.fUseAOD049CentralityPatch),
da997f6c 148 fUseCentralityPatchPbPb2011(copy.fUseCentralityPatchPbPb2011),
caef2e3c 149 fContinuousMix(copy.fContinuousMix),
03d23846 150 fNMix(copy.fNMix),
151 fMaxDiffMult(copy.fMaxDiffMult),
152 fMaxDiffVz(copy.fMaxDiffVz),
153 fMaxDiffAngle(copy.fMaxDiffAngle),
154 fOutput(0x0),
155 fHistograms(copy.fHistograms),
156 fValues(copy.fValues),
157 fHEventStat(0x0),
955ca046 158 fHAEventsVsMulti(0x0),
5654276f 159 fHAEventVz(0x0),
160 fHAEventMultiCent(0x0),
161 fHAEventPlane(0x0),
03d23846 162 fEventCuts(copy.fEventCuts),
163 fTrackCuts(copy.fTrackCuts),
164 fRsnEvent(),
c80938f5 165 fEvBuffer(0x0),
c80938f5 166 fTriggerAna(copy.fTriggerAna),
6aaeb33c 167 fESDtrackCuts(copy.fESDtrackCuts),
caef2e3c 168 fMiniEvent(0x0),
61f275d1 169 fBigOutput(copy.fBigOutput),
088ca370 170 fMixPrintRefresh(copy.fMixPrintRefresh),
171 fMaxNDaughters(copy.fMaxNDaughters),
31dbef4e 172 fCheckP(copy.fCheckP),
173 fCheckFeedDown(copy.fCheckFeedDown),
174 fOriginDselection(copy.fOriginDselection),
175 fKeepDfromB(copy.fOriginDselection),
176 fKeepDfromBOnly(copy.fKeepDfromBOnly),
177 fRejectIfNoQuark(copy.fRejectIfNoQuark)
03d23846 178{
179//
180// Copy constructor.
181// Implemented as requested by C++ standards.
182// Can be used in PROOF and by plugins.
183//
184}
185
186//__________________________________________________________________________________________________
52e6652d 187AliRsnMiniAnalysisTask &AliRsnMiniAnalysisTask::operator=(const AliRsnMiniAnalysisTask &copy)
03d23846 188{
189//
190// Assignment operator.
191// Implemented as requested by C++ standards.
192// Can be used in PROOF and by plugins.
193//
194
195 AliAnalysisTaskSE::operator=(copy);
e6f3a909 196 if (this == &copy)
61f275d1 197 return *this;
c80938f5 198 fUseMC = copy.fUseMC;
4fb0dfa3 199 fEvNum = copy.fEvNum;
200 fTriggerMask = copy.fTriggerMask;
03d23846 201 fUseCentrality = copy.fUseCentrality;
202 fCentralityType = copy.fCentralityType;
1cdc3671 203 fUseAOD049CentralityPatch = copy.fUseAOD049CentralityPatch;
da997f6c 204 fUseCentralityPatchPbPb2011 = copy.fUseCentralityPatchPbPb2011;
caef2e3c 205 fContinuousMix = copy.fContinuousMix;
03d23846 206 fNMix = copy.fNMix;
207 fMaxDiffMult = copy.fMaxDiffMult;
208 fMaxDiffVz = copy.fMaxDiffVz;
209 fMaxDiffAngle = copy.fMaxDiffAngle;
210 fHistograms = copy.fHistograms;
211 fValues = copy.fValues;
955ca046 212 fHEventStat = copy.fHEventStat;
213 fHAEventsVsMulti = copy.fHAEventsVsMulti;
5654276f 214 fHAEventVz = copy.fHAEventVz;
215 fHAEventMultiCent = copy.fHAEventMultiCent;
216 fHAEventPlane = copy.fHAEventPlane;
03d23846 217 fEventCuts = copy.fEventCuts;
218 fTrackCuts = copy.fTrackCuts;
219 fTriggerAna = copy.fTriggerAna;
c80938f5 220 fESDtrackCuts = copy.fESDtrackCuts;
caef2e3c 221 fBigOutput = copy.fBigOutput;
61f275d1 222 fMixPrintRefresh = copy.fMixPrintRefresh;
088ca370 223 fMaxNDaughters = copy.fMaxNDaughters;
224 fCheckP = copy.fCheckP;
31dbef4e 225 fCheckFeedDown = copy.fCheckFeedDown;
226 fOriginDselection = copy.fOriginDselection;
227 fKeepDfromB = copy.fOriginDselection;
228 fKeepDfromBOnly = copy.fKeepDfromBOnly;
229 fRejectIfNoQuark = copy.fRejectIfNoQuark;
03d23846 230 return (*this);
231}
232
233//__________________________________________________________________________________________________
234AliRsnMiniAnalysisTask::~AliRsnMiniAnalysisTask()
235{
236//
52e6652d 237// Destructor.
03d23846 238// Clean-up the output list, but not the histograms that are put inside
239// (the list is owner and will clean-up these histograms). Protect in PROOF case.
240//
241
d573d2fb 242
03d23846 243 if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
244 delete fOutput;
d573d2fb 245 delete fEvBuffer;
03d23846 246 }
247}
248
249//__________________________________________________________________________________________________
250Int_t AliRsnMiniAnalysisTask::AddTrackCuts(AliRsnCutSet *cuts)
251{
252//
253// Add a new cut set for a new criterion for track selection.
254// A user can add as many as he wants, and each one corresponds
255// to one of the available bits in the AliRsnMiniParticle mask.
256// The only check is the following: if a cut set with the same name
257// as the argument is there, this is not added.
258// Return value is the array position of this set.
259//
260
261 TObject *obj = fTrackCuts.FindObject(cuts->GetName());
52e6652d 262
03d23846 263 if (obj) {
264 AliInfo(Form("A cut set named '%s' already exists", cuts->GetName()));
265 return fTrackCuts.IndexOf(obj);
266 } else {
267 fTrackCuts.AddLast(cuts);
268 return fTrackCuts.IndexOf(cuts);
269 }
270}
271
272//__________________________________________________________________________________________________
273void AliRsnMiniAnalysisTask::UserCreateOutputObjects()
274{
275//
276// Initialization of outputs.
277// This is called once per worker node.
278//
279
280 // reset counter
9e7b94f5 281 fEvNum = -1;
52e6652d 282
d573d2fb 283 // message
284 AliInfo(Form("Selected event characterization: %s (%s)", (fUseCentrality ? "centrality" : "multiplicity"), fCentralityType.Data()));
03d23846 285
286 // initialize trigger analysis
c80938f5 287 if (fTriggerAna) delete fTriggerAna;
03d23846 288 fTriggerAna = new AliTriggerAnalysis;
52e6652d 289
c80938f5 290 // initialize ESD quality cuts
291 if (fESDtrackCuts) delete fESDtrackCuts;
292 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010();
03d23846 293
294 // create list and set it as owner of its content (MANDATORY)
caef2e3c 295 if (fBigOutput) OpenFile(1);
03d23846 296 fOutput = new TList();
297 fOutput->SetOwner();
52e6652d 298
03d23846 299 // initialize event statistics counter
300 fHEventStat = new TH1F("hEventStat", "Event statistics", 4, 0.0, 4.0);
301 fHEventStat->GetXaxis()->SetBinLabel(1, "CINT1B");
302 fHEventStat->GetXaxis()->SetBinLabel(2, "V0AND");
303 fHEventStat->GetXaxis()->SetBinLabel(3, "Candle");
304 fHEventStat->GetXaxis()->SetBinLabel(4, "Accepted");
305 fOutput->Add(fHEventStat);
52e6652d 306
955ca046 307 if (fUseCentrality)
308 fHAEventsVsMulti = new TH1F("hAEventsVsMulti", "Accepted events vs Centrality", 100, 0, 100.0);
309 else
e6952ec7 310 fHAEventsVsMulti = new TH1F("hAEventsVsMulti", "Accepted events vs Multiplicity",1000, 0, 1000.0);
955ca046 311 fOutput->Add(fHAEventsVsMulti);
e6952ec7 312
5654276f 313 if(fHAEventVz) fOutput->Add(fHAEventVz);
314 if(fHAEventMultiCent) fOutput->Add(fHAEventMultiCent);
315 if(fHAEventPlane) fOutput->Add(fHAEventPlane);
316
61f275d1 317 TIter next(&fTrackCuts);
318 AliRsnCutSet *cs;
319 while ((cs = (AliRsnCutSet *) next())) {
320 cs->Init(fOutput);
321 }
322
03d23846 323 // create temporary tree for filtered events
6aaeb33c 324 if (fMiniEvent) delete fMiniEvent;
c80938f5 325 fEvBuffer = new TTree("EventBuffer", "Temporary buffer for mini events");
6aaeb33c 326 fEvBuffer->Branch("events", "AliRsnMiniEvent", &fMiniEvent);
52e6652d 327
03d23846 328 // create one histogram per each stored definition (event histograms)
329 Int_t i, ndef = fHistograms.GetEntries();
330 AliRsnMiniOutput *def = 0x0;
331 for (i = 0; i < ndef; i++) {
52e6652d 332 def = (AliRsnMiniOutput *)fHistograms[i];
03d23846 333 if (!def) continue;
334 if (!def->Init(GetName(), fOutput)) {
335 AliError(Form("Def '%s': failed initialization", def->GetName()));
336 continue;
337 }
338 }
52e6652d 339
03d23846 340 // post data for ALL output slots >0 here, to get at least an empty histogram
341 PostData(1, fOutput);
342}
343
344//__________________________________________________________________________________________________
345void AliRsnMiniAnalysisTask::UserExec(Option_t *)
346{
347//
6aaeb33c 348// Computation loop.
349// In this case, it checks if the event is acceptable, and eventually
350// creates the corresponding mini-event and stores it in the buffer.
351// The real histogram filling is done at the end, in "FinishTaskOutput".
03d23846 352//
353
9e7b94f5 354 // increment event counter
03d23846 355 fEvNum++;
9e7b94f5 356
03d23846 357 // check current event
358 Char_t check = CheckCurrentEvent();
359 if (!check) return;
52e6652d 360
d573d2fb 361 // setup PID response
52e6652d 362 AliAnalysisManager *man = AliAnalysisManager::GetAnalysisManager();
363 AliInputEventHandler *inputHandler = (AliInputEventHandler *)man->GetInputEventHandler();
364 fRsnEvent.SetPIDResponse(inputHandler->GetPIDResponse());
365
6aaeb33c 366 // fill a mini-event from current
367 // and skip this event if no tracks were accepted
45aa62b9 368 FillMiniEvent(check);
52e6652d 369
6aaeb33c 370 // fill MC based histograms on mothers,
371 // which do need the original event
c80938f5 372 if (fUseMC) {
373 if (fRsnEvent.IsESD() && fMCEvent)
6aaeb33c 374 FillTrueMotherESD(fMiniEvent);
c80938f5 375 else if (fRsnEvent.IsAOD() && fRsnEvent.GetAODList())
6aaeb33c 376 FillTrueMotherAOD(fMiniEvent);
03d23846 377 }
52e6652d 378
9e7b94f5 379 // if the event is not empty, store it
380 if (fMiniEvent->IsEmpty()) {
381 AliDebugClass(2, Form("Rejecting empty event #%d", fEvNum));
382 } else {
383 Int_t id = fEvBuffer->GetEntries();
384 AliDebugClass(2, Form("Adding event #%d with ID = %d", fEvNum, id));
385 fMiniEvent->ID() = id;
386 fEvBuffer->Fill();
387 }
52e6652d 388
6aaeb33c 389 // post data for computed stuff
03d23846 390 PostData(1, fOutput);
391}
392
393//__________________________________________________________________________________________________
394void AliRsnMiniAnalysisTask::FinishTaskOutput()
395{
396//
6aaeb33c 397// This function is called at the end of the loop on available events,
398// and then the buffer will be full with all the corresponding mini-events,
399// each one containing all tracks selected by each of the available track cuts.
400// Here a loop is done on each of these events, and both single-event and mixing are computed
03d23846 401//
402
6aaeb33c 403 // security code: reassign the buffer to the mini-event cursor
404 fEvBuffer->SetBranchAddress("events", &fMiniEvent);
52e6652d 405 TStopwatch timer;
0efb7042 406 // prepare variables
6aaeb33c 407 Int_t ievt, nEvents = (Int_t)fEvBuffer->GetEntries();
408 Int_t idef, nDefs = fHistograms.GetEntries();
45aa62b9 409 Int_t imix, iloop, ifill;
6aaeb33c 410 AliRsnMiniOutput *def = 0x0;
411 AliRsnMiniOutput::EComputation compType;
52e6652d 412
61f275d1 413 Int_t printNum = fMixPrintRefresh;
414 if (printNum < 0) {
415 if (nEvents>1e5) printNum=nEvents/100;
416 else if (nEvents>1e4) printNum=nEvents/10;
417 else printNum = 0;
418 }
419
6aaeb33c 420 // loop on events, and for each one fill all outputs
421 // using the appropriate procedure depending on its type
422 // only mother-related histograms are filled in UserExec,
423 // since they require direct access to MC event
52e6652d 424 timer.Start();
6aaeb33c 425 for (ievt = 0; ievt < nEvents; ievt++) {
426 // get next entry
427 fEvBuffer->GetEntry(ievt);
52e6652d 428 if (printNum&&(ievt%printNum==0)) {
429 AliInfo(Form("[%s] Std.Event %d/%d",GetName(), ievt,nEvents));
61f275d1 430 timer.Stop(); timer.Print(); fflush(stdout); timer.Start(kFALSE);
52e6652d 431 }
45aa62b9 432 // fill
6aaeb33c 433 for (idef = 0; idef < nDefs; idef++) {
52e6652d 434 def = (AliRsnMiniOutput *)fHistograms[idef];
6aaeb33c 435 if (!def) continue;
436 compType = def->GetComputation();
437 // execute computation in the appropriate way
438 switch (compType) {
439 case AliRsnMiniOutput::kEventOnly:
9e7b94f5 440 //AliDebugClass(1, Form("Event %d, def '%s': event-value histogram filling", ievt, def->GetName()));
45aa62b9 441 ifill = 1;
0efb7042 442 def->FillEvent(fMiniEvent, &fValues);
6aaeb33c 443 break;
444 case AliRsnMiniOutput::kTruePair:
9e7b94f5 445 //AliDebugClass(1, Form("Event %d, def '%s': true-pair histogram filling", ievt, def->GetName()));
0efb7042 446 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 447 break;
448 case AliRsnMiniOutput::kTrackPair:
9e7b94f5 449 //AliDebugClass(1, Form("Event %d, def '%s': pair-value histogram filling", ievt, def->GetName()));
0efb7042 450 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 451 break;
452 case AliRsnMiniOutput::kTrackPairRotated1:
9e7b94f5 453 //AliDebugClass(1, Form("Event %d, def '%s': rotated (1) background histogram filling", ievt, def->GetName()));
0efb7042 454 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 455 break;
456 case AliRsnMiniOutput::kTrackPairRotated2:
9e7b94f5 457 //AliDebugClass(1, Form("Event %d, def '%s': rotated (2) background histogram filling", ievt, def->GetName()));
0efb7042 458 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 459 break;
460 default:
461 // other kinds are processed elsewhere
45aa62b9 462 ifill = 0;
6aaeb33c 463 AliDebugClass(2, Form("Computation = %d", (Int_t)compType));
464 }
45aa62b9 465 // message
466 AliDebugClass(1, Form("Event %6d: def = '%15s' -- fills = %5d", ievt, def->GetName(), ifill));
03d23846 467 }
468 }
52e6652d 469
0efb7042 470 // if no mixing is required, stop here and post the output
471 if (fNMix < 1) {
472 AliDebugClass(2, "Stopping here, since no mixing is required");
473 PostData(1, fOutput);
474 return;
475 }
52e6652d 476
0efb7042 477 // initialize mixing counter
9e7b94f5 478 Int_t nmatched[nEvents];
479 TString *smatched = new TString[nEvents];
0efb7042 480 for (ievt = 0; ievt < nEvents; ievt++) {
9e7b94f5 481 smatched[ievt] = "|";
482 nmatched[ievt] = 0;
0efb7042 483 }
61f275d1 484
485
52e6652d 486 AliInfo(Form("[%s] Std.Event %d/%d",GetName(), nEvents,nEvents));
61f275d1 487 timer.Stop(); timer.Print(); timer.Start(); fflush(stdout);
52e6652d 488
0efb7042 489 // search for good matchings
490 for (ievt = 0; ievt < nEvents; ievt++) {
52e6652d 491 if (printNum&&(ievt%printNum==0)) {
492 AliInfo(Form("[%s] EventMixing searching %d/%d",GetName(),ievt,nEvents));
493 timer.Stop(); timer.Print(); timer.Start(kFALSE); fflush(stdout);
494 }
9e7b94f5 495 if (nmatched[ievt] >= fNMix) continue;
0efb7042 496 fEvBuffer->GetEntry(ievt);
497 AliRsnMiniEvent evMain(*fMiniEvent);
498 for (iloop = 1; iloop < nEvents; iloop++) {
499 imix = ievt + iloop;
500 if (imix >= nEvents) imix -= nEvents;
501 if (imix == ievt) continue;
502 // text next entry
503 fEvBuffer->GetEntry(imix);
504 // skip if events are not matched
caef2e3c 505 if (!EventsMatch(&evMain, fMiniEvent)) continue;
0efb7042 506 // check that the array of good matches for mixed does not already contain main event
9e7b94f5 507 if (smatched[imix].Contains(Form("|%d|", ievt))) continue;
508 // check that the found good events has not enough matches already
509 if (nmatched[imix] >= fNMix) continue;
0efb7042 510 // add new mixing candidate
9e7b94f5 511 smatched[ievt].Append(Form("%d|", imix));
512 nmatched[ievt]++;
513 nmatched[imix]++;
514 if (nmatched[ievt] >= fNMix) break;
0efb7042 515 }
9e7b94f5 516 AliDebugClass(1, Form("Matches for event %5d = %d [%s] (missing are declared above)", evMain.ID(), nmatched[ievt], smatched[ievt].Data()));
0efb7042 517 }
61f275d1 518
52e6652d 519 AliInfo(Form("[%s] EventMixing searching %d/%d",GetName(),nEvents,nEvents));
61f275d1 520 timer.Stop(); timer.Print(); fflush(stdout); timer.Start();
52e6652d 521
0efb7042 522 // perform mixing
523 TObjArray *list = 0x0;
524 TObjString *os = 0x0;
525 for (ievt = 0; ievt < nEvents; ievt++) {
52e6652d 526 if (printNum&&(ievt%printNum==0)) {
527 AliInfo(Form("[%s] EventMixing %d/%d",GetName(),ievt,nEvents));
528 timer.Stop(); timer.Print(); timer.Start(kFALSE); fflush(stdout);
529 }
0efb7042 530 ifill = 0;
531 fEvBuffer->GetEntry(ievt);
532 AliRsnMiniEvent evMain(*fMiniEvent);
9e7b94f5 533 list = smatched[ievt].Tokenize("|");
0efb7042 534 TObjArrayIter next(list);
52e6652d 535 while ( (os = (TObjString *)next()) ) {
0efb7042 536 imix = os->GetString().Atoi();
0efb7042 537 fEvBuffer->GetEntry(imix);
538 for (idef = 0; idef < nDefs; idef++) {
52e6652d 539 def = (AliRsnMiniOutput *)fHistograms[idef];
0efb7042 540 if (!def) continue;
541 if (!def->IsTrackPairMix()) continue;
d573d2fb 542 ifill += def->FillPair(&evMain, fMiniEvent, &fValues, kTRUE);
9e7b94f5 543 if (!def->IsSymmetric()) {
544 AliDebugClass(2, "Reflecting non symmetric pair");
545 ifill += def->FillPair(fMiniEvent, &evMain, &fValues, kFALSE);
546 }
0efb7042 547 }
548 }
549 delete list;
550 }
52e6652d 551
9e7b94f5 552 delete [] smatched;
52e6652d 553
554 AliInfo(Form("[%s] EventMixing %d/%d",GetName(),nEvents,nEvents));
61f275d1 555 timer.Stop(); timer.Print(); fflush(stdout);
52e6652d 556
0efb7042 557 /*
52e6652d 558 OLD
0efb7042 559 ifill = 0;
560 for (iloop = 1; iloop < nEvents; iloop++) {
561 imix = ievt + iloop;
562 // restart from beginning if reached last event
563 if (imix >= nEvents) imix -= nEvents;
564 // avoid to mix an event with itself
565 if (imix == ievt) continue;
566 // skip all events already mixed enough times
567 if (fNMixed[ievt] >= fNMix) break;
568 if (fNMixed[imix] >= fNMix) continue;
569 fEvBuffer->GetEntry(imix);
570 // skip if events are not matched
571 if (TMath::Abs(evMain.Vz() - fMiniEvent->Vz() ) > fMaxDiffVz ) continue;
572 if (TMath::Abs(evMain.Mult() - fMiniEvent->Mult() ) > fMaxDiffMult ) continue;
573 if (TMath::Abs(evMain.Angle() - fMiniEvent->Angle()) > fMaxDiffAngle) continue;
574 // found a match: increment counter for both events
575 AliDebugClass(1, Form("Event %d, def '%s': event mixing (%d with %d)", ievt, def->GetName(), ievt, imix));
576 fNMixed[ievt]++;
577 fNMixed[imix]++;
578 // process mixing
579 ifill += def->FillPair(&evMain, fMiniEvent, &fValues);
580 // stop if mixed enough times
581 if (fNMixed[ievt] >= fNMix) break;
582 }
52e6652d 583 break;
6aaeb33c 584 // print number of mixings done with each event
45aa62b9 585 for (ievt = 0; ievt < nEvents; ievt++) {
586 AliDebugClass(2, Form("Event %6d: mixed %2d times", ievt, fNMixed[ievt]));
587 }
0efb7042 588 */
52e6652d 589
6aaeb33c 590 // post computed data
03d23846 591 PostData(1, fOutput);
592}
593
594//__________________________________________________________________________________________________
595void AliRsnMiniAnalysisTask::Terminate(Option_t *)
596{
597//
598// Draw result to screen, or perform fitting, normalizations
599// Called once at the end of the query
600//
601
52e6652d 602 fOutput = dynamic_cast<TList *>(GetOutputData(1));
603 if (!fOutput) {
604 AliError("Could not retrieve TList fOutput");
605 return;
03d23846 606 }
607}
608
609//__________________________________________________________________________________________________
610Char_t AliRsnMiniAnalysisTask::CheckCurrentEvent()
611{
612//
c80938f5 613// This method checks if current event is OK for analysis.
614// In case it is, the pointers of the local AliRsnEvent data member
615// will point to it, in order to allow cut checking, otherwise the
616// function exits with a failure message.
617// ---
618// ESD events must pass the physics selection, AOD are supposed to do.
619// ---
620// While checking the event, a histogram is filled to count the number
621// of CINT1B, V0AND and CANDLE events, which are needed for normalization
622// ---
623// Return values can be:
03d23846 624// -- 'E' if the event is accepted and is ESD
625// -- 'A' if the event is accepted and is AOD
626// -- 0 if the event is not accepted
627//
628
629 // string to sum messages
630 TString msg("");
52e6652d 631
03d23846 632 // check input type
c80938f5 633 // exit points are provided in all cases an event is bad
634 // if this block is passed, an event can be rejected only
635 // if it does not pass the set of event cuts defined in the task
03d23846 636 Char_t output = 0;
c80938f5 637 Bool_t isSelected;
638 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
639 // type ESD
03d23846 640 output = 'E';
c80938f5 641 // ESD specific check: Physics Selection
642 // --> if this is failed, the event is rejected
4fb0dfa3 643 isSelected = (((AliInputEventHandler *)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & fTriggerMask);
644
c80938f5 645 if (!isSelected) {
45aa62b9 646 AliDebugClass(2, "Event does not pass physics selections");
c80938f5 647 fRsnEvent.SetRef(0x0);
648 fRsnEvent.SetRefMC(0x0);
649 return 0;
650 }
651 // set reference to input
652 fRsnEvent.SetRef(fInputEvent);
653 // add MC if requested and available
654 if (fUseMC) {
52e6652d 655 if (fMCEvent)
c80938f5 656 fRsnEvent.SetRefMC(fMCEvent);
657 else {
658 AliWarning("MC event requested but not available");
659 fRsnEvent.SetRefMC(0x0);
660 }
661 }
662 } else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
663 // type AOD
03d23846 664 output = 'A';
c80938f5 665 // set reference to input
666 fRsnEvent.SetRef(fInputEvent);
667 // add MC if requested and available (it is in the same object)
668 if (fUseMC) {
669 fRsnEvent.SetRefMC(fInputEvent);
670 if (!fRsnEvent.GetAODList()) {
671 AliWarning("MC event requested but not available");
672 fRsnEvent.SetRefMC(0x0);
673 }
674 }
675 } else {
03d23846 676 AliError(Form("Bad input event class: %s", fInputEvent->ClassName()));
c80938f5 677 // reset pointers in local AliRsnEvent object
678 fRsnEvent.SetRef(0x0);
679 fRsnEvent.SetRefMC(0x0);
03d23846 680 return 0;
681 }
52e6652d 682
c80938f5 683 // fill counter of accepted events
684 fHEventStat->Fill(0.1);
52e6652d 685
03d23846 686 // check if it is V0AND
c80938f5 687 // --> uses a cast to AliESDEvent even if the input is an AliAODEvent
52e6652d 688 Bool_t v0A = fTriggerAna->IsOfflineTriggerFired((AliESDEvent *)fInputEvent, AliTriggerAnalysis::kV0A);
689 Bool_t v0C = fTriggerAna->IsOfflineTriggerFired((AliESDEvent *)fInputEvent, AliTriggerAnalysis::kV0C);
03d23846 690 if (v0A && v0C) {
691 msg += " -- VOAND = YES";
692 fHEventStat->Fill(1.1);
693 } else {
694 msg += " -- VOAND = NO ";
695 }
52e6652d 696
03d23846 697 // check candle
c80938f5 698 // --> requires at least one good quality track with Pt > 0.5 and |eta| <= 0.8
699 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
03d23846 700 Bool_t candle = kFALSE;
52e6652d 701 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
702 AliVTrack *track = (AliVTrack *)fInputEvent->GetTrack(iTrack);
703 AliESDtrack *esdt = dynamic_cast<AliESDtrack *>(track);
704 AliAODTrack *aodt = dynamic_cast<AliAODTrack *>(track);
03d23846 705 if (track->Pt() < 0.5) continue;
706 if(TMath::Abs(track->Eta()) > 0.8) continue;
c80938f5 707 if (esdt) if (!fESDtrackCuts->AcceptTrack(esdt)) continue;
708 if (aodt) if (!aodt->TestFilterBit(5)) continue;
03d23846 709 candle = kTRUE;
710 break;
711 }
712 if (candle) {
52e6652d 713 msg += " -- CANDLE = YES";
03d23846 714 fHEventStat->Fill(2.1);
715 } else {
52e6652d 716 msg += " -- CANDLE = NO ";
03d23846 717 }
52e6652d 718
c80938f5 719 // if event cuts are defined, they are checked here
720 // final decision on the event depends on this
721 isSelected = kTRUE;
03d23846 722 if (fEventCuts) {
723 if (!fEventCuts->IsSelected(&fRsnEvent)) {
724 msg += " -- Local cuts = REJECTED";
c80938f5 725 isSelected = kFALSE;
03d23846 726 } else {
727 msg += " -- Local cuts = ACCEPTED";
c80938f5 728 isSelected = kTRUE;
03d23846 729 }
730 } else {
731 msg += " -- Local cuts = NONE";
c80938f5 732 isSelected = kTRUE;
03d23846 733 }
52e6652d 734
03d23846 735 // if the above exit point is not taken, the event is accepted
9e7b94f5 736 AliDebugClass(2, Form("Stats: %s", msg.Data()));
c80938f5 737 if (isSelected) {
738 fHEventStat->Fill(3.1);
955ca046 739 Double_t multi = ComputeCentrality((output == 'E'));
740 fHAEventsVsMulti->Fill(multi);
5654276f 741 if(fHAEventVz) fHAEventVz->Fill(multi,fInputEvent->GetPrimaryVertex()->GetZ());
742 if(fHAEventMultiCent) fHAEventMultiCent->Fill(multi,ComputeMultiplicity(output == 'E',fHAEventMultiCent->GetYaxis()->GetTitle()));
743 if(fHAEventPlane) fHAEventPlane->Fill(multi,ComputeAngle());
c80938f5 744 return output;
745 } else {
746 return 0;
747 }
03d23846 748}
749
6aaeb33c 750//__________________________________________________________________________________________________
45aa62b9 751void AliRsnMiniAnalysisTask::FillMiniEvent(Char_t evType)
6aaeb33c 752{
753//
754// Refresh cursor mini-event data member to fill with current event.
755// Returns the total number of tracks selected.
756//
757
758 // assign event-related values
45aa62b9 759 if (fMiniEvent) delete fMiniEvent;
6aaeb33c 760 fMiniEvent = new AliRsnMiniEvent;
761 fMiniEvent->Vz() = fInputEvent->GetPrimaryVertex()->GetZ();
762 fMiniEvent->Angle() = ComputeAngle();
763 fMiniEvent->Mult() = ComputeCentrality((evType == 'E'));
45aa62b9 764 AliDebugClass(2, Form("Event %d: type = %c -- vz = %f -- mult = %f -- angle = %f", fEvNum, evType, fMiniEvent->Vz(), fMiniEvent->Mult(), fMiniEvent->Angle()));
52e6652d 765
6aaeb33c 766 // loop on daughters and assign track-related values
767 Int_t ic, ncuts = fTrackCuts.GetEntries();
768 Int_t ip, npart = fRsnEvent.GetAbsoluteSum();
45aa62b9 769 Int_t npos = 0, nneg = 0, nneu = 0;
6aaeb33c 770 AliRsnDaughter cursor;
771 AliRsnMiniParticle miniParticle;
772 for (ip = 0; ip < npart; ip++) {
773 // point cursor to next particle
774 fRsnEvent.SetDaughter(cursor, ip);
775 // copy momentum and MC info if present
776 miniParticle.CopyDaughter(&cursor);
45aa62b9 777 miniParticle.Index() = ip;
6aaeb33c 778 // switch on the bits corresponding to passed cuts
779 for (ic = 0; ic < ncuts; ic++) {
52e6652d 780 AliRsnCutSet *cuts = (AliRsnCutSet *)fTrackCuts[ic];
6aaeb33c 781 if (cuts->IsSelected(&cursor)) miniParticle.SetCutBit(ic);
782 }
783 // if a track passes at least one track cut, it is added to the pool
45aa62b9 784 if (miniParticle.CutBits()) {
785 fMiniEvent->AddParticle(miniParticle);
786 if (miniParticle.Charge() == '+') npos++;
787 else if (miniParticle.Charge() == '-') nneg++;
788 else nneu++;
789 }
6aaeb33c 790 }
52e6652d 791
6aaeb33c 792 // get number of accepted tracks
45aa62b9 793 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));
6aaeb33c 794}
795
3dced4f8 796//__________________________________________________________________________________________________
797Double_t AliRsnMiniAnalysisTask::ComputeAngle()
798{
799//
800// Get the plane angle
801//
802
cd273d20 803 AliEventplane *plane = 0x0;
52e6652d 804
cd273d20 805 if (fInputEvent->InheritsFrom(AliESDEvent::Class()))
806 plane = fInputEvent->GetEventplane();
807 else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
52e6652d 808 AliAODEvent *aodEvent = (AliAODEvent *)fInputEvent;
cd273d20 809 plane = aodEvent->GetHeader()->GetEventplaneP();
810 }
811
52e6652d 812 if (plane)
3dced4f8 813 return plane->GetEventplane("Q");
814 else {
815 AliWarning("No event plane defined");
816 return 1E20;
817 }
818}
819
03d23846 820//__________________________________________________________________________________________________
821Double_t AliRsnMiniAnalysisTask::ComputeCentrality(Bool_t isESD)
822{
823//
824// Computes event centrality/multiplicity according to the criterion defined
825// by two elements: (1) choice between multiplicity and centrality and
826// (2) the string defining what criterion must be used for specific computation.
827//
828
829 if (fUseCentrality) {
da997f6c 830 if ((!fUseMC) && (fUseCentralityPatchPbPb2011)) {
831 return ApplyCentralityPatchPbPb2011();//
832 }
833 if ((!fUseMC) && (!isESD) && (fUseAOD049CentralityPatch)) {
834 return ApplyCentralityPatchAOD049();
835 } else {
836 AliCentrality *centrality = fInputEvent->GetCentrality();
3da8cef7 837 if (!centrality) {
da997f6c 838 AliError("Cannot compute centrality!");
839 return -1.0;
3da8cef7 840 }
841 return centrality->GetCentralityPercentile(fCentralityType.Data());
da997f6c 842 }
03d23846 843 } else {
03d23846 844 if (!fCentralityType.CompareTo("TRACKS"))
845 return fInputEvent->GetNumberOfTracks();
846 else if (!fCentralityType.CompareTo("QUALITY"))
c80938f5 847 if (isESD)
52e6652d 848 return AliESDtrackCuts::GetReferenceMultiplicity((AliESDEvent *)fInputEvent, kTRUE);
c80938f5 849 else {
850 Double_t count = 0.;
851 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
52e6652d 852 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
853 AliVTrack *track = (AliVTrack *)fInputEvent->GetTrack(iTrack);
854 AliAODTrack *aodt = dynamic_cast<AliAODTrack *>(track);
c80938f5 855 if (!aodt) continue;
856 if (!aodt->TestFilterBit(5)) continue;
857 count++;
858 }
859 return count;
860 }
03d23846 861 else if (!fCentralityType.CompareTo("TRACKLETS")) {
c80938f5 862 if (isESD) {
52e6652d 863 const AliMultiplicity *mult = ((AliESDEvent *)fInputEvent)->GetMultiplicity();
c80938f5 864 Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
865 for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
866 return AliESDUtils::GetCorrSPD2(nClusters[1], fInputEvent->GetPrimaryVertex()->GetZ());
867 } else {
868 AliWarning("Cannot compute multiplicity with SPD tracklets from AOD");
869 return 1E20;
870 }
03d23846 871 } else {
872 AliError(Form("String '%s' does not define a possible multiplicity/centrality computation", fCentralityType.Data()));
873 return -1.0;
874 }
875 }
876}
877
5654276f 878//__________________________________________________________________________________________________
879Double_t AliRsnMiniAnalysisTask::ComputeMultiplicity(Bool_t isESD,TString type)
880{
881//
882// Computes event multiplicity according to the string defining
883// what criterion must be used for specific computation.
884//
885
e6952ec7 886 type.ToUpper();
887
888 if (!type.CompareTo("TRACKS"))
889 return fInputEvent->GetNumberOfTracks();
890 else if (!type.CompareTo("QUALITY"))
891 if (isESD)
892 return AliESDtrackCuts::GetReferenceMultiplicity((AliESDEvent *)fInputEvent, kTRUE);
893 else {
894 Double_t count = 0.;
895 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
896 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
897 AliVTrack *track = (AliVTrack *)fInputEvent->GetTrack(iTrack);
898 AliAODTrack *aodt = dynamic_cast<AliAODTrack *>(track);
899 if (!aodt) continue;
900 if (!aodt->TestFilterBit(5)) continue;
901 count++;
902 }
903 return count;
5654276f 904 }
e6952ec7 905 else if (!type.CompareTo("TRACKLETS")) {
906 if (isESD) {
907 const AliMultiplicity *mult = ((AliESDEvent *)fInputEvent)->GetMultiplicity();
908 Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
909 for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
910 return AliESDUtils::GetCorrSPD2(nClusters[1], fInputEvent->GetPrimaryVertex()->GetZ());
911 } else {
912 AliWarning("Cannot compute multiplicity with SPD tracklets from AOD");
913 return 1E20;
914 }
915 } else {
916 AliError(Form("String '%s' does not define a possible multiplicity/centrality computation", type.Data()));
917 return -1.0;
918 }
5654276f 919
e6952ec7 920 return 1E20;
5654276f 921}
922
03d23846 923//__________________________________________________________________________________________________
924void AliRsnMiniAnalysisTask::FillTrueMotherESD(AliRsnMiniEvent *miniEvent)
925{
926//
927// Fills the histograms with true mother (ESD version)
928//
929
930 Bool_t okMatch;
931 Int_t id, ndef = fHistograms.GetEntries();
932 Int_t ip, label1, label2, npart = fMCEvent->GetNumberOfTracks();
933 static AliRsnMiniPair miniPair;
934 AliMCParticle *daughter1, *daughter2;
935 TLorentzVector p1, p2;
936 AliRsnMiniOutput *def = 0x0;
52e6652d 937
03d23846 938 for (id = 0; id < ndef; id++) {
52e6652d 939 def = (AliRsnMiniOutput *)fHistograms[id];
03d23846 940 if (!def) continue;
941 if (!def->IsMother()) continue;
942 for (ip = 0; ip < npart; ip++) {
52e6652d 943 AliMCParticle *part = (AliMCParticle *)fMCEvent->GetTrack(ip);
e6952ec7 944 //get mother pdg code
64129b35 945 if (part->Particle()->GetPdgCode() != def->GetMotherPDG()) continue;
03d23846 946 // check that daughters match expected species
088ca370 947 if (part->Particle()->GetNDaughters() < 2) continue;
948 if (fMaxNDaughters > 0 && part->Particle()->GetNDaughters() > fMaxNDaughters) continue;
03d23846 949 label1 = part->Particle()->GetDaughter(0);
950 label2 = part->Particle()->GetDaughter(1);
52e6652d 951 daughter1 = (AliMCParticle *)fMCEvent->GetTrack(label1);
952 daughter2 = (AliMCParticle *)fMCEvent->GetTrack(label2);
03d23846 953 okMatch = kFALSE;
954 if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(1)) {
955 okMatch = kTRUE;
956 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
957 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
958 } else if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(0)) {
959 okMatch = kTRUE;
960 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
961 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
962 }
963 if (!okMatch) continue;
088ca370 964 if(fCheckP && (TMath::Abs(part->Px()-(daughter1->Px()+daughter2->Px()))/(TMath::Abs(part->Px())+1.e-13)) > 0.00001 &&
965 (TMath::Abs(part->Py()-(daughter1->Py()+daughter2->Py()))/(TMath::Abs(part->Py())+1.e-13)) > 0.00001 &&
966 (TMath::Abs(part->Pz()-(daughter1->Pz()+daughter2->Pz()))/(TMath::Abs(part->Pz())+1.e-13)) > 0.00001 ) continue;
31dbef4e 967 if(fCheckFeedDown){
968 Int_t pdgGranma = 0;
969 Int_t mother = 0;
970 mother = part->GetMother();
971 Int_t istep = 0;
972 Int_t abspdgGranma =0;
973 Bool_t isFromB=kFALSE;
974 Bool_t isQuarkFound=kFALSE;
975 while (mother >=0 ){
976 istep++;
977 AliDebug(2,Form("mother at step %d = %d", istep, mother));
978 AliMCParticle* mcGranma = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(mother));
979 if (mcGranma){
980 pdgGranma = mcGranma->PdgCode();
981 AliDebug(2,Form("Pdg mother at step %d = %d", istep, pdgGranma));
982 abspdgGranma = TMath::Abs(pdgGranma);
983 if ((abspdgGranma > 500 && abspdgGranma < 600) || (abspdgGranma > 5000 && abspdgGranma < 6000)){
984 isFromB=kTRUE;
985 }
986 if(abspdgGranma==4 || abspdgGranma==5) isQuarkFound=kTRUE;
987 mother = mcGranma->GetMother();
988 }else{
989 AliError("Failed casting the mother particle!");
990 break;
991 }
992 }
993 if(fRejectIfNoQuark && !isQuarkFound) pdgGranma = -99999;
994 if(isFromB){
995 if (!fKeepDfromB) pdgGranma = -9999; //skip particle if come from a B meson.
996 }
997 else{
998 if (fKeepDfromBOnly) pdgGranma = -999;
999
1000 if (pdgGranma == -99999){
1001 AliDebug(2,"This particle does not have a quark in his genealogy\n");
1002 continue;
1003 }
1004 if (pdgGranma == -9999){
1005 AliDebug(2,"This particle come from a B decay channel but according to the settings of the task, we keep only the prompt charm particles\n");
1006 continue;
1007 }
1008
1009 if (pdgGranma == -999){
1010 AliDebug(2,"This particle come from a prompt charm particles but according to the settings of the task, we want only the ones coming from B\n");
1011 continue;
1012 }
1013
1014 }
1015 }
03d23846 1016 // assign momenta to computation object
1017 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
1018 miniPair.FillRef(def->GetMotherMass());
1019 // do computations
45aa62b9 1020 def->FillMother(&miniPair, miniEvent, &fValues);
03d23846 1021 }
1022 }
1023}
1024
1025//__________________________________________________________________________________________________
1026void AliRsnMiniAnalysisTask::FillTrueMotherAOD(AliRsnMiniEvent *miniEvent)
1027{
1028//
1029// Fills the histograms with true mother (AOD version)
1030//
1031
1032 Bool_t okMatch;
1033 TClonesArray *list = fRsnEvent.GetAODList();
1034 Int_t id, ndef = fHistograms.GetEntries();
1035 Int_t ip, label1, label2, npart = list->GetEntries();
1036 static AliRsnMiniPair miniPair;
1037 AliAODMCParticle *daughter1, *daughter2;
1038 TLorentzVector p1, p2;
1039 AliRsnMiniOutput *def = 0x0;
52e6652d 1040
03d23846 1041 for (id = 0; id < ndef; id++) {
52e6652d 1042 def = (AliRsnMiniOutput *)fHistograms[id];
03d23846 1043 if (!def) continue;
1044 if (!def->IsMother()) continue;
1045 for (ip = 0; ip < npart; ip++) {
52e6652d 1046 AliAODMCParticle *part = (AliAODMCParticle *)list->At(ip);
64129b35 1047 if (part->GetPdgCode() != def->GetMotherPDG()) continue;
03d23846 1048 // check that daughters match expected species
1049 if (part->GetNDaughters() < 2) continue;
088ca370 1050 if (fMaxNDaughters > 0 && part->GetNDaughters() > fMaxNDaughters) continue;
03d23846 1051 label1 = part->GetDaughter(0);
1052 label2 = part->GetDaughter(1);
52e6652d 1053 daughter1 = (AliAODMCParticle *)list->At(label1);
1054 daughter2 = (AliAODMCParticle *)list->At(label2);
03d23846 1055 okMatch = kFALSE;
1056 if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(1)) {
1057 okMatch = kTRUE;
1058 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
1059 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
1060 } else if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(0)) {
1061 okMatch = kTRUE;
1062 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
1063 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
1064 }
1065 if (!okMatch) continue;
088ca370 1066 if(fCheckP && (TMath::Abs(part->Px()-(daughter1->Px()+daughter2->Px()))/(TMath::Abs(part->Px())+1.e-13)) > 0.00001 &&
1067 (TMath::Abs(part->Py()-(daughter1->Py()+daughter2->Py()))/(TMath::Abs(part->Py())+1.e-13)) > 0.00001 &&
31dbef4e 1068 (TMath::Abs(part->Pz()-(daughter1->Pz()+daughter2->Pz()))/(TMath::Abs(part->Pz())+1.e-13)) > 0.00001 ) continue;
1069 if(fCheckFeedDown){
1070 Int_t pdgGranma = 0;
1071 Int_t mother = 0;
1072 mother = part->GetMother();
1073 Int_t istep = 0;
1074 Int_t abspdgGranma =0;
1075 Bool_t isFromB=kFALSE;
1076 Bool_t isQuarkFound=kFALSE;
1077 while (mother >=0 ){
1078 istep++;
1079 AliDebug(2,Form("mother at step %d = %d", istep, mother));
1080 AliAODMCParticle* mcGranma = dynamic_cast<AliAODMCParticle*>(list->At(mother));
1081 if (mcGranma){
1082 pdgGranma = mcGranma->GetPdgCode();
1083 AliDebug(2,Form("Pdg mother at step %d = %d", istep, pdgGranma));
1084 abspdgGranma = TMath::Abs(pdgGranma);
1085 if ((abspdgGranma > 500 && abspdgGranma < 600) || (abspdgGranma > 5000 && abspdgGranma < 6000)){
1086 isFromB=kTRUE;
1087 }
1088 if(abspdgGranma==4 || abspdgGranma==5) isQuarkFound=kTRUE;
1089 mother = mcGranma->GetMother();
1090 }else{
1091 AliError("Failed casting the mother particle!");
1092 break;
1093 }
1094 }
1095 if(fRejectIfNoQuark && !isQuarkFound) pdgGranma = -99999;
1096 if(isFromB){
1097 if (!fKeepDfromB) pdgGranma = -9999; //skip particle if come from a B meson.
1098 }
1099 else{
1100 if (fKeepDfromBOnly) pdgGranma = -999;
1101 }
1102
1103 if (pdgGranma == -99999){
1104 AliDebug(2,"This particle does not have a quark in his genealogy\n");
1105 continue;
1106 }
1107 if (pdgGranma == -9999){
1108 AliDebug(2,"This particle come from a B decay channel but according to the settings of the task, we keep only the prompt charm particles\n");
1109 continue;
1110 }
1111
1112 if (pdgGranma == -999){
1113 AliDebug(2,"This particle come from a prompt charm particles but according to the settings of the task, we want only the ones coming from B\n");
1114 continue;
1115 }
1116 }
088ca370 1117 // assign momenta to computation object
03d23846 1118 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
1119 miniPair.FillRef(def->GetMotherMass());
1120 // do computations
45aa62b9 1121 def->FillMother(&miniPair, miniEvent, &fValues);
03d23846 1122 }
1123 }
1124}
31dbef4e 1125//___________________________________________________________
1126void AliRsnMiniAnalysisTask::SetDselection(UShort_t originDselection)
1127{
1128 // setting the way the D0 will be selected
1129 // 0 --> only from c quarks
1130 // 1 --> only from b quarks
1131 // 2 --> from both c quarks and b quarks
1132
1133 fOriginDselection = originDselection;
1134
1135 if (fOriginDselection == 0) {
1136 fKeepDfromB = kFALSE;
1137 fKeepDfromBOnly = kFALSE;
1138 }
1139
1140 if (fOriginDselection == 1) {
1141 fKeepDfromB = kTRUE;
1142 fKeepDfromBOnly = kTRUE;
1143 }
1144
1145 if (fOriginDselection == 2) {
1146 fKeepDfromB = kTRUE;
1147 fKeepDfromBOnly = kFALSE;
1148 }
1149
1150 return;
1151}
caef2e3c 1152//__________________________________________________________________________________________________
1153Bool_t AliRsnMiniAnalysisTask::EventsMatch(AliRsnMiniEvent *event1, AliRsnMiniEvent *event2)
1154{
1155//
1156// Check if two events are compatible.
1157// If the mixing is continuous, this is true if differences in vz, mult and angle are smaller than
52e6652d 1158// the specified values.
caef2e3c 1159// If the mixing is binned, this is true if the events are in the same bin.
1160//
1161
1162 if (!event1 || !event2) return kFALSE;
1163 Int_t ivz1, ivz2, imult1, imult2, iangle1, iangle2;
9e7b94f5 1164 Double_t dv, dm, da;
52e6652d 1165
caef2e3c 1166 if (fContinuousMix) {
9e7b94f5 1167 dv = TMath::Abs(event1->Vz() - event2->Vz() );
1168 dm = TMath::Abs(event1->Mult() - event2->Mult() );
1169 da = TMath::Abs(event1->Angle() - event2->Angle());
1170 if (dv > fMaxDiffVz) {
1171 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Vz = %f", event1->ID(), event2->ID(), dv));
1172 return kFALSE;
1173 }
1174 if (dm > fMaxDiffMult ) {
1175 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Mult = %f", event1->ID(), event2->ID(), dm));
1176 return kFALSE;
1177 }
1178 if (da > fMaxDiffAngle) {
1179 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Angle = %f", event1->ID(), event2->ID(), da));
1180 return kFALSE;
1181 }
caef2e3c 1182 return kTRUE;
1183 } else {
1184 ivz1 = (Int_t)(event1->Vz() / fMaxDiffVz);
1185 ivz2 = (Int_t)(event2->Vz() / fMaxDiffVz);
1186 imult1 = (Int_t)(event1->Mult() / fMaxDiffMult);
1187 imult2 = (Int_t)(event2->Mult() / fMaxDiffMult);
1188 iangle1 = (Int_t)(event1->Angle() / fMaxDiffAngle);
1189 iangle2 = (Int_t)(event2->Angle() / fMaxDiffAngle);
1190 if (ivz1 != ivz2) return kFALSE;
1191 if (imult1 != imult2) return kFALSE;
1192 if (iangle1 != iangle2) return kFALSE;
1193 return kTRUE;
1194 }
1195}
1196
da997f6c 1197//---------------------------------------------------------------------
1198Double_t AliRsnMiniAnalysisTask::ApplyCentralityPatchPbPb2011(){
1199 //This part rejects randomly events such that the centrality gets flat for LHC11h Pb-Pb data
1200 //for 0-5% and 10-20% centrality bin
1201
1202 if (fCentralityType!="V0M") {
1203 AliWarning("Wrong value (not centrality from V0).");
1204 return -999.0;
1205 }
1206
1207 AliCentrality *centrality = fInputEvent->GetCentrality();
1208 if (!centrality) {
1209 AliWarning("Cannot get centrality from AOD event.");
1210 return -999.0;
1211 }
1212
1213
1214 Double_t cent = (Float_t)(centrality->GetCentralityPercentile("V0M"));
1215 Double_t rnd_hc, testf, ff, N1, N2;
1216
1217 if(fUseCentralityPatchPbPb2011==5){
1218 N1 = 1.9404e+06;
1219 N2 = 1.56435e+06;
1220 ff = 5.04167e+06 - 1.49885e+06*cent + 2.35998e+05*cent*cent -1.22873e+04*cent*cent*cent;
1221 }
1222
1223 if(fUseCentralityPatchPbPb2011==1020){
1224 N1 = 1.56435e+06;
1225 N2 = 4.20e+05;
1226 ff = 1.68062e+08 - 5.19673e+07*cent + 6.4068e+06*cent*cent + 6.4068e+06*cent*cent*cent - 392687*cent*cent*cent*cent - 145.07*cent*cent*cent*cent*cent;
1227 }
1228
1229 testf = ( N2 + (N1-ff) ) / N1;
1230 rnd_hc = gRandom->Rndm();
1231
1232 //AliDebugClass(1, Form("Flat Centrality %d", fUseCentralityPatchPbPb2011));
1233
1234 if (rnd_hc < 0 || rnd_hc > 1 )
1235 {
1236 AliWarning("Wrong Random number generated");
1237 return -999.0;
1238 }
1239
1240 if (rnd_hc < testf)
1241 return cent;
1242 else
1243 return -999.0;
1244}
1cdc3671 1245//---------------------------------------------------------------------
1246Double_t AliRsnMiniAnalysisTask::ApplyCentralityPatchAOD049()
1247{
3da8cef7 1248 //
1249 //Apply centrality patch for AOD049 outliers
1250 //
1251 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
1252 AliWarning("Requested patch for AOD049 for ESD. ");
1cdc3671 1253 return -999.0;
3da8cef7 1254 }
1255
1256 if (fCentralityType!="V0M") {
1257 AliWarning("Requested patch forAOD049 for wrong value (not centrality from V0).");
1cdc3671 1258 return -999.0;
3da8cef7 1259 }
1260
1261 AliCentrality *centrality = fInputEvent->GetCentrality();
1262 if (!centrality) {
1263 AliWarning("Cannot get centrality from AOD event.");
1264 return -999.0;
1265 }
1266
1267 Float_t cent = (Float_t)(centrality->GetCentralityPercentile("V0M"));
1268 /*
1269 Bool_t isSelRun = kFALSE;
1270 Int_t selRun[5] = {138364, 138826, 138828, 138836, 138871};
1271 if(cent<0){
1272 Int_t quality = centrality->GetQuality();
1273 if(quality<=1){
1274 cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
1275 } else {
1276 Int_t runnum=aodEvent->GetRunNumber();
1277 for(Int_t ir=0;ir<5;ir++){
1278 if(runnum==selRun[ir]){
1279 isSelRun=kTRUE;
1280 break;
1281 }
1282 }
1283 if((quality==8||quality==9)&&isSelRun) cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
1284 }
1285 }
1286 */
1287
1288 if(cent>=0.0) {
1289 Float_t v0 = 0.0;
1290 AliAODEvent *aodEvent = (AliAODEvent *)fInputEvent;
1291 AliAODVZERO *aodV0 = (AliAODVZERO *) aodEvent->GetVZEROData();
1292 v0+=aodV0->GetMTotV0A();
1293 v0+=aodV0->GetMTotV0C();
1294 if ( (cent==0) && (v0<19500) ) {
1295 AliDebug(3, Form("Filtering issue in centrality -> cent = %5.2f",cent));
1296 return -999.0;
1297 }
1298 Float_t tkl = (Float_t)(aodEvent->GetTracklets()->GetNumberOfTracklets());
1299 Float_t val = 1.30552 + 0.147931 * v0;
1300
1301 Float_t tklSigma[101] = {176.644, 156.401, 153.789, 153.015, 142.476, 137.951, 136.127, 129.852, 127.436, 124.86,
1302 120.788, 115.611, 113.172, 110.496, 109.127, 104.421, 102.479, 99.9766, 97.5152, 94.0654,
1303 92.4602, 89.3364, 87.1342, 83.3497, 82.6216, 81.1084, 78.0793, 76.1234, 72.9434, 72.1334,
1304 68.0056, 68.2755, 66.0376, 62.9666, 62.4274, 59.65, 58.3776, 56.6361, 54.5184, 53.4224,
1305 51.932, 50.8922, 48.2848, 47.912, 46.5717, 43.4114, 43.2083, 41.3065, 40.1863, 38.5255,
1306 37.2851, 37.5396, 34.4949, 33.8366, 31.8043, 31.7412, 30.8392, 30.0274, 28.8793, 27.6398,
1307 26.6488, 25.0183, 25.1489, 24.4185, 22.9107, 21.2002, 21.6977, 20.1242, 20.4963, 19.0235,
1308 19.298, 17.4103, 16.868, 15.2939, 15.2939, 16.0295, 14.186, 14.186, 15.2173, 12.9504, 12.9504,
1309 12.9504, 15.264, 12.3674, 12.3674, 12.3674, 12.3674, 12.3674, 18.3811, 13.7544, 13.7544,
1310 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544
1311 };
1312
1313 if ( TMath::Abs(tkl-val) > 6.*tklSigma[(Int_t)cent] ) {
1314 AliDebug(3, Form("Outlier event in centrality -> cent = %5.2f",cent));
1315 return -999.0;
1316 }
1317 } else {
1318 //force it to be -999. whatever the negative value was
1319 cent = -999.;
1320 }
1321 return cent;
1cdc3671 1322}
5654276f 1323
1324//----------------------------------------------------------------------------------
e6952ec7 1325void AliRsnMiniAnalysisTask::SetEventQAHist(TString type,TH2F *histo)
5654276f 1326{
e6952ec7 1327 if(!histo) {
1328 AliWarning(Form("event QA histogram pointer not defined for slot %s",type.Data()));
1329 return;
1330 }
1331
1332 type.ToLower();
1333
1334 if(!type.CompareTo("vz")) fHAEventVz = histo;
1335 else if(!type.CompareTo("multicent")) {
1336 TString mtype(histo->GetYaxis()->GetTitle());
1337 mtype.ToUpper();
1338 if(mtype.CompareTo("QUALITY") && mtype.CompareTo("TRACKS") && mtype.CompareTo("TRACKLETS")) {
1339 AliWarning(Form("multiplicity vs. centrality histogram y-axis %s unknown, setting to TRACKS",mtype.Data()));
1340 histo->GetYaxis()->SetTitle("TRACKS");
1341 }
1342 fHAEventMultiCent = histo;
1343 }
1344 else if(!type.CompareTo("eventplane")) fHAEventPlane = histo;
1345 else AliWarning(Form("event QA histogram slot %s undefined",type.Data()));
1346
1347 return;
5654276f 1348}
4fb0dfa3 1349
1350//----------------------------------------------------------------------------------
1351Int_t AliRsnMiniAnalysisTask::CreateValue(AliRsnMiniValue::EType type, Bool_t useMC)
1352{
1353//
1354// Create a new value in the task,
1355// and returns its ID, which is needed for setting up histograms.
1356// If that value was already initialized, returns its ID and does not recreate it.
1357//
1358
1359 Int_t valID = ValueID(type, useMC);
1360 if (valID >= 0 && valID < fValues.GetEntries()) {
1361 AliInfo(Form("Value '%s' is already created in slot #%d", AliRsnMiniValue::ValueName(type, useMC), valID));
1362 } else {
1363 valID = fValues.GetEntries();
1364 AliInfo(Form("Creating value '%s' in slot #%d", AliRsnMiniValue::ValueName(type, useMC), valID));
1365 new (fValues[valID]) AliRsnMiniValue(type, useMC);
1366 }
1367
1368 return valID;
1369}
1370
1371//----------------------------------------------------------------------------------
1372Int_t AliRsnMiniAnalysisTask::ValueID(AliRsnMiniValue::EType type, Bool_t useMC)
1373{
1374//
1375// Searches if a value computation is initialized
1376//
1377
1378 const char *name = AliRsnMiniValue::ValueName(type, useMC);
1379 TObject *obj = fValues.FindObject(name);
1380 if (obj)
1381 return fValues.IndexOf(obj);
1382 else
1383 return -1;
1384}
1385
1386//----------------------------------------------------------------------------------
1387AliRsnMiniOutput *AliRsnMiniAnalysisTask::CreateOutput(const char *name, AliRsnMiniOutput::EOutputType type, AliRsnMiniOutput::EComputation src)
1388{
1389//
1390// Create a new histogram definition in the task,
1391// which is then returned to the user for its configuration
1392//
1393
1394 Int_t n = fHistograms.GetEntries();
1395 AliRsnMiniOutput *newDef = new (fHistograms[n]) AliRsnMiniOutput(name, type, src);
1396
1397 return newDef;
1398}
1399
1400//----------------------------------------------------------------------------------
1401AliRsnMiniOutput *AliRsnMiniAnalysisTask::CreateOutput(const char *name, const char *outType, const char *compType)
1402{
1403//
1404// Create a new histogram definition in the task,
1405// which is then returned to the user for its configuration
1406//
1407
1408 Int_t n = fHistograms.GetEntries();
1409 AliRsnMiniOutput *newDef = new (fHistograms[n]) AliRsnMiniOutput(name, outType, compType);
1410
1411 return newDef;
1412}