]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/RESONANCES/AliRsnMiniAnalysisTask.cxx
Merge branch 'TPCdev' of https://git.cern.ch/reps/AliRoot into TPCdev
[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}
920
03d23846 921//__________________________________________________________________________________________________
922void AliRsnMiniAnalysisTask::FillTrueMotherESD(AliRsnMiniEvent *miniEvent)
923{
924//
925// Fills the histograms with true mother (ESD version)
926//
927
928 Bool_t okMatch;
929 Int_t id, ndef = fHistograms.GetEntries();
930 Int_t ip, label1, label2, npart = fMCEvent->GetNumberOfTracks();
931 static AliRsnMiniPair miniPair;
932 AliMCParticle *daughter1, *daughter2;
933 TLorentzVector p1, p2;
934 AliRsnMiniOutput *def = 0x0;
52e6652d 935
03d23846 936 for (id = 0; id < ndef; id++) {
52e6652d 937 def = (AliRsnMiniOutput *)fHistograms[id];
03d23846 938 if (!def) continue;
939 if (!def->IsMother()) continue;
940 for (ip = 0; ip < npart; ip++) {
52e6652d 941 AliMCParticle *part = (AliMCParticle *)fMCEvent->GetTrack(ip);
e6952ec7 942 //get mother pdg code
64129b35 943 if (part->Particle()->GetPdgCode() != def->GetMotherPDG()) continue;
03d23846 944 // check that daughters match expected species
088ca370 945 if (part->Particle()->GetNDaughters() < 2) continue;
946 if (fMaxNDaughters > 0 && part->Particle()->GetNDaughters() > fMaxNDaughters) continue;
03d23846 947 label1 = part->Particle()->GetDaughter(0);
948 label2 = part->Particle()->GetDaughter(1);
52e6652d 949 daughter1 = (AliMCParticle *)fMCEvent->GetTrack(label1);
950 daughter2 = (AliMCParticle *)fMCEvent->GetTrack(label2);
03d23846 951 okMatch = kFALSE;
952 if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(1)) {
953 okMatch = kTRUE;
954 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
955 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
956 } else if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(0)) {
957 okMatch = kTRUE;
958 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
959 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
960 }
961 if (!okMatch) continue;
088ca370 962 if(fCheckP && (TMath::Abs(part->Px()-(daughter1->Px()+daughter2->Px()))/(TMath::Abs(part->Px())+1.e-13)) > 0.00001 &&
963 (TMath::Abs(part->Py()-(daughter1->Py()+daughter2->Py()))/(TMath::Abs(part->Py())+1.e-13)) > 0.00001 &&
964 (TMath::Abs(part->Pz()-(daughter1->Pz()+daughter2->Pz()))/(TMath::Abs(part->Pz())+1.e-13)) > 0.00001 ) continue;
31dbef4e 965 if(fCheckFeedDown){
966 Int_t pdgGranma = 0;
967 Int_t mother = 0;
968 mother = part->GetMother();
969 Int_t istep = 0;
970 Int_t abspdgGranma =0;
971 Bool_t isFromB=kFALSE;
972 Bool_t isQuarkFound=kFALSE;
973 while (mother >=0 ){
974 istep++;
975 AliDebug(2,Form("mother at step %d = %d", istep, mother));
976 AliMCParticle* mcGranma = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(mother));
977 if (mcGranma){
978 pdgGranma = mcGranma->PdgCode();
979 AliDebug(2,Form("Pdg mother at step %d = %d", istep, pdgGranma));
980 abspdgGranma = TMath::Abs(pdgGranma);
981 if ((abspdgGranma > 500 && abspdgGranma < 600) || (abspdgGranma > 5000 && abspdgGranma < 6000)){
982 isFromB=kTRUE;
983 }
984 if(abspdgGranma==4 || abspdgGranma==5) isQuarkFound=kTRUE;
985 mother = mcGranma->GetMother();
986 }else{
987 AliError("Failed casting the mother particle!");
988 break;
989 }
990 }
991 if(fRejectIfNoQuark && !isQuarkFound) pdgGranma = -99999;
992 if(isFromB){
993 if (!fKeepDfromB) pdgGranma = -9999; //skip particle if come from a B meson.
994 }
995 else{
996 if (fKeepDfromBOnly) pdgGranma = -999;
997
998 if (pdgGranma == -99999){
999 AliDebug(2,"This particle does not have a quark in his genealogy\n");
1000 continue;
1001 }
1002 if (pdgGranma == -9999){
1003 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");
1004 continue;
1005 }
1006
1007 if (pdgGranma == -999){
1008 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");
1009 continue;
1010 }
1011
1012 }
1013 }
03d23846 1014 // assign momenta to computation object
1015 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
1016 miniPair.FillRef(def->GetMotherMass());
1017 // do computations
45aa62b9 1018 def->FillMother(&miniPair, miniEvent, &fValues);
03d23846 1019 }
1020 }
1021}
1022
1023//__________________________________________________________________________________________________
1024void AliRsnMiniAnalysisTask::FillTrueMotherAOD(AliRsnMiniEvent *miniEvent)
1025{
1026//
1027// Fills the histograms with true mother (AOD version)
1028//
1029
1030 Bool_t okMatch;
1031 TClonesArray *list = fRsnEvent.GetAODList();
1032 Int_t id, ndef = fHistograms.GetEntries();
1033 Int_t ip, label1, label2, npart = list->GetEntries();
1034 static AliRsnMiniPair miniPair;
1035 AliAODMCParticle *daughter1, *daughter2;
1036 TLorentzVector p1, p2;
1037 AliRsnMiniOutput *def = 0x0;
52e6652d 1038
03d23846 1039 for (id = 0; id < ndef; id++) {
52e6652d 1040 def = (AliRsnMiniOutput *)fHistograms[id];
03d23846 1041 if (!def) continue;
1042 if (!def->IsMother()) continue;
1043 for (ip = 0; ip < npart; ip++) {
52e6652d 1044 AliAODMCParticle *part = (AliAODMCParticle *)list->At(ip);
64129b35 1045 if (part->GetPdgCode() != def->GetMotherPDG()) continue;
03d23846 1046 // check that daughters match expected species
1047 if (part->GetNDaughters() < 2) continue;
088ca370 1048 if (fMaxNDaughters > 0 && part->GetNDaughters() > fMaxNDaughters) continue;
03d23846 1049 label1 = part->GetDaughter(0);
1050 label2 = part->GetDaughter(1);
52e6652d 1051 daughter1 = (AliAODMCParticle *)list->At(label1);
1052 daughter2 = (AliAODMCParticle *)list->At(label2);
03d23846 1053 okMatch = kFALSE;
1054 if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(1)) {
1055 okMatch = kTRUE;
1056 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
1057 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
1058 } else if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(0)) {
1059 okMatch = kTRUE;
1060 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
1061 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
1062 }
1063 if (!okMatch) continue;
088ca370 1064 if(fCheckP && (TMath::Abs(part->Px()-(daughter1->Px()+daughter2->Px()))/(TMath::Abs(part->Px())+1.e-13)) > 0.00001 &&
1065 (TMath::Abs(part->Py()-(daughter1->Py()+daughter2->Py()))/(TMath::Abs(part->Py())+1.e-13)) > 0.00001 &&
31dbef4e 1066 (TMath::Abs(part->Pz()-(daughter1->Pz()+daughter2->Pz()))/(TMath::Abs(part->Pz())+1.e-13)) > 0.00001 ) continue;
1067 if(fCheckFeedDown){
1068 Int_t pdgGranma = 0;
1069 Int_t mother = 0;
1070 mother = part->GetMother();
1071 Int_t istep = 0;
1072 Int_t abspdgGranma =0;
1073 Bool_t isFromB=kFALSE;
1074 Bool_t isQuarkFound=kFALSE;
1075 while (mother >=0 ){
1076 istep++;
1077 AliDebug(2,Form("mother at step %d = %d", istep, mother));
1078 AliAODMCParticle* mcGranma = dynamic_cast<AliAODMCParticle*>(list->At(mother));
1079 if (mcGranma){
1080 pdgGranma = mcGranma->GetPdgCode();
1081 AliDebug(2,Form("Pdg mother at step %d = %d", istep, pdgGranma));
1082 abspdgGranma = TMath::Abs(pdgGranma);
1083 if ((abspdgGranma > 500 && abspdgGranma < 600) || (abspdgGranma > 5000 && abspdgGranma < 6000)){
1084 isFromB=kTRUE;
1085 }
1086 if(abspdgGranma==4 || abspdgGranma==5) isQuarkFound=kTRUE;
1087 mother = mcGranma->GetMother();
1088 }else{
1089 AliError("Failed casting the mother particle!");
1090 break;
1091 }
1092 }
1093 if(fRejectIfNoQuark && !isQuarkFound) pdgGranma = -99999;
1094 if(isFromB){
1095 if (!fKeepDfromB) pdgGranma = -9999; //skip particle if come from a B meson.
1096 }
1097 else{
1098 if (fKeepDfromBOnly) pdgGranma = -999;
1099 }
1100
1101 if (pdgGranma == -99999){
1102 AliDebug(2,"This particle does not have a quark in his genealogy\n");
1103 continue;
1104 }
1105 if (pdgGranma == -9999){
1106 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");
1107 continue;
1108 }
1109
1110 if (pdgGranma == -999){
1111 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");
1112 continue;
1113 }
1114 }
088ca370 1115 // assign momenta to computation object
03d23846 1116 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
1117 miniPair.FillRef(def->GetMotherMass());
1118 // do computations
45aa62b9 1119 def->FillMother(&miniPair, miniEvent, &fValues);
03d23846 1120 }
1121 }
1122}
31dbef4e 1123//___________________________________________________________
1124void AliRsnMiniAnalysisTask::SetDselection(UShort_t originDselection)
1125{
1126 // setting the way the D0 will be selected
1127 // 0 --> only from c quarks
1128 // 1 --> only from b quarks
1129 // 2 --> from both c quarks and b quarks
1130
1131 fOriginDselection = originDselection;
1132
1133 if (fOriginDselection == 0) {
1134 fKeepDfromB = kFALSE;
1135 fKeepDfromBOnly = kFALSE;
1136 }
1137
1138 if (fOriginDselection == 1) {
1139 fKeepDfromB = kTRUE;
1140 fKeepDfromBOnly = kTRUE;
1141 }
1142
1143 if (fOriginDselection == 2) {
1144 fKeepDfromB = kTRUE;
1145 fKeepDfromBOnly = kFALSE;
1146 }
1147
1148 return;
1149}
caef2e3c 1150//__________________________________________________________________________________________________
1151Bool_t AliRsnMiniAnalysisTask::EventsMatch(AliRsnMiniEvent *event1, AliRsnMiniEvent *event2)
1152{
1153//
1154// Check if two events are compatible.
1155// If the mixing is continuous, this is true if differences in vz, mult and angle are smaller than
52e6652d 1156// the specified values.
caef2e3c 1157// If the mixing is binned, this is true if the events are in the same bin.
1158//
1159
1160 if (!event1 || !event2) return kFALSE;
1161 Int_t ivz1, ivz2, imult1, imult2, iangle1, iangle2;
9e7b94f5 1162 Double_t dv, dm, da;
52e6652d 1163
caef2e3c 1164 if (fContinuousMix) {
9e7b94f5 1165 dv = TMath::Abs(event1->Vz() - event2->Vz() );
1166 dm = TMath::Abs(event1->Mult() - event2->Mult() );
1167 da = TMath::Abs(event1->Angle() - event2->Angle());
1168 if (dv > fMaxDiffVz) {
1169 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Vz = %f", event1->ID(), event2->ID(), dv));
1170 return kFALSE;
1171 }
1172 if (dm > fMaxDiffMult ) {
1173 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Mult = %f", event1->ID(), event2->ID(), dm));
1174 return kFALSE;
1175 }
1176 if (da > fMaxDiffAngle) {
1177 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Angle = %f", event1->ID(), event2->ID(), da));
1178 return kFALSE;
1179 }
caef2e3c 1180 return kTRUE;
1181 } else {
1182 ivz1 = (Int_t)(event1->Vz() / fMaxDiffVz);
1183 ivz2 = (Int_t)(event2->Vz() / fMaxDiffVz);
1184 imult1 = (Int_t)(event1->Mult() / fMaxDiffMult);
1185 imult2 = (Int_t)(event2->Mult() / fMaxDiffMult);
1186 iangle1 = (Int_t)(event1->Angle() / fMaxDiffAngle);
1187 iangle2 = (Int_t)(event2->Angle() / fMaxDiffAngle);
1188 if (ivz1 != ivz2) return kFALSE;
1189 if (imult1 != imult2) return kFALSE;
1190 if (iangle1 != iangle2) return kFALSE;
1191 return kTRUE;
1192 }
1193}
1194
da997f6c 1195//---------------------------------------------------------------------
1196Double_t AliRsnMiniAnalysisTask::ApplyCentralityPatchPbPb2011(){
1197 //This part rejects randomly events such that the centrality gets flat for LHC11h Pb-Pb data
1198 //for 0-5% and 10-20% centrality bin
1199
1200 if (fCentralityType!="V0M") {
1201 AliWarning("Wrong value (not centrality from V0).");
1202 return -999.0;
1203 }
1204
1205 AliCentrality *centrality = fInputEvent->GetCentrality();
1206 if (!centrality) {
1207 AliWarning("Cannot get centrality from AOD event.");
1208 return -999.0;
1209 }
1210
da997f6c 1211 Double_t cent = (Float_t)(centrality->GetCentralityPercentile("V0M"));
2a07566f 1212 Double_t rnd_hc = -1., testf = 0.0, ff = 0, N1 = -1., N2 = -1.;
da997f6c 1213
3b11fb42 1214 if(fUseCentralityPatchPbPb2011==510){
da997f6c 1215 N1 = 1.9404e+06;
3b11fb42 1216 N2 = 1.56435e+06; //N2 is the reference
da997f6c 1217 ff = 5.04167e+06 - 1.49885e+06*cent + 2.35998e+05*cent*cent -1.22873e+04*cent*cent*cent;
2a07566f 1218 } else {
1219 if(fUseCentralityPatchPbPb2011==1020){
1220 N2 = 2.0e+05; //N2 is the reference
1221 N1 = 3.7e+05;
1222 ff = -1.73979e+06 - 3.05316e+06*cent + 1.05517e+06*cent*cent - 133205*cent*cent*cent + 8187.45*cent*cent*cent*cent - 247.875*cent*cent*cent*cent*cent + 2.9676*cent*cent*cent*cent*cent*cent;
1223 } else {
1224 AliError(Form("Patch for the requested centrality (%i) is not available", fUseCentralityPatchPbPb2011));
1225 return -999.0;
1226 }
da997f6c 1227 }
da997f6c 1228 testf = ( N2 + (N1-ff) ) / N1;
1229 rnd_hc = gRandom->Rndm();
1230
1231 //AliDebugClass(1, Form("Flat Centrality %d", fUseCentralityPatchPbPb2011));
1232
1233 if (rnd_hc < 0 || rnd_hc > 1 )
1234 {
1235 AliWarning("Wrong Random number generated");
1236 return -999.0;
1237 }
1238
1239 if (rnd_hc < testf)
1240 return cent;
1241 else
1242 return -999.0;
1243}
1cdc3671 1244//---------------------------------------------------------------------
1245Double_t AliRsnMiniAnalysisTask::ApplyCentralityPatchAOD049()
1246{
3da8cef7 1247 //
1248 //Apply centrality patch for AOD049 outliers
1249 //
1250 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
1251 AliWarning("Requested patch for AOD049 for ESD. ");
1cdc3671 1252 return -999.0;
3da8cef7 1253 }
1254
1255 if (fCentralityType!="V0M") {
1256 AliWarning("Requested patch forAOD049 for wrong value (not centrality from V0).");
1cdc3671 1257 return -999.0;
3da8cef7 1258 }
1259
1260 AliCentrality *centrality = fInputEvent->GetCentrality();
1261 if (!centrality) {
1262 AliWarning("Cannot get centrality from AOD event.");
1263 return -999.0;
1264 }
1265
1266 Float_t cent = (Float_t)(centrality->GetCentralityPercentile("V0M"));
1267 /*
1268 Bool_t isSelRun = kFALSE;
1269 Int_t selRun[5] = {138364, 138826, 138828, 138836, 138871};
1270 if(cent<0){
1271 Int_t quality = centrality->GetQuality();
1272 if(quality<=1){
1273 cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
1274 } else {
1275 Int_t runnum=aodEvent->GetRunNumber();
1276 for(Int_t ir=0;ir<5;ir++){
1277 if(runnum==selRun[ir]){
1278 isSelRun=kTRUE;
1279 break;
1280 }
1281 }
1282 if((quality==8||quality==9)&&isSelRun) cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
1283 }
1284 }
1285 */
1286
1287 if(cent>=0.0) {
1288 Float_t v0 = 0.0;
1289 AliAODEvent *aodEvent = (AliAODEvent *)fInputEvent;
1290 AliAODVZERO *aodV0 = (AliAODVZERO *) aodEvent->GetVZEROData();
1291 v0+=aodV0->GetMTotV0A();
1292 v0+=aodV0->GetMTotV0C();
1293 if ( (cent==0) && (v0<19500) ) {
1294 AliDebug(3, Form("Filtering issue in centrality -> cent = %5.2f",cent));
1295 return -999.0;
1296 }
1297 Float_t tkl = (Float_t)(aodEvent->GetTracklets()->GetNumberOfTracklets());
1298 Float_t val = 1.30552 + 0.147931 * v0;
1299
1300 Float_t tklSigma[101] = {176.644, 156.401, 153.789, 153.015, 142.476, 137.951, 136.127, 129.852, 127.436, 124.86,
1301 120.788, 115.611, 113.172, 110.496, 109.127, 104.421, 102.479, 99.9766, 97.5152, 94.0654,
1302 92.4602, 89.3364, 87.1342, 83.3497, 82.6216, 81.1084, 78.0793, 76.1234, 72.9434, 72.1334,
1303 68.0056, 68.2755, 66.0376, 62.9666, 62.4274, 59.65, 58.3776, 56.6361, 54.5184, 53.4224,
1304 51.932, 50.8922, 48.2848, 47.912, 46.5717, 43.4114, 43.2083, 41.3065, 40.1863, 38.5255,
1305 37.2851, 37.5396, 34.4949, 33.8366, 31.8043, 31.7412, 30.8392, 30.0274, 28.8793, 27.6398,
1306 26.6488, 25.0183, 25.1489, 24.4185, 22.9107, 21.2002, 21.6977, 20.1242, 20.4963, 19.0235,
1307 19.298, 17.4103, 16.868, 15.2939, 15.2939, 16.0295, 14.186, 14.186, 15.2173, 12.9504, 12.9504,
1308 12.9504, 15.264, 12.3674, 12.3674, 12.3674, 12.3674, 12.3674, 18.3811, 13.7544, 13.7544,
1309 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544
1310 };
1311
1312 if ( TMath::Abs(tkl-val) > 6.*tklSigma[(Int_t)cent] ) {
1313 AliDebug(3, Form("Outlier event in centrality -> cent = %5.2f",cent));
1314 return -999.0;
1315 }
1316 } else {
1317 //force it to be -999. whatever the negative value was
1318 cent = -999.;
1319 }
1320 return cent;
1cdc3671 1321}
5654276f 1322
1323//----------------------------------------------------------------------------------
e6952ec7 1324void AliRsnMiniAnalysisTask::SetEventQAHist(TString type,TH2F *histo)
5654276f 1325{
e6952ec7 1326 if(!histo) {
1327 AliWarning(Form("event QA histogram pointer not defined for slot %s",type.Data()));
1328 return;
1329 }
1330
1331 type.ToLower();
1332
1333 if(!type.CompareTo("vz")) fHAEventVz = histo;
1334 else if(!type.CompareTo("multicent")) {
1335 TString mtype(histo->GetYaxis()->GetTitle());
1336 mtype.ToUpper();
1337 if(mtype.CompareTo("QUALITY") && mtype.CompareTo("TRACKS") && mtype.CompareTo("TRACKLETS")) {
1338 AliWarning(Form("multiplicity vs. centrality histogram y-axis %s unknown, setting to TRACKS",mtype.Data()));
1339 histo->GetYaxis()->SetTitle("TRACKS");
1340 }
1341 fHAEventMultiCent = histo;
1342 }
1343 else if(!type.CompareTo("eventplane")) fHAEventPlane = histo;
1344 else AliWarning(Form("event QA histogram slot %s undefined",type.Data()));
1345
1346 return;
5654276f 1347}
4fb0dfa3 1348
1349//----------------------------------------------------------------------------------
1350Int_t AliRsnMiniAnalysisTask::CreateValue(AliRsnMiniValue::EType type, Bool_t useMC)
1351{
1352//
1353// Create a new value in the task,
1354// and returns its ID, which is needed for setting up histograms.
1355// If that value was already initialized, returns its ID and does not recreate it.
1356//
1357
1358 Int_t valID = ValueID(type, useMC);
1359 if (valID >= 0 && valID < fValues.GetEntries()) {
1360 AliInfo(Form("Value '%s' is already created in slot #%d", AliRsnMiniValue::ValueName(type, useMC), valID));
1361 } else {
1362 valID = fValues.GetEntries();
1363 AliInfo(Form("Creating value '%s' in slot #%d", AliRsnMiniValue::ValueName(type, useMC), valID));
1364 new (fValues[valID]) AliRsnMiniValue(type, useMC);
1365 }
1366
1367 return valID;
1368}
1369
1370//----------------------------------------------------------------------------------
1371Int_t AliRsnMiniAnalysisTask::ValueID(AliRsnMiniValue::EType type, Bool_t useMC)
1372{
1373//
1374// Searches if a value computation is initialized
1375//
1376
1377 const char *name = AliRsnMiniValue::ValueName(type, useMC);
1378 TObject *obj = fValues.FindObject(name);
1379 if (obj)
1380 return fValues.IndexOf(obj);
1381 else
1382 return -1;
1383}
1384
1385//----------------------------------------------------------------------------------
1386AliRsnMiniOutput *AliRsnMiniAnalysisTask::CreateOutput(const char *name, AliRsnMiniOutput::EOutputType type, AliRsnMiniOutput::EComputation src)
1387{
1388//
1389// Create a new histogram definition in the task,
1390// which is then returned to the user for its configuration
1391//
1392
1393 Int_t n = fHistograms.GetEntries();
1394 AliRsnMiniOutput *newDef = new (fHistograms[n]) AliRsnMiniOutput(name, type, src);
1395
1396 return newDef;
1397}
1398
1399//----------------------------------------------------------------------------------
1400AliRsnMiniOutput *AliRsnMiniAnalysisTask::CreateOutput(const char *name, const char *outType, const char *compType)
1401{
1402//
1403// Create a new histogram definition in the task,
1404// which is then returned to the user for its configuration
1405//
1406
1407 Int_t n = fHistograms.GetEntries();
1408 AliRsnMiniOutput *newDef = new (fHistograms[n]) AliRsnMiniOutput(name, outType, compType);
1409
1410 return newDef;
1411}