]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG2/RESONANCES/AliRsnMiniAnalysisTask.cxx
Include variable jet patch size handling in decoding
[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
216 fEvNum = 0;
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
273 // event counter
274 fEvNum++;
275
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
298 // store event
c80938f5 299 fEvBuffer->Fill();
03d23846 300
6aaeb33c 301 // post data for computed stuff
03d23846 302 PostData(1, fOutput);
303}
304
305//__________________________________________________________________________________________________
306void AliRsnMiniAnalysisTask::FinishTaskOutput()
307{
308//
6aaeb33c 309// This function is called at the end of the loop on available events,
310// and then the buffer will be full with all the corresponding mini-events,
311// each one containing all tracks selected by each of the available track cuts.
312// Here a loop is done on each of these events, and both single-event and mixing are computed
03d23846 313//
314
6aaeb33c 315 // security code: reassign the buffer to the mini-event cursor
316 fEvBuffer->SetBranchAddress("events", &fMiniEvent);
317
0efb7042 318 // prepare variables
6aaeb33c 319 Int_t ievt, nEvents = (Int_t)fEvBuffer->GetEntries();
320 Int_t idef, nDefs = fHistograms.GetEntries();
45aa62b9 321 Int_t imix, iloop, ifill;
6aaeb33c 322 AliRsnMiniOutput *def = 0x0;
323 AliRsnMiniOutput::EComputation compType;
03d23846 324
6aaeb33c 325 // loop on events, and for each one fill all outputs
326 // using the appropriate procedure depending on its type
327 // only mother-related histograms are filled in UserExec,
328 // since they require direct access to MC event
329 for (ievt = 0; ievt < nEvents; ievt++) {
330 // get next entry
331 fEvBuffer->GetEntry(ievt);
45aa62b9 332 // fill
6aaeb33c 333 for (idef = 0; idef < nDefs; idef++) {
334 def = (AliRsnMiniOutput*)fHistograms[idef];
335 if (!def) continue;
336 compType = def->GetComputation();
337 // execute computation in the appropriate way
338 switch (compType) {
339 case AliRsnMiniOutput::kEventOnly:
0efb7042 340 AliDebugClass(1, Form("Event %d, def '%s': event-value histogram filling", ievt, def->GetName()));
45aa62b9 341 ifill = 1;
0efb7042 342 def->FillEvent(fMiniEvent, &fValues);
6aaeb33c 343 break;
344 case AliRsnMiniOutput::kTruePair:
0efb7042 345 AliDebugClass(1, Form("Event %d, def '%s': true-pair histogram filling", ievt, def->GetName()));
346 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 347 break;
348 case AliRsnMiniOutput::kTrackPair:
0efb7042 349 AliDebugClass(1, Form("Event %d, def '%s': pair-value histogram filling", ievt, def->GetName()));
350 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 351 break;
352 case AliRsnMiniOutput::kTrackPairRotated1:
0efb7042 353 AliDebugClass(1, Form("Event %d, def '%s': rotated (1) background histogram filling", ievt, def->GetName()));
354 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 355 break;
356 case AliRsnMiniOutput::kTrackPairRotated2:
0efb7042 357 AliDebugClass(1, Form("Event %d, def '%s': rotated (2) background histogram filling", ievt, def->GetName()));
358 ifill = def->FillPair(fMiniEvent, fMiniEvent, &fValues);
6aaeb33c 359 break;
360 default:
361 // other kinds are processed elsewhere
45aa62b9 362 ifill = 0;
6aaeb33c 363 AliDebugClass(2, Form("Computation = %d", (Int_t)compType));
364 }
45aa62b9 365 // message
366 AliDebugClass(1, Form("Event %6d: def = '%15s' -- fills = %5d", ievt, def->GetName(), ifill));
03d23846 367 }
368 }
369
0efb7042 370 // if no mixing is required, stop here and post the output
371 if (fNMix < 1) {
372 AliDebugClass(2, "Stopping here, since no mixing is required");
373 PostData(1, fOutput);
374 return;
375 }
376
377 // initialize mixing counter
378 TString *matched = new TString[nEvents];
379 for (ievt = 0; ievt < nEvents; ievt++) {
380 matched[ievt] = "|";
381 }
382
383 // search for good matchings
384 for (ievt = 0; ievt < nEvents; ievt++) {
385 ifill = 0;
386 fEvBuffer->GetEntry(ievt);
387 AliRsnMiniEvent evMain(*fMiniEvent);
388 for (iloop = 1; iloop < nEvents; iloop++) {
389 imix = ievt + iloop;
390 if (imix >= nEvents) imix -= nEvents;
391 if (imix == ievt) continue;
392 // text next entry
393 fEvBuffer->GetEntry(imix);
394 // skip if events are not matched
caef2e3c 395 if (!EventsMatch(&evMain, fMiniEvent)) continue;
0efb7042 396 // check that the array of good matches for mixed does not already contain main event
397 if (matched[imix].Contains(Form("|%d|", ievt))) continue;
398 // add new mixing candidate
399 matched[ievt].Append(Form("%d|", imix));
400 ifill++;
401 if (ifill >= fNMix) break;
402 }
7196ee4f 403 AliDebugClass(1, Form("Matches for event %5d = %s", ievt, matched[ievt].Data()));
0efb7042 404 }
405
406 // perform mixing
407 TObjArray *list = 0x0;
408 TObjString *os = 0x0;
409 for (ievt = 0; ievt < nEvents; ievt++) {
410 ifill = 0;
411 fEvBuffer->GetEntry(ievt);
412 AliRsnMiniEvent evMain(*fMiniEvent);
413 list = matched[ievt].Tokenize("|");
414 TObjArrayIter next(list);
415 while ( (os = (TObjString*)next()) ) {
416 imix = os->GetString().Atoi();
0efb7042 417 fEvBuffer->GetEntry(imix);
418 for (idef = 0; idef < nDefs; idef++) {
419 def = (AliRsnMiniOutput*)fHistograms[idef];
420 if (!def) continue;
421 if (!def->IsTrackPairMix()) continue;
d573d2fb 422 ifill += def->FillPair(&evMain, fMiniEvent, &fValues, kTRUE);
423 if (!def->IsSymmetric()) ifill += def->FillPair(fMiniEvent, &evMain, &fValues, kFALSE);
0efb7042 424 }
425 }
426 delete list;
427 }
428
429 delete [] matched;
430
431 /*
432 OLD
433 ifill = 0;
434 for (iloop = 1; iloop < nEvents; iloop++) {
435 imix = ievt + iloop;
436 // restart from beginning if reached last event
437 if (imix >= nEvents) imix -= nEvents;
438 // avoid to mix an event with itself
439 if (imix == ievt) continue;
440 // skip all events already mixed enough times
441 if (fNMixed[ievt] >= fNMix) break;
442 if (fNMixed[imix] >= fNMix) continue;
443 fEvBuffer->GetEntry(imix);
444 // skip if events are not matched
445 if (TMath::Abs(evMain.Vz() - fMiniEvent->Vz() ) > fMaxDiffVz ) continue;
446 if (TMath::Abs(evMain.Mult() - fMiniEvent->Mult() ) > fMaxDiffMult ) continue;
447 if (TMath::Abs(evMain.Angle() - fMiniEvent->Angle()) > fMaxDiffAngle) continue;
448 // found a match: increment counter for both events
449 AliDebugClass(1, Form("Event %d, def '%s': event mixing (%d with %d)", ievt, def->GetName(), ievt, imix));
450 fNMixed[ievt]++;
451 fNMixed[imix]++;
452 // process mixing
453 ifill += def->FillPair(&evMain, fMiniEvent, &fValues);
454 // stop if mixed enough times
455 if (fNMixed[ievt] >= fNMix) break;
456 }
457 break;
6aaeb33c 458 // print number of mixings done with each event
45aa62b9 459 for (ievt = 0; ievt < nEvents; ievt++) {
460 AliDebugClass(2, Form("Event %6d: mixed %2d times", ievt, fNMixed[ievt]));
461 }
0efb7042 462 */
03d23846 463
6aaeb33c 464 // post computed data
03d23846 465 PostData(1, fOutput);
466}
467
468//__________________________________________________________________________________________________
469void AliRsnMiniAnalysisTask::Terminate(Option_t *)
470{
471//
472// Draw result to screen, or perform fitting, normalizations
473// Called once at the end of the query
474//
475
476 fOutput = dynamic_cast<TList*>(GetOutputData(1));
477 if (!fOutput) {
478 AliError("Could not retrieve TList fOutput");
479 return;
480 }
481}
482
483//__________________________________________________________________________________________________
484Char_t AliRsnMiniAnalysisTask::CheckCurrentEvent()
485{
486//
c80938f5 487// This method checks if current event is OK for analysis.
488// In case it is, the pointers of the local AliRsnEvent data member
489// will point to it, in order to allow cut checking, otherwise the
490// function exits with a failure message.
491// ---
492// ESD events must pass the physics selection, AOD are supposed to do.
493// ---
494// While checking the event, a histogram is filled to count the number
495// of CINT1B, V0AND and CANDLE events, which are needed for normalization
496// ---
497// Return values can be:
03d23846 498// -- 'E' if the event is accepted and is ESD
499// -- 'A' if the event is accepted and is AOD
500// -- 0 if the event is not accepted
501//
502
503 // string to sum messages
504 TString msg("");
505
506 // check input type
c80938f5 507 // exit points are provided in all cases an event is bad
508 // if this block is passed, an event can be rejected only
509 // if it does not pass the set of event cuts defined in the task
03d23846 510 Char_t output = 0;
c80938f5 511 Bool_t isSelected;
512 if (fInputEvent->InheritsFrom(AliESDEvent::Class())) {
513 // type ESD
03d23846 514 output = 'E';
c80938f5 515 // ESD specific check: Physics Selection
516 // --> if this is failed, the event is rejected
517 isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kMB);
518 if (!isSelected) {
45aa62b9 519 AliDebugClass(2, "Event does not pass physics selections");
c80938f5 520 fRsnEvent.SetRef(0x0);
521 fRsnEvent.SetRefMC(0x0);
522 return 0;
523 }
524 // set reference to input
525 fRsnEvent.SetRef(fInputEvent);
526 // add MC if requested and available
527 if (fUseMC) {
528 if (fMCEvent)
529 fRsnEvent.SetRefMC(fMCEvent);
530 else {
531 AliWarning("MC event requested but not available");
532 fRsnEvent.SetRefMC(0x0);
533 }
534 }
535 } else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
536 // type AOD
03d23846 537 output = 'A';
c80938f5 538 // set reference to input
539 fRsnEvent.SetRef(fInputEvent);
540 // add MC if requested and available (it is in the same object)
541 if (fUseMC) {
542 fRsnEvent.SetRefMC(fInputEvent);
543 if (!fRsnEvent.GetAODList()) {
544 AliWarning("MC event requested but not available");
545 fRsnEvent.SetRefMC(0x0);
546 }
547 }
548 } else {
03d23846 549 AliError(Form("Bad input event class: %s", fInputEvent->ClassName()));
c80938f5 550 // reset pointers in local AliRsnEvent object
551 fRsnEvent.SetRef(0x0);
552 fRsnEvent.SetRefMC(0x0);
03d23846 553 return 0;
554 }
555
c80938f5 556 // fill counter of accepted events
557 fHEventStat->Fill(0.1);
03d23846 558
559 // check if it is V0AND
c80938f5 560 // --> uses a cast to AliESDEvent even if the input is an AliAODEvent
03d23846 561 Bool_t v0A = fTriggerAna->IsOfflineTriggerFired((AliESDEvent*)fInputEvent, AliTriggerAnalysis::kV0A);
562 Bool_t v0C = fTriggerAna->IsOfflineTriggerFired((AliESDEvent*)fInputEvent, AliTriggerAnalysis::kV0C);
563 if (v0A && v0C) {
564 msg += " -- VOAND = YES";
565 fHEventStat->Fill(1.1);
566 } else {
567 msg += " -- VOAND = NO ";
568 }
569
570 // check candle
c80938f5 571 // --> requires at least one good quality track with Pt > 0.5 and |eta| <= 0.8
572 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
03d23846 573 Bool_t candle = kFALSE;
c80938f5 574 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
03d23846 575 AliVTrack *track = (AliVTrack*)fInputEvent->GetTrack(iTrack);
576 AliESDtrack *esdt = dynamic_cast<AliESDtrack*>(track);
577 AliAODTrack *aodt = dynamic_cast<AliAODTrack*>(track);
03d23846 578 if (track->Pt() < 0.5) continue;
579 if(TMath::Abs(track->Eta()) > 0.8) continue;
c80938f5 580 if (esdt) if (!fESDtrackCuts->AcceptTrack(esdt)) continue;
581 if (aodt) if (!aodt->TestFilterBit(5)) continue;
03d23846 582 candle = kTRUE;
583 break;
584 }
585 if (candle) {
586 msg += " -- CANDLE = YES";
587 fHEventStat->Fill(2.1);
588 } else {
589 msg += " -- CANDLE = NO ";
590 }
591
c80938f5 592 // if event cuts are defined, they are checked here
593 // final decision on the event depends on this
594 isSelected = kTRUE;
03d23846 595 if (fEventCuts) {
596 if (!fEventCuts->IsSelected(&fRsnEvent)) {
597 msg += " -- Local cuts = REJECTED";
c80938f5 598 isSelected = kFALSE;
03d23846 599 } else {
600 msg += " -- Local cuts = ACCEPTED";
c80938f5 601 isSelected = kTRUE;
03d23846 602 }
603 } else {
604 msg += " -- Local cuts = NONE";
c80938f5 605 isSelected = kTRUE;
03d23846 606 }
607
608 // if the above exit point is not taken, the event is accepted
45aa62b9 609 AliDebugClass(2, Form("Stats for event %d: %s", fEvNum, msg.Data()));
c80938f5 610 if (isSelected) {
611 fHEventStat->Fill(3.1);
612 return output;
613 } else {
614 return 0;
615 }
03d23846 616}
617
6aaeb33c 618//__________________________________________________________________________________________________
45aa62b9 619void AliRsnMiniAnalysisTask::FillMiniEvent(Char_t evType)
6aaeb33c 620{
621//
622// Refresh cursor mini-event data member to fill with current event.
623// Returns the total number of tracks selected.
624//
625
626 // assign event-related values
45aa62b9 627 if (fMiniEvent) delete fMiniEvent;
6aaeb33c 628 fMiniEvent = new AliRsnMiniEvent;
45aa62b9 629 fMiniEvent->ID() = fEvNum;
6aaeb33c 630 fMiniEvent->Vz() = fInputEvent->GetPrimaryVertex()->GetZ();
631 fMiniEvent->Angle() = ComputeAngle();
632 fMiniEvent->Mult() = ComputeCentrality((evType == 'E'));
45aa62b9 633 AliDebugClass(2, Form("Event %d: type = %c -- vz = %f -- mult = %f -- angle = %f", fEvNum, evType, fMiniEvent->Vz(), fMiniEvent->Mult(), fMiniEvent->Angle()));
6aaeb33c 634
635 // loop on daughters and assign track-related values
636 Int_t ic, ncuts = fTrackCuts.GetEntries();
637 Int_t ip, npart = fRsnEvent.GetAbsoluteSum();
45aa62b9 638 Int_t npos = 0, nneg = 0, nneu = 0;
6aaeb33c 639 AliRsnDaughter cursor;
640 AliRsnMiniParticle miniParticle;
641 for (ip = 0; ip < npart; ip++) {
642 // point cursor to next particle
643 fRsnEvent.SetDaughter(cursor, ip);
644 // copy momentum and MC info if present
645 miniParticle.CopyDaughter(&cursor);
45aa62b9 646 miniParticle.Index() = ip;
6aaeb33c 647 // switch on the bits corresponding to passed cuts
648 for (ic = 0; ic < ncuts; ic++) {
649 AliRsnCutSet *cuts = (AliRsnCutSet*)fTrackCuts[ic];
650 if (cuts->IsSelected(&cursor)) miniParticle.SetCutBit(ic);
651 }
652 // if a track passes at least one track cut, it is added to the pool
45aa62b9 653 if (miniParticle.CutBits()) {
654 fMiniEvent->AddParticle(miniParticle);
655 if (miniParticle.Charge() == '+') npos++;
656 else if (miniParticle.Charge() == '-') nneg++;
657 else nneu++;
658 }
6aaeb33c 659 }
660
661 // get number of accepted tracks
45aa62b9 662 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 663}
664
3dced4f8 665//__________________________________________________________________________________________________
666Double_t AliRsnMiniAnalysisTask::ComputeAngle()
667{
668//
669// Get the plane angle
670//
671
cd273d20 672 AliEventplane *plane = 0x0;
673
674 if (fInputEvent->InheritsFrom(AliESDEvent::Class()))
675 plane = fInputEvent->GetEventplane();
676 else if (fInputEvent->InheritsFrom(AliAODEvent::Class())) {
677 AliAODEvent *aodEvent = (AliAODEvent*)fInputEvent;
678 plane = aodEvent->GetHeader()->GetEventplaneP();
679 }
680
3dced4f8 681 if (plane)
682 return plane->GetEventplane("Q");
683 else {
684 AliWarning("No event plane defined");
685 return 1E20;
686 }
687}
688
03d23846 689//__________________________________________________________________________________________________
690Double_t AliRsnMiniAnalysisTask::ComputeCentrality(Bool_t isESD)
691{
692//
693// Computes event centrality/multiplicity according to the criterion defined
694// by two elements: (1) choice between multiplicity and centrality and
695// (2) the string defining what criterion must be used for specific computation.
696//
697
698 if (fUseCentrality) {
699 AliCentrality *centrality = fInputEvent->GetCentrality();
700 if (!centrality) {
701 AliError("Cannot compute centrality!");
702 return -1.0;
703 }
704 return centrality->GetCentralityPercentile(fCentralityType.Data());
705 } else {
03d23846 706 if (!fCentralityType.CompareTo("TRACKS"))
707 return fInputEvent->GetNumberOfTracks();
708 else if (!fCentralityType.CompareTo("QUALITY"))
c80938f5 709 if (isESD)
710 return AliESDtrackCuts::GetReferenceMultiplicity((AliESDEvent*)fInputEvent, kTRUE);
711 else {
712 Double_t count = 0.;
713 Int_t iTrack, ntracksLoop = fInputEvent->GetNumberOfTracks();
714 for (iTrack = 0; iTrack < ntracksLoop; iTrack++) {
715 AliVTrack *track = (AliVTrack*)fInputEvent->GetTrack(iTrack);
716 AliAODTrack *aodt = dynamic_cast<AliAODTrack*>(track);
717 if (!aodt) continue;
718 if (!aodt->TestFilterBit(5)) continue;
719 count++;
720 }
721 return count;
722 }
03d23846 723 else if (!fCentralityType.CompareTo("TRACKLETS")) {
c80938f5 724 if (isESD) {
725 const AliMultiplicity *mult = ((AliESDEvent*)fInputEvent)->GetMultiplicity();
726 Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
727 for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
728 return AliESDUtils::GetCorrSPD2(nClusters[1], fInputEvent->GetPrimaryVertex()->GetZ());
729 } else {
730 AliWarning("Cannot compute multiplicity with SPD tracklets from AOD");
731 return 1E20;
732 }
03d23846 733 } else {
734 AliError(Form("String '%s' does not define a possible multiplicity/centrality computation", fCentralityType.Data()));
735 return -1.0;
736 }
737 }
738}
739
740//__________________________________________________________________________________________________
741void AliRsnMiniAnalysisTask::FillTrueMotherESD(AliRsnMiniEvent *miniEvent)
742{
743//
744// Fills the histograms with true mother (ESD version)
745//
746
747 Bool_t okMatch;
748 Int_t id, ndef = fHistograms.GetEntries();
749 Int_t ip, label1, label2, npart = fMCEvent->GetNumberOfTracks();
750 static AliRsnMiniPair miniPair;
751 AliMCParticle *daughter1, *daughter2;
752 TLorentzVector p1, p2;
753 AliRsnMiniOutput *def = 0x0;
754
755 for (id = 0; id < ndef; id++) {
756 def = (AliRsnMiniOutput*)fHistograms[id];
757 if (!def) continue;
758 if (!def->IsMother()) continue;
759 for (ip = 0; ip < npart; ip++) {
760 AliMCParticle *part = (AliMCParticle*)fMCEvent->GetTrack(ip);
64129b35 761 if (part->Particle()->GetPdgCode() != def->GetMotherPDG()) continue;
03d23846 762 // check that daughters match expected species
763 if (part->Particle()->GetNDaughters() < 2) continue;
764 label1 = part->Particle()->GetDaughter(0);
765 label2 = part->Particle()->GetDaughter(1);
766 daughter1 = (AliMCParticle*)fMCEvent->GetTrack(label1);
767 daughter2 = (AliMCParticle*)fMCEvent->GetTrack(label2);
768 okMatch = kFALSE;
769 if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(1)) {
770 okMatch = kTRUE;
771 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
772 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
773 } else if (TMath::Abs(daughter1->Particle()->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->Particle()->GetPdgCode()) == def->GetPDG(0)) {
774 okMatch = kTRUE;
775 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
776 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
777 }
778 if (!okMatch) continue;
779 // assign momenta to computation object
780 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
781 miniPair.FillRef(def->GetMotherMass());
782 // do computations
45aa62b9 783 def->FillMother(&miniPair, miniEvent, &fValues);
03d23846 784 }
785 }
786}
787
788//__________________________________________________________________________________________________
789void AliRsnMiniAnalysisTask::FillTrueMotherAOD(AliRsnMiniEvent *miniEvent)
790{
791//
792// Fills the histograms with true mother (AOD version)
793//
794
795 Bool_t okMatch;
796 TClonesArray *list = fRsnEvent.GetAODList();
797 Int_t id, ndef = fHistograms.GetEntries();
798 Int_t ip, label1, label2, npart = list->GetEntries();
799 static AliRsnMiniPair miniPair;
800 AliAODMCParticle *daughter1, *daughter2;
801 TLorentzVector p1, p2;
802 AliRsnMiniOutput *def = 0x0;
803
804 for (id = 0; id < ndef; id++) {
805 def = (AliRsnMiniOutput*)fHistograms[id];
806 if (!def) continue;
807 if (!def->IsMother()) continue;
808 for (ip = 0; ip < npart; ip++) {
809 AliAODMCParticle *part = (AliAODMCParticle*)list->At(ip);
64129b35 810 if (part->GetPdgCode() != def->GetMotherPDG()) continue;
03d23846 811 // check that daughters match expected species
812 if (part->GetNDaughters() < 2) continue;
813 label1 = part->GetDaughter(0);
814 label2 = part->GetDaughter(1);
815 daughter1 = (AliAODMCParticle*)list->At(label1);
816 daughter2 = (AliAODMCParticle*)list->At(label2);
817 okMatch = kFALSE;
818 if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(0) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(1)) {
819 okMatch = kTRUE;
820 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(0));
821 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(1));
822 } else if (TMath::Abs(daughter1->GetPdgCode()) == def->GetPDG(1) && TMath::Abs(daughter2->GetPdgCode()) == def->GetPDG(0)) {
823 okMatch = kTRUE;
824 p1.SetXYZM(daughter1->Px(), daughter1->Py(), daughter1->Pz(), def->GetMass(1));
825 p2.SetXYZM(daughter2->Px(), daughter2->Py(), daughter2->Pz(), def->GetMass(0));
826 }
827 if (!okMatch) continue;
828 // assign momenta to computation object
829 miniPair.Sum(0) = miniPair.Sum(1) = (p1 + p2);
830 miniPair.FillRef(def->GetMotherMass());
831 // do computations
45aa62b9 832 def->FillMother(&miniPair, miniEvent, &fValues);
03d23846 833 }
834 }
835}
caef2e3c 836
837//__________________________________________________________________________________________________
838Bool_t AliRsnMiniAnalysisTask::EventsMatch(AliRsnMiniEvent *event1, AliRsnMiniEvent *event2)
839{
840//
841// Check if two events are compatible.
842// If the mixing is continuous, this is true if differences in vz, mult and angle are smaller than
843// the specified values.
844// If the mixing is binned, this is true if the events are in the same bin.
845//
846
847 if (!event1 || !event2) return kFALSE;
848 Int_t ivz1, ivz2, imult1, imult2, iangle1, iangle2;
849
850 if (fContinuousMix) {
851 if (TMath::Abs(event1->Vz() - event2->Vz() ) > fMaxDiffVz ) return kFALSE;
852 if (TMath::Abs(event1->Mult() - event2->Mult() ) > fMaxDiffMult ) return kFALSE;
853 if (TMath::Abs(event1->Angle() - event2->Angle()) > fMaxDiffAngle) return kFALSE;
854 return kTRUE;
855 } else {
856 ivz1 = (Int_t)(event1->Vz() / fMaxDiffVz);
857 ivz2 = (Int_t)(event2->Vz() / fMaxDiffVz);
858 imult1 = (Int_t)(event1->Mult() / fMaxDiffMult);
859 imult2 = (Int_t)(event2->Mult() / fMaxDiffMult);
860 iangle1 = (Int_t)(event1->Angle() / fMaxDiffAngle);
861 iangle2 = (Int_t)(event2->Angle() / fMaxDiffAngle);
862 if (ivz1 != ivz2) return kFALSE;
863 if (imult1 != imult2) return kFALSE;
864 if (iangle1 != iangle2) return kFALSE;
865 return kTRUE;
866 }
867}
868
869