From 1ec35774aacc80cf91da247a8ac4bc34317f0dd0 Mon Sep 17 00:00:00 2001 From: Niels Van Eldik <niels.van.eldik@cern.ch> Date: Tue, 16 Sep 2014 10:05:42 +0200 Subject: [PATCH] requirements cleanup (MuonSelectorTools-00-04-01) --- .../MuonSelectorTools/IMuonSelectionTool.h | 55 ++++ .../MuonSelectorTools/MuonSelectionTool.h | 93 ++++++ .../MuonSelectorTools/errorcheck.h | 21 ++ .../MuonID/MuonSelectorTools/Root/LinkDef.h | 17 ++ .../Root/MuonSelectionTool.cxx | 280 ++++++++++++++++++ .../MuonSelectorTools/cmt/Makefile.RootCore | 16 + .../MuonID/MuonSelectorTools/cmt/requirements | 24 ++ .../python/MuonSelectorCutDefs.py | 77 +++++ .../MuonSelectorTools/python/__init__.py | 2 + .../exampleMuonSelectionAlg_jobOptions.py | 10 + .../src/MuonSelectionAlg.cxx | 53 ++++ .../MuonSelectorTools/src/MuonSelectionAlg.h | 40 +++ .../components/MuonSelectorTools_entries.cxx | 20 ++ .../src/components/MuonSelectorTools_load.cxx | 2 + .../util/MuonSelectorToolsTester.cxx | 248 ++++++++++++++++ 15 files changed, 958 insertions(+) create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/IMuonSelectionTool.h create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/MuonSelectionTool.h create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/errorcheck.h create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/Root/LinkDef.h create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/Root/MuonSelectionTool.cxx create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/cmt/Makefile.RootCore create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/cmt/requirements create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/python/MuonSelectorCutDefs.py create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/python/__init__.py create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/share/exampleMuonSelectionAlg_jobOptions.py create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/src/MuonSelectionAlg.cxx create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/src/MuonSelectionAlg.h create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/src/components/MuonSelectorTools_entries.cxx create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/src/components/MuonSelectorTools_load.cxx create mode 100644 PhysicsAnalysis/MuonID/MuonSelectorTools/util/MuonSelectorToolsTester.cxx diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/IMuonSelectionTool.h b/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/IMuonSelectionTool.h new file mode 100644 index 0000000000000..0cb3ef942244b --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/IMuonSelectionTool.h @@ -0,0 +1,55 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IMuonSelectionTool.h 299883 2014-03-28 17:34:16Z krasznaa $ +#ifndef MUONSELECTORTOOLS_IMUONSELECTIONTOOL_H +#define MUONSELECTORTOOLS_IMUONSELECTIONTOOL_H + +// Framework include(s): +#include "AsgTools/IAsgTool.h" +#include "PATCore/TAccept.h" + +// EDM include(s): +#include "xAODMuon/Muon.h" + +namespace CP { + + /// Interface for (a) muon selector tool(s) + /// + /// This is an example of how to define object selection in + /// a tool. + /// + /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + /// + /// $Revision: 299883 $ + /// $Date: 2014-03-28 18:34:16 +0100 (Fri, 28 Mar 2014) $ + /// + class IMuonSelectionTool : public virtual asg::IAsgTool { + + /// Declare the interface that the class provides + ASG_TOOL_INTERFACE( CP::IMuonSelectionTool ) + + public: + /// Decide whether the muon in question is a "good muon" or not + virtual const Root::TAccept& accept( const xAOD::Muon& mu ) const = 0; + + /// set the passes ID cuts variable of the muon + virtual void setPassesIDCuts( xAOD::Muon& mu ) const = 0; + + /// set the passes quality variable of the muon + virtual void setQuality( xAOD::Muon& mu ) const = 0; + + /// Returns true if the muon passes the standard MCP ID cuts. To set the value on the muon, instead call setPassesIDCuts(xAOD::Muon&) const + virtual bool passedIDCuts(const xAOD::Muon&) const =0; + + /// Returns the quality of the muon. To set the value on the muon, instead call setQuality(xAOD::Muon&) const + virtual xAOD::Muon::Quality getQuality(const xAOD::Muon& mu ) const =0; + + }; // class IMuonSelectionTool + +} // namespace CP + +#endif // CPTOOLTESTS_IMUONSELECTIONTOOL_H diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/MuonSelectionTool.h b/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/MuonSelectionTool.h new file mode 100644 index 0000000000000..c522c5e96b721 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/MuonSelectionTool.h @@ -0,0 +1,93 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: MuonSelectionTool.h 299883 2014-03-28 17:34:16Z krasznaa $ +#ifndef MUONSELECTORTOOLS_MUONSELECTIONTOOL_H +#define MUONSELECTORTOOLS_MUONSELECTIONTOOL_H + +// Framework include(s): +#include "AsgTools/AsgTool.h" +#include "PATCore/IAsgSelectionTool.h" + +// Local include(s): +#include "MuonSelectorTools/IMuonSelectionTool.h" + +namespace CP { + + /// Implementation of the muon selector tool + /// + /// Example implementation of how an object selector tool should + /// look according to the TF3 recommendations. + /// + /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + /// + /// $Revision: 299883 $ + /// $Date: 2014-03-28 18:34:16 +0100 (Fri, 28 Mar 2014) $ + /// + class MuonSelectionTool : public virtual IAsgSelectionTool, + public virtual IMuonSelectionTool, + public asg::AsgTool { + + /// Create a proper constructor for Athena + ASG_TOOL_CLASS2( MuonSelectionTool, IAsgSelectionTool, + CP::IMuonSelectionTool ) + + public: + /// Constructor for standalone usage + MuonSelectionTool( const std::string& name ); + + /// @name Function(s) implementing the asg::IAsgTool interface + /// @{ + + /// Function initialising the tool + virtual StatusCode initialize(); + + /// @} + + /// @name Function(s) implementing the IAsgSelectionTool interface + /// @{ + + /// Get an object describing the "selection steps" of the tool + virtual const Root::TAccept& getTAccept() const; + + /// Get the decision using a generic IParticle pointer + virtual const Root::TAccept& accept( const xAOD::IParticle* p ) const; + + /// @} + + /// @name Function(s) implementing the IMuonSelectorTool interface + /// @{ + + /// Get the decision for a specific Muon object + virtual const Root::TAccept& accept( const xAOD::Muon& mu ) const; + + /// set the passes ID cuts variable of the muon + void setPassesIDCuts(xAOD::Muon&) const; + + /// set the passes quality variable of the muon + void setQuality( xAOD::Muon& mu ) const; + + /// Returns true if the muon passes the standard MCP ID cuts. To set the value on the muon, instead call setPassesIDCuts(xAOD::Muon&) const + bool passedIDCuts(const xAOD::Muon&) const; + + /// Returns the quality of the muon. To set the value on the muon, instead call setQuality(xAOD::Muon&) const + xAOD::Muon::Quality getQuality(const xAOD::Muon& mu ) const; + + /// @} + + + private: + /// Maximum pseudorapidity for the selected muons + double m_maxEta; + + /// Object used to store the last decision + mutable Root::TAccept m_accept; + + }; // class MuonSelectionTool + +} // namespace CP + +#endif // CPTOOLTESTS_MUONSELECTIONTOOL_H diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/errorcheck.h b/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/errorcheck.h new file mode 100644 index 0000000000000..6c22677eec197 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/MuonSelectorTools/errorcheck.h @@ -0,0 +1,21 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: errorcheck.h 299732 2014-03-27 17:41:34Z krasznaa $ +#ifndef CPTOOLTESTS_ERRORCHECK_H +#define CPTOOLTESTS_ERRORCHECK_H + +#define CHECK( ARG ) \ + do { \ + const bool result = ARG; \ + if( ! result ) { \ + ::Error( APP_NAME, "Failed to execute: \"%s\"", \ + #ARG ); \ + return 1; \ + } \ + } while( false ) + +#endif // CPTOOLTESTS_ERRORCHECK_H diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/LinkDef.h b/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/LinkDef.h new file mode 100644 index 0000000000000..3501b674da8fe --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/LinkDef.h @@ -0,0 +1,17 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef __MUONSELECTORTOOLS__ +#define __MUONSELECTORTOOLS__ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; +#pragma link C++ nestedclass; + +#endif + +#endif diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/MuonSelectionTool.cxx b/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/MuonSelectionTool.cxx new file mode 100644 index 0000000000000..a301d2d6cc0de --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/MuonSelectionTool.cxx @@ -0,0 +1,280 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: MuonSelectionTool.cxx 299883 2014-03-28 17:34:16Z krasznaa $ + +// Local include(s): +#include "MuonSelectorTools/MuonSelectionTool.h" +#include "xAODTracking/TrackingPrimitives.h" + +namespace CP { + + MuonSelectionTool::MuonSelectionTool( const std::string& name ) + : asg::AsgTool( name ), + m_accept( "MuonSelection" ) { + + declareProperty( "MaxEta", m_maxEta = 2.5 ); + } + + StatusCode MuonSelectionTool::initialize() { + + // Greet the user: + ATH_MSG_INFO( "Initialising..." ); + ATH_MSG_DEBUG( "Maximum eta: " << m_maxEta ); + + // Set up the TAccept object: + m_accept.addCut( "Eta", + "Selection of muons according to their pseudorapidity" ); + m_accept.addCut( "Quality", + "Selection of muons according to their tightness" ); + m_accept.addCut( "IDHits", + "Selection of muons according to whether they passed the MCP ID Hit cuts" ); + // Return gracefully: + return StatusCode::SUCCESS; + } + + const Root::TAccept& MuonSelectionTool::getTAccept() const { + + return m_accept; + } + + const Root::TAccept& + MuonSelectionTool::accept( const xAOD::IParticle* p ) const { + + // Reset the result: + m_accept.clear(); + + // Check if this is a muon: + if( p->type() != xAOD::Type::Muon ) { + ATH_MSG_ERROR( "accept(...) Function received a non-muon" ); + return m_accept; + } + + // Cast it to a muon: + const xAOD::Muon* mu = dynamic_cast< const xAOD::Muon* >( p ); + if( ! mu ) { + ATH_MSG_FATAL( "accept(...) Failed to cast particle to muon" ); + return m_accept; + } + + // Let the specific function do the work: + return accept( *mu ); + } + + const Root::TAccept& MuonSelectionTool::accept( const xAOD::Muon& mu ) const { + + // Reset the result: + m_accept.clear(); + + // Do the eta cut: + ATH_MSG_VERBOSE( "Muon eta: " << mu.eta() ); + if( std::abs( mu.eta() ) > m_maxEta ) { + return m_accept; + } + m_accept.setCutResult( "Eta", true ); + + // Medium quality doesn't exist yet, hack for now with getQuality method + // Do the quality cut(s): + // ATH_MSG_VERBOSE( "Muon quality: " << mu.quality() ); + // if( mu.quality()!=xAOD::Muon::Medium ) { + // return m_accept; + // } + + ATH_MSG_VERBOSE( "Muon quality: " << getQuality(mu)); + if(getQuality(mu) != xAOD::Muon::Medium){ + return m_accept; + } + + m_accept.setCutResult( "Muon quality", true ); + + // Check not standalone + ATH_MSG_VERBOSE( "Type: " << mu.muonType () ); + if( mu.muonType ()==xAOD::Muon::MuonStandAlone ) { + return m_accept; + } + m_accept.setCutResult( "Type", true ); + + // Passes ID hit cuts + // ATH_MSG_VERBOSE( "Passes ID Hit cuts " << mu.passesIDCuts () ); + // if( !mu.passesIDCuts () ) { + // return m_accept; + // } + + ATH_MSG_VERBOSE( "Passes ID Hit cuts " << passedIDCuts(mu) ); + if( !passedIDCuts (mu) ) { + return m_accept; + } + + m_accept.setCutResult( "IDHits", true ); + + // Return the result: + return m_accept; + } + + void MuonSelectionTool::setQuality( xAOD::Muon& mu ) const { + mu.setQuality(getQuality(mu)); + return; + } + + xAOD::Muon::Quality MuonSelectionTool::getQuality(const xAOD::Muon& mu ) const { + using namespace xAOD; + + // ATH_MSG_VERBOSE( "Type: " << mu.muonType () ); + // ATH_MSG_VERBOSE( "Quality: " << mu.quality () ); + + // Combined muons + if (mu.muonType()==Muon_v1::Combined){ + + uint8_t nprecisionLayers,nprecisionHoleLayers; + + if (!mu.primaryTrackParticle()->summaryValue(nprecisionLayers, numberOfPrecisionLayers) || + !mu.primaryTrackParticle()->summaryValue(nprecisionHoleLayers, numberOfPrecisionHoleLayers)){ + ATH_MSG_VERBOSE("getQuality - #precision layers missing in combined muon! Aborting."); + return Muon_v1::Loose; + } + + float momBalanceSig=0.0; + + // if (!mu.parameter(momBalanceSig, Muon_v1::momentumBalanceSignificance)){ + // ATH_MSG_VERBOSE("getQuality - momentumBalanceSignificance missing in combined muon! Don't abort yet since these variables are not filled!"); + // //momentum balance signficance variable is missing, proceed with a check of the precision layers + // //return Muon_v1::Medium; + // } + + if( (momBalanceSig<4.0) + && (nprecisionLayers > 0 || ( nprecisionLayers == 1 && nprecisionHoleLayers < 2 ) ) ) { + return Muon_v1::Medium; + } + + //didn't pass the set of requirements for a medium combined muon + return Muon_v1::Loose; + } + + if (mu.author()==Muon_v1::STACO || mu.author()==Muon_v1::MuTag){ + // What about MuTagIMO? CHECK! + return Muon_v1::Medium; + } + + // SA muons + if (mu.muonType()==Muon_v1::MuonStandAlone && fabs(mu.eta())>2.5){ + uint8_t nprecisionLayers; + uint8_t ninnerSmallHits; + if (!mu.primaryTrackParticle()->summaryValue(nprecisionLayers, numberOfPrecisionLayers)){ + ATH_MSG_VERBOSE("getQuality - numberOfPrecisionLayers missing in SA muon! Aborting."); + return Muon_v1::Loose; + } + if (!mu.summaryValue(ninnerSmallHits, innerSmallHits)){ + ATH_MSG_VERBOSE("getQuality - innerSmallHits missing in SA muon! Aborting."); + return Muon_v1::Loose; + } + + if( nprecisionLayers>2 || ninnerSmallHits>3 ) { + return Muon_v1::Medium; // Can't currently get tighter than medium... will need to change logic here if this is no longer true. + } + } + + // CaloTagged and SegmentTagged muons + if (mu.muonType()==Muon_v1::SegmentTagged || mu.muonType()==Muon_v1::CaloTagged ){ + return Muon_v1::Loose; + } + + //mu.setQuality(Muon_v1::Loose); // Is this really what we want to do? Having all other muons 'loose' with no selection, wasting information. + return Muon_v1::Loose; + } + + + + void MuonSelectionTool::setPassesIDCuts( xAOD::Muon& mu ) const { + // Any time a cut is failed, we just abort - the bit is set to true only at the very end + // This is a bit contrary to the concept of using TAccept, but we want to be able to call this in standard reco tools, without lots of output. + // Might add DEBUG/VERBOSE level output, later. + // mu.setPassesIDCuts(false);// Explicitly set this here, in case this is being called on an updated muon (i.e. might be true) + // using namespace xAOD; + // uint8_t value1=0; + // uint8_t value2=0; + // if (mu.primaryTrackParticle()->summaryValue(value1, numberOfPixelHits) && + // mu.primaryTrackParticle()->summaryValue(value2, numberOfPixelDeadSensors) ) { + // if (value1+value2==0) return; + // } else { + // ATH_MSG_WARNING("setPassesIDCuts - pixel values are missing! Aborting."); + // return; + // } + // + // if (mu.primaryTrackParticle()->summaryValue(value1, numberOfSCTHits) && + // mu.primaryTrackParticle()->summaryValue(value2, numberOfSCTDeadSensors)){ + // if (value1+value2<=4) return; + // } else { + // ATH_MSG_WARNING("setPassesIDCuts - SCT values are missing! Aborting."); + // return; + // } + // + // if (mu.primaryTrackParticle()->summaryValue(value1, numberOfPixelHoles) && + // mu.primaryTrackParticle()->summaryValue(value2, numberOfSCTHoles)){ + // if (value1+value2>=3) return; + // } else { + // ATH_MSG_WARNING("setPassesIDCuts - Si hole values are missing! Aborting."); + // return; + // } + // + // float abseta = std::abs(mu.eta()); + // if (mu.primaryTrackParticle()->summaryValue(value1, numberOfTRTHits) && + // mu.primaryTrackParticle()->summaryValue(value2, numberOfTRTOutliers)){ + // // Okay, so have values available - now check if TRT cuts met... + // uint8_t totTRThits=value1+value2; + // if (!((0.1<abseta && abseta<=1.9 && totTRThits>5 && value2<(0.9 * totTRThits)) || (abseta <= 0.1 || abseta > 1.9))) + // return; + // } else { + // ATH_MSG_WARNING("setPassesIDCuts - TRT values are missing! Aborting."); + // return; + // } + // // Reached end - all ID hit cuts are passed. + // + mu.setPassesIDCuts(passedIDCuts(mu)); + } + + bool MuonSelectionTool::passedIDCuts( const xAOD::Muon& mu ) const { + using namespace xAOD; + uint8_t value1=0; + uint8_t value2=0; + + if (mu.primaryTrackParticle()->summaryValue(value1, numberOfPixelHits) && + mu.primaryTrackParticle()->summaryValue(value2, numberOfPixelDeadSensors) ) { + if (value1+value2==0) return false; + } else { + ATH_MSG_WARNING("isPassedIDCuts - pixel values are missing! Aborting."); + return false; + } + + if (mu.primaryTrackParticle()->summaryValue(value1, numberOfSCTHits) && + mu.primaryTrackParticle()->summaryValue(value2, numberOfSCTDeadSensors)){ + if (value1+value2<=4) return false; + } else { + ATH_MSG_WARNING("isPassedIDCuts - SCT values are missing! Aborting."); + return false; + } + + if (mu.primaryTrackParticle()->summaryValue(value1, numberOfPixelHoles) && + mu.primaryTrackParticle()->summaryValue(value2, numberOfSCTHoles)){ + if (value1+value2>=3) return false; + } else { + ATH_MSG_WARNING("isPassedIDCuts - Si hole values are missing! Aborting."); + return false; + } + + float abseta = std::abs(mu.eta()); + if (mu.primaryTrackParticle()->summaryValue(value1, numberOfTRTHits) && + mu.primaryTrackParticle()->summaryValue(value2, numberOfTRTOutliers)){ + // Okay, so have values available - now check if the TRT cuts are met... + uint8_t totTRThits=value1+value2; + if (!((0.1<abseta && abseta<=1.9 && totTRThits>5 && value2<(0.9 * totTRThits)) || (abseta <= 0.1 || abseta > 1.9))) + return false; + } else { + + ATH_MSG_WARNING("isPassedIDCuts - TRT values are missing! Aborting."); + return false; + } + // Reached end - all ID hit cuts are passed. + return true; + } // passedIDCuts +} // namespace CP diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/cmt/Makefile.RootCore b/PhysicsAnalysis/MuonID/MuonSelectorTools/cmt/Makefile.RootCore new file mode 100644 index 0000000000000..3784968a0d906 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/cmt/Makefile.RootCore @@ -0,0 +1,16 @@ +PACKAGE = MuonSelectorTools +PACKAGE_PRELOAD = +PACKAGE_CXXFLAGS = +PACKAGE_LDFLAGS = +PACKAGE_BINFLAGS = +PACKAGE_LIBFLAGS = +PACKAGE_DEP = AsgTools PATCore xAODMuon xAODEventInfo xAODTracking +PACKAGE_TRYDEP = +PACKAGE_CLEAN = +PACKAGE_NOGRID = +PACKAGE_PEDANTIC = 0 +PACKAGE_NOOPT = 0 +PACKAGE_NOCC = 0 +PACKAGE_REFLEX = 0 + +include $(ROOTCOREDIR)/Makefile-common diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/cmt/requirements b/PhysicsAnalysis/MuonID/MuonSelectorTools/cmt/requirements new file mode 100644 index 0000000000000..91066ef5bf0dc --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/cmt/requirements @@ -0,0 +1,24 @@ +package MuonSelectorTools + +author Karsten Koeneke <karsten.koeneke@cern.ch> + +public +use AtlasPolicy AtlasPolicy-* +use AsgTools AsgTools-* Control/AthToolSupport +use GaudiInterface GaudiInterface-* External +use PATCore PATCore-* PhysicsAnalysis/AnalysisCommon +use xAODMuon xAODMuon-* Event/xAOD +private +use AthenaBaseComps AthenaBaseComps-* Control +use AtlasROOT AtlasROOT-* External + +use xAODTracking xAODTracking-* Event/xAOD +use xAODEventInfo xAODEventInfo-* Event/xAOD +end_private + +library MuonSelectorTools *.cxx ../Root/*.cxx components/*.cxx +apply_pattern component_library + +## install our job options files +apply_pattern declare_joboptions files="*.py" + diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/python/MuonSelectorCutDefs.py b/PhysicsAnalysis/MuonID/MuonSelectorTools/python/MuonSelectorCutDefs.py new file mode 100644 index 0000000000000..15e47261c6c23 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/python/MuonSelectorCutDefs.py @@ -0,0 +1,77 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +##============================================================================= +## Name: MuonSelectorCutDefs +## +## Author: Karsten Koeneke (CERN) +## Created: July 2011 +## +## Description: Define the cut values for the MuonSelectors +## +##============================================================================= + +# import the needed Reflex and ROOT stuff +import PyCintex +PyCintex.Cintex.Enable() +import ROOT + +# Import a needed helper +from PATCore.HelperUtils import * + +# Define GeV +GeV = 1000.0 + + + +def MuonSelectorConfig(theTool) : + """ + This defines the cut values for the muon + """ + theTool = GetTool(theTool) + theTool.nPixMin = 1 + theTool.nSCTMin = 5 + theTool.nIDHolesMax = 2 + theTool.etaMax = 1.9 + theTool.etaMin = 0.1 + theTool.nTRTMin = 6 + pass + +def MuonSelectorConfig2011(theTool) : + """ + This defines the cut values for the muons in 2011 + """ + theTool = GetTool(theTool) + theTool.nBLMin = 1 + theTool.nPixMin = 2 + theTool.nSCTMin = 6 + theTool.nIDHolesMax = 2 + theTool.etaMax = 1.9 + theTool.etaMin = 0. + theTool.nTRTMin = 6 + pass + +def CaloMuonSelectorConfig(theTool) : + """ + This defines the cut values for the muon + """ + theTool = GetTool(theTool) + theTool.nPixMin = 1 + theTool.nSCTMin = 5 + theTool.nIDHolesMax = 2 + theTool.etaMax = 1.9 + theTool.etaMin = 0.1 + theTool.caloEtaMax = 0.1 + theTool.caloMuonIDTagMin = 11 + theTool.caloLRLikelihoodMin = 0.9 + pass + +def StandAloneMuonSelectorConfig(theTool) : + """ + This defines the cut values for the muon + """ + theTool = GetTool(theTool) + theTool.nCSCHitsMin = 1 + theTool.nMDTEMHitsMin = 1 + theTool.nMDTEOHitsMin = 1 + pass + diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/python/__init__.py b/PhysicsAnalysis/MuonID/MuonSelectorTools/python/__init__.py new file mode 100644 index 0000000000000..74583d364ec2c --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/python/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/share/exampleMuonSelectionAlg_jobOptions.py b/PhysicsAnalysis/MuonID/MuonSelectorTools/share/exampleMuonSelectionAlg_jobOptions.py new file mode 100644 index 0000000000000..d3801a3ace2f7 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/share/exampleMuonSelectionAlg_jobOptions.py @@ -0,0 +1,10 @@ + +import AthenaPoolCnvSvc.ReadAthenaPool + +svcMgr.EventSelector.InputCollections = [ "/afs/cern.ch/atlas/project/PAT/xAODs/r5534/valid2.117050.PowhegPythia_P2011C_ttbar.digit.AOD.e2657_s1933_s1964_r5534/AOD.01482225._000107.pool.root.1" ] + +algseq = CfgMgr.AthSequencer("AthAlgSeq") +algseq += CfgMgr.CP__MuonSelectionAlg(Input="Muons",Output="SelectedMuons",OutputLevel=DEBUG) + + +theApp.EvtMax=10 diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/src/MuonSelectionAlg.cxx b/PhysicsAnalysis/MuonID/MuonSelectorTools/src/MuonSelectionAlg.cxx new file mode 100644 index 0000000000000..d2cd6f8811c25 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/src/MuonSelectionAlg.cxx @@ -0,0 +1,53 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "MuonSelectionAlg.h" + +#include "xAODMuon/MuonContainer.h" + +namespace CP { + +MuonSelectionAlg::MuonSelectionAlg(const std::string& name, ISvcLocator* svcloc) : AthAlgorithm(name,svcloc), + m_tool("CP::MuonSelectionTool") /*public tool*/ { + + declareProperty("Input",m_inputMuons=""); + declareProperty("Output",m_outputMuons=""); + declareProperty("Tool",m_tool); + +} + + +StatusCode MuonSelectionAlg::initialize() { + if(m_inputMuons=="") { ATH_MSG_ERROR("You must specify an INPUT muon collection"); return StatusCode::FAILURE; } + if(m_outputMuons=="") { ATH_MSG_ERROR("You must specify an OUTPUT muon collection"); return StatusCode::FAILURE; } + CHECK( m_tool.retrieve() ); + + return StatusCode::SUCCESS; +} + + +StatusCode MuonSelectionAlg::execute() { + + //fetch input collection + const xAOD::MuonContainer* muons = 0; + CHECK( evtStore()->retrieve(muons,m_inputMuons) ); + + //create a view container for the selected muons + //basically acts like pointers to the selected muons in the muon container + xAOD::MuonContainer* out = new xAOD::MuonContainer(SG::VIEW_ELEMENTS); + + for(auto iMuon : *muons) { + if(m_tool->accept(*iMuon)) out->push_back(const_cast<xAOD::Muon*>(iMuon)); + } + ATH_MSG_DEBUG("Selected " << out->size() << " muons"); + + + CHECK( evtStore()->record(out,m_outputMuons) ); + //if(evtStore()->proxy(muons)->isConst()) CHECK( evtStore()->setConst(out) ); - may allow in the future + CHECK( evtStore()->setConst(out) ); //for now we just always lock everything we put into storegate + + return StatusCode::SUCCESS; +} + +} //CP namespace diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/src/MuonSelectionAlg.h b/PhysicsAnalysis/MuonID/MuonSelectorTools/src/MuonSelectionAlg.h new file mode 100644 index 0000000000000..bd03d9134b9f8 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/src/MuonSelectionAlg.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +//Simple alg to wrap the selectiontool +//outputs a view container of the selected muons, if m_outputMuons different to m_inputMuons + +//author: will buttinger <will@cern.ch> + + +#ifndef MUONSELECTORTOOLS_MUONSELECTIONALG +#define MUONSELECTORTOOLS_MUONSELECTIONALG + +#include "AthenaBaseComps/AthAlgorithm.h" +#include "GaudiKernel/ToolHandle.h" +#include "MuonSelectorTools/IMuonSelectionTool.h" + +namespace CP { + + + +class MuonSelectionAlg : public AthAlgorithm { + + public: + MuonSelectionAlg( const std::string& name, ISvcLocator* svcloc); + + virtual StatusCode initialize(); + virtual StatusCode execute(); + + private: + std::string m_inputMuons; + std::string m_outputMuons; + ToolHandle<CP::IMuonSelectionTool> m_tool; + +}; + +} + +#endif \ No newline at end of file diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/src/components/MuonSelectorTools_entries.cxx b/PhysicsAnalysis/MuonID/MuonSelectorTools/src/components/MuonSelectorTools_entries.cxx new file mode 100644 index 0000000000000..daad9ecaccb80 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/src/components/MuonSelectorTools_entries.cxx @@ -0,0 +1,20 @@ +#include "GaudiKernel/DeclareFactoryEntries.h" + +#include "MuonSelectorTools/MuonSelectionTool.h" +#include "../MuonSelectionAlg.h" + + +using namespace CP; + + +DECLARE_NAMESPACE_TOOL_FACTORY(CP, MuonSelectionTool )//DECLARE_TOOL_FACTORY( MuonSelectionTool ) is there a difference!? +DECLARE_NAMESPACE_ALGORITHM_FACTORY(CP, MuonSelectionAlg ) + +DECLARE_FACTORY_ENTRIES( MuonSelectorTools ) +{ + DECLARE_NAMESPACE_ALGTOOL(CP,MuonSelectionTool)//DECLARE_ALGTOOL( CP::MuonSelectionTool ) + + DECLARE_NAMESPACE_ALGORITHM( CP, MuonSelectionAlg ) +} + + diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/src/components/MuonSelectorTools_load.cxx b/PhysicsAnalysis/MuonID/MuonSelectorTools/src/components/MuonSelectorTools_load.cxx new file mode 100644 index 0000000000000..f56f4380949ca --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/src/components/MuonSelectorTools_load.cxx @@ -0,0 +1,2 @@ +#include "GaudiKernel/LoadFactoryEntries.h" +LOAD_FACTORY_ENTRIES(MuonSelectorTools) diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/util/MuonSelectorToolsTester.cxx b/PhysicsAnalysis/MuonID/MuonSelectorTools/util/MuonSelectorToolsTester.cxx new file mode 100644 index 0000000000000..f889afc515484 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/util/MuonSelectorToolsTester.cxx @@ -0,0 +1,248 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/// a simple testing macro for the MuonSelectorTools_xAOD package +/// shamelessly stolen from CPToolTests.cxx + +// System include(s): +#include <memory> +#include <cstdlib> +#include <string> +#include <map> + +// ROOT include(s): +#include <TFile.h> +#include <TError.h> +#include <TStopwatch.h> +#include <TString.h> + +// Infrastructure include(s): +#ifdef ROOTCORE +# include "xAODRootAccess/Init.h" +# include "xAODRootAccess/TEvent.h" +#endif // ROOTCORE + +// EDM include(s): +#include "xAODEventInfo/EventInfo.h" +#include "xAODMuon/MuonContainer.h" +#include "xAODTracking/TrackingPrimitives.h" +#include "xAODTracking/TrackParticleContainer.h" + +// Local include(s): +#include "MuonSelectorTools/errorcheck.h" +#include "MuonSelectorTools/MuonSelectionTool.h" + +/// Example of how to run the MuonSelectorTools package to obtain information from muons + +int main( int argc, char* argv[] ) { + + + // The application's name: + const char* APP_NAME = argv[ 0 ]; + + // Check if we received a file name: + if( argc < 2 ) { + Error( APP_NAME, "No file name received!" ); + Error( APP_NAME, " Usage: %s [xAOD file name]", APP_NAME ); + return 1; + } + + // Initialise the application: + CHECK( xAOD::Init( APP_NAME ) ); + + // Open the input file: + const TString fileName = argv[ 1 ]; + Info( APP_NAME, "Opening file: %s", fileName.Data() ); + std::auto_ptr< TFile > ifile( TFile::Open( fileName, "READ" ) ); + CHECK( ifile.get() ); + + // Create a TEvent object: + xAOD::TEvent event; + CHECK(event.readFrom( ifile.get(), xAOD::TEvent::kClassAccess )); + Info( APP_NAME, "Number of events in the file: %i", + static_cast< int >( event.getEntries() ) ); + + // Decide how many events to run over: + Long64_t entries = event.getEntries(); + if( argc > 2 ) { + const Long64_t e = atoll( argv[ 2 ] ); + if( e < entries ) { + entries = e; + } + } + + + CP::MuonSelectionTool m_muonSelection("MuonSelection"); + + m_muonSelection.msg().setLevel( MSG::VERBOSE ); + m_muonSelection.setProperty( "MaxEta", 2.4 ); + //m_muonSelection.setProperty( "Author", 12 ); + //m_muonSelection.initialize(); + CHECK (m_muonSelection.initialize().isSuccess()); + + int allMuons = 0; + int allgoodMuons = 0; + + // Loop over the events: + for( Long64_t entry = 0; entry < entries; ++entry ) { + + // Tell the object which entry to look at: + event.getEntry( entry ); + + int goodMuons = 0; + + // Print some event information for fun: + const xAOD::EventInfo* ei = 0; + CHECK( event.retrieve( ei, "EventInfo" ) ); + Info( APP_NAME, + "===>>> start processing event #%i, " + "run #%i %i events processed so far <<<===", + static_cast< int >( ei->eventNumber() ), + static_cast< int >( ei->runNumber() ), + static_cast< int >( entry ) ); + + // Get the Muons from the event: + const xAOD::MuonContainer* muons = 0; + CHECK( event.retrieve( muons, "Muons" ) ); + Info( APP_NAME, "Number of muons: %i", + static_cast< int >( muons->size() ) ); + + // Print their properties, using the tools: + xAOD::MuonContainer::const_iterator mu_itr = muons->begin(); + xAOD::MuonContainer::const_iterator mu_end = muons->end(); + for( ; mu_itr != mu_end; ++mu_itr ) { + + allMuons++; + uint8_t PixHits = 0, PixDead = 0, SCTHits = 0, SCTDead = 0, PixHoles = 0, SCTHoles = 0, TRTHits = 0, TRTOut = 0; + + + // std::cout << "ENTERING ACCEPT FUNCTION " << std::endl; + // if(!m_muonSelection.accept(**mu_itr)) continue; + // std::cout << "PASSED ACCEPT FUNCTION " << std::endl; + + if(!(*mu_itr)->primaryTrackParticle()->summaryValue(PixHits,xAOD::numberOfPixelHits)) + Info( APP_NAME, "Missing info!"); + Info( APP_NAME, "Primary track: PixHits %i ", PixHits); + + if(!(*mu_itr)->primaryTrackParticle()->summaryValue(PixDead,xAOD::numberOfPixelDeadSensors)) + Info( APP_NAME, "Missing info!"); + Info( APP_NAME, "Primary track: PixDead %i ", PixDead); + + if(!(*mu_itr)->primaryTrackParticle()->summaryValue(SCTHits,xAOD::numberOfSCTHits)) + Info( APP_NAME, "Missing info!"); + Info( APP_NAME, "Primary track: SCTHits %i ", SCTHits); + + if(!(*mu_itr)->primaryTrackParticle()->summaryValue(SCTDead,xAOD::numberOfSCTDeadSensors)) + Info( APP_NAME, "Missing info!"); + Info( APP_NAME, "Primary track: SCTDead %i ", SCTDead); + + + if(!(*mu_itr)->primaryTrackParticle()->summaryValue(PixHoles,xAOD::numberOfPixelHoles)) + Info( APP_NAME, "Missing info!"); + Info( APP_NAME, "Primary track: PixHoles %i ", PixHoles); + + if(!(*mu_itr)->primaryTrackParticle()->summaryValue(SCTHoles,xAOD::numberOfSCTHoles)) + Info( APP_NAME, "Missing info!"); + Info( APP_NAME, "Primary track: SCTHoles %i ", SCTHoles); + + float abseta = std::abs((*mu_itr)->eta()); + + if(!(*mu_itr)->primaryTrackParticle()->summaryValue(TRTHits,xAOD::numberOfTRTHits)) + Info( APP_NAME, "Missing info!"); + Info( APP_NAME, "Primary track: TRTHits %i ", TRTHits); + + if(!(*mu_itr)->primaryTrackParticle()->summaryValue(TRTOut,xAOD::numberOfTRTOutliers)) + Info( APP_NAME, "Missing info!"); + Info( APP_NAME, "Primary track: TRTOut %i ", TRTOut); + + uint8_t totTRT = TRTHits+TRTOut; + + Info( APP_NAME, "Muon eta: %g ", std::abs((*mu_itr)->eta())); + Info( APP_NAME, "TotTRT %i > 5; OutCond %i < %g ", totTRT, TRTOut, 0.9*totTRT); + + if (!((0.1<abseta && abseta<=1.9 && totTRT>5 && TRTOut<(0.9 * totTRT)) || (abseta <= 0.1 || abseta > 1.9))) + std::cout << "didn't pass the TRT cuts! v1 " << std::endl; + + if ((0.1<abseta && abseta<=1.9) && !(totTRT>5 && TRTOut<(0.9 * totTRT))) + std::cout << "didn't pass the TRT cuts! v2 " << std::endl; + + + // Select "good" muons: + // if( ! m_muonSelection.accept( **mu_itr ) ) std::cout << "didn't pass! " << std::endl; + if( ! m_muonSelection.passedIDCuts( **mu_itr ) ) { + Info(APP_NAME, "DIDNT PASS THE ID CUTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + continue; + } + + if( (*mu_itr)->quality() == xAOD::Muon_v1::Tight) + std::cout << "tight " << std::endl; + else if( (*mu_itr)->quality() == xAOD::Muon_v1::Medium) + std::cout << "medium " << std::endl; + else if( (*mu_itr)->quality() == xAOD::Muon_v1::Loose) + std::cout << "loose " << std::endl; + else + std::cout << "no quality! " << std::endl; + + if( (*mu_itr)->muonType() == xAOD::Muon_v1::Combined) + std::cout << "combined " << std::endl; + else if( (*mu_itr)->muonType() == xAOD::Muon_v1::MuonStandAlone) + std::cout << "stand-alone " << std::endl; + else if( (*mu_itr)->muonType() == xAOD::Muon_v1::SegmentTagged) + std::cout << "segment-tagged " << std::endl; + else if( (*mu_itr)->muonType() == xAOD::Muon_v1::CaloTagged) + std::cout << "calo-tagged " << std::endl; + else if( (*mu_itr)->muonType() == xAOD::Muon_v1::SiliconAssociatedForwardMuon) + std::cout << "forward " << std::endl; + else + std::cout << "no type! " << std::endl; + + Info(APP_NAME, "MyVerboseType %i ", (*mu_itr)->muonType()); + Info(APP_NAME, "MyVerboseQuality %i ", (*mu_itr)->quality()); + + Info(APP_NAME, "MyVerboseGetQuality %i ", m_muonSelection.getQuality( **mu_itr )); + + if(m_muonSelection.getQuality( **mu_itr ) != xAOD::Muon_v1::Medium) { + Info(APP_NAME, "DIDNT PASS THE QUALITY CUTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + continue; + } + + goodMuons++; + allgoodMuons++; + + // // Print some info about the selected muon: + // Info( APP_NAME, " Selected muon: eta = %g, phi = %g, pt = %g", + // ( *mu_itr )->eta(), ( *mu_itr )->phi(), ( *mu_itr )->pt() ); + // Info( APP_NAME, " Primary track: eta = %g, phi = %g, pt = %g", + // ( *mu_itr )->primaryTrackParticle()->eta(), + // ( *mu_itr )->primaryTrackParticle()->phi(), + // ( *mu_itr )->primaryTrackParticle()->pt() ); + + // const xAOD::TrackParticle* idtrack = + // ( *mu_itr )->trackParticle( xAOD::Muon::InnerDetectorTrackParticle ); + // if( idtrack ) { + // Info( APP_NAME, " ID track: eta = %g, phi = %g, pt = %g", + // idtrack->eta(), idtrack->phi(), idtrack->pt() ); + // } + + } + + Info( APP_NAME, "Number of good muons: %i", + goodMuons ); + + // Close with a message: + Info( APP_NAME, + "===>>> done processing event #%i, " + "run #%i %i events processed so far <<<===", + static_cast< int >( ei->eventNumber() ), + static_cast< int >( ei->runNumber() ), + static_cast< int >( entry + 1 ) ); + } + + Info(APP_NAME, "All muons %i and good muons %i " , allMuons, allgoodMuons); + + // Return gracefully: + return 0; + + +} -- GitLab