]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG/muon/AliAnalysisTaskMuMu.cxx
Changed the IntegratedLuminosity signature to allow for more flexibility (Laurent)
[u/mrichter/AliRoot.git] / PWG / muon / AliAnalysisTaskMuMu.cxx
CommitLineData
2f331ac9 1#include "AliAnalysisTaskMuMu.h"
2
3#include "AliAnalysisManager.h"
4#include "AliCentrality.h"
5#include "AliCounterCollection.h"
6#include "AliHistogramCollection.h"
7#include "AliInputEventHandler.h"
8#include "AliLog.h"
9#include "AliMuonTrackCuts.h"
10#include "Riostream.h"
11#include "TCanvas.h"
12#include "TDatabasePDG.h"
13#include "TFormula.h"
14#include "TH1.h"
15#include "TH2.h"
16#include "THashList.h"
17#include "TList.h"
18#include "TMath.h"
19#include "TObjString.h"
20#include "TPaveText.h"
21#include "TROOT.h"
22#include <algorithm>
23#include "AliAODEvent.h"
24#include "AliESDEvent.h"
25#include "AliESDMuonTrack.h"
26#include "AliAODTrack.h"
27#include "AliAODTZERO.h"
28#include "AliESDTZERO.h"
29#include "AliCodeTimer.h"
30
31//
32// AliAnalysisTaskMuMu : base class for mu pairs analysis
33//
34// Mainly invariant mass (for J/psi and Upsilon) but also
35// some single control histograms.
36//
37// This base class contains common things for ESD-based
38// and AOD-based analysis
39//
40// The output contains an AliHistogramCollection and
41// an AliCounterCollection
42//
43// author: L. Aphecetche (Subatech)
44//
45
46using std::cout;
47using std::endl;
48
49ClassImp(AliAnalysisTaskMuMu)
50ClassImp(AliAnalysisTaskMuMu::PairCut)
51
52namespace
53{
54 Int_t GetNbins(Double_t xmin, Double_t xmax, Double_t xstep)
55 {
56 if ( TMath::AreEqualRel(xstep,0.0,1E-9) ) return 1;
57
58 return TMath::Nint(TMath::Abs((xmax-xmin)/xstep));
59 }
60
61 TObjArray* GetMuonTriggerList()
62 {
63 TObjArray* a = new TObjArray;
64 a->SetOwner(kTRUE);
65
66 a->Add(new TObjString("CMUL"));
67 a->Add(new TObjString("CMLL"));
68 a->Add(new TObjString("C0MUL"));
69 a->Add(new TObjString("CMSL"));
70 a->Add(new TObjString("CMSH"));
71
72 return a;
73 }
74
75 TObjArray* GetEmcalTriggerList()
76 {
77 TObjArray* a = new TObjArray;
78 a->SetOwner(kTRUE);
79
80 a->Add(new TObjString("CEMC"));
81
82 return a;
83 }
84
85 TObjArray* GetMBTriggerList()
86 {
87 TObjArray* a = new TObjArray;
88 a->SetOwner(kTRUE);
89
90 a->Add(new TObjString("CINT7-S-"));
91 a->Add(new TObjString("CINT8-S-"));
92
93 return a;
94 }
95
96}
97
98//_____________________________________________________________________________
99void AliAnalysisTaskMuMu::PairCut::Print(Option_t* /*opt*/) const
100{
101 std::cout << Form("PAIR CUT %20s SINGLE MASK %x PAIR MASK %x",GetName(),MaskForOneOrBothTrack(),MaskForTrackPair())
102 << std::endl;
103}
104
105//_____________________________________________________________________________
106AliAnalysisTaskMuMu::AliAnalysisTaskMuMu() : AliAnalysisTaskSE("AliAnalysisTaskMuMu"),
107fOutput(0),
108fHistogramCollection(0),
109fEventCounters(0),
110fMuonTrackCuts(0x0),
111fPrecomputedTrackMasks(),
112fIsFromESD(kFALSE),
113fIsDynamicTriggerClasses(kFALSE),
114fShouldSeparatePlusAndMinus(kFALSE),
115fIsHistogrammingDisabled(kFALSE),
116fBeamYear("pp"),
117fCentralityLimits(),
118fTriggerClasses(0),
119fSingleTrackCutNames(0x0),
120fPairTrackCutNames(0x0),
121fCentralityNames(0x0),
122fEventCutNames(0x0),
123fUseBackgroundTriggers(kFALSE)
124{
125 /// default ctor
126}
127
128//_____________________________________________________________________________
129AliAnalysisTaskMuMu::AliAnalysisTaskMuMu(Bool_t fromESD, const char* beamYear, TArrayF* centralities)
130: AliAnalysisTaskSE(Form("AliAnalysisTaskMuMu-from%s",fromESD ? "ESD":"AOD")),
131fOutput(0),
132fHistogramCollection(0),
133fEventCounters(0),
134fMuonTrackCuts(0x0),
135fPrecomputedTrackMasks(),
136fIsFromESD(fromESD),
137fIsDynamicTriggerClasses(kTRUE),
138fShouldSeparatePlusAndMinus(kFALSE),
139fIsHistogrammingDisabled(kFALSE),
140fBeamYear(beamYear),
141fCentralityLimits(),
142fTriggerClasses(new THashList),
143fSingleTrackCutNames(0x0),
144fPairTrackCutNames(0x0),
145fCentralityNames(new TObjArray),
146fEventCutNames(0x0),
147fUseBackgroundTriggers(kFALSE)
148{
149 /// Constructor
150 /// The list of triggers to be considered will be updated on the fly
151 /// (see method AddTriggerClasses)
152
153 fTriggerClasses->SetOwner(kTRUE);
154
155 DefineOutput(1, TList::Class());
156
157 DefineCentralityClasses(centralities);
158}
159
160//_____________________________________________________________________________
161AliAnalysisTaskMuMu::AliAnalysisTaskMuMu(Bool_t fromESD, TList* triggerClasses, const char* beamYear, TArrayF* centralities)
162: AliAnalysisTaskSE(Form("AliAnalysisTaskMuMu-from%s",fromESD ? "ESD":"AOD")),
163fOutput(0),
164fHistogramCollection(0),
165fEventCounters(0),
166fMuonTrackCuts(0x0),
167fPrecomputedTrackMasks(),
168fIsFromESD(fromESD),
169fIsDynamicTriggerClasses(kFALSE),
170fShouldSeparatePlusAndMinus(kFALSE),
171fIsHistogrammingDisabled(kFALSE),
172fBeamYear(beamYear),
173fCentralityLimits(),
174fTriggerClasses(new THashList),
175fSingleTrackCutNames(0x0),
176fPairTrackCutNames(0x0),
177fCentralityNames(new TObjArray),
178fEventCutNames(0x0),
179fUseBackgroundTriggers(kFALSE)
180{
181 /// Constructor with a predefined list of triggers to consider
182
183 fTriggerClasses->SetOwner(kTRUE);
184
185 DefineOutput(1, TList::Class());
186
187 TObjString* tname;
188 TIter next(triggerClasses);
189
190 while ( ( tname = static_cast<TObjString*>(next()) ) )
191 {
192 fTriggerClasses->Add(new TObjString(*tname));
193 if ( !beamYear )
194 {
195 if ( tname->String().BeginsWith("CMB") )
196 {
197 fBeamYear = "PbPb2010";
198 }
199 if ( tname->String().BeginsWith("CPBI") )
200 {
201 fBeamYear = "PbPb2011";
202 }
203 }
204 }
205
206 DefineCentralityClasses(centralities);
207}
208
209//_____________________________________________________________________________
210AliAnalysisTaskMuMu::~AliAnalysisTaskMuMu()
211{
212 /// dtor
213
214 if (fOutput && ! AliAnalysisManager::GetAnalysisManager()->IsProofMode())
215 {
216 delete fOutput;
217 }
218
219 delete fMuonTrackCuts;
220
221 delete fTriggerClasses;
222 delete fSingleTrackCutNames;
223 delete fPairTrackCutNames;
224 delete fCentralityNames;
225 delete fEventCutNames;
226}
227
228//_____________________________________________________________________________
229void AliAnalysisTaskMuMu::AddTriggerClasses(const char* triggerlist)
230{
231 /// Given a list of trigger names (triggerlist) separated by spaces
232 /// add those which we don't know yet (selecting only the few ones
233 /// we're interested in, e.g CINT* CMU* CMB*
234 ///
235
236 TString slist(triggerlist);
237
238 TObjArray* a = slist.Tokenize(" ");
239 TObjString* s;
240 TIter next(a);
241
242 while ( ( s = static_cast<TObjString*>(next()) ) )
243 {
244 TString trigger(s->String());
245 Bool_t add(kFALSE);
246
247 if ( trigger.Contains("WU") )
248 {
249 add = kFALSE;
250 continue;
251 }
252
253 // MB triggers
254 if ( trigger.BeginsWith("CMB") && trigger.Contains("-B-") ) add = kTRUE; // MB PbPb 2010
255
256 if ( trigger.BeginsWith("CPBI") && trigger.Contains("-B-") ) add = kTRUE; // MB PbPb 2011
257 if ( trigger.BeginsWith("CVHN") && trigger.Contains("-B-") ) add = kTRUE; // Central PbPb 2011
258 if ( trigger.BeginsWith("CVLN") && trigger.Contains("-B-") ) add = kTRUE; // Semi Central PbPb 2011
259
260 if ( ( trigger.BeginsWith("CINT") /* || trigger.BeginsWith("CTRUE") */ ) && TriggerSBACECondition(trigger) ) add = kTRUE;
261
262 // main muon triggers
263 if ( ( trigger.BeginsWith("CMU") || trigger.BeginsWith("CMS") || trigger.BeginsWith("CML") ) &&
264 TriggerSBACECondition(trigger) ) add = kTRUE;
265
266 // muon triggers not in coincidence with anything else
267 if ( trigger.BeginsWith("C0MUL") ) add = kTRUE;
268
269 /*
270 if ( trigger.BeginsWith("CMUP") ||
271 trigger.BeginsWith("CCUP") )
272 {
273 // discard ultra-peripheral triggers
274 add = kFALSE;
275 }
276 */
277
278 // triggers in Monte-Carlo
279 if ( trigger.BeginsWith("MB") ||
280 trigger.BeginsWith("SC") ||
281 ( trigger.BeginsWith("CE") && !trigger.BeginsWith("CEMC") ) ||
282 trigger.BeginsWith("DMU") ||
283 trigger.BeginsWith("DML") ||
284 trigger.BeginsWith("MU") ||
285 trigger.BeginsWith("CMSNGL") ||
286 trigger.BeginsWith("CMLK") )
287 {
288 add = kTRUE; // for MC
289 }
290
291 if ( add && !fTriggerClasses->FindObject(trigger.Data()) )
292 {
293 AliDebug(1,Form("Adding %s to considered trigger classes",trigger.Data()));
294 fTriggerClasses->Add(new TObjString(trigger));
295 }
296
297 }
298
299 delete a;
300}
301
302//_____________________________________________________________________________
303void AliAnalysisTaskMuMu::AddPairCut(const char* cutName, UInt_t maskForOneOrBothTrack, UInt_t maskForTrackPair)
304{
305 /// Add a cut for a pair.
306 /// maskForOneOrBothTrack is the mask of cuts that at least one track must satisfy
307 /// maskForTrackPair is the mask of cuts that *both* tracks must satisfy.
308 /// if maskForTrackPair is 0, then no (extra) condition is applied to the pair
309
310 if ( !fPairTrackCutNames )
311 {
312 fPairTrackCutNames = new TObjArray;
313 fPairTrackCutNames->SetOwner(kTRUE);
314 }
315 fPairTrackCutNames->Add(new AliAnalysisTaskMuMu::PairCut(cutName,maskForOneOrBothTrack,maskForTrackPair));
316}
317
318//_____________________________________________________________________________
319void AliAnalysisTaskMuMu::AddSingleCut(const char* name, UInt_t mask)
320{
321 /// Add a cut for single tracks
322 if ( !fSingleTrackCutNames )
323 {
324 fSingleTrackCutNames = new TObjArray;
325 fSingleTrackCutNames->SetOwner(kTRUE);
326 }
327 TObjString* oname = new TObjString(Form("s%s",name));
328 oname->SetUniqueID(mask);
329 fSingleTrackCutNames->Add(oname);
330}
331
332//_____________________________________________________________________________
333void AliAnalysisTaskMuMu::AddEventCut(const char* name, UInt_t mask)
334{
335 /// Add a cut at event level
336 if ( !fEventCutNames )
337 {
338 fEventCutNames = new TObjArray;
339 fEventCutNames->SetOwner(kTRUE);
340 }
341 TObjString* oname = new TObjString(Form("%s",name));
342 oname->SetUniqueID(mask);
343 fEventCutNames->Add(oname);
344}
345
346
347//_____________________________________________________________________________
348void AliAnalysisTaskMuMu::AssertHistogramCollection(const char* physics, const char* triggerClassName)
349{
350 // insure that a given set of histogram is created
351 if (!fHistogramCollection->Histo(physics,triggerClassName,DefaultCentralityName(),"Zvertex"))
352 {
353 FillHistogramCollection(physics,triggerClassName);
354 }
355}
356
357//_____________________________________________________________________________
358void AliAnalysisTaskMuMu::BeautifyHistos()
359{
360 /// Put the titles, marker sizes, color, etc...
361
362 TIter next(fHistogramCollection->CreateIterator());
363 TH1* h;
364
365 while ( ( h = static_cast<TH1*>(next()) ) )
366 {
367 TString name(h->GetName());
368
369 if ( name.Contains("Plus") )
370 {
371 h->SetMarkerStyle(kFullCircle);
372 h->SetMarkerColor(kBlue);
373 h->SetLineColor(kBlue);
374 }
375 else
376 {
377 h->SetMarkerStyle(kOpenCircle);
378 h->SetMarkerColor(kRed);
379 h->SetLineColor(kRed);
380 }
381 }
382}
383
384//_____________________________________________________________________________
385const char*
386AliAnalysisTaskMuMu::CentralityName(Double_t centrality) const
387{
388 /// Get centrality name corresponding to the floating ^point value
389
390 if ( centrality > 0 && centrality <= 100.0 )
391 {
392 return Form("CENT%02d",TMath::Nint(centrality));
393 }
394 else
395 {
396 return DefaultCentralityName();
397 }
398}
399
400//_____________________________________________________________________________
401Bool_t
402AliAnalysisTaskMuMu::CheckTriggerClass(const TString& toCheck,
403 const TString& firedTriggerClasses) const
404{
405 // Check if the "toCheck" class (or logical combination of classes)
406 // are within the "firedTriggerClasses"
407
408 Bool_t ok(kFALSE);
409
410 TString tn(toCheck);
411 TString comp("");
412
413 if ( tn.Contains("(") || tn.Contains(")") || tn.Contains("&") || tn.Contains("|") )
414 {
415 comp=tn;
416 tn.ReplaceAll("(","");
417 tn.ReplaceAll(")","");
418 tn.ReplaceAll("&","");
419 tn.ReplaceAll("|","");
420 TObjArray* a = tn.Tokenize(" ");
421 TIter nextA(a);
422 TObjString* an;
423 while ( ( an = static_cast<TObjString*>(nextA()) ) )
424 {
425 // AliDebug(1,Form(" an %s => %d",an->String().Data(),firedTriggerClasses.Contains(an->String().Data())));
426 comp.ReplaceAll(an->String().Data(),Form("%d",firedTriggerClasses.Contains(an->String().Data())));
427 }
428 delete a;
429
430 TFormula formula("TriggerClassFormulaCheck", comp.Data());
431 if (formula.Compile() > 0)
432 {
433 AliError(Form("Could not evaluate formula %s",comp.Data()));
434 }
435 else
436 {
437 ok = formula.Eval(0);
438 }
439 }
440 else
441 {
442 ok = firedTriggerClasses.Contains(toCheck);
443 }
444
445 AliDebug(1,Form("tname %s => %d comp=%s",toCheck.Data(),ok,comp.Data()));
446
447 return ok;
448}
449
450//_____________________________________________________________________________
451void
452AliAnalysisTaskMuMu::CreateSingleHisto(const char* physics,
453 const char* triggerClassName,
454 const char* hname, const char* htitle,
455 Int_t nbinsx, Double_t xmin, Double_t xmax,
456 Int_t nbinsy, Double_t ymin, Double_t ymax,
457 Bool_t separatePlusAndMinus) const
458{
459 /// Append histograms for single track to our histogram collection
460
461 if ( separatePlusAndMinus )
462 {
463 const char* suffix[] = { "Plus", "Minus" };
464 const char* symbol[] = { "+", "-" };
465
466 for ( Int_t i = 0; i < 2; ++i )
467 {
468 TString shtitle(htitle);
469 TString shname(hname);
470
471 shtitle.ReplaceAll("#mu",Form("#mu^{%s}",symbol[i]));
472
473 shname += suffix[i];
474
475 CreateHisto(fSingleTrackCutNames,physics,triggerClassName,shname.Data(),shtitle.Data(),
476 nbinsx,xmin,xmax,nbinsy,ymin,ymax);
477 }
478 }
479 else
480 {
481 CreateHisto(fSingleTrackCutNames,physics,triggerClassName,hname,htitle,
482 nbinsx,xmin,xmax,nbinsy,ymin,ymax);
483 }
484}
485
486//_____________________________________________________________________________
487void
488AliAnalysisTaskMuMu::CreatePairHisto(const char* physics,
489 const char* triggerClassName,
490 const char* hname, const char* htitle,
491 Int_t nbinsx, Double_t xmin, Double_t xmax,
492 Int_t nbinsy, Double_t ymin, Double_t ymax) const
493{
494 /// Append histograms for track pairs to our histogram collection
495
496 CreateHisto(fPairTrackCutNames,physics,triggerClassName,hname,htitle,
497 nbinsx,xmin,xmax,nbinsy,ymin,ymax);
498}
499
500//_____________________________________________________________________________
501void
502AliAnalysisTaskMuMu::CreateEventHisto(const char* physics,
503 const char* triggerClassName,
504 const char* hname, const char* htitle,
505 Int_t nbinsx, Double_t xmin, Double_t xmax,
506 Int_t nbinsy, Double_t ymin, Double_t ymax) const
507{
508 /// Append histograms at the event level
509
510 TIter next(fCentralityNames);
511 TObjString* cent;
512
513 while ( ( cent = static_cast<TObjString*>(next()) ) )
514 {
515 TH1* h(0x0);
516
517 if ( nbinsy > 0 )
518 {
519 h = new TH2F(hname,htitle,nbinsx,xmin,xmax,nbinsy,ymin,ymax);
520 }
521 else
522 {
523 h = new TH1F(hname,htitle,nbinsx,xmin,xmax);
524 }
525
526 fHistogramCollection->Adopt(physics,triggerClassName,cent->String().Data(),h);
527 }
528}
529
530//_____________________________________________________________________________
531void
532AliAnalysisTaskMuMu::CreateHisto(TObjArray* array,
533 const char* physics,
534 const char* triggerClassName,
535 const char* hname, const char* htitle,
536 Int_t nbinsx, Double_t xmin, Double_t xmax,
537 Int_t nbinsy, Double_t ymin, Double_t ymax) const
538{
539 /// Create a bunch of histograms for all centralities
540 /// FIXME: have a way to specify the histo precision (i.e. F vs I vs S ...)
541
542 TIter next(array);
543 TObjString* tcn;
544 while ( ( tcn = static_cast<TObjString*>(next()) ) )
545 {
546 TIter nextCent(fCentralityNames);
547 TObjString* cent;
548
549 while ( ( cent = static_cast<TObjString*>(nextCent()) ) )
550 {
551 TH1* h(0x0);
552
553 if ( nbinsy > 0 )
554 {
555 h = new TH2F(hname,htitle,nbinsx,xmin,xmax,nbinsy,ymin,ymax);
556 }
557 else
558 {
559 h = new TH1F(hname,htitle,nbinsx,xmin,xmax);
560 }
561
562 fHistogramCollection->Adopt(physics,triggerClassName,cent->String().Data(),tcn->String().Data(),h);
563 }
564 }
565}
566
567//_____________________________________________________________________________
568const char*
569AliAnalysisTaskMuMu::DefaultCentralityName() const
570{
571 /// Get default centrality name
572 if ( !fBeamYear.Contains("pp") ) return "CENTX";
573 else return "PP";
574}
575
576//_____________________________________________________________________________
577void AliAnalysisTaskMuMu::DefineCentralityClasses(TArrayF* centralities)
578{
579 /// Define the default centrality classes that will be used.
580
581 if ( !fBeamYear.Contains("pp") )
582 {
583 if ( !centralities )
584 {
585 // default values
586 fCentralityLimits.push_back(10.0);
587 fCentralityLimits.push_back(30.0);
588 fCentralityLimits.push_back(50.0);
589 fCentralityLimits.push_back(80.0);
590 }
591 else
592 {
593 for ( Int_t i = 0; i < centralities->GetSize(); ++i )
594 {
595 fCentralityLimits.push_back(centralities->At(i));
596 }
597 }
598 }
599
600 for ( std::vector<double>::size_type i = 0; i < fCentralityLimits.size(); ++i )
601 {
602 Double_t limit = fCentralityLimits[i];
603 fCentralityNames->Add(new TObjString(CentralityName(limit)));
604 }
605
606 fCentralityNames->Add(new TObjString(DefaultCentralityName()));
607 fCentralityNames->SetOwner(kTRUE);
608}
609
610//_____________________________________________________________________________
611void AliAnalysisTaskMuMu::EAComputeTrackMasks(const AliVEvent& event)
612{
613 // compute the track masks for the event
614
615 fPrecomputedTrackMasks.Reset();
616 Int_t n = EAGetNumberOfMuonTracks(event);
617 fPrecomputedTrackMasks.Set(n);
618
619 if ( event.IsA() == AliESDEvent::Class() )
620 {
621 const AliESDEvent& esd = static_cast<const AliESDEvent&>(event);
622 AliESDEvent& ncesd = const_cast<AliESDEvent&>(esd);
623
624 for ( Int_t i = 0; i < n; ++i )
625 {
626 ComputeTrackMask(*(ncesd.GetMuonTrack(i)),i);
627 }
628 }
629 else if ( event.IsA() == AliAODEvent::Class() )
630 {
631 const AliAODEvent& aod = static_cast<const AliAODEvent&>(event);
632 for ( Int_t i = 0; i < n; ++i )
633 {
634 ComputeTrackMask(*(aod.GetTrack(i)),i);
635 }
636 }
637
638}
639
640//_____________________________________________________________________________
641TString AliAnalysisTaskMuMu::EAGetFiredTriggerClasses(const AliVEvent& event) const
642{
643 // hack (this method should really be part of AliVEvent itself) FIXME
644
645 if ( event.IsA() == AliESDEvent::Class() )
646 {
647 return static_cast<const AliESDEvent&>(event).GetFiredTriggerClasses();
648 }
649 else if ( event.IsA() == AliAODEvent::Class() )
650 {
651 return static_cast<const AliAODEvent&>(event).GetFiredTriggerClasses();
652 }
653 else
654 {
655 AliError(Form("Unknown class for the event = %s",event.ClassName()));
656 return "";
657 }
658}
659
660//_____________________________________________________________________________
661UInt_t AliAnalysisTaskMuMu::EAGetL0TriggerInputs(const AliVEvent& event) const
662{
663 // Get the list of level 0 trigger inputs
664
665 if ( event.IsA() == AliESDEvent::Class() )
666 {
667 return static_cast<const AliESDEvent&>(event).GetNumberOfMuonTracks();
668 }
669 else if ( event.IsA() == AliAODEvent::Class() )
670 {
671 return static_cast<const AliAODEvent&>(event).GetHeader()->GetL0TriggerInputs();
672 }
673 else
674 {
675 AliError(Form("Unknown class for the event = %s",event.ClassName()));
676 return 0;
677 }
678
679 return 0;
680}
681
682//_____________________________________________________________________________
683Int_t AliAnalysisTaskMuMu::EAGetNumberOfMuonTracks(const AliVEvent& event) const
684{
685 // get the number of muon tracks from the event
686 if ( event.IsA() == AliESDEvent::Class() )
687 {
688 return static_cast<const AliESDEvent&>(event).GetNumberOfMuonTracks();
689 }
690 else if ( event.IsA() == AliAODEvent::Class() )
691 {
692 return static_cast<const AliAODEvent&>(event).GetNumberOfTracks();
693 }
694 else
695 {
696 AliError(Form("Unknown class for the event = %s",event.ClassName()));
697 return 0;
698 }
699}
700
701//_____________________________________________________________________________
702AliVParticle* AliAnalysisTaskMuMu::EAGetTrack(const AliVEvent& event, Int_t i) const
703{
704 // get the i-th track from the event
705 if ( event.IsA() == AliESDEvent::Class() )
706 {
707 AliESDMuonTrack* track = static_cast<AliESDEvent&>(const_cast<AliVEvent&>(event)).GetMuonTrack(i);
708 if ( track->ContainTrackerData() )
709 {
710 return track;
711 }
712 return 0x0;
713 }
714 else if ( event.IsA() == AliAODEvent::Class() )
715 {
716 AliAODTrack* part = static_cast<const AliAODEvent&>(event).GetTrack(i);
717 if ( part->IsMuonTrack() )
718 {
719 return part;
720 }
721 return 0x0;
722 }
723 else
724 {
725 AliError(Form("Unknown class for the event = %s",event.ClassName()));
726 }
727 return 0x0;
728}
729
730//_____________________________________________________________________________
731Double_t AliAnalysisTaskMuMu::EAGetTrackDCA(const AliVParticle& track) const
732{
733 // Get track DCA
734
735 Double_t xdca(1E9);
736 Double_t ydca(xdca);
737
738 if ( track.IsA() == AliAODTrack::Class() )
739 {
740 xdca = static_cast<const AliAODTrack&>(track).XAtDCA();
741 ydca = static_cast<const AliAODTrack&>(track).YAtDCA();
742 }
743 else if ( track.IsA() == AliESDMuonTrack::Class() )
744 {
745 xdca = static_cast<const AliESDMuonTrack&>(track).GetNonBendingCoorAtDCA();
746 ydca = static_cast<const AliESDMuonTrack&>(track).GetBendingCoorAtDCA();
747 }
748 else
749 {
750 AliError(Form("Unknown track class: %s",track.ClassName()));
751 }
752
753 return TMath::Sqrt(xdca*xdca+ydca*ydca);
754}
755
756//_____________________________________________________________________________
757Double_t AliAnalysisTaskMuMu::EAGetTrackNormalizedChi2(const AliVParticle& track) const
758{
759 // get the chi2 per NDF of the track
760
761 Double_t chi2(1E9);
762
763 if ( track.IsA() == AliAODTrack::Class() )
764 {
765 chi2 = static_cast<const AliAODTrack&>(track).Chi2perNDF();
766 }
767 else if ( track.IsA() == AliESDMuonTrack::Class() )
768 {
769 chi2 = static_cast<const AliESDMuonTrack&>(track).GetNormalizedChi2();
770 }
771 else
772 {
773 AliError(Form("Unknown track class: %s",track.ClassName()));
774 }
775
776 return chi2;
777
778}
779
780//_____________________________________________________________________________
781Double_t AliAnalysisTaskMuMu::EAGetTrackChi2MatchTrigger(const AliVParticle& track) const
782{
783 /// Get the Chi2 of the matching MCH - MTR
784
785 if ( track.IsA() == AliAODTrack::Class() )
786 {
787 return static_cast<const AliAODTrack&>(track).GetChi2MatchTrigger();
788 }
789 else
790 {
791 return static_cast<const AliESDMuonTrack&>(track).GetChi2MatchTrigger();
792 }
793}
794
795//_____________________________________________________________________________
796Double_t AliAnalysisTaskMuMu::GetTrackTheta(const AliVParticle& track) const
797{
798 // Get track theta (in radian)
799
800 return TMath::ATan(EAGetTrackRabs(track)/AbsZEnd());
801}
802
803//_____________________________________________________________________________
804Double_t AliAnalysisTaskMuMu::EAGetTrackRabs(const AliVParticle& track) const
805{
806 // Get track DCA
807
808 Double_t rabs(1E9);
809
810 if ( track.IsA() == AliAODTrack::Class() )
811 {
812 rabs = static_cast<const AliAODTrack&>(track).GetRAtAbsorberEnd();
813 }
814 else if ( track.IsA() == AliESDMuonTrack::Class() )
815 {
816 rabs = static_cast<const AliESDMuonTrack&>(track).GetRAtAbsorberEnd();
817 }
818 else
819 {
820 AliError(Form("Unknown track class: %s",track.ClassName()));
821 }
822
823 return TMath::ATan(rabs)/AbsZEnd();
824}
825
826//_____________________________________________________________________________
827Bool_t AliAnalysisTaskMuMu::EAGetTZEROFlags(const AliVEvent& event, Bool_t& backgroundFlag, Bool_t& pileupFlag, Bool_t& satelliteFlag) const
828{
829 // get the TZERO decisions
830 // return false if there's no tzero information in this event
831
832 Bool_t rv(kFALSE);
833
834 if ( event.IsA() == AliESDEvent::Class() )
835 {
836 const AliESDTZERO* tzero = static_cast<AliESDEvent&>(const_cast<AliVEvent&>(event)).GetESDTZERO();
837 if ( tzero )
838 {
839 backgroundFlag = tzero->GetBackgroundFlag();
840 pileupFlag = tzero->GetPileupFlag();
841 satelliteFlag = tzero->GetSatellite();
842 rv = kTRUE;
843 }
844 }
845 else if ( event.IsA() == AliAODEvent::Class() )
846 {
847 AliAODTZERO* tzero = static_cast<const AliAODEvent&>(event).GetTZEROData();
848 if ( tzero )
849 {
850 backgroundFlag = tzero->GetBackgroundFlag();
851 pileupFlag = tzero->GetPileupFlag();
852 satelliteFlag = tzero->GetSatellite();
853 rv = kTRUE;
854 }
855 }
856 else
857 {
858 AliError(Form("Unknown class for the event = %s",event.ClassName()));
859 }
860
861 return rv;
862
863}
864
865//_____________________________________________________________________________
866Bool_t
867AliAnalysisTaskMuMu::AtLeastOneMBTrigger(const TString& firedTriggerClasses) const
868{
869 // whether or not we have a least one MB trigger in the fired trigger classes
870 static TObjArray* triggerList = GetMBTriggerList();
871 TIter next(triggerList);
872 TObjString* str;
873
874 while ( ( str = static_cast<TObjString*>(next())))
875 {
876 if ( firedTriggerClasses.Contains(str->String().Data())) return kTRUE;
877 }
878
879 return kFALSE;
880}
881
882//_____________________________________________________________________________
883Bool_t
884AliAnalysisTaskMuMu::AtLeastOneMuonTrigger(const TString& firedTriggerClasses) const
885{
886 // whether or not we have a least one muon trigger in the fired trigger classes
887 static TObjArray* triggerList = GetMuonTriggerList();
888 TIter next(triggerList);
889 TObjString* str;
890
891 while ( ( str = static_cast<TObjString*>(next())))
892 {
893 if ( firedTriggerClasses.Contains(str->String().Data())) return kTRUE;
894 }
895
896 return kFALSE;
897}
898
899//_____________________________________________________________________________
900Bool_t
901AliAnalysisTaskMuMu::AtLeastOneEmcalTrigger(const TString& firedTriggerClasses) const
902{
903 // whether or not we have a least one emcal trigger in the fired trigger classes
904 static TObjArray* triggerList = GetEmcalTriggerList();
905 TIter next(triggerList);
906 TObjString* str;
907
908 while ( ( str = static_cast<TObjString*>(next())))
909 {
910 if ( firedTriggerClasses.Contains(str->String().Data())) return kTRUE;
911 }
912
913 return kFALSE;
914}
915
916//_____________________________________________________________________________
917void AliAnalysisTaskMuMu::Fill(const char* eventtype,
918 TObjString* tname,
919 const char* centrality,
920 float fcent,
921 const AliVEvent& event)
922{
923 // Fill one set of histograms
924
925 TString seventtype(eventtype);
926 seventtype.ToLower();
927
928 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", seventtype.Data(), tname->GetName(), fCurrentRunNumber));
929
930 if ( !IsHistogrammingDisabled() )
931 {
932 AssertHistogramCollection(eventtype,tname->String().Data());
933 FillHistos(eventtype,tname->String().Data(),centrality,event);
934 fHistogramCollection->Histo(eventtype,tname->String().Data(),"Centrality")->Fill(fcent);
935 }
936}
937
938//_____________________________________________________________________________
939void AliAnalysisTaskMuMu::FillHistogramCollection(const char* physics, const char* triggerClassName)
940{
941 /// Actually create the histograms for phyics/triggerClassName
942
943 AliDebug(1,Form("(%s,%s)",physics,triggerClassName));
944
945 Double_t ptMin = 0;
946 Double_t ptMax = 12*3;
947 Int_t nbinsPt = GetNbins(ptMin,ptMax,0.5);
948 Double_t pMin = 0;
949 Double_t pMax = 100*3;
950 Int_t nbinsP = GetNbins(pMin,pMax,2.0);
951 Double_t etaMin = -5;
952 Double_t etaMax = -2;
953 Int_t nbinsEta = GetNbins(etaMin,etaMax,0.05);
954
955 Double_t rapidityMin = -5;
956 Double_t rapidityMax = -2;
957 Int_t nbinsRapidity = GetNbins(rapidityMin,rapidityMax,0.05);
958
959 CreateSingleHisto(physics,triggerClassName,"Chi2MatchTrigger","Chi2 Match Trigger",72,0,72);
960
961 CreateSingleHisto(physics,triggerClassName,"EtaRapidityMu", "Eta distribution vs Rapidity for #mu", nbinsRapidity,rapidityMin,rapidityMax,nbinsEta,etaMin,etaMax, fShouldSeparatePlusAndMinus);
962
963 CreateSingleHisto(physics,triggerClassName,"PtEtaMu", "P_{T} distribution vs Eta for #mu", nbinsEta,etaMin,etaMax, nbinsPt,ptMin,ptMax,fShouldSeparatePlusAndMinus);
964
965 CreateSingleHisto(physics,triggerClassName,"PtRapidityMu", "P_{T} distribution vs Rapidity for #mu", nbinsRapidity,rapidityMin,rapidityMax, nbinsPt,ptMin,ptMax,fShouldSeparatePlusAndMinus);
966
967 CreateSingleHisto(physics,triggerClassName,"PEtaMu", "P distribution for #mu",nbinsEta,etaMin,etaMax,nbinsP,pMin,pMax,fShouldSeparatePlusAndMinus);
968
969 Double_t chi2min = 0;
970 Double_t chi2max = 20;
971 Int_t nbinchi2 = GetNbins(chi2min,chi2max,0.05);
972
973 CreateSingleHisto(physics, triggerClassName, "Chi2Mu", "chisquare per NDF #mu", nbinchi2, chi2min, chi2max,fShouldSeparatePlusAndMinus);
974
975 Double_t minvMin = 0;
976 Double_t minvMax = 16;
977 Int_t nMinvBins = GetNbins(minvMin,minvMax,0.025);
978
979 CreatePairHisto(physics,triggerClassName,"Chi12","Chi2MatchTrigger of muon 1 vs muon 2",72,0,72,72,0,72);
980 CreatePairHisto(physics,triggerClassName,"Rabs12","Rabs of muon 1 vs muon ",100,0,100,100,0,100);
981
982 CreatePairHisto(physics,triggerClassName,"MinvUSPt", "#mu+#mu- inv. mass vs Pt",nbinsPt,ptMin,ptMax,nMinvBins,minvMin,minvMax);
983 CreatePairHisto(physics,triggerClassName,"MinvUSRapidity", "#mu+#mu- inv. mass vs rapidity",nbinsRapidity,rapidityMin,rapidityMax,nMinvBins,minvMin,minvMax);
984 CreatePairHisto(physics,triggerClassName,"USPtRapidity", "#mu+#mu- Pt vs Rapidity",nbinsRapidity,rapidityMin,rapidityMax,nbinsPt,ptMin,ptMax);
985
986 CreatePairHisto(physics,triggerClassName,"MinvLSPt", "unlike sign inv. mass vs Pt",nbinsPt,ptMin,ptMax,nMinvBins,minvMin,minvMax);
987
988 Double_t xmin = -40;
989 Double_t xmax = +40;
990 Int_t nbins = GetNbins(xmin,xmax,0.5);
991
992 CreateEventHisto(physics,triggerClassName,"Zvertex","z vertex",nbins,xmin,xmax);
993
994 xmin = -5;
995 xmax = 5;
996 nbins = GetNbins(xmin,xmax,0.01);
997
998 CreateEventHisto(physics,triggerClassName,"Xvertex","x vertex",nbins,xmin,xmax);
999 CreateEventHisto(physics,triggerClassName,"Yvertex","y vertex",nbins,xmin,xmax);
1000
1001// CreateEventHisto(physics,triggerClassName,"YXvertex","y vs x vertex",nbins,xmin,xmax,nbins,xmin,xmax);
1002
1003// if (!fIsFromESD)
1004// {
1005//
1006// CreateEventHisto(physics,triggerClassName,"PileUpZvertex","pileup z vertex",nbins,xmin,xmax);
1007//
1008// CreateEventHisto(physics,triggerClassName,"PileUpXvertex","pileup x vertex",nbins,xmin,xmax);
1009// CreateEventHisto(physics,triggerClassName,"PileUpYvertex","pileup y vertex",nbins,xmin,xmax);
1010//
1011// CreateEventHisto(physics,triggerClassName,"PileUpYXvertex","pileup y vs x vertex",nbins,xmin,xmax,
1012// nbins,xmin,xmax);
1013//
1014// }
1015
1016 CreateEventHisto(physics,triggerClassName,"Nevents","number of events",2,-0.5,1.5);
1017
1018 xmin = 0;
1019 xmax = 3564;
1020 nbins = GetNbins(xmin,xmax,1.0);
1021
1022 CreateEventHisto(physics,triggerClassName,"BCX","bunch-crossing ids",nbins,xmin-0.5,xmax-0.5);
1023
1024 CreateEventHisto(physics,triggerClassName,"BCXD","bunch-crossing distances",nbins,xmin-0.5,xmax-0.5);
1025
1026 xmin = -200;
1027 xmax = +200;
1028 nbins = GetNbins(xmin,xmax,1.0);
1029
1030 xmin = 0;
1031 xmax = 150;
1032 nbins = GetNbins(xmin,xmax,2.0);
1033
1034 CreateSingleHisto(physics,triggerClassName,"dcaP23Mu","#mu DCA vs P for 2-3 degrees;P (GeV);DCA (cm)",nbinsP,pMin,pMax,nbins,xmin,xmax,fShouldSeparatePlusAndMinus);
1035
1036 CreateSingleHisto(physics,triggerClassName,"dcaP310Mu","#mu DCA vs P for 3-10 degrees;P (GeV);DCA (cm)",nbinsP,pMin,pMax,nbins,xmin,xmax,fShouldSeparatePlusAndMinus);
1037
1038 CreateSingleHisto(physics,triggerClassName,"dcaPwPtCut23Mu","#mu DCA vs P for 2-3 degrees with Pt Cut;P (GeV);DCA (cm)",nbinsP,pMin,pMax,nbins,xmin,xmax,fShouldSeparatePlusAndMinus);
1039
1040 CreateSingleHisto(physics,triggerClassName,"dcaPwPtCut310Mu","#mu DCA vs P for 3-10 degrees with Pt Cut;P (GeV);DCA (cm)",nbinsP,pMin,pMax,nbins,xmin,xmax,fShouldSeparatePlusAndMinus);
1041
1042 xmin = -30;
1043 xmax = +30;
1044 nbins = GetNbins(xmin,xmax,0.1);
1045
1046 CreateEventHisto(physics,triggerClassName,"V02D","V0C+V0A versus V0A-V0C;Time V0A - V0C (ns);Time V0A+V0C (ns)",nbins,xmin,xmax,nbins,xmin,xmax);
1047
1048 CreateEventHisto(physics,triggerClassName,"V02DwT0BB","V0C+V0A versus V0A-V0C with T0 BB;Time V0A - V0C (ns);Time V0A+V0C (ns)",nbins,xmin,xmax,nbins,xmin,xmax);
1049
1050 CreateEventHisto(physics,triggerClassName,"V02DwT0BG","V0C+V0A versus V0A-V0C with T0 background flag on;Time V0A - V0C (ns);Time V0A+V0C (ns)",nbins,xmin,xmax,nbins,xmin,xmax);
1051
1052 CreateEventHisto(physics,triggerClassName,"V02DwT0PU","V0C+V0A versus V0A-V0C with T0 pile up flag on;Time V0A - V0C (ns);Time V0A+V0C (ns)",nbins,xmin,xmax,nbins,xmin,xmax);
1053
1054 CreateEventHisto(physics,triggerClassName,"V02DwT0SAT","V0C+V0A versus V0A-V0C with T0 satellite flag on;Time V0A - V0C (ns);Time V0A+V0C (ns)",nbins,xmin,xmax,nbins,xmin,xmax);
1055
1056 /*
1057 CreateEventHisto(physics,triggerClassName,"T02D","(T0C+T0A)/2 versus (T0A-T0C)/2;Time (T0A-T0C)/2 (ns);Time (T0A+T0C)/2 (ns)",nbins,xmin,xmax,nbins,xmin,xmax);
1058 CreateEventHisto(physics,triggerClassName,"T0Flags","T0 flags",3,0,3);
1059 */
1060
1061
1062 TH1* h = new TH1F("Centrality","Centrality",12,-10,110);
1063
1064 fHistogramCollection->Adopt(physics,triggerClassName,h);
1065
1066 xmin = 0;
1067 xmax = 5000;
1068 nbins = GetNbins(xmin,xmax,10);
1069
1070 CreateEventHisto(physics,triggerClassName,"Tracklets","Number of tracklets",nbins,xmin,xmax);
1071
1072}
1073
1074//_____________________________________________________________________________
1075void AliAnalysisTaskMuMu::FillHistosForTrack(const char* physics,
1076 const char* triggerClassName,
1077 const char* centrality,
1078 const AliVParticle& track,
1079 Int_t trackIndex)
1080{
1081 /// Fill histograms for one track
1082
1083 TLorentzVector p(track.Px(),track.Py(),track.Pz(),
1084 TMath::Sqrt(MuonMass2()+track.P()*track.P()));
1085
1086
1087 TString charge("");
1088
1089 if ( ShouldSeparatePlusAndMinus() )
1090 {
1091 if ( track.Charge() < 0 )
1092 {
1093 charge = "Minus";
1094 }
1095 else
1096 {
1097 charge = "Plus";
1098 }
1099 }
1100
1101 UInt_t mask = GetTrackMask(trackIndex);
1102
1103 Double_t dca = EAGetTrackDCA(track);
1104
1105 Double_t theta = GetTrackTheta(track);
1106
1107 TIter next(fSingleTrackCutNames);
1108 TObjString* str;
1109
1110 while ( ( str = static_cast<TObjString*>(next()) ) )
1111 {
1112 Bool_t test = ( ( str->GetUniqueID() & mask ) == str->GetUniqueID() );
1113
1114 if ( test )
1115 {
1116 Histo(physics,triggerClassName,centrality,str->String().Data(),"Chi2MatchTrigger")->Fill(EAGetTrackChi2MatchTrigger(track));
1117
1118 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("EtaRapidityMu%s",charge.Data()))->Fill(p.Rapidity(),p.Eta());
1119
1120 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("PtEtaMu%s",charge.Data()))->Fill(p.Eta(),p.Pt());
1121 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("PtRapidityMu%s",charge.Data()))->Fill(p.Rapidity(),p.Pt());
1122
1123 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("PEtaMu%s",charge.Data()))->Fill(p.Eta(),p.P());
1124
1125
1126 // Histo(physics,triggerClassName,centrality,str->String().Data(),Form("XYdcaMu%s",charge.Data()))->Fill(ydca,xdca);
1127
1128 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("Chi2Mu%s",charge.Data()))->Fill(EAGetTrackNormalizedChi2(track));
1129
1130 if ( theta >= Deg2() && theta < Deg3() )
1131 {
1132 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("dcaP23Mu%s",charge.Data()))->Fill(p.P(),dca);
1133 if ( p.Pt() > 2 )
1134 {
1135 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("dcaPwPtCut23Mu%s",charge.Data()))->Fill(p.P(),dca);
1136 }
1137 }
1138 else if ( theta >= Deg3() && theta < Deg10() )
1139 {
1140 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("dcaP310Mu%s",charge.Data()))->Fill(p.P(),dca);
1141 if ( p.Pt() > 2 )
1142 {
1143 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("dcaPwPtCut310Mu%s",charge.Data()))->Fill(p.P(),dca);
1144 }
1145 }
1146 }
1147 }
1148
1149
1150}
1151
1152//_____________________________________________________________________________
1153void AliAnalysisTaskMuMu::FillHistos(const char* physics, const char* triggerClassName,
1154 const char* centrality, const AliVEvent& event)
1155{
1156 /// Fill histograms for /physics/triggerClassName/centrality
1157
1158 Histo(physics,triggerClassName,centrality,"BCX")->Fill(1.0*event.GetBunchCrossNumber());
1159
1160 Histo(physics,triggerClassName,centrality,"Nevents")->Fill(1.0);
1161
1162 const AliVVertex* vertex = event.GetPrimaryVertex();
1163
1164 if ( vertex )
1165 {
1166 Histo(physics,triggerClassName,centrality,"Xvertex")->Fill(vertex->GetX());
1167 Histo(physics,triggerClassName,centrality,"Yvertex")->Fill(vertex->GetY());
1168 Histo(physics,triggerClassName,centrality,"Zvertex")->Fill(vertex->GetZ());
1169 }
1170
1171 AliVVZERO* vzero = event.GetVZEROData();
1172
1173 if (vzero)
1174 {
1175 Float_t v0a = vzero->GetV0ATime();
1176 Float_t v0c = vzero->GetV0CTime();
1177
1178 Float_t x = v0a-v0c;
1179 Float_t y = v0a+v0c;
1180
1181 Histo(physics,triggerClassName,centrality,"V02D")->Fill(x,y);
1182
1183 Bool_t background,pileup,satellite;
1184
1185 Bool_t tzero = EAGetTZEROFlags(event,background,pileup,satellite);
1186
1187 if (tzero)
1188 {
1189 if ( background )
1190 {
1191 Histo(physics,triggerClassName,centrality,"V02DwT0BG")->Fill(x,y);
1192 }
1193
1194 if ( pileup )
1195 {
1196 Histo(physics,triggerClassName,centrality,"V02DwT0PU")->Fill(x,y);
1197 }
1198
1199 if ( satellite )
1200 {
1201 Histo(physics,triggerClassName,centrality,"V02DwT0SAT")->Fill(x,y);
1202 }
1203
1204 if ( !background && !pileup && !satellite )
1205 {
1206 Histo(physics,triggerClassName,centrality,"V02DwT0BB")->Fill(x,y);
1207 }
1208 }
1209 }
1210
1211 /* FIXME : how to properly get multiplicity from AOD and ESD consistently ?
1212 is is doable at all ?
1213 Int_t ntracklets(0);
1214 AliAODTracklets* tracklets = aod.GetTracklets();
1215 if ( tracklets )
1216 {
1217 ntracklets = tracklets->GetNumberOfTracklets();
1218 }
1219 Histo(physics,triggerClassName,centrality,"Tracklets")->Fill(ntracklets);
1220 */
1221
1222 // Track loop
1223
1224 Int_t nMuonTracks = EAGetNumberOfMuonTracks(event);
1225
1226 for (Int_t i = 0; i < nMuonTracks; ++i)
1227 {
1228 AliVParticle* tracki = EAGetTrack(event,i);
1229
1230 if (!tracki) continue;
1231
1232 FillHistosForTrack(physics,triggerClassName,centrality,*tracki,i);
1233
1234 TLorentzVector pi(tracki->Px(),tracki->Py(),tracki->Pz(),
1235 TMath::Sqrt(MuonMass2()+tracki->P()*tracki->P()));
1236
1237 for (Int_t j = i+1; j < nMuonTracks; ++j)
1238 {
1239 AliVParticle* trackj = EAGetTrack(event,j);
1240
1241 if (!trackj) continue;
1242
1243 TLorentzVector pj(trackj->Px(),trackj->Py(),trackj->Pz(),
1244 TMath::Sqrt(MuonMass2()+trackj->P()*trackj->P()));
1245
1246 pj += pi;
1247
1248 TIter next(fPairTrackCutNames);
1249 AliAnalysisTaskMuMu::PairCut* str;
1250
1251 UInt_t maski(0),maskj(0),maskij(0);
1252
1253 GetPairMask(*tracki,*trackj,i,j,maski,maskj,maskij);
1254
1255 while ( ( str = static_cast<AliAnalysisTaskMuMu::PairCut*>(next()) ) )
1256 {
1257 UInt_t singleTrackMask = str->MaskForOneOrBothTrack();
1258 UInt_t pairMask = str->MaskForTrackPair();
1259
1260 Bool_t testi = ( ( maski & singleTrackMask ) == singleTrackMask ) ;
1261 Bool_t testj = ( ( maskj & singleTrackMask ) == singleTrackMask ) ;
1262 Bool_t testij(kTRUE);
1263
1264 if (pairMask>0) testij = ( ( maskij & pairMask ) == pairMask ) ;
1265
1266 if ( ( testi || testj ) && testij )
1267 {
1268 Histo(physics,triggerClassName,centrality,str->GetName(),"Chi12")->Fill(EAGetTrackChi2MatchTrigger(*tracki),
1269 EAGetTrackChi2MatchTrigger(*trackj));
1270
1271 Histo(physics,triggerClassName,centrality,str->GetName(),"Rabs12")->Fill(EAGetTrackRabs(*tracki),
1272 EAGetTrackRabs(*trackj));
1273
1274 if ( tracki->Charge() != trackj->Charge() )
1275 {
1276 Histo(physics,triggerClassName,centrality,str->GetName(),"MinvUSPt")->Fill(pj.Pt(),pj.M());
1277 Histo(physics,triggerClassName,centrality,str->GetName(),"MinvUSRapidity")->Fill(pj.Rapidity(),pj.M());
1278 Histo(physics,triggerClassName,centrality,str->GetName(),"USPtRapidity")->Fill(pj.Rapidity(),pj.Pt());
1279 }
1280 else
1281 {
1282 Histo(physics,triggerClassName,centrality,str->GetName(),"MinvLSPt")->Fill(pj.Pt(),pj.M());
1283 }
1284 }
1285 }
1286 }
1287 } //track loop
1288}
1289
1290//_____________________________________________________________________________
1291void AliAnalysisTaskMuMu::FinishTaskOutput()
1292{
1293 /// prune empty histograms BEFORE mergin, in order to save some bytes...
1294
1295 if ( fHistogramCollection )
1296 {
1297 fHistogramCollection->PruneEmptyHistograms();
1298 }
1299}
1300
1301//_____________________________________________________________________________
1302UInt_t AliAnalysisTaskMuMu::GetEventMask(const AliVEvent& event) const
1303{
1304 /// Compute the event mask
1305
1306 /*
1307
1308 kEventAll = all events
1309 kEventPS = physics selected events
1310 kEventTVX = events with 0TVX input present
1311 kEventV0AND = events with 0VBA and 0VBC present
1312 kEventV0UP = a check of events within a narrow square range of v0a+c vs v0a-c
1313 kEventZSPD = events with a vertex computed by SPD
1314 kEventZ7 = events with | zvertex | < 7cm
1315 kEventZ10 = events with | zvertex | < 10 cm
1316 kEventSD2 = events with 0SD2 input present (was for PbPb 2010)
1317
1318 */
1319
1320 UInt_t m(AliAnalysisTaskMuMu::kEventAll);
1321
1322 if ( PassPhysicsSelection() ) m |= AliAnalysisTaskMuMu::kEventPS;
1323
1324 UInt_t trigger = EAGetL0TriggerInputs(event);
1325
1326 UInt_t l0TVXBIT = (1<<3); // 0TVX FIXME: get this number (3) from the CTP config !
1327
1328 if ( ( trigger & (l0TVXBIT) ) == l0TVXBIT )
1329 {
1330 m |= AliAnalysisTaskMuMu::kEventTVX;
1331 }
1332
1333 UInt_t l0VBABIT = (1<<0); // 0VBA FIXME: get this number (0) from the CTP config !
1334 UInt_t l0VBCBIT = (1<<1); // 0VBC FIXME: get this number (1) from the CTP config !
1335
1336 if ( ( ( trigger & (l0VBABIT ) ) == l0VBABIT ) &&
1337 ( ( trigger & (l0VBCBIT ) ) == l0VBCBIT ) )
1338 {
1339 m |= AliAnalysisTaskMuMu::kEventV0AND;
1340 }
1341
1342 if ( fBeamYear == "PbPb2010" )
1343 {
1344 // consider only events with OSM2 fired
1345 UInt_t sd2 = (1<<12);
1346 if ( ( trigger & sd2 ) == sd2 )
1347 {
1348 m |= AliAnalysisTaskMuMu::kEventSD2;
1349 }
1350 }
1351
1352 // Bool_t hasPileUp = aod->IsPileupFromSPD(3,0.8);
1353 // Bool_t hasPileUp2 = aod->IsPileupFromSPD(5,0.8);
1354 // Bool_t isIsolated = ( aod->GetBunchCrossNumber() > 1000 && aod->GetBunchCrossNumber() < 2900 );
1355
1356 // Bool_t hasPileUp2 = aod->IsPileupFromSPDInMultBins();
1357
1358 // TIter nextV(aod->GetVertices());
1359 // AliAODVertex* v;
1360 // while ( ( v = static_cast<AliAODVertex*>(nextV())) && !hasPileUp2 )
1361 // {
1362 // if ( v->GetType() == AliAODVertex::kPileupSPD ) hasPileUp2 = kTRUE;
1363 // }
1364
1365 // Bool_t isIsolated = false;//( aod->GetClosestBunchCrossingDistance() > 10 );
1366
1367 const AliVVertex* vertex = event.GetPrimaryVertex();
1368
1369 if ( vertex->IsA() == AliAODVertex::Class() )
1370 {
1371 AliAODVertex* spdVertex = static_cast<const AliAODEvent&>(event).GetPrimaryVertexSPD();
1372
1373 if ( spdVertex && spdVertex->GetNContributors() > 0 )
1374 {
1375 m |= AliAnalysisTaskMuMu::kEventZSPD;
1376 }
1377 }
1378
1379 if ( TMath::Abs(vertex->GetZ()) < 10.0 )
1380 {
1381 m |= AliAnalysisTaskMuMu::kEventZ10;
1382 }
1383
1384 if ( TMath::Abs(vertex->GetZ()) < 7.0 )
1385 {
1386 m |= AliAnalysisTaskMuMu::kEventZ7;
1387 }
1388
1389 AliVVZERO* vzero = event.GetVZEROData();
1390
1391 if (vzero)
1392 {
1393 Float_t v0a = vzero->GetV0ATime();
1394 Float_t v0c = vzero->GetV0CTime();
1395
1396 Float_t x = v0a-v0c;
1397 Float_t y = v0a+v0c;
1398
1399 if ( ( x > 6 && x < 10 ) && y > 20 )
1400 {
1401 m |= AliAnalysisTaskMuMu::kEventV0UP;
1402 }
1403 }
1404
1405 return m;
1406}
1407
1408
1409//_____________________________________________________________________________
1410void AliAnalysisTaskMuMu::GetPairMask(const AliVParticle& t1, const AliVParticle& t2,
1411 Int_t trackIndex1, Int_t trackIndex2,
1412 UInt_t& mask1, UInt_t& mask2,
1413 UInt_t& mask12) const
1414{
1415 /// Get the mask of the track pair
1416
1417 mask1 = GetTrackMask(trackIndex1);
1418 mask2 = GetTrackMask(trackIndex2);
1419
1420 mask12 = mask1 & mask2;
1421
1422 if ( PairRapidityCut(t1,t2) ) mask12 |= kPairRapidity;
1423}
1424
1425//_____________________________________________________________________________
1426UInt_t AliAnalysisTaskMuMu::GetTrackMask(Int_t trackIndex) const
1427{
1428 /// Get the mask of all the cuts this track pass
1429
1430 return static_cast<UInt_t>(fPrecomputedTrackMasks.At(trackIndex));
1431}
1432
1433//_____________________________________________________________________________
1434void AliAnalysisTaskMuMu::ComputeTrackMask(const AliVParticle& track, Int_t trackIndex)
1435{
1436 // Compute the track mask
1437 UInt_t m(kAll);
1438
1439 UInt_t selectionMask = fMuonTrackCuts ? fMuonTrackCuts->GetSelectionMask(&track) : 0;
1440
1441 if ( ( selectionMask & AliMuonTrackCuts::kMuThetaAbs ) == AliMuonTrackCuts::kMuThetaAbs ) m |= kRabs;
1442
1443 Double_t angle = GetTrackTheta(track);
1444
1445 if ( angle >= Deg2() && angle < Deg3() ) m |= kDeg23;
1446
1447 if ( angle >= Deg3() && angle < Deg10() ) m |= kDeg310;
1448
1449 if ( selectionMask & AliMuonTrackCuts::kMuEta ) m |= kEta;
1450
1451 Double_t pt = track.Pt();
1452
1453 if ( pt > 1.0 ) m |= kPt1;
1454 if ( pt > 1.2 ) m |= kPt1dot2;
1455 if ( pt > 1.5 ) m |= kPt1dot5;
1456 if ( pt > 2.0 ) m |= kPt2;
1457
1458 if ( track.P() > 10.0 ) m |= kP10;
1459
1460 if ( pt < 4.0 ) m |= kBelowPt;
1461
1462 if ( ( selectionMask & AliMuonTrackCuts::kMuMatchApt ) == AliMuonTrackCuts::kMuMatchApt ) m |= kMatched;
1463
1464 if ( ( selectionMask & AliMuonTrackCuts::kMuMatchLpt ) == AliMuonTrackCuts::kMuMatchLpt ) m |= kMatchedLow;
1465
1466 if ( ( selectionMask & AliMuonTrackCuts::kMuMatchHpt ) == AliMuonTrackCuts::kMuMatchHpt) m |= kMatchedHigh;
1467
1468 if ( ( selectionMask & AliMuonTrackCuts::kMuTrackChiSquare ) == AliMuonTrackCuts::kMuTrackChiSquare ) m |= kChi2;
1469
1470 if ( ( selectionMask & AliMuonTrackCuts::kMuPdca ) == AliMuonTrackCuts::kMuPdca ) m |= kDCA;
1471
1472 if ( EAGetTrackChi2MatchTrigger(track) < 16.0 ) m |= kChi2MatchTrigger;
1473
1474 fPrecomputedTrackMasks.SetAt(m,trackIndex);
1475}
1476
1477
1478//_____________________________________________________________________________
1479TH1* AliAnalysisTaskMuMu::Histo(const char* physics, const char* triggerClassName, const char* histoname)
1480{
1481 /// Get one histo back
1482 return fHistogramCollection ? fHistogramCollection->Histo(physics,triggerClassName,histoname) : 0x0;
1483}
1484
1485//_____________________________________________________________________________
1486TH1* AliAnalysisTaskMuMu::Histo(const char* physics, const char* histoname)
1487{
1488 /// Get one histo back
1489 return fHistogramCollection ? fHistogramCollection->Histo(physics,histoname) : 0x0;
1490}
1491
1492//_____________________________________________________________________________
1493TH1* AliAnalysisTaskMuMu::Histo(const char* physics,
1494 const char* triggerClassName,
1495 const char* what,
1496 const char* histoname)
1497{
1498 /// Get one histo back
1499 return fHistogramCollection ? fHistogramCollection->Histo(physics,triggerClassName,what,histoname) : 0x0;
1500}
1501
1502//_____________________________________________________________________________
1503TH1* AliAnalysisTaskMuMu::Histo(const char* physics,
1504 const char* triggerClassName,
1505 const char* cent,
1506 const char* what,
1507 const char* histoname)
1508{
1509 /// Get one histo back
1510
1511 return fHistogramCollection ? fHistogramCollection->Histo(physics,triggerClassName,cent,what,histoname) : 0x0;
1512}
1513
1514//_____________________________________________________________________________
1515Bool_t AliAnalysisTaskMuMu::IsPP() const
1516{
1517 // whether we're dealing with proton proton collisions
1518 return fBeamYear.Contains("pp");
1519}
1520
1521//_____________________________________________________________________________
1522void AliAnalysisTaskMuMu::MergeCentralities(AliHistogramCollection* histogramCollection)
1523{
1524 /// Merge CENT10 + CENT20 + ... into CENTMB
1525
1526 TList* listA = histogramCollection->CreateListOfKeysA();
1527 TList* listB = histogramCollection->CreateListOfKeysB();
1528 TList* listC = histogramCollection->CreateListOfKeysC();
1529 TList* listD = histogramCollection->CreateListOfKeysD();
1530
1531 if (!listA)
1532 {
1533 AliErrorClass("listA=0x0");
1534 return;
1535 }
1536
1537 if (!listB)
1538 {
1539 AliErrorClass("listB=0x0");
1540 return;
1541 }
1542
1543 if (!listC)
1544 {
1545 AliErrorClass("listC=0x0");
1546 return;
1547 }
1548
1549 if (!listD)
1550 {
1551 AliErrorClass("listD=0x0");
1552 return;
1553 }
1554
1555 for ( Int_t id = 0; id <= listD->GetLast(); ++id )
1556 {
1557 TString keyD = static_cast<TObjString*>(listD->At(id))->String();
1558
1559 for ( Int_t ia = 0; ia <= listA->GetLast(); ++ia )
1560 {
1561 TString keyA = static_cast<TObjString*>(listA->At(ia))->String();
1562
1563 for ( Int_t ib = 0; ib <= listB->GetLast(); ++ib )
1564 {
1565 TString keyB = static_cast<TObjString*>(listB->At(ib))->String();
1566
1567 TList* list = new TList;
1568 list->SetOwner(kTRUE);
1569
1570 AliHistogramCollection* hmerge(0x0);
1571
1572 for ( Int_t ic = 0; ic <= listC->GetLast(); ++ic )
1573 {
1574 TString keyC = static_cast<TObjString*>(listC->At(ic))->String();
1575
1576 if ( keyC != "CENTX" && keyC != "CENTMB" )
1577 {
1578 AliHistogramCollection* hc = histogramCollection->Project(keyA.Data(),keyB.Data(),keyC.Data(),keyD.Data());
1579 if (!hmerge)
1580 {
1581 hmerge = hc;
1582 }
1583 else
1584 {
1585 list->Add(hc);
1586 }
1587 }
1588 }
1589 if (hmerge)
1590 {
1591 hmerge->Merge(list);
1592 TIter next(hmerge->CreateIterator());
1593 TH1* h;
1594 while ( ( h = static_cast<TH1*>(next()) ) )
1595 {
1596 histogramCollection->Adopt(keyA.Data(),keyB.Data(),"CENTMB",keyD.Data(),static_cast<TH1*>(h->Clone()));
1597 }
1598 }
1599 delete list;
1600 delete hmerge;
1601 }
1602 }
1603 }
1604
1605 delete listA;
1606 delete listB;
1607 delete listC;
1608 delete listD;
1609}
1610
1611//_____________________________________________________________________________
1612Double_t AliAnalysisTaskMuMu::MuonMass2() const
1613{
1614 /// A usefull constant
1615 static Double_t m2 = 1.11636129640000012e-02; // using a constant here as the line below is a problem for CINT...
1616 // static Double_t m2 = TDatabasePDG::Instance()->GetParticle("mu-")->Mass()*TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
1617 return m2;
1618}
1619
1620//_____________________________________________________________________________
1621void AliAnalysisTaskMuMu::NotifyRun()
1622{
1623 /// Called at each change of run
1624
1625 AliDebug(1,Form("Run %09d File %s",fCurrentRunNumber,CurrentFileName()));
1626
1627 if (!fMuonTrackCuts)
1628 {
1629 fMuonTrackCuts = new AliMuonTrackCuts;
1630
1631 fMuonTrackCuts->SetAllowDefaultParams(kTRUE );
1632
1633
1634 fMuonTrackCuts->SetFilterMask(AliMuonTrackCuts::kMuEta |
1635 AliMuonTrackCuts::kMuThetaAbs |
1636 AliMuonTrackCuts::kMuPdca |
1637 AliMuonTrackCuts::kMuMatchApt |
1638 AliMuonTrackCuts::kMuMatchLpt |
1639 AliMuonTrackCuts::kMuMatchHpt |
1640 AliMuonTrackCuts::kMuTrackChiSquare);
1641 }
1642
1643 fMuonTrackCuts->SetRun(fInputHandler);
1644}
1645
1646//_____________________________________________________________________________
1647Bool_t AliAnalysisTaskMuMu::PairRapidityCut(const AliVParticle& t1, const AliVParticle& t2) const
1648{
1649 /// Whether the pair passes the rapidity cut
1650
1651 TLorentzVector p1(t1.Px(),t1.Py(),t1.Pz(),TMath::Sqrt(MuonMass2()+t1.P()*t1.P()));
1652 TLorentzVector p2(t2.Px(),t2.Py(),t2.Pz(),TMath::Sqrt(MuonMass2()+t2.P()*t2.P()));
1653
1654 TLorentzVector total(p1+p2);
1655
1656 Double_t y = total.Rapidity();
1657
1658 Bool_t ok = ( y < -2.5 && y > -4.0 );
1659
1660 return ok;
1661}
1662
1663
1664//_____________________________________________________________________________
1665Bool_t AliAnalysisTaskMuMu::PassPhysicsSelection() const
1666{
1667 /// Whether the event pass the physics selection or not
1668
1669 AliInputEventHandler* inputEventHandler = static_cast<AliInputEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
1670
1671 Bool_t isPhysicsSelected = (inputEventHandler->IsEventSelected() & AliVEvent::kAny);
1672
1673 /*
1674 ( inputEventHandler->IsEventSelected() & AliVEvent::kMUSH7 )
1675 || ( inputEventHandler->IsEventSelected() & AliVEvent::kMUL7 )
1676 || ( inputEventHandler->IsEventSelected() & AliVEvent::kMUS7 )
1677 || ( inputEventHandler->IsEventSelected() & AliVEvent::kMUU7 )
1678 || ( inputEventHandler->IsEventSelected() & AliVEvent::kMuonSingleLowPt8 )
1679 || ( inputEventHandler->IsEventSelected() & AliVEvent::kMuonSingleHighPt8 )
1680 || ( inputEventHandler->IsEventSelected() & AliVEvent::kMuonLikeLowPt8 )
1681 || ( inputEventHandler->IsEventSelected() & AliVEvent::kMuonUnlikeLowPt8 );
1682
1683 if ( IsPP() )
1684 {
1685 isPhysicsSelected = isPhysicsSelected || ( inputEventHandler->IsEventSelected() & AliVEvent::kINT7 ) || ( inputEventHandler->IsEventSelected() & AliVEvent::kINT8 );
1686 }
1687 else
1688 {
1689 isPhysicsSelected = isPhysicsSelected || ( inputEventHandler->IsEventSelected() & AliVEvent::kAny );
1690 }
1691 */
1692
1693 return isPhysicsSelected;
1694}
1695
1696//_____________________________________________________________________________
1697void
1698AliAnalysisTaskMuMu::Print(Option_t* /*opt*/) const
1699{
1700 /// Print the definition of this analysis
1701
1702 cout << ClassName() << " - " << GetName() << " - " << fBeamYear.Data() << endl;
1703
1704 if ( !fSingleTrackCutNames || !fSingleTrackCutNames )
1705 {
1706 cout << "No single track cut defined yet" << endl;
1707 }
1708 else
1709 {
1710 TIter next(fSingleTrackCutNames);
1711 TObjString* str;
1712
1713 while ( ( str = static_cast<TObjString*>(next()) ) )
1714 {
1715 cout << Form("SINGLE CUT %20s MASK %x",str->String().Data(),str->GetUniqueID()) << endl;
1716 }
1717 }
1718
1719 if ( !fPairTrackCutNames || !fPairTrackCutNames )
1720 {
1721 cout << "No track pair cut defined yet" << endl;
1722 }
1723 else
1724 {
1725 TIter next2(fPairTrackCutNames);
1726 AliAnalysisTaskMuMu::PairCut* str;
1727
1728 while ( ( str = static_cast<AliAnalysisTaskMuMu::PairCut*>(next2()) ) )
1729 {
1730 str->Print();
1731 }
1732 }
1733
1734 if ( !fTriggerClasses || !fTriggerClasses->First() )
1735 {
1736 cout << "No trigger classes defined yet" << endl;
1737 }
1738 else
1739 {
1740 cout << "Trigger classes that will be considered:" << endl;
1741 TIter next(fTriggerClasses);
1742 TObjString* s;
1743
1744 while ( ( s = static_cast<TObjString*>(next()) ) )
1745 {
1746 cout << s->String().Data() << endl;
1747 }
1748 }
1749}
1750
1751//_____________________________________________________________________________
1752void
1753AliAnalysisTaskMuMu::Terminate(Option_t *)
1754{
1755 /// Called once at the end of the query
1756 /// Just a simple printout of the stat we analyse and how many histograms
1757 /// we got
1758
1759 fOutput = dynamic_cast<TList*>(GetOutputData(1));
1760
1761 if (!fOutput) return;
1762
1763 fHistogramCollection = dynamic_cast<AliHistogramCollection*>(fOutput->FindObject("mumu"));
1764
1765 if (!fHistogramCollection)
1766 {
1767 AliError("Could not find back histogram collection in output...");
1768 return;
1769 }
1770
1771 fHistogramCollection->PruneEmptyHistograms();
1772
1773 UInt_t size2 = fHistogramCollection->EstimateSize();
1774
1775 AliInfo(Form("size after prune histograms = %5.1f MB",size2/1024.0/1024.0));
1776
1777 if ( !IsPP() && fCentralityLimits.size() > 1 )
1778 {
1779 MergeCentralities(fHistogramCollection);
1780 }
1781
1782 BeautifyHistos();
1783
1784 fHistogramCollection->Print("*Minv*");
1785
1786 fEventCounters = dynamic_cast<AliCounterCollection*>(fOutput->FindObject("eventCounters"));
1787
1788 if (!fEventCounters)
1789 {
1790 AliError("Could not find back counters in output...");
1791 return;
1792 }
1793
1794 fEventCounters->Print("trigger");
1795}
1796
1797//_____________________________________________________________________________
1798Bool_t AliAnalysisTaskMuMu::TriggerSBACECondition(const TString& triggerName) const
1799{
1800 // check the beam condition in the trigger name
1801
1802 if ( triggerName.Contains("-S-") ) return kTRUE;
1803
1804 if ( triggerName.Contains("-B-") ) return kTRUE;
1805
1806 if ( fUseBackgroundTriggers )
1807 {
1808 if ( triggerName.Contains("-ACE-") ) return kTRUE;
1809 }
1810 return kFALSE;
1811}
1812
1813//_____________________________________________________________________________
1814void AliAnalysisTaskMuMu::UserExec(Option_t* /*opt*/)
1815{
1816 /// Executed at each event
1817
1818 AliVEvent* event = InputEvent();
1819
1820 if (!event) return;
1821
1822 Bool_t anyTrigger(kFALSE);
1823
1824 if ( IsDynamicTriggerClasses() )
1825 {
1826 AddTriggerClasses(EAGetFiredTriggerClasses(*event));
1827 }
1828 else
1829 {
1830 if (fTriggerClasses->Contains("ANY") )
1831 {
1832 anyTrigger = kTRUE;
1833 }
1834 }
1835
1836 TString centrality(DefaultCentralityName());
1837
1838 Float_t fcent(-1);
1839
1840 AliCentrality* acent = event->GetCentrality();
1841
1842 if (acent) fcent = acent->GetCentralityPercentile("V0M");
1843
1844 Double_t cent(-100);
1845
1846 if ( fcent > 0 )
1847 {
1848 for ( std::vector<double>::size_type i = 0 ; i < fCentralityLimits.size() && cent < 0 ; ++i )
1849 {
1850 if ( fcent < fCentralityLimits[i] )
1851 {
1852 cent = fCentralityLimits[i];
1853 }
1854 }
1855 }
1856
1857 if ( cent > -1 )
1858 {
1859 centrality = CentralityName(cent);
1860 }
1861
1862 int nmu = EAGetNumberOfMuonTracks(*event);
1863
1864 EAComputeTrackMasks(*event);
1865
1866 TIter next(fTriggerClasses);
1867 TObjString* tname;
1868 TString firedTriggerClasses(EAGetFiredTriggerClasses(*event));
1869
1870 // first loop to count things not associated to a specific trigger
1871 TIter nextEventCut(fEventCutNames);
1872 TObjString* et;
1873
1874 UInt_t mask = GetEventMask(*event);
1875
1876 while ( ( et = static_cast<TObjString*>(nextEventCut()) ) )
1877 {
1878 Bool_t test = ( ( et->GetUniqueID() & mask ) == et->GetUniqueID() );
1879
1880 if ( test )
1881 {
1882 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", et->String().Data(), "EVERYTHING", fCurrentRunNumber));
1883
1884 if ( firedTriggerClasses == "" )
1885 {
1886 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", et->String().Data(), "EMPTY", fCurrentRunNumber));
1887 }
1888
1889 if (nmu)
1890 {
1891 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", et->String().Data(), "ATLEASTONEMUONTRACK", fCurrentRunNumber));
1892 }
1893
1894 if ( AtLeastOneMuonTrigger(firedTriggerClasses) )
1895 {
1896 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", et->String().Data(), "ATLEASTONEMUONTRIGGER", fCurrentRunNumber));
1897 }
1898
1899 if ( AtLeastOneMBTrigger(firedTriggerClasses) )
1900 {
1901 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", et->String().Data(), "ATLEASTONEMBTRIGGER", fCurrentRunNumber));
1902 }
1903
1904 if ( AtLeastOneMuonTrigger(firedTriggerClasses) && AtLeastOneMBTrigger(firedTriggerClasses) )
1905 {
1906 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", et->String().Data(), "ATLEASTONEMUONORMBTRIGGER", fCurrentRunNumber));
1907 }
1908
1909 if ( AtLeastOneEmcalTrigger(firedTriggerClasses) )
1910 {
1911 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", et->String().Data(), "ATLEASTONEEMCALTRIGGER", fCurrentRunNumber));
1912 }
1913
1914 if ( AtLeastOneEmcalTrigger(firedTriggerClasses) && AtLeastOneMBTrigger(firedTriggerClasses) )
1915 {
1916 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", et->String().Data(), "ATLEASTONEEMCALORMBTRIGGER", fCurrentRunNumber));
1917 }
1918
1919
1920 }
1921 }
1922
1923 // second loop to count only the triggers we're interested in
1924 while ( ( tname = static_cast<TObjString*>(next()) ) )
1925 {
1926 if ( !CheckTriggerClass(tname->String(),firedTriggerClasses) ) continue;
1927
1928 nextEventCut.Reset();
1929
1930 while ( ( et = static_cast<TObjString*>(nextEventCut()) ) )
1931 {
1932 Bool_t test = ( ( et->GetUniqueID() & mask ) == et->GetUniqueID() );
1933
1934 if ( test )
1935 {
1936 Fill(et->String().Data(),tname,centrality,fcent,*event);
1937 }
1938 }
1939 }
1940
1941 // Post output data.
1942 PostData(1, fOutput);
1943}
1944
1945//_____________________________________________________________________________
1946void AliAnalysisTaskMuMu::UserCreateOutputObjects()
1947{
1948 // Create histograms
1949 // Called once
1950
1951 OpenFile(1);
1952
1953 fTriggerClasses->Print();
1954
1955 fOutput = new TList;
1956 fOutput->SetOwner(kTRUE);
1957
1958 fHistogramCollection = new AliHistogramCollection("mumu");
1959
1960 fOutput->Add(fHistogramCollection);
1961
1962 // initialize event counters
1963 fEventCounters = new AliCounterCollection("eventCounters");
1964
1965 TIter nextEventCutName(fEventCutNames);
1966 TObjString* str;
1967 TString eventRubric;
1968 while ( ( str = static_cast<TObjString*>(nextEventCutName()) ) )
1969 {
1970 if ( eventRubric.Length() > 0 ) eventRubric += "/";
1971 eventRubric += str->String();
1972 }
1973
1974 eventRubric += "/SCALER";
1975
1976 fEventCounters->AddRubric("event", eventRubric.Data());
1977
1978 fEventCounters->AddRubric("trigger", 100);
1979
1980 fEventCounters->AddRubric("run", 1000000);
1981
1982 fEventCounters->Init();
1983
1984 fOutput->Add(fEventCounters);
1985
1986 // Post output data.
1987 PostData(1, fOutput);
1988}