1) Adding class AliAnalysisMuonUtility which contains static methods allowing to...
authorpcrochet <pcrochet@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 21 Sep 2012 14:05:45 +0000 (14:05 +0000)
committerpcrochet <pcrochet@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 21 Sep 2012 14:05:45 +0000 (14:05 +0000)
PWG/muon/AliAnalysisMuonUtility.cxx [new file with mode: 0644]
PWG/muon/AliAnalysisMuonUtility.h [new file with mode: 0644]
PWG/muon/AliMuonEventCuts.cxx [new file with mode: 0644]
PWG/muon/AliMuonEventCuts.h [new file with mode: 0644]

diff --git a/PWG/muon/AliAnalysisMuonUtility.cxx b/PWG/muon/AliAnalysisMuonUtility.cxx
new file mode 100644 (file)
index 0000000..0e640da
--- /dev/null
@@ -0,0 +1,410 @@
+/**************************************************************************
+ * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id: AliAnalysisMuonUtility.cxx 47782 2011-02-24 18:37:31Z martinez $ */
+
+//-----------------------------------------------------------------------------
+/// \class AliAnalysisMuonUtility
+/// Static tilities for muon analysis
+/// The class allows to treat AODs and ESDs
+/// as well as MC AODs and MC in a transparent way
+///
+/// \author Diego Stocco
+//-----------------------------------------------------------------------------
+
+#include "AliAnalysisMuonUtility.h"
+
+// ROOT includes
+#include "TAxis.h"
+#include "TMath.h"
+#include "TLorentzVector.h"
+
+// STEER includes
+#include "AliAODEvent.h"
+#include "AliAODTrack.h"
+#include "AliAODMCParticle.h"
+#include "AliMCEvent.h"
+#include "AliMCParticle.h"
+#include "AliESDEvent.h"
+#include "AliESDMuonTrack.h"
+#include "AliVVertex.h"
+#include "AliAODMCHeader.h"
+#include "AliLog.h"
+
+// CORRFW includes
+#include "AliCFGridSparse.h"
+
+/// \cond CLASSIMP
+ClassImp(AliAnalysisMuonUtility) // Class implementation in ROOT context
+/// \endcond
+
+
+//________________________________________________________________________
+Bool_t AliAnalysisMuonUtility::IsAODEvent ( const AliVEvent* event )
+{
+  /// Check if event is from ESD or AOD
+  return ( event->IsA() == AliAODEvent::Class() );
+}
+
+//________________________________________________________________________
+Bool_t AliAnalysisMuonUtility::IsAODTrack ( const AliVParticle* track )
+{
+  /// Check if track is from ESD or AOD
+  return ( track->IsA() == AliAODTrack::Class() );
+}
+
+//________________________________________________________________________
+Bool_t AliAnalysisMuonUtility::IsMuonTrack ( const AliVParticle* track )
+{
+  /// Check if track has muon tracker info
+  return ( IsAODTrack(track) ) ? static_cast<const AliAODTrack*>(track)->IsMuonTrack() : static_cast<const AliESDMuonTrack*>(track)->ContainTrackerData();
+}
+
+//________________________________________________________________________
+Bool_t AliAnalysisMuonUtility::IsMuonGhost ( const AliVParticle* track )
+{
+  /// Check if track has trigger info
+  return ( IsAODTrack(track) ) ? kFALSE : ( ! static_cast<const AliESDMuonTrack*>(track)->ContainTrackerData() );
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetRabs ( const AliVParticle* track )
+{
+  /// Get Rabs
+  return ( IsAODTrack(track) ) ? static_cast<const AliAODTrack*>(track)->GetRAtAbsorberEnd() : static_cast<const AliESDMuonTrack*>(track)->GetRAtAbsorberEnd();
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetThetaAbsDeg ( const AliVParticle* track )
+{
+  /// Get Theta at absorber end (in deg)
+  return TMath::ATan( GetRabs(track) / 505. ) * TMath::RadToDeg();
+}
+
+//________________________________________________________________________
+Int_t AliAnalysisMuonUtility::GetMatchTrigger ( const AliVParticle* track )
+{
+  /// Get match trigger
+  return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->GetMatchTrigger() : static_cast<const AliESDMuonTrack*>(track)->GetMatchTrigger();
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetChi2perNDFtracker ( const AliVParticle* track )
+{
+  /// Get Theta at absorber end (in deg)
+  return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->Chi2perNDF() : static_cast<const AliESDMuonTrack*>(track)->GetNormalizedChi2();
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetXatVertex ( const AliVParticle* track )
+{
+  /// Get X at vertex
+  Double_t coor = 0.;
+  if ( IsAODTrack(track) ) {
+    Double_t vtxPos[3];
+    static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos);
+    coor = vtxPos[0];
+  }
+  else coor = static_cast<const AliESDMuonTrack*>(track)->GetNonBendingCoor();
+  
+  return coor;
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetYatVertex ( const AliVParticle* track )
+{
+  /// Get Y at vertex
+  Double_t coor = 0.;
+  if ( IsAODTrack(track) ) {
+    Double_t vtxPos[3];
+    static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos);
+    coor = vtxPos[1];
+  }
+  else coor = static_cast<const AliESDMuonTrack*>(track)->GetBendingCoor();
+  
+  return coor;
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetZatVertex ( const AliVParticle* track )
+{
+  /// Get Z at vertex
+  Double_t coor = 0.;
+  if ( IsAODTrack(track) ) {
+    Double_t vtxPos[3];
+    static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos);
+    coor = vtxPos[2];
+  }
+  else coor = static_cast<const AliESDMuonTrack*>(track)->GetZ();
+  
+  return coor;
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetXatDCA ( const AliVParticle* track )
+{
+  /// Get X at DCA
+  return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->XAtDCA() : static_cast<const AliESDMuonTrack*>(track)->GetNonBendingCoorAtDCA();
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetYatDCA ( const AliVParticle* track )
+{
+  /// Get Y at DCA
+  return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->YAtDCA() : static_cast<const AliESDMuonTrack*>(track)->GetBendingCoorAtDCA();
+}
+
+//________________________________________________________________________
+UInt_t AliAnalysisMuonUtility::GetMUONTrigHitsMapTrk ( const AliVParticle* track )
+{
+  /// Get hit pattern in trigger chambers from tracker track extrapolation
+  return ( IsAODTrack(track) ) ? const_cast<AliAODTrack*>(static_cast<const AliAODTrack*>(track))->GetMUONTrigHitsMapTrk() : static_cast<const AliESDMuonTrack*>(track)->GetHitsPatternInTrigChTrk();
+}
+
+//________________________________________________________________________
+UInt_t AliAnalysisMuonUtility::GetMUONTrigHitsMapTrg ( const AliVParticle* track )
+{
+  /// Get hit pattern in trigger chambers from tracker track extrapolation
+  return ( IsAODTrack(track) ) ? const_cast<AliAODTrack*>(static_cast<const AliAODTrack*>(track))->GetMUONTrigHitsMapTrg() : static_cast<const AliESDMuonTrack*>(track)->GetHitsPatternInTrigCh();
+}
+
+//________________________________________________________________________
+TString AliAnalysisMuonUtility::GetFiredTriggerClasses ( const AliVEvent* event )
+{
+  /// Check if track is from ESD or AOD
+  return ( IsAODEvent(event) ) ? static_cast<const AliAODEvent*>(event)->GetFiredTriggerClasses() : static_cast<const AliESDEvent*>(event)->GetFiredTriggerClasses();
+}
+
+//________________________________________________________________________
+Int_t AliAnalysisMuonUtility::GetNTracks ( const AliVEvent* event )
+{
+  //
+  /// Return the number of tracks in event
+  //
+  return ( IsAODEvent(event) ) ? static_cast<const AliAODEvent*>(event)->GetNTracks() : static_cast<const AliESDEvent*>(event)->GetNumberOfMuonTracks();
+}
+
+
+//________________________________________________________________________
+AliVParticle* AliAnalysisMuonUtility::GetTrack ( Int_t itrack, const AliVEvent* event )
+{
+  //
+  /// Get the current track
+  //
+  AliVParticle* track = 0x0;
+  if ( IsAODEvent(event) ) track = static_cast<const AliAODEvent*>(event)->GetTrack(itrack);
+  else {
+    AliESDEvent* esdEvent = const_cast<AliESDEvent*>(static_cast<const AliESDEvent*> (event));
+    track = esdEvent->GetMuonTrack(itrack);
+  }
+  return track;
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::MuonMass2()
+{
+  /// A usefull constant
+  return 1.11636129640000012e-02;
+}
+
+//________________________________________________________________________
+TLorentzVector AliAnalysisMuonUtility::GetTrackPair ( const AliVParticle* track1, const AliVParticle* track2 )
+{
+  //
+  /// Get track pair
+  //
+  const 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;
+}
+
+//________________________________________________________________________
+Bool_t AliAnalysisMuonUtility::IsMCEvent ( const AliVEvent* event, const AliMCEvent* mcEvent )
+{
+  //
+  /// Contains MC info
+  //
+  return ( mcEvent || ( IsAODEvent(event) && static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCParticle::StdBranchName()) ) );
+}
+
+
+//________________________________________________________________________
+Bool_t AliAnalysisMuonUtility::IsAODMCTrack( const AliVParticle* mcParticle )
+{
+  /// Check if track is from AOD MC
+  return ( mcParticle->IsA() == AliAODMCParticle::Class() );
+}
+
+
+//________________________________________________________________________
+Int_t AliAnalysisMuonUtility::GetNMCTracks ( const AliVEvent* event, const AliMCEvent* mcEvent )
+{
+  //
+  /// Return the number of MC tracks in event
+  //
+  Int_t nMCtracks = 0;
+  if ( mcEvent ) nMCtracks = mcEvent->GetNumberOfTracks();
+  else if ( IsAODEvent(event) ) {
+    TClonesArray* mcArray = (TClonesArray*)static_cast<const AliAODEvent*>(event)->GetList()->FindObject(AliAODMCParticle::StdBranchName());
+    if ( mcArray ) nMCtracks = mcArray->GetEntries();
+  }
+  return nMCtracks;
+}
+
+//________________________________________________________________________
+AliVParticle* AliAnalysisMuonUtility::GetMCTrack ( Int_t trackLabel, const AliVEvent* event, const AliMCEvent* mcEvent )
+{
+  //
+  /// 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 ( mcEvent ) mcTrack = mcEvent->GetTrack(trackLabel);
+  else if ( IsAODEvent(event) ) {
+    TClonesArray* mcArray = (TClonesArray*)static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCParticle::StdBranchName());
+    if ( mcArray ) mcTrack =  (AliVParticle*)mcArray->At(trackLabel);
+  }
+  if ( ! mcTrack ) AliWarningClass(Form("No track with label %i!", trackLabel));
+  return mcTrack;
+}
+
+//________________________________________________________________________
+Double_t AliAnalysisMuonUtility::GetMCVertexZ ( const AliVEvent* event, const AliMCEvent* mcEvent )
+{
+  /// Get MC vertex Z
+  Double_t vz = 0.;
+  if ( mcEvent ) vz = mcEvent->GetPrimaryVertex()->GetZ();
+  else if ( IsAODEvent(event) ) {
+    AliAODMCHeader* aodMCHeader = static_cast<AliAODMCHeader*> (static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCHeader::StdBranchName()));
+    vz = aodMCHeader->GetVtxZ();
+  }
+  else AliErrorClass("No MC event found");
+  return vz;
+}
+
+//________________________________________________________________________
+Int_t AliAnalysisMuonUtility::GetMotherIndex ( const AliVParticle* mcParticle )
+{
+  //
+  /// Return the mother index
+  //
+  return ( IsAODMCTrack(mcParticle) ) ? static_cast<const AliAODMCParticle*>(mcParticle)->GetMother() : static_cast<const AliMCParticle*>(mcParticle)->GetMother();
+}
+
+//________________________________________________________________________
+Int_t AliAnalysisMuonUtility::GetDaughterIndex ( const AliVParticle* mcParticle, Int_t idaughter )
+{
+  //
+  /// Return the daughter index
+  /// idaughter can be:
+  /// 0 -> first daughter
+  /// 1 -> last daughter
+  //
+  if ( idaughter < 0 || idaughter > 1 ) {
+    AliErrorClass(Form("Requested daughter %i Daughter index can be either 0 (first) or 1 (last)", idaughter));
+    return -1;
+  }
+  
+  if ( IsAODMCTrack(mcParticle) ) return static_cast<const AliAODMCParticle*>(mcParticle)->GetDaughter(idaughter);
+  
+  if ( idaughter == 0 ) return static_cast<const AliMCParticle*>(mcParticle)->GetFirstDaughter();
+  else return static_cast<const AliMCParticle*>(mcParticle)->GetLastDaughter();
+}
+
+//________________________________________________________________________
+Bool_t AliAnalysisMuonUtility::IsPrimary ( const AliVParticle* mcParticle, const AliMCEvent* mcEvent )
+{
+  /// Check if the particle is primary
+  
+  Bool_t isPrimary = kFALSE;
+  if ( mcEvent ) {
+    // First get the index of the current particle in the stack.
+    // For this: get the mother, and get its daughter.
+    // Since the mother can have many daughters, you can come up to a "sister"
+    // of the particle. Nevertheless, if it is primary, then also the particle itself should be.
+    Int_t imother = static_cast<const AliMCParticle*> (mcParticle)->GetMother();
+    if ( imother < 0 ) isPrimary = kTRUE;
+    else if ( static_cast<const AliMCParticle*>(mcEvent->GetTrack(imother))->GetFirstDaughter() < const_cast<AliMCEvent*>(mcEvent)->GetNumberOfPrimaries() ) isPrimary = kTRUE;
+  }
+  else isPrimary = static_cast<const AliAODMCParticle*>(mcParticle)->IsPrimary();
+  return isPrimary;
+}
+
+
+//________________________________________________________________________
+AliVVertex* AliAnalysisMuonUtility::GetVertexSPD ( const AliVEvent* event )
+{
+  //
+  /// Get vertex SPD
+  //
+  
+  AliVVertex* primaryVertex = ( IsAODEvent(event) ) ? (AliVVertex*)static_cast<const AliAODEvent*>(event)->GetPrimaryVertexSPD() : (AliVVertex*)static_cast<const AliESDEvent*>(event)->GetPrimaryVertexSPD();
+  return primaryVertex;
+}
+
+
+//_______________________________________________________________________
+Bool_t AliAnalysisMuonUtility::SetSparseRange(AliCFGridSparse* gridSparse,
+                                        Int_t ivar, TString labelName,
+                                        Double_t varMin, Double_t varMax,
+                                        TString option)
+{
+  //
+  /// Set range in a smart way.
+  /// Allows to select a bin from the label.
+  /// 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;
+  
+  gridSparse->SetRangeUser(ivar, axis->GetBinCenter(minVarBin), axis->GetBinCenter(maxVarBin));
+  
+  return kTRUE;
+}
diff --git a/PWG/muon/AliAnalysisMuonUtility.h b/PWG/muon/AliAnalysisMuonUtility.h
new file mode 100644 (file)
index 0000000..d54ec64
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef ALIANALYSISMUONUTILITY_H
+#define ALIANALYSISMUONUTILITY_H
+
+/* $Id: AliAnalysisMuonUtility.h 47782 2011-02-24 18:37:31Z martinez $ */ 
+
+//
+// Utilities for muon analysis
+//
+// Author: Diego Stocco
+//
+
+#include "TObject.h"
+#include "TString.h"
+
+class TLorentzVector;
+class AliVEvent;
+class AliMCEvent;
+class AliVParticle;
+class AliVVertex;
+class AliCFGridSparse;
+
+class AliAnalysisMuonUtility : public TObject {
+ public:
+  
+  // Utility methods for CF container
+  static Bool_t SetSparseRange(AliCFGridSparse* gridSparse,
+                               Int_t ivar, TString labelName,
+                               Double_t varMin, Double_t varMax,
+                               TString option = "");
+  
+  // Transparently handle ESD/AOD
+  static Bool_t IsAODEvent ( const AliVEvent* event );
+  static TString GetFiredTriggerClasses ( const AliVEvent* event );
+  static Int_t GetNTracks ( const AliVEvent* event );
+  static AliVParticle* GetTrack ( Int_t itrack, const AliVEvent* event );
+  
+  static Bool_t IsAODTrack ( const AliVParticle* track );
+  static Bool_t IsMuonTrack ( const AliVParticle* track );
+  static Bool_t IsMuonGhost ( const AliVParticle* track );
+  static Double_t GetRabs ( const AliVParticle* track );
+  static Double_t GetThetaAbsDeg ( const AliVParticle* track );
+  static Int_t GetMatchTrigger ( const AliVParticle* track );
+  static Bool_t MatchApt ( const AliVParticle* track ) { return GetMatchTrigger(track) >= 1; }
+  static Bool_t MatchLpt ( const AliVParticle* track ) { return GetMatchTrigger(track) >= 2; }
+  static Bool_t MatchHpt ( const AliVParticle* track ) { return GetMatchTrigger(track) >= 3; }
+  static Double_t GetChi2perNDFtracker ( const AliVParticle* track );
+  static Double_t GetXatVertex ( const AliVParticle* track );
+  static Double_t GetYatVertex ( const AliVParticle* track );
+  static Double_t GetZatVertex ( const AliVParticle* track );
+  static Double_t GetXatDCA ( const AliVParticle* track );
+  static Double_t GetYatDCA ( const AliVParticle* track );
+  static Double_t GetZatDCA ( const AliVParticle* track ) { return GetZatVertex(track); }
+  static UInt_t GetMUONTrigHitsMapTrk ( const AliVParticle* track );
+  static UInt_t GetMUONTrigHitsMapTrg ( const AliVParticle* track );
+  static TLorentzVector GetTrackPair ( const AliVParticle* track1, const AliVParticle* track2 );
+
+  
+  // Transparently handle MC
+  static Bool_t IsMCEvent ( const AliVEvent* event, const AliMCEvent* mcEvent );
+  static Int_t GetNMCTracks ( const AliVEvent* event, const AliMCEvent* mcEvent );
+  static AliVParticle* GetMCTrack ( Int_t trackLabel, const AliVEvent* event, const AliMCEvent* mcEvent );
+  static Double_t GetMCVertexZ ( const AliVEvent* event, const AliMCEvent* mcEvent );
+  
+  static Bool_t IsAODMCTrack ( const AliVParticle* mcParticle );
+  static Int_t GetMotherIndex ( const AliVParticle* mcParticle );
+  static Int_t GetDaughterIndex ( const AliVParticle* mcParticle, Int_t idaughter );
+  static Bool_t IsPrimary ( const AliVParticle* mcParticle, const AliMCEvent* mcEvent );
+  
+  // A useful constant
+  static Double_t MuonMass2();
+  
+  // Transparently handle vertex
+  static AliVVertex* GetVertexSPD ( const AliVEvent* event );
+  
+  ClassDef(AliAnalysisMuonUtility, 0);
+};
+
+#endif
diff --git a/PWG/muon/AliMuonEventCuts.cxx b/PWG/muon/AliMuonEventCuts.cxx
new file mode 100644 (file)
index 0000000..058b1f2
--- /dev/null
@@ -0,0 +1,645 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+#include "AliMuonEventCuts.h"
+
+#include "TMath.h"
+#include "THashList.h"
+#include "TArrayD.h"
+#include "TObjArray.h"
+#include "TObjString.h"
+#include "TFile.h"
+#include "TParameter.h"
+#include "TKey.h"
+#include "TSystem.h"
+#include "TAxis.h"
+#include "TArrayI.h"
+
+#include "AliLog.h"
+#include "AliInputEventHandler.h"
+#include "AliVEvent.h"
+#include "AliESDEvent.h"
+#include "AliAODEvent.h"
+#include "AliVVertex.h"
+#include "AliCentrality.h"
+#include "AliTimeStamp.h"
+
+#include "AliAnalysisMuonUtility.h"
+//#include "AliAnalysisManager.h"
+
+/// \cond CLASSIMP
+ClassImp(AliMuonEventCuts) // Class implementation in ROOT context
+/// \endcond
+
+
+//________________________________________________________________________
+AliMuonEventCuts::AliMuonEventCuts() :
+  AliAnalysisCuts(),
+//fIsMC(kFALSE),
+//fUseCustomParam(kFALSE),
+  fPhysicsSelectionMask(0),
+  fParameters(TArrayD(kNParameters)),
+  fDefaultTrigClassPatterns(""),
+  fSelectedTrigPattern(0x0),
+  fRejectedTrigPattern(0x0),
+  fSelectedTrigLevel(0x0),
+  fAllSelectedTrigClasses(0x0),
+  fCentralityClasses(0x0),
+  fTimeStamp(0x0),
+  fSelectedTrigClassesInEvent(0x0)
+{
+  /// Default ctor.
+  fParameters.Reset();
+}
+
+//________________________________________________________________________
+AliMuonEventCuts::AliMuonEventCuts(const char* name, const char* title ) :
+AliAnalysisCuts(name, title),
+  //fIsMC(kFALSE),
+  //fUseCustomParam(kFALSE),
+  fPhysicsSelectionMask(AliVEvent::kAny),
+  fParameters(TArrayD(kNParameters)),
+  fDefaultTrigClassPatterns(""),
+  fSelectedTrigPattern(new TObjArray()),
+  fRejectedTrigPattern(new TObjArray()),
+  fSelectedTrigLevel(new TObjArray()),
+  fAllSelectedTrigClasses(new THashList()),
+  fCentralityClasses(0x0),
+  fTimeStamp(0x0),
+  fSelectedTrigClassesInEvent(new TObjArray())
+{
+  /// Constructor
+  fParameters.Reset();
+  SetDefaultParameters();
+  SetDefaultFilterMask();
+  SetDefaultTrigClassPatterns();
+  SetTrigClassLevels();
+  SetCentralityClasses();
+  fAllSelectedTrigClasses->SetOwner();
+  fSelectedTrigClassesInEvent->SetOwner();
+}
+
+//________________________________________________________________________
+AliMuonEventCuts::AliMuonEventCuts(const AliMuonEventCuts& obj) :
+  AliAnalysisCuts(obj),
+  //fIsMC(obj.fIsMC),
+  //fUseCustomParam(obj.fUseCustomParam),
+  fPhysicsSelectionMask(obj.fPhysicsSelectionMask),
+  fParameters(obj.fParameters),
+  fDefaultTrigClassPatterns(obj.fDefaultTrigClassPatterns),
+  fSelectedTrigPattern(obj.fSelectedTrigPattern),
+  fRejectedTrigPattern(obj.fRejectedTrigPattern),
+  fSelectedTrigLevel(obj.fSelectedTrigLevel),
+  fAllSelectedTrigClasses(obj.fAllSelectedTrigClasses),
+  fCentralityClasses(obj.fCentralityClasses),
+  fTimeStamp(obj.fTimeStamp),
+  fSelectedTrigClassesInEvent(obj.fSelectedTrigClassesInEvent)
+{
+  /// Copy constructor
+}
+
+
+//________________________________________________________________________
+AliMuonEventCuts& AliMuonEventCuts::operator=(const AliMuonEventCuts& obj)
+{
+  /// Assignment operator
+  if ( this != &obj ) { 
+    AliAnalysisCuts::operator=(obj);
+    //fIsMC = obj.fIsMC;
+    //fUseCustomParam = obj.fUseCustomParam;
+    fPhysicsSelectionMask = obj.fPhysicsSelectionMask;
+    fParameters = obj.fParameters;
+    fDefaultTrigClassPatterns = obj.fDefaultTrigClassPatterns;
+    fSelectedTrigPattern = obj.fSelectedTrigPattern;
+    fRejectedTrigPattern = obj.fRejectedTrigPattern;
+    fSelectedTrigLevel = obj.fSelectedTrigLevel;
+    fAllSelectedTrigClasses = obj.fAllSelectedTrigClasses;
+    fCentralityClasses = obj.fCentralityClasses;
+    fTimeStamp = obj.fTimeStamp;
+    fSelectedTrigClassesInEvent = obj.fSelectedTrigClassesInEvent;
+  }
+  return *this;
+}
+
+
+//________________________________________________________________________
+AliMuonEventCuts::~AliMuonEventCuts()
+{
+  /// Destructor
+  delete fSelectedTrigPattern;
+  delete fRejectedTrigPattern;
+  delete fSelectedTrigLevel;
+  delete fAllSelectedTrigClasses;
+  delete fSelectedTrigClassesInEvent;
+  delete fCentralityClasses;
+  delete fTimeStamp;
+}
+
+//________________________________________________________________________
+//Bool_t AliMuonEventCuts::RunMatchesRange( Int_t runNumber, const Char_t* objName ) const
+//{
+//  /// Check if the object contains the run
+//  TString sname(objName);
+//  TObjArray* array = sname.Tokenize("_");
+//  array->SetOwner();
+//  Int_t runRange[2] = { -1, -1 };
+//  if ( array->GetEntries() >= 3 ) {
+//    for ( Int_t irun=0; irun<2; ++irun ) {
+//      TString currRun = array->At(irun+1)->GetName();
+//      if ( currRun.IsDigit() ) runRange[irun] = currRun.Atoi();
+//    }
+//  }
+//  delete array;
+//  return ( runNumber >= runRange[0] && runNumber <= runRange[1]);
+//}
+//
+//________________________________________________________________________
+//void AliMuonEventCuts::SetUseCustomParam( Bool_t useCustomParam, Int_t runNumber  )
+//{
+//  /// Flag to select custom parameters
+//  /// It first searches the default parameters in OADB
+//  /// then disables the access to the OADB
+//  /// and allows to manually modify parameters
+//
+//  if ( ! fUseCustomParam && useCustomParam ) SetRun(runNumber);
+//  fUseCustomParam = useCustomParam;
+//}
+//
+//________________________________________________________________________
+//Bool_t AliMuonEventCuts::SetRun( Int_t runNumber )
+//{
+//  /// Get parameters from OADB for runNumber
+//  
+//  if ( fUseCustomParam ) return kFALSE;
+//  return StreamParameters(runNumber, -1);
+//}
+//
+//
+//________________________________________________________________________
+//Bool_t AliMuonEventCuts::StreamParameters( Int_t runNumber,  Int_t runMax )
+//{
+//  if ( runMax > 0 ) { // Stream to OADB
+//    if ( ! fUseCustomParam ) {
+//      AliError("Users are not allowed to update OADB. Use SetUseCustomParam() instead");
+//      return kFALSE;
+//    }
+//  }
+//
+//  TString filename = Form("%s/PWG/MUON/MuonEventCuts.root",AliAnalysisManager::GetOADBPath());
+//  if ( fIsMC ) filename.ReplaceAll(".root", "_MC.root");
+//
+//  TString parNames[kNParameters];
+//  parNames[kMeanDcaX]       = "MeanDcaX";
+//  parNames[kMeanDcaY]       = "MeanDcaY";
+//  parNames[kMeanDcaZ]       = "MeanDcaZ";
+//  parNames[kMeanPCorr23]    = "MeanPCorr23";
+//  parNames[kMeanPCorr310]   = "MeanPCorr310";
+//  parNames[kSigmaPdca23]    = "SigmaPdca23";
+//  parNames[kSigmaPdca310]   = "SigmaPdca310";
+//  parNames[kNSigmaPdcaCut]  = "NSigmaPdcaCut";
+//  parNames[kChi2NormCut]    = "Chi2NormCut";
+//  parNames[kRelPResolution] = "RelPResolution";
+//  parNames[kSharpPtApt]     = "SharpPtApt";
+//  parNames[kSharpPtLpt]     = "SharpPtLpt";
+//  parNames[kSharpPtHpt]     = "SharpPtHpt";
+//
+//  TObjArray* paramList = 0x0;
+//
+//  if ( runMax < 0 ) { // Get from OADB
+//    TFile* file = TFile::Open(filename.Data(), "READ");
+//    if ( ! file ) {
+//      AliError(Form("OADB file %s not found!", filename.Data()));
+//      return kFALSE;
+//    }
+//
+//    TList* listOfKeys = file->GetListOfKeys();
+//    TIter next(listOfKeys);
+//    TObject* key = 0x0;
+//    Bool_t foundMatch = kFALSE;
+//    TObject* defaultObj = 0x0;
+//    while ( ( key = next() ) ) {
+//      TString objName = key->GetName();
+//      objName.ToUpper();
+//      if ( RunMatchesRange(runNumber, objName.Data()) ) {
+//        paramList = static_cast<TObjArray*>(file->Get(key->GetName()));
+//        foundMatch = kTRUE;
+//        break;
+//      }
+//      if ( objName.Contains("DEFAULT") ) defaultObj = file->Get(key->GetName());
+//    }
+//
+//    if ( ! foundMatch ) {
+//      AliWarning("Run number not found in OADB: using default");
+//      if ( defaultObj ) paramList = static_cast<TObjArray*>(defaultObj);
+//      else {
+//        file->Close();
+//        AliError("Default parameters not found in OADB!");
+//        return kFALSE;
+//      }
+//    }
+//
+//    AliInfo(Form("Required run %i. Param. set: %s", runNumber, paramList->GetName()));
+//
+//    for ( Int_t ipar=0; ipar<kNParameters; ++ipar ) {
+//      TParameter<Double_t>* param = static_cast<TParameter<Double_t>*>(paramList->FindObject(parNames[ipar].Data()));
+//      if ( ! param ) {
+//        AliWarning(Form("Parameter %s not set", parNames[ipar].Data()));
+//        continue;
+//      }
+//      fParameters[ipar] = param->GetVal();
+//    }
+//
+//    file->Close();
+//  }
+//  else {
+//    if ( ! paramList ) {
+//      paramList = new TObjArray(kNParameters);
+//      paramList->SetOwner();
+//    }
+//    for ( Int_t ipar=0; ipar<kNParameters; ++ipar ) {
+//      TParameter<Double_t>* param= new TParameter<Double_t>(parNames[ipar].Data(), fParameters[ipar]);
+//      paramList->AddAt(param, ipar);
+//    }
+//
+//    TString paramListName = "EventCuts_";
+//    paramListName += ( runNumber < 0 ) ? "Default" : Form("%i_%i",runNumber, runMax);
+//    AliInfo(Form("Adding %s to file %s", paramListName.Data(), filename.Data()));
+//    paramList->SetName(paramListName.Data());
+//    TFile* file = TFile::Open(filename.Data(), "UPDATE");
+//    paramList->Write(paramListName.Data(), TObject::kSingleKey);
+//    file->Close();
+//    delete paramList;
+//  }
+//  return kTRUE;
+//}
+
+//________________________________________________________________________
+Bool_t AliMuonEventCuts::SetParameter(Int_t iparam, Float_t value)
+{
+  /// Set parameter
+//  if ( fUseCustomParam ) {
+    fParameters.SetAt(value, iparam);
+    return kTRUE;
+//  }
+//
+//  AliWarning("Parameters automatically taken from OADB. If you want to use with custom parameters, use SetUseCustomParam()");
+//  return kFALSE;
+}
+
+
+//________________________________________________________________________
+Bool_t AliMuonEventCuts::IsSelected( TObject* obj )
+{
+  /// Track is selected
+  UInt_t filterMask = GetFilterMask();
+  UInt_t selectionMask = GetSelectionMask(obj);
+  
+  return ( ( selectionMask & filterMask ) == filterMask );
+}
+
+
+//________________________________________________________________________
+UInt_t AliMuonEventCuts::GetSelectionMask( const TObject* obj )
+{
+  /// Get selection mask
+  
+  UInt_t selectionMask = 0;
+  
+  const AliInputEventHandler* inputHandler = static_cast<const AliInputEventHandler*> ( obj );
+  
+  if ( const_cast<AliInputEventHandler*>(inputHandler)->IsEventSelected() & fPhysicsSelectionMask ) selectionMask |= kPhysicsSelected;
+  
+  const AliVEvent* event = inputHandler->GetEvent();
+  
+  Double_t centrality = GetCentrality(event);
+  if ( centrality >= fCentralityClasses->GetXmin() && centrality <= fCentralityClasses->GetXmax() ) selectionMask |= kSelectedCentrality;
+  
+  UpdateEvent(event);
+  
+  if ( fSelectedTrigClassesInEvent->GetEntries() > 0 ) selectionMask |= kSelectedTrig;
+  
+  AliVVertex* vertex = AliAnalysisMuonUtility::GetVertexSPD(event);
+  if ( vertex->GetNContributors() >= GetVertexMinNContributors() && 
+      vertex->GetZ() >= GetVertexVzMin() && vertex->GetZ() <= GetVertexVzMax() ) selectionMask |= kGoodVertex;
+  
+  AliDebug(1, Form("Selection mask 0x%x\n", selectionMask));
+
+  return selectionMask;
+}
+
+
+//________________________________________________________________________
+Bool_t AliMuonEventCuts::IsSelected( TList* /* list */)
+{
+  /// Not implemented
+  AliError("Function not implemented: Use IsSelected(TObject*)");
+  return kFALSE;
+}
+
+//________________________________________________________________________
+Bool_t AliMuonEventCuts::UpdateEvent ( const AliVEvent* event )
+{
+  /// Update the transient data member per event
+  
+  AliTimeStamp currTimeStamp(event->GetOrbitNumber(), event->GetPeriodNumber(), event->GetBunchCrossNumber());
+  if ( fTimeStamp && fTimeStamp->Compare(&currTimeStamp) == 0 ) return kFALSE;
+  
+  BuildTriggerClasses(AliAnalysisMuonUtility::GetFiredTriggerClasses(event));
+  
+  delete fTimeStamp;
+  fTimeStamp = new AliTimeStamp(currTimeStamp);
+  
+  return kTRUE;
+}
+
+//________________________________________________________________________
+void AliMuonEventCuts::SetDefaultTrigClassPatterns ()
+{
+  /// Set the default patterns
+  /// (done in such a way to get all muon triggers)
+  fDefaultTrigClassPatterns = "CINT CMU CMBAC CPBI !-ACE- !-AC- !-E- !WU !EGA !EJE !PHS";
+  SetTrigClassPatterns(fDefaultTrigClassPatterns);
+}
+
+//________________________________________________________________________
+void AliMuonEventCuts::SetTrigClassPatterns ( TString pattern )
+{
+  /// Set trigger classes
+  ///
+  /// Classes are filled dynamically according to the pattern
+  /// - if name contains ! (without spaces): reject it
+  /// - otherwise, keep it
+  /// example:
+  /// SetTrigClassPatterns("CMBAC !ALLNOTRD")
+  /// keeps classes containing CMBAC, and not containing ALLNOTRD.
+  ///
+  /// 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();
+  
+  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 fSelectedTrigPattern->AddLast(new TObjString(currPattern));
+  }
+  
+  delete fullList;
+}
+
+//________________________________________________________________________
+void AliMuonEventCuts::SetTrigClassLevels ( TString pattern )
+{
+  /// Set trigger cut level associated to the trigger class
+  ///
+  /// example:
+  /// SetTrigClassLevels("MSL:Lpt MSH:Hpt MUL:LptLpt")
+  ///
+  /// For the trigger classes defined in SetTrigClassPatterns
+  /// it check if they contains the keywords MSL or MSH
+  /// Hence, in the analysis, the function
+  /// TrackPtCutMatchTrigClass(track, "CPBIMSL") returns true if track match Lpt
+  /// TrackPtCutMatchTrigClass(track, "CPBIMSH") returns true if track match Hpt
+  /// TrackPtCutMatchTrigClass(track, "CMBAC") always returns true
+  
+  fSelectedTrigLevel->SetOwner();
+  if ( fSelectedTrigLevel->GetEntries() > 0 ) fSelectedTrigLevel->Delete();
+  
+  pattern.ReplaceAll("  "," ");
+  pattern.ReplaceAll(" :",":");
+  
+  TObjArray* fullList = pattern.Tokenize(" ");
+  UInt_t offset = 2;
+  for ( Int_t ipat=0; ipat<fullList->GetEntries(); ++ipat ) {
+    TString currPattern = fullList->At(ipat)->GetName();
+    TObjArray* arr = currPattern.Tokenize(":");
+    TObjString* trigClassPattern = new TObjString(arr->At(0)->GetName());
+    TString selTrigLevel = arr->At(1)->GetName();
+    selTrigLevel.ToUpper();
+    UInt_t trigLevel = 0;
+    if ( selTrigLevel.Contains("LPT") ) {
+      trigLevel = 2;
+      if ( selTrigLevel.Contains("LPTLPT") ) trigLevel += 2<<offset;
+    }
+    else if ( selTrigLevel.Contains("HPT") ) {
+      trigLevel = 3;
+      if ( selTrigLevel.Contains("HPTHPT") ) trigLevel += 3<<offset;
+    }
+    trigClassPattern->SetUniqueID(trigLevel);
+    fSelectedTrigLevel->AddLast(trigClassPattern);
+    delete arr;
+  }
+  
+  delete fullList;
+}
+
+//________________________________________________________________________
+TArrayI AliMuonEventCuts::GetTrigClassPtCutLevel ( const TString trigClassName) const
+{
+  /// Get trigger class pt cut level for tracking/trigger matching
+  TObject* obj = fAllSelectedTrigClasses->FindObject(trigClassName.Data());
+  if ( ! obj ) {
+    AliWarning(Form("Class %s not in the list!", trigClassName.Data()));
+    return -1;
+  }
+  
+  TArrayI ptCutLevel(2);
+  ptCutLevel.Reset();
+  ptCutLevel[0] = obj->GetUniqueID() & 0x3;
+  ptCutLevel[1] = ( obj->GetUniqueID() >> 2 ) & 0x3;
+  
+  AliDebug(1,Form("Class %s ptCutLevel %i %i",trigClassName.Data(),ptCutLevel[0],ptCutLevel[1]));
+  
+  return ptCutLevel;
+}
+
+
+//________________________________________________________________________
+TObjArray* AliMuonEventCuts::GetSelectedTrigClassesInEvent( const AliVEvent* event )
+{
+  /// Return the selected trigger classes in the current event
+  UpdateEvent(event);
+  return fSelectedTrigClassesInEvent;
+}
+
+
+//________________________________________________________________________
+void AliMuonEventCuts::BuildTriggerClasses ( const TString firedTrigClasses )
+{
+  //
+  /// Return the list of trigger classes to be considered
+  /// for current event. Update the global list if necessary
+  //
+  
+  delete fSelectedTrigClassesInEvent;
+  fSelectedTrigClassesInEvent = new TObjArray(0);
+  fSelectedTrigClassesInEvent->SetOwner();
+
+  TString firedTrigClassesAny = "ANY " + firedTrigClasses;
+  TObjArray* firedTrigClassesList = firedTrigClassesAny.Tokenize(" ");
+  
+  UInt_t trigLevel = 0;
+  for ( Int_t itrig=0; itrig<firedTrigClassesList->GetEntries(); ++itrig ) {
+    TString trigName = ((TObjString*)firedTrigClassesList->At(itrig))->GetString();
+    
+    TObject* foundTrig = fAllSelectedTrigClasses->FindObject(trigName.Data());
+    if ( foundTrig ) trigLevel = foundTrig->GetUniqueID();
+    else {
+      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;
+      
+      rejectTrig = kTRUE;
+      for ( Int_t ipat=0; ipat<fSelectedTrigPattern->GetEntries(); ++ipat ) {
+        if ( trigName.Contains(fSelectedTrigPattern->At(ipat)->GetName() ) ) {
+          rejectTrig = kFALSE;
+          break;
+        }
+      } // loop on keep pattern
+      if ( rejectTrig ) continue;
+      
+      trigLevel = 0;
+      for ( Int_t ipat=0; ipat<fSelectedTrigLevel->GetEntries(); ++ipat ) {
+        if ( trigName.Contains(fSelectedTrigLevel->At(ipat)->GetName() ) ) {
+          trigLevel = fSelectedTrigLevel->At(ipat)->GetUniqueID();
+          break;
+        }
+      } // loop on trig level patterns      
+    }
+    TObjString* currTrig = new TObjString(trigName);
+    currTrig->SetUniqueID(trigLevel);
+    fSelectedTrigClassesInEvent->AddLast(currTrig);
+    
+    if ( foundTrig ) continue;
+    AliInfo(Form("Adding %s (trig level %u) to considered trigger classes",trigName.Data(),trigLevel));
+    TObjString* addTrig = new TObjString(trigName);
+    addTrig->SetUniqueID(trigLevel);
+    fAllSelectedTrigClasses->Add(addTrig);
+  } // loop on trigger classes
+  
+  delete firedTrigClassesList;
+}
+
+//________________________________________________________________________
+void AliMuonEventCuts::SetCentralityClasses(Int_t nCentralityBins, Double_t* centralityBins)
+{
+  //
+  /// Set centrality classes
+  //
+  Double_t* bins = centralityBins;
+  Int_t nbins = nCentralityBins;
+  
+  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;
+  }
+  
+  TString centralityEstimator = "V0M";
+  if ( fCentralityClasses ) {
+    centralityEstimator = GetCentralityEstimator();
+    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());
+  }
+  
+  SetCentralityEstimator(centralityEstimator);
+}
+
+//________________________________________________________________________
+void AliMuonEventCuts::SetCentralityEstimator ( const TString centralityEstimator )
+{
+  /// Set centrality estimator
+  fCentralityClasses->SetName(centralityEstimator.Data());
+}
+
+
+//________________________________________________________________________
+TString AliMuonEventCuts::GetCentralityEstimator () const
+{
+  /// Get centrality estimator
+  return fCentralityClasses->GetName();
+}
+
+//________________________________________________________________________
+Double_t AliMuonEventCuts::GetCentrality ( const AliVEvent* event ) const
+{
+  /// Get centrality
+  AliVEvent* evt = const_cast<AliVEvent*>(event);
+  return evt->GetCentrality()->GetCentralityPercentile(GetCentralityEstimator());
+}
+
+//________________________________________________________________________
+void AliMuonEventCuts::SetDefaultParameters ()
+{
+  /// Standard parameters for muon event
+  SetPhysicsSelectionMask(AliVEvent::kAny);
+  SetVertexMinNContributors(1);
+  SetVertexVzLimits();
+}
+
+
+//________________________________________________________________________
+void AliMuonEventCuts::SetDefaultFilterMask ()
+{
+  /// Standard cuts for muon event
+  SetFilterMask ( kPhysicsSelected | kSelectedTrig | kGoodVertex );
+}
+
+//________________________________________________________________________
+void AliMuonEventCuts::Print(Option_t* option) const
+{
+  //
+  /// Print info
+  //
+  TString sopt(option);
+  sopt.ToLower();
+  if ( sopt.IsNull() || sopt.Contains("*") || sopt.Contains("all") ) sopt = "mask param";
+  UInt_t filterMask = GetFilterMask();
+  if ( sopt.Contains("mask") ) {
+    printf(" *** Muon event filter mask: *** \n");
+    printf("  0x%x\n", filterMask);
+    if ( filterMask & kPhysicsSelected ) printf("  Pass physics selection 0x%x\n", fPhysicsSelectionMask);
+    if ( filterMask & kSelectedCentrality ) printf(  "%g < centrality < %g", fCentralityClasses->GetXmin(), fCentralityClasses->GetXmax() );
+    if ( filterMask & kSelectedTrig )    printf("  Has selected trigger classes\n");
+    if ( filterMask & kGoodVertex )      printf("  SPD vertex with %i contributors && %g < Vz < %g\n", GetVertexMinNContributors(), GetVertexVzMin(), GetVertexVzMax());
+    printf(" ******************** \n");
+  }
+//  if ( sopt.Contains("param") ) {
+//    printf(" *** Muon track parameter summary: ***\n");
+//    printf(" ********************************\n");
+//  }
+}
diff --git a/PWG/muon/AliMuonEventCuts.h b/PWG/muon/AliMuonEventCuts.h
new file mode 100644 (file)
index 0000000..533c8ee
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef ALIMUONEVENTCUTS_H
+#define ALIMUONEVENTCUTS_H
+
+#include "AliAnalysisCuts.h"
+#include "TArrayD.h"
+
+class AliVEvent;
+class AliVVertex;
+class TList;
+class TAxis;
+class AliTimeStamp;
+class TArrayI;
+
+class AliMuonEventCuts : public AliAnalysisCuts
+{
+ public:
+  
+  enum {
+    kPhysicsSelected = BIT(0),
+    kSelectedCentrality = BIT(1),
+    kSelectedTrig = BIT(2),
+    kGoodVertex = BIT(3)
+  };
+  
+  AliMuonEventCuts();
+  AliMuonEventCuts(const char* name, const char* title);
+  AliMuonEventCuts(const AliMuonEventCuts& obj);
+  AliMuonEventCuts& operator=(const AliMuonEventCuts& obj);
+  
+  virtual ~AliMuonEventCuts();
+  
+  virtual UInt_t GetSelectionMask ( const TObject* obj );
+  virtual Bool_t IsSelected ( TObject* obj );
+  virtual Bool_t IsSelected ( TList* /*list */ );
+  
+  void SetDefaultFilterMask();
+  void SetDefaultParameters();
+  
+  enum {
+    kVertexMinNContributors,
+    kVertexVzMin,
+    kVertexVzMax,
+    kNParameters
+  };
+  
+  // Handle trigger
+  void SetTrigClassPatterns ( const TString pattern );
+  /// Get default trigger class patterns
+  TString GetDefaultTrigClassPatterns() { return fDefaultTrigClassPatterns; };
+  void SetTrigClassLevels ( const TString pattern = "MSL:Lpt MSH:Hpt MUL:LptLpt MLL:LptLpt" );
+  TArrayI GetTrigClassPtCutLevel ( const TString trigClassName ) const;
+  /// Get trigger classes found in run
+  TList* GetAllSelectedTrigClasses () const { return fAllSelectedTrigClasses; }
+  TObjArray* GetSelectedTrigClassesInEvent ( const AliVEvent* event );
+
+  
+  // Handle centrality
+  void SetCentralityClasses(Int_t nCentralityBins = -1, Double_t* centralityBins = 0x0);
+  /// Get centrality classes
+  TAxis* GetCentralityClasses() const { return fCentralityClasses; }
+  
+  void SetCentralityEstimator ( const TString centralityEstimator = "V0M" );
+  TString GetCentralityEstimator () const;
+  Double_t GetCentrality ( const AliVEvent* event ) const;
+  
+  
+  /// Set Physics selection mask
+  void SetPhysicsSelectionMask ( const UInt_t physicsSelectionMask ) { fPhysicsSelectionMask = physicsSelectionMask; }
+  
+  
+  /// Set minimum number of vertex contributors
+  void SetVertexMinNContributors ( const Int_t vertexMinNContributors ) { SetParameter(kVertexMinNContributors, (Double_t)vertexMinNContributors); }
+  /// Get minimum number of vertex contributors
+  Int_t GetVertexMinNContributors () const { return (Int_t)fParameters[kVertexMinNContributors]; }
+  /// Set Vz limits
+  void SetVertexVzLimits ( Double_t vzMin = -999., Double_t vzMax = 999. ) { SetParameter(kVertexVzMin, vzMin); SetParameter(kVertexVzMax, vzMax); }
+  /// Get Vtx vz min
+  Double_t GetVertexVzMin () const { return fParameters[kVertexVzMin]; }
+  /// Get Vtx vz max
+  Double_t GetVertexVzMax () const { return fParameters[kVertexVzMax]; }
+  
+  //Bool_t SetRun(Int_t runNumber);
+  //void SetUseCustomParam( Bool_t useCustomParam = kTRUE, Int_t runNumber = -1 );
+  //void SetIsMC(Bool_t isMC = kTRUE) { fIsMC = isMC; }
+
+  void Print ( Option_t* option = "" ) const;
+
+  //Bool_t StreamParameters ( Int_t runNumber, Int_t maxRun );
+
+ protected:
+  
+  Bool_t SetParameter ( Int_t iparam, Float_t value );
+  void BuildTriggerClasses ( const TString firedTrigClasses );
+  Bool_t UpdateEvent( const AliVEvent* event );
+  void SetDefaultTrigClassPatterns();
+  
+  //Bool_t RunMatchesRange ( Int_t runNumber, const Char_t* objName ) const;
+
+  //Bool_t fIsMC;             ///< Monte Carlo analysis
+  //Bool_t fUseCustomParam;   ///< Use custom parameters (do not search in OADB)
+  
+  UInt_t fPhysicsSelectionMask; ///< Physics selection mask
+  
+  TArrayD fParameters;      ///< List of parameters
+  
+  TString fDefaultTrigClassPatterns; ///< Default trigger class patterns
+  TObjArray* fSelectedTrigPattern; ///< List of triggers to be kept
+  TObjArray* fRejectedTrigPattern; ///< List of triggers to be rejected
+  TObjArray* fSelectedTrigLevel;   ///< Track-trigger pt cut for selected trigger class
+  TList* fAllSelectedTrigClasses;  ///< List of all selected trigger classes found
+  TAxis* fCentralityClasses;   ///< Centrality classes
+  
+  private:
+  AliTimeStamp* fTimeStamp; //!< current event time stamp
+  TObjArray* fSelectedTrigClassesInEvent; //!< list of selected trigger classes in current event 
+  
+  ClassDef(AliMuonEventCuts, 1); // Class for muon event filters
+};
+
+#endif
+