]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG/muon/AliVAnalysisMuon.cxx
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWG / muon / AliVAnalysisMuon.cxx
index e1a3ef1f7226407b559ada9da2c805a20a394add..e513c2a3678b2db11f039499e01631fe3ad53106 100644 (file)
@@ -38,6 +38,7 @@
 #include "TStyle.h"
 //#include "TMCProcess.h"
 #include "TLorentzVector.h"
+#include "TRegexp.h"
 
 // STEER includes
 #include "AliInputEventHandler.h"
@@ -52,6 +53,7 @@
 #include "AliESDEvent.h"
 #include "AliESDMuonTrack.h"
 #include "AliCounterCollection.h"
+#include "AliVVertex.h"
 
 // ANALYSIS includes
 #include "AliAnalysisManager.h"
 // CORRFW includes
 #include "AliCFGridSparse.h"
 
-// PWG3 includes
+// PWG includes
 #include "AliMergeableCollection.h"
+#include "AliMuonEventCuts.h"
 #include "AliMuonTrackCuts.h"
 #include "AliMuonPairCuts.h"
+#include "AliAnalysisMuonUtility.h"
+#include "AliUtilityMuonAncestor.h"
 
 /// \cond CLASSIMP
 ClassImp(AliVAnalysisMuon) // Class implementation in ROOT context
@@ -75,6 +80,7 @@ ClassImp(AliVAnalysisMuon) // Class implementation in ROOT context
 //________________________________________________________________________
 AliVAnalysisMuon::AliVAnalysisMuon() :
   AliAnalysisTaskSE(),
+  fMuonEventCuts(0x0),
   fMuonTrackCuts(0x0),
   fMuonPairCuts(0x0),
   fESDEvent(0x0),
@@ -83,14 +89,11 @@ AliVAnalysisMuon::AliVAnalysisMuon() :
   fChargeKeys(0x0),
   fSrcKeys(0x0),
   fPhysSelKeys(0x0),
-  fTriggerClasses(0x0),
-  fCentralityClasses(0x0),
+  fWeights(0x0),
+  fUtilityMuonAncestor(0x0),
   fEventCounters(0x0),
   fMergeableCollection(0x0),
   fOutputList(0x0),
-  fSelectedTrigPattern(0x0),
-  fRejectedTrigPattern(0x0),
-  fSelectedTrigLevel(0x0),
   fOutputPrototypeList(0x0)
 {
   /// Default ctor.
@@ -99,6 +102,7 @@ AliVAnalysisMuon::AliVAnalysisMuon() :
 //________________________________________________________________________
 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts, const AliMuonPairCuts& pairCuts) :
   AliAnalysisTaskSE(name),
+  fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
   fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
   fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
   fESDEvent(0x0),
@@ -107,24 +111,21 @@ AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& tra
   fChargeKeys(0x0),
   fSrcKeys(0x0),
   fPhysSelKeys(0x0),
-  fTriggerClasses(new THashList()),
-  fCentralityClasses(0x0),
+  fWeights(new THashList()),
+  fUtilityMuonAncestor(0x0),
   fEventCounters(0x0),
   fMergeableCollection(0x0),
   fOutputList(0x0),
-  fSelectedTrigPattern(new TObjArray()),
-  fRejectedTrigPattern(new TObjArray()),
-  fSelectedTrigLevel(new TObjArray()),
   fOutputPrototypeList(0x0)
 {
   //
   /// Constructor.
   //
   
-  fTriggerClasses->SetOwner();
   InitKeys();
-  SetTrigClassPatterns();
+  SetTrigClassPatterns("");
   SetCentralityClasses();
+  fWeights->SetOwner();
 
   DefineOutput(1, TObjArray::Class());
 }
@@ -132,6 +133,7 @@ AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& tra
 //________________________________________________________________________
 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts) :
   AliAnalysisTaskSE(name),
+  fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
   fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
   fMuonPairCuts(0x0),
   fESDEvent(0x0),
@@ -140,24 +142,21 @@ AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& tra
   fChargeKeys(0x0),
   fSrcKeys(0x0),
   fPhysSelKeys(0x0),
-  fTriggerClasses(new THashList()),
-  fCentralityClasses(0x0),
+  fWeights(new THashList()),
+  fUtilityMuonAncestor(0x0),
   fEventCounters(0x0),
   fMergeableCollection(0x0),
   fOutputList(0x0),
-  fSelectedTrigPattern(new TObjArray()),
-  fRejectedTrigPattern(new TObjArray()),
-  fSelectedTrigLevel(new TObjArray()),
   fOutputPrototypeList(0x0)
 {
   //
   /// Constructor.
   //
   
-  fTriggerClasses->SetOwner();
   InitKeys();
-  SetTrigClassPatterns();
+  SetTrigClassPatterns("");
   SetCentralityClasses();
+  fWeights->SetOwner();
   
   DefineOutput(1, TObjArray::Class());
 }
@@ -166,6 +165,7 @@ AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& tra
 //________________________________________________________________________
 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonPairCuts& pairCuts) :
   AliAnalysisTaskSE(name),
+  fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
   fMuonTrackCuts(0x0),
   fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
   fESDEvent(0x0),
@@ -174,23 +174,20 @@ AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonPairCuts& pair
   fChargeKeys(0x0),
   fSrcKeys(0x0),
   fPhysSelKeys(0x0),
-  fTriggerClasses(new THashList()),
-  fCentralityClasses(0x0),
+  fWeights(new THashList()),
+  fUtilityMuonAncestor(0x0),
   fEventCounters(0x0),
   fMergeableCollection(0x0),
   fOutputList(0x0),
-  fSelectedTrigPattern(new TObjArray()),
-  fRejectedTrigPattern(new TObjArray()),
-  fSelectedTrigLevel(new TObjArray()),
   fOutputPrototypeList(0x0)
 {
   //
   /// Constructor.
   //
-  fTriggerClasses->SetOwner();
   InitKeys();
-  SetTrigClassPatterns();
+  SetTrigClassPatterns("");
   SetCentralityClasses();
+  fWeights->SetOwner();
     
   DefineOutput(1, TObjArray::Class());
 }
@@ -203,17 +200,15 @@ AliVAnalysisMuon::~AliVAnalysisMuon()
   /// Destructor
   //
 
+  delete fMuonEventCuts;
   delete fMuonTrackCuts;
   delete fMuonPairCuts;
   delete fTerminateOptions;
   delete fChargeKeys;
   delete fSrcKeys;
   delete fPhysSelKeys;
-  delete fTriggerClasses;
-  delete fCentralityClasses;
-  delete fSelectedTrigPattern;
-  delete fRejectedTrigPattern;
-  delete fSelectedTrigLevel;
+  delete fWeights;
+  delete fUtilityMuonAncestor;
   delete fOutputPrototypeList;
 
 
@@ -232,8 +227,6 @@ void AliVAnalysisMuon::FinishTaskOutput()
 
 
   fMergeableCollection->PruneEmptyObjects();
-
-  TString objectName = "";
   
   // Add stat. info from physics selection
   // (usefull when running on AODs)
@@ -242,7 +235,7 @@ void AliVAnalysisMuon::FinishTaskOutput()
       TString statType = ( istat == 0 ) ? "ALL" : "BIN0";
       TH2* hStat = dynamic_cast<TH2*>(fInputHandler->GetStatistics(statType.Data()));
       if ( hStat ) {
-        objectName = Form("%s_%s", hStat->GetName(), GetName());
+        TString objectName = Form("%s_%s", hStat->GetName(), GetName());
         TH2* cloneStat = static_cast<TH2*>(hStat->Clone(objectName.Data()));
         cloneStat->SetDirectory(0);
         fOutputList->Add(cloneStat);
@@ -260,8 +253,8 @@ void AliVAnalysisMuon::FinishTaskOutput()
 void AliVAnalysisMuon::NotifyRun()
 {
   /// Set run number for cuts
-  if ( fMuonTrackCuts ) fMuonTrackCuts->SetRun(fCurrentRunNumber);
-  if ( fMuonPairCuts ) fMuonPairCuts->SetRun(fCurrentRunNumber);
+  if ( fMuonTrackCuts ) fMuonTrackCuts->SetRun(fInputHandler);
+  if ( fMuonPairCuts ) fMuonPairCuts->SetRun(fInputHandler);
 }
 
 //___________________________________________________________________________
@@ -277,15 +270,16 @@ void AliVAnalysisMuon::UserCreateOutputObjects()
 
   fEventCounters = new AliCounterCollection("eventCounters");
 
-  if ( ! fCentralityClasses ) SetCentralityClasses();
+  if ( ! GetCentralityClasses() ) SetCentralityClasses();
   TString centralityClasses = "";
-  for ( Int_t icent=1; icent<=fCentralityClasses->GetNbins(); ++icent ) {
+  for ( Int_t icent=1; icent<=GetCentralityClasses()->GetNbins(); ++icent ) {
     if ( ! centralityClasses.IsNull() ) centralityClasses += "/";
-    centralityClasses += fCentralityClasses->GetBinLabel(icent);
+    centralityClasses += GetCentralityClasses()->GetBinLabel(icent);
   }
   fEventCounters->AddRubric("selected", "yes/no");
   fEventCounters->AddRubric("trigger", 100);
   fEventCounters->AddRubric("centrality", centralityClasses);
+  fEventCounters->AddRubric("run", 10000);
   fEventCounters->Init();
   fOutputList->Add(fEventCounters);
  
@@ -294,7 +288,11 @@ void AliVAnalysisMuon::UserCreateOutputObjects()
 
   PostData(1, fOutputList);
   
+  fMuonEventCuts->Print();
+  
   MyUserCreateOutputObjects();
+  
+  fUtilityMuonAncestor = new AliUtilityMuonAncestor();
 }
 
 
@@ -314,35 +312,27 @@ void AliVAnalysisMuon::UserExec(Option_t * /*option*/)
     AliError ("AOD or ESD event not found. Nothing done!");
     return;
   }
+  
+  if ( ! fMuonEventCuts->IsSelected(fInputHandler) ) return;
 
   Int_t physSel = ( fInputHandler->IsEventSelected() & AliVEvent::kAny ) ? kPhysSelPass : kPhysSelReject;
 
   //
   // Global event info
   //
+  const TObjArray* selectTrigClasses = fMuonEventCuts->GetSelectedTrigClassesInEvent(InputEvent());
 
-  TString firedTrigClasses = ( fAODEvent ) ? fAODEvent->GetFiredTriggerClasses() : fESDEvent->GetFiredTriggerClasses();
-  firedTrigClasses.Prepend("ANY ");
-  AliDebug(2, Form("Fired classes %s", firedTrigClasses.Data()));
-  TObjArray* selectTrigClasses = BuildTriggerClasses(firedTrigClasses);
-  if ( selectTrigClasses->GetEntries() == 0 ) {
-    delete selectTrigClasses;
-    return;
-  }
-
-  Double_t centrality = InputEvent()->GetCentrality()->GetCentralityPercentile("V0M");
-  Int_t centralityBin = fCentralityClasses->FindBin(centrality);
-  TString centralityBinLabel = fCentralityClasses->GetBinLabel(centralityBin);
+  Double_t centrality = fMuonEventCuts->GetCentrality(InputEvent());
+  Int_t centralityBin = GetCentralityClasses()->FindBin(centrality);
+  TString centralityBinLabel = GetCentralityClasses()->GetBinLabel(centralityBin);
 
   TString selKey = ( physSel == kPhysSelPass ) ? "yes" : "no";
   for ( Int_t itrig=0; itrig<selectTrigClasses->GetEntries(); ++itrig ) {
     TString trigName = selectTrigClasses->At(itrig)->GetName();
-    fEventCounters->Count(Form("trigger:%s/selected:%s/centrality:%s", trigName.Data(), selKey.Data(), centralityBinLabel.Data()));
+    fEventCounters->Count(Form("trigger:%s/selected:%s/centrality:%s/run:%i", trigName.Data(), selKey.Data(), centralityBinLabel.Data(),fCurrentRunNumber));
   }
 
-  ProcessEvent(fPhysSelKeys->At(physSel)->GetName(), *selectTrigClasses, fCentralityClasses->GetBinLabel(centralityBin));
-
-  delete selectTrigClasses;
+  ProcessEvent(fPhysSelKeys->At(physSel)->GetName(), *selectTrigClasses, centralityBinLabel);
 
   // Post final data. It will be written to a file with option "RECREATE"
   PostData(1, fOutputList);
@@ -355,227 +345,47 @@ void AliVAnalysisMuon::Terminate(Option_t *)
   /// Draw some histogram at the end.
   //
   
-  if ( gROOT->IsBatch() ) return;
+  if ( ! fTerminateOptions ) SetTerminateOptions();
+  
+  TString furtherOpt = ((TObjString*)fTerminateOptions->At(3))->GetString();
+  furtherOpt.ToUpper();
+  if ( gROOT->IsBatch() && ! furtherOpt.Contains("FORCEBATCH") ) return;
     
   fOutputList = dynamic_cast<TObjArray*>(GetOutputData(1));
   if ( ! fOutputList ) return;
   fEventCounters = static_cast<AliCounterCollection*>(fOutputList->FindObject("eventCounters"));
   fMergeableCollection = static_cast<AliMergeableCollection*>(fOutputList->FindObject("outputObjects"));
   
-  if ( ! fTerminateOptions ) SetTerminateOptions();
   if ( ! fMergeableCollection ) return;
-  AliInfo(Form("Histogram collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
+  AliInfo(Form("Mergeable collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
   if ( fTerminateOptions->At(3) ) {
     TString sopt = fTerminateOptions->At(3)->GetName();
     if ( sopt.Contains("verbose") ) fMergeableCollection->Print("*"); 
   }
+  SetCentralityClassesFromOutput();
 }
 
 
-
 //________________________________________________________________________
-Int_t AliVAnalysisMuon::GetNTracks()
-{
-  //
-  /// Return the number of tracks in event
-  //
-  return ( fAODEvent ) ? fAODEvent->GetNTracks() : fESDEvent->GetNumberOfMuonTracks();
-}
-
-
-//________________________________________________________________________
-AliVParticle* AliVAnalysisMuon::GetTrack(Int_t itrack)
-{
-  //
-  /// Get the current track
-  //
-  AliVParticle* track = 0x0;
-  if ( fAODEvent ) track = fAODEvent->GetTrack(itrack);
-  else track = fESDEvent->GetMuonTrack(itrack);
-  return track;
-}
-
-//________________________________________________________________________
-Double_t AliVAnalysisMuon::MuonMass2() const
-{
-  /// A usefull constant
-  static Double_t m2 = 1.11636129640000012e-02; // using a constant here as the line below is a problem for CINT...
-  return m2;
-}
-
-//________________________________________________________________________
-TLorentzVector AliVAnalysisMuon::GetTrackPair(AliVParticle* track1, AliVParticle* track2) const
-{
-  //
-  /// Get track pair
-  //
-  
-  AliVParticle* tracks[2] = {track1, track2};
-  
-  TLorentzVector vec[2];
-  for ( Int_t itrack=0; itrack<2; ++itrack ) {
-    Double_t trackP = tracks[itrack]->P();
-    Double_t energy = TMath::Sqrt(trackP*trackP + MuonMass2());
-    vec[itrack].SetPxPyPzE(tracks[itrack]->Px(), tracks[itrack]->Py(), tracks[itrack]->Pz(), energy);
-  }
-  
-  TLorentzVector vecPair = vec[0] + vec[1];
-  return vecPair;
-}
-
-
-//________________________________________________________________________
-Int_t AliVAnalysisMuon::GetNMCTracks()
-{
-  //
-  /// Return the number of MC tracks in event
-  //
-  Int_t nMCtracks = 0;
-  if ( fMCEvent ) nMCtracks = fMCEvent->GetNumberOfTracks();
-  else if ( fAODEvent ) {
-    TClonesArray* mcArray = (TClonesArray*)fAODEvent->GetList()->FindObject(AliAODMCParticle::StdBranchName());
-    if ( mcArray ) nMCtracks = mcArray->GetEntries();
-  }
-  return nMCtracks;
-}
-
-//________________________________________________________________________
-AliVParticle* AliVAnalysisMuon::GetMCTrack(Int_t trackLabel)
-{
-  //
-  /// MC information can be provided by the MC input handler
-  /// (mostly when analyising ESDs) or can be found inside AODs
-  /// This method returns the correct one
-  //
-  AliVParticle* mcTrack = 0x0;
-  if ( fMCEvent ) mcTrack = fMCEvent->GetTrack(trackLabel);
-  else if ( fAODEvent ) {
-    TClonesArray* mcArray = (TClonesArray*)fAODEvent->FindListObject(AliAODMCParticle::StdBranchName());
-    if ( mcArray ) mcTrack =  (AliVParticle*)mcArray->At(trackLabel);
-  }
-  if ( ! mcTrack ) AliWarning(Form("No track with label %i!", trackLabel));
-  return mcTrack;
-}
-
-//________________________________________________________________________
-Int_t AliVAnalysisMuon::GetMotherIndex(AliVParticle* mcParticle)
-{
-  //
-  /// Return the mother index
-  //
-  Int_t imother = ( fMCEvent ) ? ((AliMCParticle*)mcParticle)->GetMother() : ((AliAODMCParticle*)mcParticle)->GetMother();
-  return imother;
-}
-
-//________________________________________________________________________
-Int_t AliVAnalysisMuon::GetDaughterIndex(AliVParticle* mcParticle, Int_t idaughter)
-{
-  //
-  /// Return the daughter index
-  /// idaughter can be:
-  /// 0 -> first daughter
-  /// 1 -> last daughter
-  //
-  if ( idaughter < 0 || idaughter > 1 ) {
-    AliError(Form("Requested daughter %i Daughter index can be either 0 (first) or 1 (last)", idaughter));
-    return -1;
-  }
-  
-  if ( fMCEvent ) {
-    if ( idaughter == 0 ) return ((AliMCParticle*)mcParticle)->GetFirstDaughter();
-    else return ((AliMCParticle*)mcParticle)->GetLastDaughter();
-  }
-  
-  return ((AliAODMCParticle*)mcParticle)->GetDaughter(idaughter);
-}
-
-
-
-//________________________________________________________________________
-Bool_t AliVAnalysisMuon::IsMC()
-{
-  //
-  /// Contains MC info
-  //
-  return ( fMCEvent || ( fAODEvent && fAODEvent->FindListObject(AliAODMCParticle::StdBranchName()) ) );
-}
-
-
-//________________________________________________________________________
-Int_t AliVAnalysisMuon::GetParticleType(AliVParticle* track)
+Int_t AliVAnalysisMuon::GetParticleType ( AliVParticle* track )
 {
   //
   /// Get particle type from mathced MC track
   //
   
-  Int_t trackSrc = kUnidentified;
-  Int_t trackLabel = track->GetLabel();
-  if ( trackLabel >= 0 ) {
-    AliVParticle* matchedMCTrack = GetMCTrack(trackLabel);
-    if ( matchedMCTrack ) trackSrc = RecoTrackMother(matchedMCTrack);
-  } // track has MC label
-  return trackSrc;
+  if ( fUtilityMuonAncestor->IsUnidentified(track,MCEvent()) ) return kUnidentified;
+  if ( fUtilityMuonAncestor->IsBeautyMu(track,MCEvent()) ) return kBeautyMu;
+  if ( fUtilityMuonAncestor->IsCharmMu(track,MCEvent()) ) return kCharmMu;
+  if ( fUtilityMuonAncestor->IsWBosonMu(track,MCEvent()) ) return kWbosonMu;
+  if ( fUtilityMuonAncestor->IsZBosonMu(track,MCEvent()) ) return kZbosonMu;
+  if ( fUtilityMuonAncestor->IsDecayMu(track,MCEvent()) ) return kDecayMu;
+  if ( fUtilityMuonAncestor->IsQuarkoniumMu(track,MCEvent()) ) return kQuarkoniumMu;
+  if ( fUtilityMuonAncestor->IsHadron(track,MCEvent()) ) return kRecoHadron;
+  if ( fUtilityMuonAncestor->IsSecondaryMu(track,MCEvent()) ) return kSecondaryMu;
+  return kDecayMu;
 }
 
 
-//________________________________________________________________________
-Int_t AliVAnalysisMuon::RecoTrackMother(AliVParticle* mcParticle)
-{
-  //
-  /// Find track mother from kinematics
-  //
-  
-  Int_t recoPdg = mcParticle->PdgCode();
-  
-  // Track is not a muon
-  if ( TMath::Abs(recoPdg) != 13 ) return kRecoHadron;
-  
-  Int_t imother = GetMotherIndex(mcParticle);
-  
-  Int_t den[3] = {100, 1000, 1};
-  
-  Int_t motherType = kDecayMu;
-  while ( imother >= 0 ) {
-    AliVParticle* part = GetMCTrack(imother);
-    //if ( ! part ) return motherType;
-    
-    Int_t absPdg = TMath::Abs(part->PdgCode());
-    
-    Bool_t isPrimary = ( fMCEvent ) ? ( imother < fMCEvent->GetNumberOfPrimaries() ) : ((AliAODMCParticle*)part)->IsPrimary();
-    
-    if ( isPrimary ) {
-      if ( absPdg == 24 ) return kWbosonMu;
-      
-      for ( Int_t idec=0; idec<3; idec++ ) {
-        Int_t flv = (absPdg%100000)/den[idec];
-        if ( flv > 0 && flv < 4 ) return kDecayMu;
-        else if ( flv == 0 || flv > 5 ) continue;
-        else {
-          if ( den[idec] == 100 ) motherType = kQuarkoniumMu;
-          else if ( flv == 4 ) motherType = kCharmMu;
-          else motherType = kBeautyMu;
-          break; // break loop on pdg code
-          // but continue the global loop to find higher mass HF
-        }
-      } // loop on pdg code
-      if ( absPdg < 10 ) break; // particle loop
-    } // is primary
-    else {
-      if ( part->Zv() < -90. ) {
-        // If hadronic process => secondary
-        //if ( part->GetUniqueID() == kPHadronic ) {
-        return kSecondaryMu;
-        //}
-      }
-    } // is secondary
-    
-    imother = GetMotherIndex(part);
-    
-  } // loop on mothers
-  
-  return motherType;
-}
-
 //________________________________________________________________________
 Bool_t AliVAnalysisMuon::AddObjectToCollection(TObject* object, Int_t index)
 {
@@ -623,14 +433,15 @@ TObject* AliVAnalysisMuon::GetSum(TString physSel, TString trigClassNames, TStri
   /// Sum objects
   /// - physSel, trigClassNames must be in the form: key1,key2
   /// - centrality must be in the form minValue_maxValue
-  /// - objectPattern must be in the form match1&match2&match3,match4
-  ///   meaning that the object name must contain match1 and match2 and either one of match3 and match4
+  /// - objectPattern must be in the form match1,match2
+  ///   meaning that the object name must contain match1 or match2
+  ///   wildcard * is allowed
   
   if ( ! fMergeableCollection ) return 0x0;
   
   // Get centrality range
   Int_t firstCentrality = 1;
-  Int_t lastCentrality = fCentralityClasses->GetNbins();
+  Int_t lastCentrality = GetCentralityClasses()->GetNbins();
   
   TObjArray* centralityRange = centrality.Tokenize("_");
   Float_t range[2] = {0., 100.};
@@ -638,26 +449,26 @@ TObject* AliVAnalysisMuon::GetSum(TString physSel, TString trigClassNames, TStri
     for ( Int_t irange=0; irange<2; ++irange ) {
       range[irange] = ((TObjString*)centralityRange->At(irange))->GetString().Atof();
     }
-    firstCentrality = fCentralityClasses->FindBin(range[0]+0.0001);
-    lastCentrality = fCentralityClasses->FindBin(range[1]-0.0001);
+    firstCentrality = GetCentralityClasses()->FindBin(range[0]+0.0001);
+    lastCentrality = GetCentralityClasses()->FindBin(range[1]-0.0001);
   }
   delete centralityRange;
   
   TString sumCentralityString = "";
   for ( Int_t icent=firstCentrality; icent<=lastCentrality; ++icent ) {
     if ( ! sumCentralityString.IsNull() ) sumCentralityString += ",";
-    sumCentralityString += fCentralityClasses->GetBinLabel(icent);
+    sumCentralityString += GetCentralityClasses()->GetBinLabel(icent);
   }
   
-  objectPattern.ReplaceAll(" ","");
-  TObjArray* objPatternList = objectPattern.Tokenize("&");
-  TObjArray objPatternMatrix(objPatternList->GetEntries());
-  objPatternMatrix.SetOwner();
-  for ( Int_t ikey=0; ikey<objPatternList->GetEntries(); ikey++ ) {
-    TObjArray* subKeyList = ((TObjString*)objPatternList->At(ikey))->GetString().Tokenize(",");
-    objPatternMatrix.AddAt(subKeyList, ikey);
-  }
-  delete objPatternList;
+//  objectPattern.ReplaceAll(" ","");
+//  TObjArray* objPatternList = objectPattern.Tokenize("&");
+//  TObjArray objPatternMatrix(objPatternList->GetEntries());
+//  objPatternMatrix.SetOwner();
+//  for ( Int_t ikey=0; ikey<objPatternList->GetEntries(); ikey++ ) {
+//    TObjArray* subKeyList = ((TObjString*)objPatternList->At(ikey))->GetString().Tokenize(",");
+//    objPatternMatrix.AddAt(subKeyList, ikey);
+//  }
+//  delete objPatternList;
   
 
   TObjArray objectNameInCollection;
@@ -681,30 +492,53 @@ TObject* AliVAnalysisMuon::GetSum(TString physSel, TString trigClassNames, TStri
   delete physSelList;
   delete trigClassList;
   delete centralityList;
+  
+  TObjArray* objPatternList = objectPattern.Tokenize(",");
 
   TString matchingObjectNames = "";
   for ( Int_t iobj=0; iobj<objectNameInCollection.GetEntries(); iobj++ ) {
     TString objName = objectNameInCollection.At(iobj)->GetName();
-    Bool_t matchAnd = kTRUE;
-    for ( Int_t ikey=0; ikey<objPatternMatrix.GetEntries(); ikey++ ) {
-      TObjArray*  subKeyList = (TObjArray*)objPatternMatrix.At(ikey);
-      Bool_t matchOr = kFALSE;
-      for ( Int_t isub=0; isub<subKeyList->GetEntries(); isub++ ) {
-        TString subKeyString = ((TObjString*)subKeyList->At(isub))->GetString();
-        if ( objName.Contains(subKeyString.Data()) ) {
-          matchOr = kTRUE;
-          break;
-        }
-      }
-      if ( ! matchOr ) {
-        matchAnd = kFALSE;
-        break;
+    for ( Int_t ipat=0; ipat<objPatternList->GetEntries(); ipat++ ) {
+      TString currPattern = ((TObjString*)objPatternList->At(ipat))->GetString();
+      if ( currPattern.Contains("*") ) {
+        if ( ! objName.Contains(TRegexp(currPattern.Data(),kTRUE)) ) continue;
       }
+      else if ( objName != currPattern ) continue;
+
+      if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
+      matchingObjectNames += objName;
     }
-    if ( ! matchAnd ) continue;
-    if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
-    matchingObjectNames += objName;
   }
+  delete objPatternList;
+  
+//  for ( Int_t iobj=0; iobj<objectNameInCollection.GetEntries(); iobj++ ) {
+//    TString objName = objectNameInCollection.At(iobj)->GetName();
+//    Bool_t matchAnd = kTRUE;
+//    for ( Int_t ikey=0; ikey<objPatternMatrix.GetEntries(); ikey++ ) {
+//      TObjArray*  subKeyList = (TObjArray*)objPatternMatrix.At(ikey);
+//      Bool_t matchOr = kFALSE;
+//      for ( Int_t isub=0; isub<subKeyList->GetEntries(); isub++ ) {
+//        TString subKeyString = ((TObjString*)subKeyList->At(isub))->GetString();
+//        if ( subKeyString.Contains("*") ) {
+//          if ( objName.Contains(TRegexp(subKeyString.Data())) ) {
+//            matchOr = kTRUE;
+//            break;
+//          }
+//        }
+//        else if ( objName == subKeyString ) {
+//          matchOr = kTRUE;
+//          break;
+//        }
+//      }
+//      if ( ! matchOr ) {
+//        matchAnd = kFALSE;
+//        break;
+//      }
+//    }
+//    if ( ! matchAnd ) continue;
+//    if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
+//    matchingObjectNames += objName;
+//  }
 
   TString idPattern = Form("/%s/%s/%s/%s", physSel.Data(), trigClassNames.Data(), sumCentralityString.Data(), matchingObjectNames.Data());
   idPattern.ReplaceAll(" ","");
@@ -740,92 +574,35 @@ Bool_t AliVAnalysisMuon::SetSparseRange(AliCFGridSparse* gridSparse,
   /// Check the bin limits.
   //
   
-  option.ToUpper();
-  Int_t minVarBin = -1, maxVarBin = -1;
-  TAxis* axis = gridSparse->GetAxis(ivar);
-  
-  if ( ! axis ) {
-    printf("Warning: Axis %i not found in %s", ivar, gridSparse->GetName());
-    return kFALSE;
-  }
-  
-  if ( ! labelName.IsNull() ) {
-    minVarBin = axis->FindBin(labelName.Data());
-    maxVarBin = minVarBin;
-    if ( minVarBin < 1 ) {
-      printf("Warning: %s: label %s not found. Nothing done", gridSparse->GetName(), labelName.Data());
-      return kFALSE;
-    }
-  }
-  else if ( option.Contains( "USEBIN" ) ) {
-    minVarBin = (Int_t)varMin;
-    maxVarBin = (Int_t)varMax;
-  }
-  else {
-    minVarBin = axis->FindBin(varMin);
-    maxVarBin = axis->FindBin(varMax);
-  }
-  
-  if ( axis->GetFirst() == minVarBin && axis->GetLast() == maxVarBin ) return kFALSE;
+  // Keep for backward compatibility
   
-  gridSparse->SetRangeUser(ivar, axis->GetBinCenter(minVarBin), axis->GetBinCenter(maxVarBin));
-  
-  return kTRUE;
+  return AliAnalysisMuonUtility::SetSparseRange(gridSparse,ivar,labelName,varMin, varMax,option);
+}
+
+//________________________________________________________________________
+TString AliVAnalysisMuon::GetDefaultTrigClassPatterns() const
+{
+  /// Get default trigger class patterns
+  return fMuonEventCuts->GetDefaultTrigClassPatterns();
 }
 
 //________________________________________________________________________
-void AliVAnalysisMuon::SetTrigClassPatterns(TString pattern)
+void AliVAnalysisMuon::SetTrigClassPatterns(const TString pattern)
 {
   /// Set trigger classes
-  ///
-  /// Classes are filled dynamically according to the pattern
-  /// - if name contains ! (without spaces): reject it
-  /// - in the matching pattern it is also possible to specify the
-  ///   pt cut level associated to the trigger
-  /// example:
-  /// SetTrigClassPatterns("CMBAC CPBI1MSL:Lpt CPBI1MSH:Hpt !ALLNOTRD")
-  /// keeps classes containing CMBAC, CPBI1MSL and CPBI1MSH and not containing ALLNOTRD.
-  /// In addition, it knows that the class matching CPBI1MSL requires an Lpt trigger
-  /// and the one with CPBI1MSH requires a Hpt trigger.
-  /// Hence, in the analysis, the function
-  /// TrackPtCutMatchTrigClass(track, "CPBIMSL") returns true if track match Lpt
-  /// TrackPtCutMatchTrigClass(track, "CPBIMSL") returns true if track match Hpt
-  /// TrackPtCutMatchTrigClass(track, "CMBAC") always returns true
-  ///
-  /// CAVEAT: if you use an fCFContainer and you want an axis to contain the trigger classes,
-  ///         please be sure that each pattern matches only 1 trigger class, or triggers will be mixed up
-  ///         when merging different chuncks.
-
-  fSelectedTrigPattern->SetOwner();
-  if ( fSelectedTrigPattern->GetEntries() > 0 ) fSelectedTrigPattern->Delete();
-  fRejectedTrigPattern->SetOwner();
-  if ( fRejectedTrigPattern->GetEntries() > 0 ) fRejectedTrigPattern->Delete();
-  fSelectedTrigLevel->SetOwner();
-  if ( fSelectedTrigLevel->GetEntries() > 0 ) fSelectedTrigLevel->Delete();
-
-  pattern.ReplaceAll("  "," ");
-  pattern.ReplaceAll("! ","!");
-  pattern.ReplaceAll(" :",":");
-
-  TObjArray* fullList = pattern.Tokenize(" ");
-
-  for ( Int_t ipat=0; ipat<fullList->GetEntries(); ++ipat ) {
-    TString currPattern = fullList->At(ipat)->GetName();
-    if ( currPattern.Contains("!") ) {
-      currPattern.ReplaceAll("!","");
-      fRejectedTrigPattern->AddLast(new TObjString(currPattern));
-    }
-    else {
-      TObjArray* arr = currPattern.Tokenize(":");
-      fSelectedTrigPattern->AddLast(new TObjString(arr->At(0)->GetName()));
-      TString selTrigLevel = ( arr->At(1) ) ? arr->At(1)->GetName() : "none";
-      selTrigLevel.ToUpper();
-      fSelectedTrigLevel->AddLast(new TObjString(selTrigLevel));
-      delete arr;
-    }
+  TString currPattern = pattern;
+  if ( currPattern.IsNull() ) { 
+    currPattern = GetDefaultTrigClassPatterns();
+    currPattern.Append(",!CMUP*"); // by default do not account for UltraPeripheral events
   }
-  
-  delete fullList;
+  fMuonEventCuts->SetTrigClassPatterns(currPattern);
+}
+
+//________________________________________________________________________
+TList* AliVAnalysisMuon::GetAllSelectedTrigClasses() const
+{
+  /// Get trigger classes
+  return fMuonEventCuts->GetAllSelectedTrigClasses();
 }
 
 //________________________________________________________________________
@@ -834,22 +611,57 @@ void AliVAnalysisMuon::SetCentralityClasses(Int_t nCentralityBins, Double_t* cen
   //
   /// Set centrality classes
   //
-  Double_t* bins = centralityBins;
-  Int_t nbins = nCentralityBins;
+  fMuonEventCuts->SetCentralityClasses(nCentralityBins, centralityBins);
+}
+
+//________________________________________________________________________
+TAxis* AliVAnalysisMuon::GetCentralityClasses() const
+{
+  //
+  /// Set centrality classes
+  //
+  return fMuonEventCuts->GetCentralityClasses();
+}
+
+//________________________________________________________________________
+Bool_t AliVAnalysisMuon::SetCentralityClassesFromOutput()
+{
+  //
+  /// Get axis of centrality classes from output key
+  //
+  if ( ! fMergeableCollection ) return kFALSE;
+  TList* centrKeyList = fMergeableCollection->CreateListOfKeys(2);
+  TObjArray centrLimitsList;
+  centrLimitsList.SetOwner();
+  if ( ! centrKeyList ) return kFALSE;
+  for ( Int_t ikey=0; ikey<centrKeyList->GetEntries(); ikey++ ) {
+    TString centr = static_cast<TObjString*>(centrKeyList->At(ikey))->GetString();
+    TObjArray* array = centr.Tokenize("_");
+    for ( Int_t ilim=0; ilim<array->GetEntries(); ilim++ ) {
+      TString currLim = static_cast<TObjString*>(array->At(ilim))->GetString();
+      if ( ! centrLimitsList.FindObject(currLim.Data()) ) centrLimitsList.Add(new TObjString(currLim));
+    }
+    delete array;
+  }
+  delete centrKeyList;
   
-  Double_t defaultCentralityBins[] = {-5., 0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 100., 105.};
-  if ( ! centralityBins ) {
-    bins = defaultCentralityBins;
-    nbins = sizeof(defaultCentralityBins)/sizeof(defaultCentralityBins[0])-1;
+  // Get unsorted array
+  TArrayD bins(centrLimitsList.GetEntries());
+  for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
+    bins[ibin] = static_cast<TObjString*>(centrLimitsList.At(ibin))->GetString().Atof();
   }
-
-  if ( fCentralityClasses ) delete fCentralityClasses;
-  fCentralityClasses = new TAxis(nbins, bins);
-  TString currClass = "";
-  for ( Int_t ibin=1; ibin<=fCentralityClasses->GetNbins(); ++ibin ){
-    currClass = Form("%.0f_%.0f",fCentralityClasses->GetBinLowEdge(ibin),fCentralityClasses->GetBinUpEdge(ibin));
-    fCentralityClasses->SetBinLabel(ibin, currClass.Data());
+  
+  // Sort it
+  Int_t index[bins.GetSize()];
+  TMath::Sort(bins.GetSize(),bins.GetArray(),index, kFALSE);
+  
+  TArrayD sortedBins(bins.GetSize());
+  for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
+    sortedBins[ibin] = bins[index[ibin]];
   }
+  
+  SetCentralityClasses(sortedBins.GetSize()-1, sortedBins.GetArray());
+  return kTRUE;
 }
 
 //________________________________________________________________________
@@ -871,88 +683,36 @@ void AliVAnalysisMuon::SetTerminateOptions(TString physSel, TString trigClass, T
 //________________________________________________________________________
 void AliVAnalysisMuon::InitKeys()
 {
+  //
+  /// Init keys
+  //
   TString chargeKeys = "MuMinus MuPlus";
   fChargeKeys = chargeKeys.Tokenize(" ");
   
-  TString srcKeys = "CharmMu BeautyMu QuarkoniumMu WbosonMu DecayMu SecondaryMu Hadron Unidentified";
+  TString srcKeys = "CharmMu BeautyMu QuarkoniumMu WbosonMu ZbosonMu DecayMu SecondaryMu Hadron Unidentified";
   fSrcKeys = srcKeys.Tokenize(" ");
   
   TString physSelKeys = "PhysSelPass PhysSelReject";
   fPhysSelKeys = physSelKeys.Tokenize(" ");
 }
 
+
 //________________________________________________________________________
-TObjArray* AliVAnalysisMuon::BuildTriggerClasses(TString firedTrigClasses)
+void AliVAnalysisMuon::SetWeight ( TObject* wgtObj )
 {
-  //
-  /// Return the list of trigger classes to be considered
-  /// for current event. Update the global list if necessary
-  //
-
-  TObjArray* selectedTrigClasses = new TObjArray(0);
-  selectedTrigClasses->SetOwner();
-  
-  TObjArray* firedTrigClassesList = firedTrigClasses.Tokenize(" ");
-
-  for ( Int_t itrig=0; itrig<firedTrigClassesList->GetEntries(); ++itrig ) {
-    TString trigName = ((TObjString*)firedTrigClassesList->At(itrig))->GetString();
-    Bool_t rejectTrig = kFALSE;
-    for ( Int_t ipat=0; ipat<fRejectedTrigPattern->GetEntries(); ++ipat ) {
-      if ( trigName.Contains(fRejectedTrigPattern->At(ipat)->GetName() ) ) {
-        rejectTrig = kTRUE;
-        break;
-      }
-    } // loop on reject pattern
-    if ( rejectTrig ) continue;
-
-    Int_t matchPatternIndex = -1;
-    for ( Int_t ipat=0; ipat<fSelectedTrigPattern->GetEntries(); ++ipat ) {
-      if ( trigName.Contains(fSelectedTrigPattern->At(ipat)->GetName() ) ) {
-        matchPatternIndex = ipat;
-        break;
-      }
-    } // loop on keep pattern
-    if ( matchPatternIndex < 0 ) continue;
-
-    selectedTrigClasses->AddLast(new TObjString(trigName));
-    if ( fTriggerClasses->FindObject(trigName.Data()) ) continue;
-    Int_t trigLevel = 0;
-    TString trigLevelString = fSelectedTrigLevel->At(matchPatternIndex)->GetName();
-    if ( trigLevelString.Contains("APT") ) trigLevel = 1;
-    else if ( trigLevelString.Contains("LPT") ) trigLevel = 2;
-    else if ( trigLevelString.Contains("HPT") ) trigLevel = 3;
-    AliInfo(Form("Adding %s to considered trigger classes",trigName.Data()));
-    TObjString* addTrig = new TObjString(trigName);
-    UInt_t uniqueId = trigLevel;
-    addTrig->SetUniqueID(uniqueId);
-    fTriggerClasses->Add(addTrig);
-  } // loop on trigger classes
-
-  delete firedTrigClassesList;
-
-  return selectedTrigClasses;
+  /// Set weight
+  if ( fWeights->FindObject(wgtObj->GetName()) ) {
+    AliWarning(Form("Weight object %s is already in the list",wgtObj->GetName()));
+    return;
+  }
+  fWeights->Add(wgtObj);
 }
 
-
 //________________________________________________________________________
-Bool_t AliVAnalysisMuon::TrackPtCutMatchTrigClass(AliVParticle* track, TString trigClassName)
+TObject* AliVAnalysisMuon::GetWeight ( const Char_t* wgtName )
 {
-  /// Check if track passes the trigger pt cut level used in the trigger class
-  Int_t matchTrig = ( fAODEvent ) ? ((AliAODTrack*)track)->GetMatchTrigger() : ((AliESDMuonTrack*)track)->GetMatchTrigger();
-  Int_t classMatchLevel = GetTrigClassPtCutLevel(trigClassName);
-  return matchTrig >= classMatchLevel;
+  /// Get weight
+  return fWeights->FindObject(wgtName);
 }
 
 
-//________________________________________________________________________
-Int_t AliVAnalysisMuon::GetTrigClassPtCutLevel(TString trigClassName)
-{
-  /// Get trigger class pt cut level for tracking/trigger matching
-  TObject* obj = fTriggerClasses->FindObject(trigClassName.Data());
-  if ( ! obj ) {
-    AliWarning(Form("Class %s not in the list!", trigClassName.Data()));
-    return -1;
-  }
-  
-  return obj->GetUniqueID();
-}