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