1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 /* $Id: AliVAnalysisMuon.cxx 47782 2011-02-24 18:37:31Z martinez $ */
18 //-----------------------------------------------------------------------------
19 /// \class AliVAnalysisMuon
20 /// Base class with utilities for muon analysis
22 /// \author Diego Stocco
23 //-----------------------------------------------------------------------------
25 #include "AliVAnalysisMuon.h"
35 #include "TObjString.h"
36 #include "TObjArray.h"
37 #include "THashList.h"
39 //#include "TMCProcess.h"
40 #include "TLorentzVector.h"
44 #include "AliInputEventHandler.h"
45 #include "AliCentrality.h"
47 #include "AliAODEvent.h"
48 #include "AliAODTrack.h"
49 #include "AliAODMCParticle.h"
50 #include "AliMCEvent.h"
51 #include "AliMCParticle.h"
52 //#include "AliStack.h"
53 #include "AliESDEvent.h"
54 #include "AliESDMuonTrack.h"
55 #include "AliCounterCollection.h"
56 #include "AliVVertex.h"
59 #include "AliAnalysisManager.h"
60 #include "AliAnalysisTaskSE.h"
61 #include "AliAnalysisDataSlot.h"
62 #include "AliAnalysisDataContainer.h"
65 #include "AliCFGridSparse.h"
68 #include "AliMergeableCollection.h"
69 #include "AliMuonEventCuts.h"
70 #include "AliMuonTrackCuts.h"
71 #include "AliMuonPairCuts.h"
72 #include "AliAnalysisMuonUtility.h"
73 #include "AliUtilityMuonAncestor.h"
76 ClassImp(AliVAnalysisMuon) // Class implementation in ROOT context
80 //________________________________________________________________________
81 AliVAnalysisMuon::AliVAnalysisMuon() :
88 fTerminateOptions(0x0),
93 fUtilityMuonAncestor(0x0),
95 fMergeableCollection(0x0),
97 fOutputPrototypeList(0x0)
102 //________________________________________________________________________
103 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts, const AliMuonPairCuts& pairCuts) :
104 AliAnalysisTaskSE(name),
105 fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
106 fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
107 fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
110 fTerminateOptions(0x0),
114 fWeights(new THashList()),
115 fUtilityMuonAncestor(0x0),
117 fMergeableCollection(0x0),
119 fOutputPrototypeList(0x0)
126 SetTrigClassPatterns("");
127 SetCentralityClasses();
128 fWeights->SetOwner();
130 DefineOutput(1, TObjArray::Class());
133 //________________________________________________________________________
134 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts) :
135 AliAnalysisTaskSE(name),
136 fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
137 fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
141 fTerminateOptions(0x0),
145 fWeights(new THashList()),
146 fUtilityMuonAncestor(0x0),
148 fMergeableCollection(0x0),
150 fOutputPrototypeList(0x0)
157 SetTrigClassPatterns("");
158 SetCentralityClasses();
159 fWeights->SetOwner();
161 DefineOutput(1, TObjArray::Class());
165 //________________________________________________________________________
166 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonPairCuts& pairCuts) :
167 AliAnalysisTaskSE(name),
168 fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
170 fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
173 fTerminateOptions(0x0),
177 fWeights(new THashList()),
178 fUtilityMuonAncestor(0x0),
180 fMergeableCollection(0x0),
182 fOutputPrototypeList(0x0)
188 SetTrigClassPatterns("");
189 SetCentralityClasses();
190 fWeights->SetOwner();
192 DefineOutput(1, TObjArray::Class());
196 //________________________________________________________________________
197 AliVAnalysisMuon::~AliVAnalysisMuon()
203 delete fMuonEventCuts;
204 delete fMuonTrackCuts;
205 delete fMuonPairCuts;
206 delete fTerminateOptions;
211 delete fUtilityMuonAncestor;
212 delete fOutputPrototypeList;
215 // For proof: do not delete output containers
216 if ( ! AliAnalysisManager::GetAnalysisManager() || ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() ) {
221 //___________________________________________________________________________
222 void AliVAnalysisMuon::FinishTaskOutput()
225 /// Remove empty histograms to reduce the number of histos to be merged
229 fMergeableCollection->PruneEmptyObjects();
231 // Add stat. info from physics selection
232 // (usefull when running on AODs)
233 if ( fInputHandler ) {
234 for ( Int_t istat=0; istat<2; istat++ ) {
235 TString statType = ( istat == 0 ) ? "ALL" : "BIN0";
236 TH2* hStat = dynamic_cast<TH2*>(fInputHandler->GetStatistics(statType.Data()));
238 TString objectName = Form("%s_%s", hStat->GetName(), GetName());
239 TH2* cloneStat = static_cast<TH2*>(hStat->Clone(objectName.Data()));
240 cloneStat->SetDirectory(0);
241 fOutputList->Add(cloneStat);
244 AliWarning("Stat histogram not available");
247 } // loop on stat type
252 //___________________________________________________________________________
253 void AliVAnalysisMuon::NotifyRun()
255 /// Set run number for cuts
256 if ( fMuonTrackCuts ) fMuonTrackCuts->SetRun(fInputHandler);
257 if ( fMuonPairCuts ) fMuonPairCuts->SetRun(fInputHandler);
260 //___________________________________________________________________________
261 void AliVAnalysisMuon::UserCreateOutputObjects()
264 /// Create output objects
266 AliInfo(Form(" CreateOutputObjects of task %s\n", GetName()));
268 fOutputList = new TObjArray();
269 fOutputList->SetOwner();
271 fEventCounters = new AliCounterCollection("eventCounters");
273 if ( ! GetCentralityClasses() ) SetCentralityClasses();
274 TString centralityClasses = "";
275 for ( Int_t icent=1; icent<=GetCentralityClasses()->GetNbins(); ++icent ) {
276 if ( ! centralityClasses.IsNull() ) centralityClasses += "/";
277 centralityClasses += GetCentralityClasses()->GetBinLabel(icent);
279 fEventCounters->AddRubric("selected", "yes/no");
280 fEventCounters->AddRubric("trigger", 100);
281 fEventCounters->AddRubric("centrality", centralityClasses);
282 fEventCounters->AddRubric("run", 10000);
283 fEventCounters->Init();
284 fOutputList->Add(fEventCounters);
286 fMergeableCollection = new AliMergeableCollection("outputObjects");
287 fOutputList->Add(fMergeableCollection);
289 PostData(1, fOutputList);
291 fMuonEventCuts->Print();
293 MyUserCreateOutputObjects();
295 fUtilityMuonAncestor = new AliUtilityMuonAncestor();
299 //________________________________________________________________________
300 void AliVAnalysisMuon::UserExec(Option_t * /*option*/)
304 /// Called for each event
307 fAODEvent = dynamic_cast<AliAODEvent*> (InputEvent());
309 fESDEvent = dynamic_cast<AliESDEvent*> (InputEvent());
311 if ( ! fAODEvent && ! fESDEvent ) {
312 AliError ("AOD or ESD event not found. Nothing done!");
316 if ( ! fMuonEventCuts->IsSelected(fInputHandler) ) return;
318 Int_t physSel = ( fInputHandler->IsEventSelected() & AliVEvent::kAny ) ? kPhysSelPass : kPhysSelReject;
323 const TObjArray* selectTrigClasses = fMuonEventCuts->GetSelectedTrigClassesInEvent(InputEvent());
325 Double_t centrality = fMuonEventCuts->GetCentrality(InputEvent());
326 Int_t centralityBin = GetCentralityClasses()->FindBin(centrality);
327 TString centralityBinLabel = GetCentralityClasses()->GetBinLabel(centralityBin);
329 TString selKey = ( physSel == kPhysSelPass ) ? "yes" : "no";
330 for ( Int_t itrig=0; itrig<selectTrigClasses->GetEntries(); ++itrig ) {
331 TString trigName = selectTrigClasses->At(itrig)->GetName();
332 fEventCounters->Count(Form("trigger:%s/selected:%s/centrality:%s/run:%i", trigName.Data(), selKey.Data(), centralityBinLabel.Data(),fCurrentRunNumber));
335 ProcessEvent(fPhysSelKeys->At(physSel)->GetName(), *selectTrigClasses, centralityBinLabel);
337 // Post final data. It will be written to a file with option "RECREATE"
338 PostData(1, fOutputList);
341 //________________________________________________________________________
342 void AliVAnalysisMuon::Terminate(Option_t *)
345 /// Draw some histogram at the end.
348 if ( ! fTerminateOptions ) SetTerminateOptions();
350 TString furtherOpt = ((TObjString*)fTerminateOptions->At(3))->GetString();
351 furtherOpt.ToUpper();
352 if ( gROOT->IsBatch() && ! furtherOpt.Contains("FORCEBATCH") ) return;
354 fOutputList = dynamic_cast<TObjArray*>(GetOutputData(1));
355 if ( ! fOutputList ) return;
356 fEventCounters = static_cast<AliCounterCollection*>(fOutputList->FindObject("eventCounters"));
357 fMergeableCollection = static_cast<AliMergeableCollection*>(fOutputList->FindObject("outputObjects"));
359 if ( ! fMergeableCollection ) return;
360 AliInfo(Form("Mergeable collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
361 if ( fTerminateOptions->At(3) ) {
362 TString sopt = fTerminateOptions->At(3)->GetName();
363 if ( sopt.Contains("verbose") ) fMergeableCollection->Print("*");
365 SetCentralityClassesFromOutput();
369 //________________________________________________________________________
370 Int_t AliVAnalysisMuon::GetParticleType ( AliVParticle* track )
373 /// Get particle type from mathced MC track
376 if ( fUtilityMuonAncestor->IsUnidentified(track,MCEvent()) ) return kUnidentified;
377 if ( fUtilityMuonAncestor->IsBeautyMu(track,MCEvent()) ) return kBeautyMu;
378 if ( fUtilityMuonAncestor->IsCharmMu(track,MCEvent()) ) return kCharmMu;
379 if ( fUtilityMuonAncestor->IsWBosonMu(track,MCEvent()) ) return kWbosonMu;
380 if ( fUtilityMuonAncestor->IsZBosonMu(track,MCEvent()) ) return kZbosonMu;
381 if ( fUtilityMuonAncestor->IsDecayMu(track,MCEvent()) ) return kDecayMu;
382 if ( fUtilityMuonAncestor->IsQuarkoniumMu(track,MCEvent()) ) return kQuarkoniumMu;
383 if ( fUtilityMuonAncestor->IsHadron(track,MCEvent()) ) return kRecoHadron;
384 if ( fUtilityMuonAncestor->IsSecondaryMu(track,MCEvent()) ) return kSecondaryMu;
389 //________________________________________________________________________
390 Bool_t AliVAnalysisMuon::AddObjectToCollection(TObject* object, Int_t index)
393 /// Add object to collection
396 if ( ! fOutputPrototypeList ) {
397 fOutputPrototypeList = new TObjArray();
398 fOutputPrototypeList->SetOwner();
400 if ( fOutputPrototypeList->FindObject(object->GetName() ) ) {
401 AliWarning(Form("Object with name %s already in the list", object->GetName()));
404 if ( index < 0 ) fOutputPrototypeList->Add(object);
405 else fOutputPrototypeList->AddAtAndExpand(object, index);
410 //________________________________________________________________________
411 TObject* AliVAnalysisMuon::GetMergeableObject(TString physSel, TString trigClassName, TString centrality, TString objectName)
414 /// Get mergeable object
415 /// (create collection if necessary)
418 TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
420 TObject* obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
422 CreateMergeableObjects(physSel, trigClassName, centrality);
423 obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
424 AliInfo(Form("Mergeable object collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
429 //________________________________________________________________________
430 TObject* AliVAnalysisMuon::GetSum(TString physSel, TString trigClassNames, TString centrality, TString objectPattern)
434 /// - physSel, trigClassNames must be in the form: key1,key2
435 /// - centrality must be in the form minValue_maxValue
436 /// - objectPattern must be in the form match1,match2
437 /// meaning that the object name must contain match1 or match2
438 /// wildcard * is allowed
440 if ( ! fMergeableCollection ) return 0x0;
442 // Get centrality range
443 Int_t firstCentrality = 1;
444 Int_t lastCentrality = GetCentralityClasses()->GetNbins();
446 TObjArray* centralityRange = centrality.Tokenize("_");
447 Float_t range[2] = {0., 100.};
448 if ( centralityRange->GetEntries() >= 2 ) {
449 for ( Int_t irange=0; irange<2; ++irange ) {
450 range[irange] = ((TObjString*)centralityRange->At(irange))->GetString().Atof();
452 firstCentrality = GetCentralityClasses()->FindBin(range[0]+0.0001);
453 lastCentrality = GetCentralityClasses()->FindBin(range[1]-0.0001);
455 delete centralityRange;
457 TString sumCentralityString = "";
458 for ( Int_t icent=firstCentrality; icent<=lastCentrality; ++icent ) {
459 if ( ! sumCentralityString.IsNull() ) sumCentralityString += ",";
460 sumCentralityString += GetCentralityClasses()->GetBinLabel(icent);
463 // objectPattern.ReplaceAll(" ","");
464 // TObjArray* objPatternList = objectPattern.Tokenize("&");
465 // TObjArray objPatternMatrix(objPatternList->GetEntries());
466 // objPatternMatrix.SetOwner();
467 // for ( Int_t ikey=0; ikey<objPatternList->GetEntries(); ikey++ ) {
468 // TObjArray* subKeyList = ((TObjString*)objPatternList->At(ikey))->GetString().Tokenize(",");
469 // objPatternMatrix.AddAt(subKeyList, ikey);
471 // delete objPatternList;
474 TObjArray objectNameInCollection;
475 objectNameInCollection.SetOwner();
476 TObjArray* physSelList = physSel.Tokenize(",");
477 TObjArray* trigClassList = trigClassNames.Tokenize(",");
478 TObjArray* centralityList = sumCentralityString.Tokenize(",");
479 for ( Int_t isel=0; isel<physSelList->GetEntries(); isel++ ) {
480 for ( Int_t itrig = 0; itrig<trigClassList->GetEntries(); itrig++ ) {
481 for ( Int_t icent=0; icent<centralityList->GetEntries(); icent++ ) {
482 TString currId = Form("/%s/%s/%s/", physSelList->At(isel)->GetName(), trigClassList->At(itrig)->GetName(),centralityList->At(icent)->GetName());
483 TList* objNameList = fMergeableCollection->CreateListOfObjectNames(currId.Data());
484 for ( Int_t iobj=0; iobj<objNameList->GetEntries(); iobj++ ) {
485 TString objName = objNameList->At(iobj)->GetName();
486 if ( ! objectNameInCollection.FindObject(objName.Data()) ) objectNameInCollection.Add(new TObjString(objName.Data()));
493 delete trigClassList;
494 delete centralityList;
496 TObjArray* objPatternList = objectPattern.Tokenize(",");
498 TString matchingObjectNames = "";
499 for ( Int_t iobj=0; iobj<objectNameInCollection.GetEntries(); iobj++ ) {
500 TString objName = objectNameInCollection.At(iobj)->GetName();
501 for ( Int_t ipat=0; ipat<objPatternList->GetEntries(); ipat++ ) {
502 TString currPattern = ((TObjString*)objPatternList->At(ipat))->GetString();
503 if ( currPattern.Contains("*") ) {
504 if ( ! objName.Contains(TRegexp(currPattern.Data(),kTRUE)) ) continue;
506 else if ( objName != currPattern ) continue;
508 if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
509 matchingObjectNames += objName;
512 delete objPatternList;
514 // for ( Int_t iobj=0; iobj<objectNameInCollection.GetEntries(); iobj++ ) {
515 // TString objName = objectNameInCollection.At(iobj)->GetName();
516 // Bool_t matchAnd = kTRUE;
517 // for ( Int_t ikey=0; ikey<objPatternMatrix.GetEntries(); ikey++ ) {
518 // TObjArray* subKeyList = (TObjArray*)objPatternMatrix.At(ikey);
519 // Bool_t matchOr = kFALSE;
520 // for ( Int_t isub=0; isub<subKeyList->GetEntries(); isub++ ) {
521 // TString subKeyString = ((TObjString*)subKeyList->At(isub))->GetString();
522 // if ( subKeyString.Contains("*") ) {
523 // if ( objName.Contains(TRegexp(subKeyString.Data())) ) {
528 // else if ( objName == subKeyString ) {
533 // if ( ! matchOr ) {
534 // matchAnd = kFALSE;
538 // if ( ! matchAnd ) continue;
539 // if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
540 // matchingObjectNames += objName;
543 TString idPattern = Form("/%s/%s/%s/%s", physSel.Data(), trigClassNames.Data(), sumCentralityString.Data(), matchingObjectNames.Data());
544 idPattern.ReplaceAll(" ","");
546 AliDebug(1,Form("Sum pattern %s", idPattern.Data()));
548 return fMergeableCollection->GetSum(idPattern.Data());
551 //___________________________________________________________________________
552 void AliVAnalysisMuon::CreateMergeableObjects(TString physSel, TString trigClassName, TString centrality)
555 TString objectName = "";
556 TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
557 for ( Int_t iobj=0; iobj<fOutputPrototypeList->GetEntries(); ++iobj ) {
558 objectName = fOutputPrototypeList->At(iobj)->GetName();
559 obj = fOutputPrototypeList->At(iobj)->Clone(objectName.Data());
560 fMergeableCollection->Adopt(identifier, obj);
565 //_______________________________________________________________________
566 Bool_t AliVAnalysisMuon::SetSparseRange(AliCFGridSparse* gridSparse,
567 Int_t ivar, TString labelName,
568 Double_t varMin, Double_t varMax,
572 /// Set range in a smart way.
573 /// Allows to select a bin from the label.
574 /// Check the bin limits.
577 // Keep for backward compatibility
579 return AliAnalysisMuonUtility::SetSparseRange(gridSparse,ivar,labelName,varMin, varMax,option);
582 //________________________________________________________________________
583 TString AliVAnalysisMuon::GetDefaultTrigClassPatterns() const
585 /// Get default trigger class patterns
586 return fMuonEventCuts->GetDefaultTrigClassPatterns();
589 //________________________________________________________________________
590 void AliVAnalysisMuon::SetTrigClassPatterns(const TString pattern)
592 /// Set trigger classes
593 TString currPattern = pattern;
594 if ( currPattern.IsNull() ) {
595 currPattern = GetDefaultTrigClassPatterns();
596 currPattern.Append(",!CMUP*"); // by default do not account for UltraPeripheral events
598 fMuonEventCuts->SetTrigClassPatterns(currPattern);
601 //________________________________________________________________________
602 TList* AliVAnalysisMuon::GetAllSelectedTrigClasses() const
604 /// Get trigger classes
605 return fMuonEventCuts->GetAllSelectedTrigClasses();
608 //________________________________________________________________________
609 void AliVAnalysisMuon::SetCentralityClasses(Int_t nCentralityBins, Double_t* centralityBins)
612 /// Set centrality classes
614 fMuonEventCuts->SetCentralityClasses(nCentralityBins, centralityBins);
617 //________________________________________________________________________
618 TAxis* AliVAnalysisMuon::GetCentralityClasses() const
621 /// Set centrality classes
623 return fMuonEventCuts->GetCentralityClasses();
626 //________________________________________________________________________
627 Bool_t AliVAnalysisMuon::SetCentralityClassesFromOutput()
630 /// Get axis of centrality classes from output key
632 if ( ! fMergeableCollection ) return kFALSE;
633 TList* centrKeyList = fMergeableCollection->CreateListOfKeys(2);
634 TObjArray centrLimitsList;
635 centrLimitsList.SetOwner();
636 if ( ! centrKeyList ) return kFALSE;
637 for ( Int_t ikey=0; ikey<centrKeyList->GetEntries(); ikey++ ) {
638 TString centr = static_cast<TObjString*>(centrKeyList->At(ikey))->GetString();
639 TObjArray* array = centr.Tokenize("_");
640 for ( Int_t ilim=0; ilim<array->GetEntries(); ilim++ ) {
641 TString currLim = static_cast<TObjString*>(array->At(ilim))->GetString();
642 if ( ! centrLimitsList.FindObject(currLim.Data()) ) centrLimitsList.Add(new TObjString(currLim));
648 // Get unsorted array
649 TArrayD bins(centrLimitsList.GetEntries());
650 for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
651 bins[ibin] = static_cast<TObjString*>(centrLimitsList.At(ibin))->GetString().Atof();
655 Int_t index[bins.GetSize()];
656 TMath::Sort(bins.GetSize(),bins.GetArray(),index, kFALSE);
658 TArrayD sortedBins(bins.GetSize());
659 for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
660 sortedBins[ibin] = bins[index[ibin]];
663 SetCentralityClasses(sortedBins.GetSize()-1, sortedBins.GetArray());
667 //________________________________________________________________________
668 void AliVAnalysisMuon::SetTerminateOptions(TString physSel, TString trigClass, TString centralityRange, TString furtherOpts)
671 /// Set terminate options
673 if ( ! fTerminateOptions ) {
674 fTerminateOptions = new TObjArray(4);
675 fTerminateOptions->SetOwner();
677 fTerminateOptions->AddAt(new TObjString(physSel), 0);
678 fTerminateOptions->AddAt(new TObjString(trigClass), 1);
679 fTerminateOptions->AddAt(new TObjString(centralityRange),2);
680 fTerminateOptions->AddLast(new TObjString(furtherOpts));
683 //________________________________________________________________________
684 void AliVAnalysisMuon::InitKeys()
689 TString chargeKeys = "MuMinus MuPlus";
690 fChargeKeys = chargeKeys.Tokenize(" ");
692 TString srcKeys = "CharmMu BeautyMu QuarkoniumMu WbosonMu ZbosonMu DecayMu SecondaryMu Hadron Unidentified";
693 fSrcKeys = srcKeys.Tokenize(" ");
695 TString physSelKeys = "PhysSelPass PhysSelReject";
696 fPhysSelKeys = physSelKeys.Tokenize(" ");
700 //________________________________________________________________________
701 void AliVAnalysisMuon::SetWeight ( TObject* wgtObj )
704 if ( fWeights->FindObject(wgtObj->GetName()) ) {
705 AliWarning(Form("Weight object %s is already in the list",wgtObj->GetName()));
708 fWeights->Add(wgtObj);
711 //________________________________________________________________________
712 TObject* AliVAnalysisMuon::GetWeight ( const Char_t* wgtName )
715 return fWeights->FindObject(wgtName);