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