]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/RESONANCES/AliRsnMiniAnalysisTask.cxx
edit to output container arg list from Claude
[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>
03d23846 19
20#include "AliLog.h"
6aaeb33c 21#include "AliEventplane.h"
22#include "AliMultiplicity.h"
23#include "AliTriggerAnalysis.h"
03d23846 24#include "AliAnalysisManager.h"
6aaeb33c 25#include "AliInputEventHandler.h"
26
03d23846 27#include "AliESDtrackCuts.h"
28#include "AliESDUtils.h"
6aaeb33c 29
03d23846 30#include "AliAODEvent.h"
03d23846 31#include "AliAODMCParticle.h"
32
33#include "AliRsnCutSet.h"
6aaeb33c 34#include "AliRsnMiniPair.h"
03d23846 35#include "AliRsnMiniEvent.h"
36#include "AliRsnMiniParticle.h"
03d23846 37
38#include "AliRsnMiniAnalysisTask.h"
39
52e6652d 40
03d23846 41ClassImp(AliRsnMiniAnalysisTask)
42
43//__________________________________________________________________________________________________
44AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask() :
45 AliAnalysisTaskSE(),
c80938f5 46 fUseMC(kFALSE),
03d23846 47 fEvNum(0),
48 fUseCentrality(kFALSE),
49 fCentralityType("QUALITY"),
1cdc3671 50 fUseAOD049CentralityPatch(kFALSE),
caef2e3c 51 fContinuousMix(kTRUE),
03d23846 52 fNMix(0),
53 fMaxDiffMult(10),
54 fMaxDiffVz(1.0),
55 fMaxDiffAngle(1E20),
56 fOutput(0x0),
57 fHistograms("AliRsnMiniOutput", 0),
58 fValues("AliRsnMiniValue", 0),
59 fHEventStat(0x0),
60 fEventCuts(0x0),
61 fTrackCuts(0),
62 fRsnEvent(),
c80938f5 63 fEvBuffer(0x0),
c80938f5 64 fTriggerAna(0x0),
6aaeb33c 65 fESDtrackCuts(0x0),
caef2e3c 66 fMiniEvent(0x0),
61f275d1 67 fBigOutput(kFALSE),
68 fMixPrintRefresh(-1)
03d23846 69{
70//
71// Dummy constructor ALWAYS needed for I/O.
72//
73}
74
75//__________________________________________________________________________________________________
c80938f5 76AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const char *name, Bool_t useMC) :
03d23846 77 AliAnalysisTaskSE(name),
c80938f5 78 fUseMC(useMC),
03d23846 79 fEvNum(0),
80 fUseCentrality(kFALSE),
81 fCentralityType("QUALITY"),
1cdc3671 82 fUseAOD049CentralityPatch(kFALSE),
caef2e3c 83 fContinuousMix(kTRUE),
03d23846 84 fNMix(0),
85 fMaxDiffMult(10),
86 fMaxDiffVz(1.0),
87 fMaxDiffAngle(1E20),
88 fOutput(0x0),
89 fHistograms("AliRsnMiniOutput", 0),
90 fValues("AliRsnMiniValue", 0),
91 fHEventStat(0x0),
92 fEventCuts(0x0),
93 fTrackCuts(0),
94 fRsnEvent(),
c80938f5 95 fEvBuffer(0x0),
c80938f5 96 fTriggerAna(0x0),
6aaeb33c 97 fESDtrackCuts(0x0),
caef2e3c 98 fMiniEvent(0x0),
61f275d1 99 fBigOutput(kFALSE),
100 fMixPrintRefresh(-1)
03d23846 101{
102//
103// Default constructor.
104// Define input and output slots here (never in the dummy constructor)
105// Input slot #0 works with a TChain - it is connected to the default input container
106// Output slot #1 writes into a TH1 container
107//
108
109 DefineOutput(1, TList::Class());
110}
111
112//__________________________________________________________________________________________________
52e6652d 113AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const AliRsnMiniAnalysisTask &copy) :
03d23846 114 AliAnalysisTaskSE(copy),
c80938f5 115 fUseMC(copy.fUseMC),
03d23846 116 fEvNum(0),
117 fUseCentrality(copy.fUseCentrality),
118 fCentralityType(copy.fCentralityType),
1cdc3671 119 fUseAOD049CentralityPatch(copy.fUseAOD049CentralityPatch),
caef2e3c 120 fContinuousMix(copy.fContinuousMix),
03d23846 121 fNMix(copy.fNMix),
122 fMaxDiffMult(copy.fMaxDiffMult),
123 fMaxDiffVz(copy.fMaxDiffVz),
124 fMaxDiffAngle(copy.fMaxDiffAngle),
125 fOutput(0x0),
126 fHistograms(copy.fHistograms),
127 fValues(copy.fValues),
128 fHEventStat(0x0),
129 fEventCuts(copy.fEventCuts),
130 fTrackCuts(copy.fTrackCuts),
131 fRsnEvent(),
c80938f5 132 fEvBuffer(0x0),
c80938f5 133 fTriggerAna(copy.fTriggerAna),
6aaeb33c 134 fESDtrackCuts(copy.fESDtrackCuts),
caef2e3c 135 fMiniEvent(0x0),
61f275d1 136 fBigOutput(copy.fBigOutput),
137 fMixPrintRefresh(copy.fMixPrintRefresh)
03d23846 138{
139//
140// Copy constructor.
141// Implemented as requested by C++ standards.
142// Can be used in PROOF and by plugins.
143//
144}
145
146//__________________________________________________________________________________________________
52e6652d 147AliRsnMiniAnalysisTask &AliRsnMiniAnalysisTask::operator=(const AliRsnMiniAnalysisTask &copy)
03d23846 148{
149//
150// Assignment operator.
151// Implemented as requested by C++ standards.
152// Can be used in PROOF and by plugins.
153//
154
155 AliAnalysisTaskSE::operator=(copy);
e6f3a909 156 if (this == &copy)
61f275d1 157 return *this;
c80938f5 158 fUseMC = copy.fUseMC;
03d23846 159 fUseCentrality = copy.fUseCentrality;
160 fCentralityType = copy.fCentralityType;
1cdc3671 161 fUseAOD049CentralityPatch = copy.fUseAOD049CentralityPatch;
caef2e3c 162 fContinuousMix = copy.fContinuousMix;
03d23846 163 fNMix = copy.fNMix;
164 fMaxDiffMult = copy.fMaxDiffMult;
165 fMaxDiffVz = copy.fMaxDiffVz;
166 fMaxDiffAngle = copy.fMaxDiffAngle;
167 fHistograms = copy.fHistograms;
168 fValues = copy.fValues;
169 fEventCuts = copy.fEventCuts;
170 fTrackCuts = copy.fTrackCuts;
171 fTriggerAna = copy.fTriggerAna;
c80938f5 172 fESDtrackCuts = copy.fESDtrackCuts;
caef2e3c 173 fBigOutput = copy.fBigOutput;
61f275d1 174 fMixPrintRefresh = copy.fMixPrintRefresh;
03d23846 175 return (*this);
176}
177
178//__________________________________________________________________________________________________
179AliRsnMiniAnalysisTask::~AliRsnMiniAnalysisTask()
180{
181//
52e6652d 182// Destructor.
03d23846 183// Clean-up the output list, but not the histograms that are put inside
184// (the list is owner and will clean-up these histograms). Protect in PROOF case.
185//
186
d573d2fb 187
03d23846 188 if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
189 delete fOutput;
d573d2fb 190 delete fEvBuffer;
03d23846 191 }
192}
193
194//__________________________________________________________________________________________________
195Int_t AliRsnMiniAnalysisTask::AddTrackCuts(AliRsnCutSet *cuts)
196{
197//
198// Add a new cut set for a new criterion for track selection.
199// A user can add as many as he wants, and each one corresponds
200// to one of the available bits in the AliRsnMiniParticle mask.
201// The only check is the following: if a cut set with the same name
202// as the argument is there, this is not added.
203// Return value is the array position of this set.
204//
205
206 TObject *obj = fTrackCuts.FindObject(cuts->GetName());
52e6652d 207
03d23846 208 if (obj) {
209 AliInfo(Form("A cut set named '%s' already exists", cuts->GetName()));
210 return fTrackCuts.IndexOf(obj);
211 } else {
212 fTrackCuts.AddLast(cuts);
213 return fTrackCuts.IndexOf(cuts);
214 }
215}
216
217//__________________________________________________________________________________________________
218void AliRsnMiniAnalysisTask::UserCreateOutputObjects()
219{
220//
221// Initialization of outputs.
222// This is called once per worker node.
223//
224
225 // reset counter
9e7b94f5 226 fEvNum = -1;
52e6652d 227
d573d2fb 228 // message
229 AliInfo(Form("Selected event characterization: %s (%s)", (fUseCentrality ? "centrality" : "multiplicity"), fCentralityType.Data()));
03d23846 230
231 // initialize trigger analysis
c80938f5 232 if (fTriggerAna) delete fTriggerAna;
03d23846 233 fTriggerAna = new AliTriggerAnalysis;
52e6652d 234
c80938f5 235 // initialize ESD quality cuts
236 if (fESDtrackCuts) delete fESDtrackCuts;
237 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010();
03d23846 238
239 // create list and set it as owner of its content (MANDATORY)
caef2e3c 240 if (fBigOutput) OpenFile(1);
03d23846 241 fOutput = new TList();
242 fOutput->SetOwner();
52e6652d 243
03d23846 244 // initialize event statistics counter
245 fHEventStat = new TH1F("hEventStat", "Event statistics", 4, 0.0, 4.0);
246 fHEventStat->GetXaxis()->SetBinLabel(1, "CINT1B");
247 fHEventStat->GetXaxis()->SetBinLabel(2, "V0AND");
248 fHEventStat->GetXaxis()->SetBinLabel(3, "Candle");
249 fHEventStat->GetXaxis()->SetBinLabel(4, "Accepted");
250 fOutput->Add(fHEventStat);
52e6652d 251
61f275d1 252 TIter next(&fTrackCuts);
253 AliRsnCutSet *cs;
254 while ((cs = (AliRsnCutSet *) next())) {
255 cs->Init(fOutput);
256 }
257
03d23846 258 // create temporary tree for filtered events
6aaeb33c 259 if (fMiniEvent) delete fMiniEvent;
c80938f5 260 fEvBuffer = new TTree("EventBuffer", "Temporary buffer for mini events");
6aaeb33c 261 fEvBuffer->Branch("events", "AliRsnMiniEvent", &fMiniEvent);
52e6652d 262
03d23846 263 // create one histogram per each stored definition (event histograms)
264 Int_t i, ndef = fHistograms.GetEntries();
265 AliRsnMiniOutput *def = 0x0;
266 for (i = 0; i < ndef; i++) {
52e6652d 267 def = (AliRsnMiniOutput *)fHistograms[i];
03d23846 268 if (!def) continue;
269 if (!def->Init(GetName(), fOutput)) {
270 AliError(Form("Def '%s': failed initialization", def->GetName()));
271 continue;
272 }
273 }
52e6652d 274
03d23846 275 // post data for ALL output slots >0 here, to get at least an empty histogram
276 PostData(1, fOutput);
277}
278
279//__________________________________________________________________________________________________
280void AliRsnMiniAnalysisTask::UserExec(Option_t *)
281{
282//
6aaeb33c 283// Computation loop.
284// In this case, it checks if the event is acceptable, and eventually
285// creates the corresponding mini-event and stores it in the buffer.
286// The real histogram filling is done at the end, in "FinishTaskOutput".
03d23846 287//
288
9e7b94f5 289 // increment event counter
03d23846 290 fEvNum++;
9e7b94f5 291
03d23846 292 // check current event
293 Char_t check = CheckCurrentEvent();
294 if (!check) return;
52e6652d 295
d573d2fb 296 // setup PID response
52e6652d 297 AliAnalysisManager *man = AliAnalysisManager::GetAnalysisManager();
298 AliInputEventHandler *inputHandler = (AliInputEventHandler *)man->GetInputEventHandler();
299 fRsnEvent.SetPIDResponse(inputHandler->GetPIDResponse());
300
6aaeb33c 301 // fill a mini-event from current
302 // and skip this event if no tracks were accepted
45aa62b9 303 FillMiniEvent(check);
52e6652d 304
6aaeb33c 305 // fill MC based histograms on mothers,
306 // which do need the original event
c80938f5 307 if (fUseMC) {
308 if (fRsnEvent.IsESD() && fMCEvent)
6aaeb33c 309 FillTrueMotherESD(fMiniEvent);
c80938f5 310 else if (fRsnEvent.IsAOD() && fRsnEvent.GetAODList())
6aaeb33c 311 FillTrueMotherAOD(fMiniEvent);
03d23846 312 }
52e6652d 313
9e7b94f5 314 // if the event is not empty, store it
315 if (fMiniEvent->IsEmpty()) {
316 AliDebugClass(2, Form("Rejecting empty event #%d", fEvNum));
317 } else {
318 Int_t id = fEvBuffer->GetEntries();
319 AliDebugClass(2, Form("Adding event #%d with ID = %d", fEvNum, id));
320 fMiniEvent->ID() = id;
321 fEvBuffer->Fill();
322 }
52e6652d 323
6aaeb33c 324 // post data for computed stuff
03d23846 325 PostData(1, fOutput);
326}
327
328//__________________________________________________________________________________________________
329void AliRsnMiniAnalysisTask::FinishTaskOutput()
330{
331//
6aaeb33c 332// This function is called at the end of the loop on available events,
333// and then the buffer will be full with all the corresponding mini-events,
334// each one containing all tracks selected by each of the available track cuts.
335// Here a loop is done on each of these events, and both single-event and mixing are computed
03d23846 336//
337
6aaeb33c 338 // security code: reassign the buffer to the mini-event cursor
339 fEvBuffer->SetBranchAddress("events", &fMiniEvent);
52e6652d 340 TStopwatch timer;
0efb7042 341 // prepare variables
6aaeb33c 342 Int_t ievt, nEvents = (Int_t)fEvBuffer->GetEntries();
343 Int_t idef, nDefs = fHistograms.GetEntries();
45aa62b9 344 Int_t imix, iloop, ifill;
6aaeb33c 345 AliRsnMiniOutput *def = 0x0;
346 AliRsnMiniOutput::EComputation compType;
52e6652d 347
61f275d1 348 Int_t printNum = fMixPrintRefresh;
349 if (printNum < 0) {
350 if (nEvents>1e5) printNum=nEvents/100;
351 else if (nEvents>1e4) printNum=nEvents/10;
352 else printNum = 0;
353 }
354
6aaeb33c 355 // loop on events, and for each one fill all outputs
356 // using the appropriate procedure depending on its type
357 // only mother-related histograms are filled in UserExec,
358 // since they require direct access to MC event
52e6652d 359 timer.Start();
6aaeb33c 360 for (ievt = 0; ievt < nEvents; ievt++) {
361 // get next entry
362 fEvBuffer->GetEntry(ievt);
52e6652d 363 if (printNum&&(ievt%printNum==0)) {
364 AliInfo(Form("[%s] Std.Event %d/%d",GetName(), ievt,nEvents));
61f275d1 365 timer.Stop(); timer.Print(); fflush(stdout); timer.Start(kFALSE);
52e6652d 366 }
45aa62b9 367 // fill
6aaeb33c 368 for (idef = 0; idef < nDefs; idef++) {
52e6652d 369 def = (AliRsnMiniOutput *)fHistograms[idef];
6aaeb33c 370 if (!def) continue;
371 compType = def->GetComputation();
372 // execute computation in the appropriate way
373 switch (compType) {
374 case AliRsnMiniOutput::kEventOnly:
9e7b94f5 375 //AliDebugClass(1, Form("Event %d, def '%s': event-value histogram filling", ievt, def->GetName()));
45aa62b9 376 ifill = 1;
0efb7042 377 def->FillEvent(fMiniEvent, &fValues);
6aaeb33c 378 break;
379 case AliRsnMiniOutput::kTruePair:
9e7b94f5 380 //AliDebugClass(1, Form("Event %d, def '%s': true-pair histogram filling", ievt, def->GetName()));
0efb7042 381 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 382 break;
383 case AliRsnMiniOutput::kTrackPair:
9e7b94f5 384 //AliDebugClass(1, Form("Event %d, def '%s': pair-value histogram filling", ievt, def->GetName()));
0efb7042 385 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 386 break;
387 case AliRsnMiniOutput::kTrackPairRotated1:
9e7b94f5 388 //AliDebugClass(1, Form("Event %d, def '%s': rotated (1) background histogram filling", ievt, def->GetName()));
0efb7042 389 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 390 break;
391 case AliRsnMiniOutput::kTrackPairRotated2:
9e7b94f5 392 //AliDebugClass(1, Form("Event %d, def '%s': rotated (2) background histogram filling", ievt, def->GetName()));
0efb7042 393 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 394 break;
395 default:
396 // other kinds are processed elsewhere
45aa62b9 397 ifill = 0;
6aaeb33c 398 AliDebugClass(2, Form("Computation = %d", (Int_t)compType));
399 }
45aa62b9 400 // message
401 AliDebugClass(1, Form("Event %6d: def = '%15s' -- fills = %5d", ievt, def->GetName(), ifill));
03d23846 402 }
403 }
52e6652d 404
0efb7042 405 // if no mixing is required, stop here and post the output
406 if (fNMix < 1) {
407 AliDebugClass(2, "Stopping here, since no mixing is required");
408 PostData(1, fOutput);
409 return;
410 }
52e6652d 411
0efb7042 412 // initialize mixing counter
9e7b94f5 413 Int_t nmatched[nEvents];
414 TString *smatched = new TString[nEvents];
0efb7042 415 for (ievt = 0; ievt < nEvents; ievt++) {
9e7b94f5 416 smatched[ievt] = "|";
417 nmatched[ievt] = 0;
0efb7042 418 }
61f275d1 419
420
52e6652d 421 AliInfo(Form("[%s] Std.Event %d/%d",GetName(), nEvents,nEvents));
61f275d1 422 timer.Stop(); timer.Print(); timer.Start(); fflush(stdout);
52e6652d 423
0efb7042 424 // search for good matchings
425 for (ievt = 0; ievt < nEvents; ievt++) {
52e6652d 426 if (printNum&&(ievt%printNum==0)) {
427 AliInfo(Form("[%s] EventMixing searching %d/%d",GetName(),ievt,nEvents));
428 timer.Stop(); timer.Print(); timer.Start(kFALSE); fflush(stdout);
429 }
9e7b94f5 430 if (nmatched[ievt] >= fNMix) continue;
0efb7042 431 fEvBuffer->GetEntry(ievt);
432 AliRsnMiniEvent evMain(*fMiniEvent);
433 for (iloop = 1; iloop < nEvents; iloop++) {
434 imix = ievt + iloop;
435 if (imix >= nEvents) imix -= nEvents;
436 if (imix == ievt) continue;
437 // text next entry
438 fEvBuffer->GetEntry(imix);
439 // skip if events are not matched
caef2e3c 440 if (!EventsMatch(&evMain, fMiniEvent)) continue;
0efb7042 441 // check that the array of good matches for mixed does not already contain main event
9e7b94f5 442 if (smatched[imix].Contains(Form("|%d|", ievt))) continue;
443 // check that the found good events has not enough matches already
444 if (nmatched[imix] >= fNMix) continue;
0efb7042 445 // add new mixing candidate
9e7b94f5 446 smatched[ievt].Append(Form("%d|", imix));
447 nmatched[ievt]++;
448 nmatched[imix]++;
449 if (nmatched[ievt] >= fNMix) break;
0efb7042 450 }
9e7b94f5 451 AliDebugClass(1, Form("Matches for event %5d = %d [%s] (missing are declared above)", evMain.ID(), nmatched[ievt], smatched[ievt].Data()));
0efb7042 452 }
61f275d1 453
52e6652d 454 AliInfo(Form("[%s] EventMixing searching %d/%d",GetName(),nEvents,nEvents));
61f275d1 455 timer.Stop(); timer.Print(); fflush(stdout); timer.Start();
52e6652d 456
0efb7042 457 // perform mixing
458 TObjArray *list = 0x0;
459 TObjString *os = 0x0;
460 for (ievt = 0; ievt < nEvents; ievt++) {
52e6652d 461 if (printNum&&(ievt%printNum==0)) {
462 AliInfo(Form("[%s] EventMixing %d/%d",GetName(),ievt,nEvents));
463 timer.Stop(); timer.Print(); timer.Start(kFALSE); fflush(stdout);
464 }
0efb7042 465 ifill = 0;
466 fEvBuffer->GetEntry(ievt);
467 AliRsnMiniEvent evMain(*fMiniEvent);
9e7b94f5 468 list = smatched[ievt].Tokenize("|");
0efb7042 469 TObjArrayIter next(list);
52e6652d 470 while ( (os = (TObjString *)next()) ) {
0efb7042 471 imix = os->GetString().Atoi();
0efb7042 472 fEvBuffer->GetEntry(imix);
473 for (idef = 0; idef < nDefs; idef++) {
52e6652d 474 def = (AliRsnMiniOutput *)fHistograms[idef];
0efb7042 475 if (!def) continue;
476 if (!def->IsTrackPairMix()) continue;
d573d2fb 477 ifill += def->FillPair(&evMain, fMiniEvent, &fValues, kTRUE);
9e7b94f5 478 if (!def->IsSymmetric()) {
479 AliDebugClass(2, "Reflecting non symmetric pair");
480 ifill += def->FillPair(fMiniEvent, &evMain, &fValues, kFALSE);
481 }
0efb7042 482 }
483 }
484 delete list;
485 }
52e6652d 486
9e7b94f5 487 delete [] smatched;
52e6652d 488
489 AliInfo(Form("[%s] EventMixing %d/%d",GetName(),nEvents,nEvents));
61f275d1 490 timer.Stop(); timer.Print(); fflush(stdout);
52e6652d 491
0efb7042 492 /*
52e6652d 493 OLD
0efb7042 494 ifill = 0;
495 for (iloop = 1; iloop < nEvents; iloop++) {
496 imix = ievt + iloop;
497 // restart from beginning if reached last event
498 if (imix >= nEvents) imix -= nEvents;
499 // avoid to mix an event with itself
500 if (imix == ievt) continue;
501 // skip all events already mixed enough times
502 if (fNMixed[ievt] >= fNMix) break;
503 if (fNMixed[imix] >= fNMix) continue;
504 fEvBuffer->GetEntry(imix);
505 // skip if events are not matched
506 if (TMath::Abs(evMain.Vz() - fMiniEvent->Vz() ) > fMaxDiffVz ) continue;
507 if (TMath::Abs(evMain.Mult() - fMiniEvent->Mult() ) > fMaxDiffMult ) continue;
508 if (TMath::Abs(evMain.Angle() - fMiniEvent->Angle()) > fMaxDiffAngle) continue;
509 // found a match: increment counter for both events
510 AliDebugClass(1, Form("Event %d, def '%s': event mixing (%d with %d)", ievt, def->GetName(), ievt, imix));
511 fNMixed[ievt]++;
512 fNMixed[imix]++;
513 // process mixing
514 ifill += def->FillPair(&evMain, fMiniEvent, &fValues);
515 // stop if mixed enough times
516 if (fNMixed[ievt] >= fNMix) break;
517 }
52e6652d 518 break;
6aaeb33c 519 // print number of mixings done with each event
45aa62b9 520 for (ievt = 0; ievt < nEvents; ievt++) {
521 AliDebugClass(2, Form("Event %6d: mixed %2d times", ievt, fNMixed[ievt]));
522 }
0efb7042 523 */
52e6652d 524
6aaeb33c 525 // post computed data
03d23846 526 PostData(1, fOutput);
527}
528
529//__________________________________________________________________________________________________
530void AliRsnMiniAnalysisTask::Terminate(Option_t *)
531{
532//
533// Draw result to screen, or perform fitting, normalizations
534// Called once at the end of the query
535//
536
52e6652d 537 fOutput = dynamic_cast<TList *>(GetOutputData(1));
538 if (!fOutput) {
539 AliError("Could not retrieve TList fOutput");
540 return;
03d23846 541 }
542}
543
544//__________________________________________________________________________________________________
545Char_t AliRsnMiniAnalysisTask::CheckCurrentEvent()
546{
547//
c80938f5 548// This method checks if current event is OK for analysis.
549// In case it is, the pointers of the local AliRsnEvent data member
550// will point to it, in order to allow cut checking, otherwise the
551// function exits with a failure message.
552// ---
553// ESD events must pass the physics selection, AOD are supposed to do.
554// ---
555// While checking the event, a histogram is filled to count the number
556// of CINT1B, V0AND and CANDLE events, which are needed for normalization
557// ---
558// Return values can be:
03d23846 559// -- 'E' if the event is accepted and is ESD
560// -- 'A' if the event is accepted and is AOD
561// -- 0 if the event is not accepted
562//
563
564 // string to sum messages
565 TString msg("");
52e6652d 566
03d23846 567 // check input type
c80938f5 568 // exit points are provided in all cases an event is bad
569 // if this block is passed, an event can be rejected only
570 // if it does not pass the set of event cuts defined in the task
03d23846 571 Char_t output = 0;
c80938f5 572 Bool_t isSelected;
573 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
574 // type ESD
03d23846 575 output = 'E';
c80938f5 576 // ESD specific check: Physics Selection
577 // --> if this is failed, the event is rejected
52e6652d 578 isSelected = (((AliInputEventHandler *)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kMB);
c80938f5 579 if (!isSelected) {
45aa62b9 580 AliDebugClass(2, "Event does not pass physics selections");
c80938f5 581 fRsnEvent.SetRef(0x0);
582 fRsnEvent.SetRefMC(0x0);
583 return 0;
584 }
585 // set reference to input
586 fRsnEvent.SetRef(fInputEvent);
587 // add MC if requested and available
588 if (fUseMC) {
52e6652d 589 if (fMCEvent)
c80938f5 590 fRsnEvent.SetRefMC(fMCEvent);
591 else {
592 AliWarning("MC event requested but not available");
593 fRsnEvent.SetRefMC(0x0);
594 }
595 }
596 } else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
597 // type AOD
03d23846 598 output = 'A';
c80938f5 599 // set reference to input
600 fRsnEvent.SetRef(fInputEvent);
601 // add MC if requested and available (it is in the same object)
602 if (fUseMC) {
603 fRsnEvent.SetRefMC(fInputEvent);
604 if (!fRsnEvent.GetAODList()) {
605 AliWarning("MC event requested but not available");
606 fRsnEvent.SetRefMC(0x0);
607 }
608 }
609 } else {
03d23846 610 AliError(Form("Bad input event class: %s", fInputEvent->ClassName()));
c80938f5 611 // reset pointers in local AliRsnEvent object
612 fRsnEvent.SetRef(0x0);
613 fRsnEvent.SetRefMC(0x0);
03d23846 614 return 0;
615 }
52e6652d 616
c80938f5 617 // fill counter of accepted events
618 fHEventStat->Fill(0.1);
52e6652d 619
03d23846 620 // check if it is V0AND
c80938f5 621 // --> uses a cast to AliESDEvent even if the input is an AliAODEvent
52e6652d 622 Bool_t v0A = fTriggerAna->IsOfflineTriggerFired((AliESDEvent *)fInputEvent, AliTriggerAnalysis::kV0A);
623 Bool_t v0C = fTriggerAna->IsOfflineTriggerFired((AliESDEvent *)fInputEvent, AliTriggerAnalysis::kV0C);
03d23846 624 if (v0A && v0C) {
625 msg += " -- VOAND = YES";
626 fHEventStat->Fill(1.1);
627 } else {
628 msg += " -- VOAND = NO ";
629 }
52e6652d 630
03d23846 631 // check candle
c80938f5 632 // --> requires at least one good quality track with Pt > 0.5 and |eta| <= 0.8
633 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
03d23846 634 Bool_t candle = kFALSE;
52e6652d 635 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
636 AliVTrack *track = (AliVTrack *)fInputEvent->GetTrack(iTrack);
637 AliESDtrack *esdt = dynamic_cast<AliESDtrack *>(track);
638 AliAODTrack *aodt = dynamic_cast<AliAODTrack *>(track);
03d23846 639 if (track->Pt() < 0.5) continue;
640 if(TMath::Abs(track->Eta()) > 0.8) continue;
c80938f5 641 if (esdt) if (!fESDtrackCuts->AcceptTrack(esdt)) continue;
642 if (aodt) if (!aodt->TestFilterBit(5)) continue;
03d23846 643 candle = kTRUE;
644 break;
645 }
646 if (candle) {
52e6652d 647 msg += " -- CANDLE = YES";
03d23846 648 fHEventStat->Fill(2.1);
649 } else {
52e6652d 650 msg += " -- CANDLE = NO ";
03d23846 651 }
52e6652d 652
c80938f5 653 // if event cuts are defined, they are checked here
654 // final decision on the event depends on this
655 isSelected = kTRUE;
03d23846 656 if (fEventCuts) {
657 if (!fEventCuts->IsSelected(&fRsnEvent)) {
658 msg += " -- Local cuts = REJECTED";
c80938f5 659 isSelected = kFALSE;
03d23846 660 } else {
661 msg += " -- Local cuts = ACCEPTED";
c80938f5 662 isSelected = kTRUE;
03d23846 663 }
664 } else {
665 msg += " -- Local cuts = NONE";
c80938f5 666 isSelected = kTRUE;
03d23846 667 }
52e6652d 668
03d23846 669 // if the above exit point is not taken, the event is accepted
9e7b94f5 670 AliDebugClass(2, Form("Stats: %s", msg.Data()));
c80938f5 671 if (isSelected) {
672 fHEventStat->Fill(3.1);
673 return output;
674 } else {
675 return 0;
676 }
03d23846 677}
678
6aaeb33c 679//__________________________________________________________________________________________________
45aa62b9 680void AliRsnMiniAnalysisTask::FillMiniEvent(Char_t evType)
6aaeb33c 681{
682//
683// Refresh cursor mini-event data member to fill with current event.
684// Returns the total number of tracks selected.
685//
686
687 // assign event-related values
45aa62b9 688 if (fMiniEvent) delete fMiniEvent;
6aaeb33c 689 fMiniEvent = new AliRsnMiniEvent;
690 fMiniEvent->Vz() = fInputEvent->GetPrimaryVertex()->GetZ();
691 fMiniEvent->Angle() = ComputeAngle();
692 fMiniEvent->Mult() = ComputeCentrality((evType == 'E'));
45aa62b9 693 AliDebugClass(2, Form("Event %d: type = %c -- vz = %f -- mult = %f -- angle = %f", fEvNum, evType, fMiniEvent->Vz(), fMiniEvent->Mult(), fMiniEvent->Angle()));
52e6652d 694
6aaeb33c 695 // loop on daughters and assign track-related values
696 Int_t ic, ncuts = fTrackCuts.GetEntries();
697 Int_t ip, npart = fRsnEvent.GetAbsoluteSum();
45aa62b9 698 Int_t npos = 0, nneg = 0, nneu = 0;
6aaeb33c 699 AliRsnDaughter cursor;
700 AliRsnMiniParticle miniParticle;
701 for (ip = 0; ip < npart; ip++) {
702 // point cursor to next particle
703 fRsnEvent.SetDaughter(cursor, ip);
704 // copy momentum and MC info if present
705 miniParticle.CopyDaughter(&cursor);
45aa62b9 706 miniParticle.Index() = ip;
6aaeb33c 707 // switch on the bits corresponding to passed cuts
708 for (ic = 0; ic < ncuts; ic++) {
52e6652d 709 AliRsnCutSet *cuts = (AliRsnCutSet *)fTrackCuts[ic];
6aaeb33c 710 if (cuts->IsSelected(&cursor)) miniParticle.SetCutBit(ic);
711 }
712 // if a track passes at least one track cut, it is added to the pool
45aa62b9 713 if (miniParticle.CutBits()) {
714 fMiniEvent->AddParticle(miniParticle);
715 if (miniParticle.Charge() == '+') npos++;
716 else if (miniParticle.Charge() == '-') nneg++;
717 else nneu++;
718 }
6aaeb33c 719 }
52e6652d 720
6aaeb33c 721 // get number of accepted tracks
45aa62b9 722 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 723}
724
3dced4f8 725//__________________________________________________________________________________________________
726Double_t AliRsnMiniAnalysisTask::ComputeAngle()
727{
728//
729// Get the plane angle
730//
731
cd273d20 732 AliEventplane *plane = 0x0;
52e6652d 733
cd273d20 734 if (fInputEvent->InheritsFrom(AliESDEvent::Class()))
735 plane = fInputEvent->GetEventplane();
736 else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
52e6652d 737 AliAODEvent *aodEvent = (AliAODEvent *)fInputEvent;
cd273d20 738 plane = aodEvent->GetHeader()->GetEventplaneP();
739 }
740
52e6652d 741 if (plane)
3dced4f8 742 return plane->GetEventplane("Q");
743 else {
744 AliWarning("No event plane defined");
745 return 1E20;
746 }
747}
748
03d23846 749//__________________________________________________________________________________________________
750Double_t AliRsnMiniAnalysisTask::ComputeCentrality(Bool_t isESD)
751{
752//
753// Computes event centrality/multiplicity according to the criterion defined
754// by two elements: (1) choice between multiplicity and centrality and
755// (2) the string defining what criterion must be used for specific computation.
756//
757
758 if (fUseCentrality) {
1cdc3671 759
760 if ((!fUseMC) && (!isESD) && (fUseAOD049CentralityPatch)) {
761 return ApplyCentralityPatchAOD049();
762 } else {
763 AliCentrality *centrality = fInputEvent->GetCentrality();
764 if (!centrality) {
765 AliError("Cannot compute centrality!");
766 return -1.0;
767 }
768 return centrality->GetCentralityPercentile(fCentralityType.Data());
769 }
03d23846 770 } else {
03d23846 771 if (!fCentralityType.CompareTo("TRACKS"))
772 return fInputEvent->GetNumberOfTracks();
773 else if (!fCentralityType.CompareTo("QUALITY"))
c80938f5 774 if (isESD)
52e6652d 775 return AliESDtrackCuts::GetReferenceMultiplicity((AliESDEvent *)fInputEvent, kTRUE);
c80938f5 776 else {
777 Double_t count = 0.;
778 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
52e6652d 779 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
780 AliVTrack *track = (AliVTrack *)fInputEvent->GetTrack(iTrack);
781 AliAODTrack *aodt = dynamic_cast<AliAODTrack *>(track);
c80938f5 782 if (!aodt) continue;
783 if (!aodt->TestFilterBit(5)) continue;
784 count++;
785 }
786 return count;
787 }
03d23846 788 else if (!fCentralityType.CompareTo("TRACKLETS")) {
c80938f5 789 if (isESD) {
52e6652d 790 const AliMultiplicity *mult = ((AliESDEvent *)fInputEvent)->GetMultiplicity();
c80938f5 791 Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
792 for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
793 return AliESDUtils::GetCorrSPD2(nClusters[1], fInputEvent->GetPrimaryVertex()->GetZ());
794 } else {
795 AliWarning("Cannot compute multiplicity with SPD tracklets from AOD");
796 return 1E20;
797 }
03d23846 798 } else {
799 AliError(Form("String '%s' does not define a possible multiplicity/centrality computation", fCentralityType.Data()));
800 return -1.0;
801 }
802 }
803}
804
805//__________________________________________________________________________________________________
806void AliRsnMiniAnalysisTask::FillTrueMotherESD(AliRsnMiniEvent *miniEvent)
807{
808//
809// Fills the histograms with true mother (ESD version)
810//
811
812 Bool_t okMatch;
813 Int_t id, ndef = fHistograms.GetEntries();
814 Int_t ip, label1, label2, npart = fMCEvent->GetNumberOfTracks();
815 static AliRsnMiniPair miniPair;
816 AliMCParticle *daughter1, *daughter2;
817 TLorentzVector p1, p2;
818 AliRsnMiniOutput *def = 0x0;
52e6652d 819
03d23846 820 for (id = 0; id < ndef; id++) {
52e6652d 821 def = (AliRsnMiniOutput *)fHistograms[id];
03d23846 822 if (!def) continue;
823 if (!def->IsMother()) continue;
824 for (ip = 0; ip < npart; ip++) {
52e6652d 825 AliMCParticle *part = (AliMCParticle *)fMCEvent->GetTrack(ip);
64129b35 826 if (part->Particle()->GetPdgCode() != def->GetMotherPDG()) continue;
03d23846 827 // check that daughters match expected species
828 if (part->Particle()->GetNDaughters() < 2) continue;
829 label1 = part->Particle()->GetDaughter(0);
830 label2 = part->Particle()->GetDaughter(1);
52e6652d 831 daughter1 = (AliMCParticle *)fMCEvent->GetTrack(label1);
832 daughter2 = (AliMCParticle *)fMCEvent->GetTrack(label2);
03d23846 833 okMatch = kFALSE;
834 if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(1)) {
835 okMatch = kTRUE;
836 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
837 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
838 } else if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(0)) {
839 okMatch = kTRUE;
840 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
841 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
842 }
843 if (!okMatch) continue;
844 // assign momenta to computation object
845 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
846 miniPair.FillRef(def->GetMotherMass());
847 // do computations
45aa62b9 848 def->FillMother(&miniPair, miniEvent, &fValues);
03d23846 849 }
850 }
851}
852
853//__________________________________________________________________________________________________
854void AliRsnMiniAnalysisTask::FillTrueMotherAOD(AliRsnMiniEvent *miniEvent)
855{
856//
857// Fills the histograms with true mother (AOD version)
858//
859
860 Bool_t okMatch;
861 TClonesArray *list = fRsnEvent.GetAODList();
862 Int_t id, ndef = fHistograms.GetEntries();
863 Int_t ip, label1, label2, npart = list->GetEntries();
864 static AliRsnMiniPair miniPair;
865 AliAODMCParticle *daughter1, *daughter2;
866 TLorentzVector p1, p2;
867 AliRsnMiniOutput *def = 0x0;
52e6652d 868
03d23846 869 for (id = 0; id < ndef; id++) {
52e6652d 870 def = (AliRsnMiniOutput *)fHistograms[id];
03d23846 871 if (!def) continue;
872 if (!def->IsMother()) continue;
873 for (ip = 0; ip < npart; ip++) {
52e6652d 874 AliAODMCParticle *part = (AliAODMCParticle *)list->At(ip);
64129b35 875 if (part->GetPdgCode() != def->GetMotherPDG()) continue;
03d23846 876 // check that daughters match expected species
877 if (part->GetNDaughters() < 2) continue;
878 label1 = part->GetDaughter(0);
879 label2 = part->GetDaughter(1);
52e6652d 880 daughter1 = (AliAODMCParticle *)list->At(label1);
881 daughter2 = (AliAODMCParticle *)list->At(label2);
03d23846 882 okMatch = kFALSE;
883 if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(1)) {
884 okMatch = kTRUE;
885 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
886 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
887 } else if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(0)) {
888 okMatch = kTRUE;
889 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
890 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
891 }
892 if (!okMatch) continue;
893 // assign momenta to computation object
894 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
895 miniPair.FillRef(def->GetMotherMass());
896 // do computations
45aa62b9 897 def->FillMother(&miniPair, miniEvent, &fValues);
03d23846 898 }
899 }
900}
caef2e3c 901
902//__________________________________________________________________________________________________
903Bool_t AliRsnMiniAnalysisTask::EventsMatch(AliRsnMiniEvent *event1, AliRsnMiniEvent *event2)
904{
905//
906// Check if two events are compatible.
907// If the mixing is continuous, this is true if differences in vz, mult and angle are smaller than
52e6652d 908// the specified values.
caef2e3c 909// If the mixing is binned, this is true if the events are in the same bin.
910//
911
912 if (!event1 || !event2) return kFALSE;
913 Int_t ivz1, ivz2, imult1, imult2, iangle1, iangle2;
9e7b94f5 914 Double_t dv, dm, da;
52e6652d 915
caef2e3c 916 if (fContinuousMix) {
9e7b94f5 917 dv = TMath::Abs(event1->Vz() - event2->Vz() );
918 dm = TMath::Abs(event1->Mult() - event2->Mult() );
919 da = TMath::Abs(event1->Angle() - event2->Angle());
920 if (dv > fMaxDiffVz) {
921 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Vz = %f", event1->ID(), event2->ID(), dv));
922 return kFALSE;
923 }
924 if (dm > fMaxDiffMult ) {
925 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Mult = %f", event1->ID(), event2->ID(), dm));
926 return kFALSE;
927 }
928 if (da > fMaxDiffAngle) {
929 //AliDebugClass(2, Form("Events #%4d and #%4d don't match due to a too large diff in Angle = %f", event1->ID(), event2->ID(), da));
930 return kFALSE;
931 }
caef2e3c 932 return kTRUE;
933 } else {
934 ivz1 = (Int_t)(event1->Vz() / fMaxDiffVz);
935 ivz2 = (Int_t)(event2->Vz() / fMaxDiffVz);
936 imult1 = (Int_t)(event1->Mult() / fMaxDiffMult);
937 imult2 = (Int_t)(event2->Mult() / fMaxDiffMult);
938 iangle1 = (Int_t)(event1->Angle() / fMaxDiffAngle);
939 iangle2 = (Int_t)(event2->Angle() / fMaxDiffAngle);
940 if (ivz1 != ivz2) return kFALSE;
941 if (imult1 != imult2) return kFALSE;
942 if (iangle1 != iangle2) return kFALSE;
943 return kTRUE;
944 }
945}
946
52e6652d 947
1cdc3671 948//---------------------------------------------------------------------
949Double_t AliRsnMiniAnalysisTask::ApplyCentralityPatchAOD049()
950{
951 //
952 //Apply centrality patch for AOD049 outliers
953 //
954 if (fInputEvent->InheritsFrom(AliESDEvent::Class())){
955 AliWarning("Requested patch for AOD049 for ESD. ");
956 return -999.0;
957 }
958
959 if (fCentralityType!="V0M"){
960 AliWarning("Requested patch forAOD049 for wrong value (not centrality from V0).");
961 return -999.0;
962 }
963
964 AliCentrality *centrality = fInputEvent->GetCentrality();
965 if (!centrality) {
966 AliWarning("Cannot get centrality from AOD event.");
967 return -999.0;
968 }
969
970 Float_t cent = (Float_t)(centrality->GetCentralityPercentile("V0M"));
971 /*
972 Bool_t isSelRun = kFALSE;
973 Int_t selRun[5] = {138364, 138826, 138828, 138836, 138871};
974 if(cent<0){
975 Int_t quality = centrality->GetQuality();
976 if(quality<=1){
977 cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
978 } else {
979 Int_t runnum=aodEvent->GetRunNumber();
980 for(Int_t ir=0;ir<5;ir++){
981 if(runnum==selRun[ir]){
982 isSelRun=kTRUE;
983 break;
984 }
985 }
986 if((quality==8||quality==9)&&isSelRun) cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
987 }
988 }
989 */
990
991 if(cent>=0.0) {
992 Float_t v0 = 0.0;
993 AliAODEvent *aodEvent = (AliAODEvent *)fInputEvent;
994 AliAODVZERO* aodV0 = (AliAODVZERO*) aodEvent->GetVZEROData();
995 v0+=aodV0->GetMTotV0A();
996 v0+=aodV0->GetMTotV0C();
997 if ( (cent==0) && (v0<19500) ) {
998 AliDebug(3, Form("Filtering issue in centrality -> cent = %5.2f",cent));
999 return -999.0;
1000 }
1001 Float_t tkl = (Float_t)(aodEvent->GetTracklets()->GetNumberOfTracklets());
1002 Float_t val = 1.30552 + 0.147931 * v0;
1003
1004 Float_t tklSigma[101] = {176.644, 156.401, 153.789, 153.015, 142.476, 137.951, 136.127, 129.852, 127.436, 124.86,
1005 120.788, 115.611, 113.172, 110.496, 109.127, 104.421, 102.479, 99.9766, 97.5152, 94.0654,
1006 92.4602, 89.3364, 87.1342, 83.3497, 82.6216, 81.1084, 78.0793, 76.1234, 72.9434, 72.1334,
1007 68.0056, 68.2755, 66.0376, 62.9666, 62.4274, 59.65, 58.3776, 56.6361, 54.5184, 53.4224,
1008 51.932, 50.8922, 48.2848, 47.912, 46.5717, 43.4114, 43.2083, 41.3065, 40.1863, 38.5255,
1009 37.2851, 37.5396, 34.4949, 33.8366, 31.8043, 31.7412, 30.8392, 30.0274, 28.8793, 27.6398,
1010 26.6488, 25.0183, 25.1489, 24.4185, 22.9107, 21.2002, 21.6977, 20.1242, 20.4963, 19.0235,
1011 19.298, 17.4103, 16.868, 15.2939, 15.2939, 16.0295, 14.186, 14.186, 15.2173, 12.9504, 12.9504,
1012 12.9504, 15.264, 12.3674, 12.3674, 12.3674, 12.3674, 12.3674, 18.3811, 13.7544, 13.7544,
1013 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544, 13.7544 };
1014
1015 if ( TMath::Abs(tkl-val) > 6.*tklSigma[(Int_t)cent] ) {
1016 AliDebug(3, Form("Outlier event in centrality -> cent = %5.2f",cent));
1017 return -999.0;
1018 }
1019 } else {
1020 //force it to be -999. whatever the negative value was
1021 cent = -999.;
1022 }
1023 return cent;
1024}