From bc4eb98da856ac712f1e9fdc25b791694aa7fd38 Mon Sep 17 00:00:00 2001 From: Atlas-Software Librarian <Atlas-Software.Librarian@cern.ch> Date: Fri, 8 Apr 2016 15:54:16 +0200 Subject: [PATCH] 'CMakeLists.txt' (MuonTPTools-00-00-15) * Tagging MuonTPTools-00-00-15 2015-06-23 Massimiliano Bellomo <massimiliano.bellomo@cern.ch> * Added Event trigger branches to MuonTPTreeTool and needed changes to MuonTPEfficiencyTool interfance to read trigger for probes * Improved consistency of some tree branches * Added support for High Pt working point 2015-06-23 Max Goblirsch <goblirsc@CERN.CH> * Added flag to the Tree tool to write SF info only when needed * Writing match dR only for nominal matching scenarios 2015-06-22 Max Goblirsch <goblirsc@CERN.CH> * MuonTPTreeTool: added tag trigger matching information * MuonTPSelectionTool: added method to retrieve trigger list * Actually implemented the match dR systematic in MuonTrigTPEfficiencyTool.... 2015-06-22 Massimiliano Bellomo <massimiliano.bellomo@cern.ch> * DiMuonTPSelectionTool, MuonTPSelectionTool added option to select truth matched reco probes * MuonTPPlotTool removed useDirDefault option, not neeeded anymore * DiMuonTPTreeTool renamed tag and probes branches ... (Long ChangeLog diff - truncated) --- .../MuonTPTools/CMakeLists.txt | 40 + ...umuMuonTPPlotTool.h => DiMuonTPPlotTool.h} | 13 +- ...electionTool.h => DiMuonTPSelectionTool.h} | 29 +- .../MuonTPTools/DiMuonTPTreeTool.h | 121 +++ .../MuonTPTools/IMuonTPEfficiencyTool.h | 6 + .../MuonTPTools/MuonTPTools/IMuonTPPlotTool.h | 2 +- .../MuonTPTools/IMuonTPSelectionTool.h | 8 + .../MuonTPTools/MuonTPTools/IMuonTPTreeTool.h | 20 +- .../MuonTPTools/JPsiMuonTPEfficiencyTool.h | 34 - .../MuonTPTools/JPsiMuonTPPlotTool.h | 34 - .../MuonTPTools/JPsiMuonTPSelectionTool.h | 62 -- .../MuonTPTools/MuonIsolTPEfficiencyTool.h | 32 + .../MuonTPTools/MuonRecoTPEfficiencyTool.h | 54 +- .../MuonTPTools/MuonTPEfficiencyTool.h | 17 +- .../MuonTPTools/MuonTPTools/MuonTPPlotTool.h | 36 +- .../MuonTPTools/MuonTPSelectionTool.h | 36 +- .../MuonTPTools/MuonTPTools/MuonTPTool.h | 4 +- .../MuonTPTools/MuonTPTools/MuonTPTreeTool.h | 68 +- .../MuonTPTools/MuonTrigTPEfficiencyTool.h | 5 +- .../MuonTPTools/MuonTrigTPPlotTool.h | 38 - .../MuonTPTools/MuonTrigTPTreeTool.h | 50 -- .../ZmumuMuonTPIsolationTreeTool.h | 91 -- .../MuonTPTools/ZmumuMuonTPTreeTool.h | 64 -- .../MuonTPTools/Root/DiMuonTPPlotTool.cxx | 56 ++ ...tionTool.cxx => DiMuonTPSelectionTool.cxx} | 216 +++-- .../MuonTPTools/Root/DiMuonTPTreeTool.cxx | 437 ++++++++++ .../Root/JPsiMuonTPEfficiencyTool.cxx | 94 -- .../MuonTPTools/Root/JPsiMuonTPPlotTool.cxx | 24 - .../Root/JPsiMuonTPSelectionTool.cxx | 156 ---- .../Root/MuonIsolTPEfficiencyTool.cxx | 32 + .../Root/MuonRecoTPEfficiencyTool.cxx | 276 ++++-- .../MuonTPTools/Root/MuonTPEfficiencyTool.cxx | 41 +- .../MuonTPTools/Root/MuonTPPlotTool.cxx | 313 +++---- .../MuonTPTools/Root/MuonTPSelectionTool.cxx | 323 ++++--- .../MuonTPTools/Root/MuonTPTool.cxx | 34 +- .../MuonTPTools/Root/MuonTPTreeTool.cxx | 274 ++++-- .../Root/MuonTrigTPEfficiencyTool.cxx | 61 +- .../MuonTPTools/Root/MuonTrigTPPlotTool.cxx | 45 - .../MuonTPTools/Root/MuonTrigTPTreeTool.cxx | 129 --- .../Root/ZmumuMuonTPIsolationTreeTool.cxx | 227 ----- .../MuonTPTools/Root/ZmumuMuonTPPlotTool.cxx | 47 - .../MuonTPTools/Root/ZmumuMuonTPTreeTool.cxx | 164 ---- .../MuonTPTools/cmt/Makefile.RootCore | 2 +- .../MuonTPTools/cmt/requirements | 13 +- .../MuonTPTools/macros/CreateSF.py | 266 ++++++ .../MuonTPTools/macros/DSConfig.py | 23 + .../MuonTPTools/macros/Defs.py | 79 ++ .../MuonTPTools/macros/EffPlots.py | 818 ++++++++++++++++++ .../MuonTPTools/macros/HistoDefs.py | 229 +++++ .../MuonTPTools/macros/Histos.py | 715 +++++++++++++++ .../MuonTPTools/macros/PlotUtils.py | 281 ++++++ .../MuonTPTools/macros/ProbePlots.py | 254 ++++++ .../MuonTPTools/macros/TestRecoSF.py | 71 ++ .../MuonTPTools/macros/Utils.py | 253 ++++++ .../src/components/MuonTPTools_entries.cxx | 74 +- 55 files changed, 4900 insertions(+), 1991 deletions(-) create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/CMakeLists.txt rename PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/{ZmumuMuonTPPlotTool.h => DiMuonTPPlotTool.h} (75%) rename PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/{ZmumuMuonTPSelectionTool.h => DiMuonTPSelectionTool.h} (76%) create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPTreeTool.h delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPEfficiencyTool.h delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPPlotTool.h delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPSelectionTool.h create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonIsolTPEfficiencyTool.h delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPPlotTool.h delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPTreeTool.h delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPIsolationTreeTool.h delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPTreeTool.h create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPPlotTool.cxx rename PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/{ZmumuMuonTPSelectionTool.cxx => DiMuonTPSelectionTool.cxx} (59%) create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPTreeTool.cxx delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPEfficiencyTool.cxx delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPPlotTool.cxx delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPSelectionTool.cxx create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonIsolTPEfficiencyTool.cxx delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPPlotTool.cxx delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPTreeTool.cxx delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPIsolationTreeTool.cxx delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPPlotTool.cxx delete mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPTreeTool.cxx create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/CreateSF.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/DSConfig.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Defs.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/EffPlots.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/HistoDefs.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Histos.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/PlotUtils.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/ProbePlots.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/TestRecoSF.py create mode 100644 PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Utils.py diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/CMakeLists.txt b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/CMakeLists.txt new file mode 100644 index 00000000000..8b4b6685db3 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/CMakeLists.txt @@ -0,0 +1,40 @@ +################################################################################ +# Package: MuonTPTools +################################################################################ + +# Declare the package name: +atlas_subdir( MuonTPTools ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( PUBLIC + Control/AthToolSupport/AsgTools + DataQuality/GoodRunsLists + Event/xAOD/xAODBase + Event/xAOD/xAODMuon + PhysicsAnalysis/MuonID/MuonIDAnalysis/MuonEfficiencyCorrections + PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonPerformanceHistUtils + PhysicsAnalysis/MuonID/MuonSelectorTools + Trigger/TrigAnalysis/TrigDecisionTool + Trigger/TrigAnalysis/TrigMuonMatching + PRIVATE + Event/xAOD/xAODEventInfo + Event/xAOD/xAODEventShape + Event/xAOD/xAODJet + Event/xAOD/xAODTracking + Event/xAOD/xAODTruth + GaudiKernel + PhysicsAnalysis/MCTruthClassifier ) + +# External dependencies: +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# Component(s) in the package: +atlas_add_component( MuonTPTools + Root/*.cxx + src/components/*.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools GoodRunsListsLib xAODBase xAODMuon MuonEfficiencyCorrectionsLib MuonPerformanceHistUtils MuonSelectorToolsLib TrigDecisionToolLib TrigMuonMatchingLib xAODEventInfo xAODEventShape xAODJet xAODTracking xAODTruth GaudiKernel MCTruthClassifierLib ) + +# Install files from the package: +atlas_install_headers( MuonTPTools ) + diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPPlotTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPPlotTool.h similarity index 75% rename from PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPPlotTool.h rename to PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPPlotTool.h index 17beae37b08..2d1dc834fc9 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPPlotTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPPlotTool.h @@ -18,22 +18,25 @@ #include "AsgTools/AsgTool.h" #include <map> -class ZmumuMuonTPPlotTool: +class DiMuonTPPlotTool: public MuonTPPlotTool { - ASG_TOOL_CLASS(ZmumuMuonTPPlotTool, IMuonTPPlotTool) + ASG_TOOL_CLASS(DiMuonTPPlotTool, IMuonTPPlotTool) public: - ZmumuMuonTPPlotTool(std::string name); + DiMuonTPPlotTool(std::string name); virtual std::vector<MuonTPEfficiencyPlotBase*> AddPlots(std::string sDir, bool isMatched); virtual std::vector<MuonTPCutFlowBase*> AddCutFlowPlots(std::string sDir); protected: - bool m_do_TPBasic; + bool m_do_TPBasic_JPsi; + bool m_do_TPBasic_Zmm; + bool m_do_DiLepton_Zmm; + bool m_do_DiLepton_JPsi; bool m_do_TPFineEtaPhi; + bool m_do_TriggerPlots; bool m_do_DetRegions; bool m_do_Valid; - bool m_do_DiLepton; bool m_apply_SF; }; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPSelectionTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPSelectionTool.h similarity index 76% rename from PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPSelectionTool.h rename to PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPSelectionTool.h index 5c4c0ad9384..6b5cae054fd 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPSelectionTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPSelectionTool.h @@ -3,27 +3,24 @@ */ /* - * ZmumuMuonTPSelectionTool.h + * DiMuonTPSelectionTool.h * - * Created on: Aug 26, 2014 + * Created on: Jun 18, 2015 * Author: goblirsc<at>CERN.CH */ #ifndef ZMUMUMUONTPSELECTIONTOOL_H_ #define ZMUMUMUONTPSELECTIONTOOL_H_ -/// This is the implementation of the IMuonTPSelectionTool for the Z->mm tag and probe -/// efficiency measurement. +/// This is the implementation of the IMuonTPSelectionTool for the tag and probe +/// efficiency measurement using dimuon resonances (JPsi and Z). #include "MuonTPTools/MuonTPSelectionTool.h" #include "AsgTools/AsgTool.h" -class ZmumuMuonTPSelectionTool: - virtual public IMuonTPSelectionTool, - virtual public asg::AsgTool, - public MuonTPSelectionTool{ - ASG_TOOL_CLASS(ZmumuMuonTPSelectionTool, IMuonTPSelectionTool) +class DiMuonTPSelectionTool: public MuonTPSelectionTool{ + ASG_TOOL_CLASS(DiMuonTPSelectionTool, IMuonTPSelectionTool) public: - ZmumuMuonTPSelectionTool(std::string myname); + DiMuonTPSelectionTool(std::string myname); virtual StatusCode initialize(); @@ -69,6 +66,7 @@ private: bool m_CBProbe; bool m_MSProbe; bool m_TruthProbe; + bool m_TruthMatchedProbe; bool m_only_A_side; bool m_only_C_side; @@ -83,8 +81,17 @@ private: double m_probe_z0; - double m_deltaPhiCut; + double m_deltaPhiCut; + double m_deltaEtaCut; + bool m_doProbeChargeSys; + std::string m_ProbeCharge; + + bool m_VeryLooseProbe; + bool m_LooseProbe; + bool m_MediumProbe; + bool m_TightProbe; + bool m_HighPtProbe; }; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPTreeTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPTreeTool.h new file mode 100644 index 00000000000..5f72f0076e0 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/DiMuonTPTreeTool.h @@ -0,0 +1,121 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + + #ifndef ZMUMUMUONTPTreeTOOL_H_ + #define ZMUMUMUONTPTreeTOOL_H_ + #include "MuonTPTools/IMuonTPTreeTool.h" + #include "MuonTPTools/IMuonTPSelectionTool.h" + #include "MuonTPTools/IMuonTPEfficiencyTool.h" + #include "MuonTPTools/MuonTPTreeTool.h" + #include "MuonEfficiencyCorrections/fineEtaPhiBinning.h" + #include "MuonPerformanceHistUtils/EtaPhiBinning.h" + #include "AsgTools/AsgTool.h" + #include "MuonSelectorTools/MuonSelectionTool.h" + #include <map> + +class DiMuonTPTreeTool: + public MuonTPTreeTool { // for now, a 1:1 copy + ASG_TOOL_CLASS(DiMuonTPTreeTool, IMuonTPTreeTool) + + public: + DiMuonTPTreeTool(std::string name); + virtual StatusCode initialize(); + virtual void FillCustomStuff(Probe& probe); // can override to fill custom branches + virtual void AddCustomBranches(TTree* tree); // can override to add custom branches + + protected: + UInt_t m_runNumber; + ULong64_t m_eventNumber; + UInt_t m_lumiblock; + float m_average_mu; + float m_actual_mu; + int m_PV_n; + + float m_mcEventWeight; + float m_pt; + float m_eta; + float m_phi; + int m_type; // 1 for CB, 2 for SA, 3 for ST, 4 for CT + int m_author; + int m_quality; + int m_fineEtaPhi; + int m_detregion; + int m_q; + float m_d0; + float m_d0err; + float m_z0; + + float m_tagPt; + float m_tagEta; + float m_tagPhi; + int m_tag_q; + float m_tag_d0; + float m_tag_d0err; + float m_tag_z0; + + float m_mll; + float m_dPhi; + float m_dilep_pt; + float m_dilep_tof; + + float m_tag_deltaR; + float m_deltaR; + + + + // Extra iso stuff + float m_tagiso_neflowisol20; + float m_tagiso_topoetcone20; + float m_tagiso_ptcone20; + float m_tagiso_etcone20; + float m_tagiso_ptvarcone20; + + float m_tagiso_neflowisol30; + float m_tagiso_topoetcone30; + float m_tagiso_ptcone30; + float m_tagiso_etcone30; + float m_tagiso_ptvarcone30; + + float m_tagiso_neflowisol40; + float m_tagiso_topoetcone40; + float m_tagiso_ptcone40; + float m_tagiso_etcone40; + float m_tagiso_ptvarcone40; + + float m_tag_topocore; + + float m_probeiso_neflowisol20; + float m_probeiso_topoetcone20; + float m_probeiso_ptcone20; + float m_probeiso_etcone20; + float m_probeiso_ptvarcone20; + + float m_probeiso_neflowisol30; + float m_probeiso_topoetcone30; + float m_probeiso_ptcone30; + float m_probeiso_etcone30; + float m_probeiso_ptvarcone30; + + float m_probeiso_neflowisol40; + float m_probeiso_topoetcone40; + float m_probeiso_ptcone40; + float m_probeiso_etcone40; + float m_probeiso_ptvarcone40; + + float m_probe_topocore; + + float m_energyDensity_central; + float m_energyDensity_forward; + + + fineEtaPhiBinning m_fepb; + EtaPhiBinning m_epb; + ToolHandle<CP::IMuonSelectionTool> m_muon_selection_tool; + + bool m_extended_Iso_Info; + +}; + + #endif /* ZMUMUMUONTPTreeTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPEfficiencyTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPEfficiencyTool.h index a636254589a..75fdee3ceef 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPEfficiencyTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPEfficiencyTool.h @@ -23,6 +23,12 @@ public: /// Get Efficiency Flag virtual std::string efficiencyFlag() =0; + + // check if the tool represents a nominal run or a sys variation + virtual bool isNominal() const=0; + + // return the triger item (if any configured) + virtual std::string triggerItem() =0; }; #endif diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPPlotTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPPlotTool.h index dea4e9f0486..fbaa413c505 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPPlotTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPPlotTool.h @@ -30,7 +30,7 @@ public: virtual StatusCode RegisterPlots (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools) = 0; // fill the histos - virtual void fill(Probe& probe, ToolHandle <IMuonTPSelectionTool> & tp_tool, ToolHandle <IMuonTPEfficiencyTool> eff_tool) = 0; + virtual void fill(Probe& probe, ToolHandle <IMuonTPSelectionTool> & tp_tool, ToolHandle <IMuonTPEfficiencyTool> & eff_tool) = 0; // fill the cut flow virtual void fillCutFlow (std::string stage, double weight, ToolHandle <IMuonTPSelectionTool> & tp_tool) = 0; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPSelectionTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPSelectionTool.h index 51434dde876..69840df712f 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPSelectionTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPSelectionTool.h @@ -27,6 +27,14 @@ public: /// Get Efficiency Flag virtual std::string efficiencyFlag() =0; + + // check if the tool represents a nominal run or a sys variation + virtual bool isNominal() const=0; + + // check if the tool is a systematic variation that can not be evaluated using the nominal ntuples + virtual bool notIncludedInNominal() const=0; + + virtual std::vector<std::string> tagTriggerList() const = 0; }; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPTreeTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPTreeTool.h index bcfbb410ea6..656bf45447d 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPTreeTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/IMuonTPTreeTool.h @@ -25,19 +25,19 @@ class IMuonTPEfficiencyTool; class IMuonTPTreeTool : virtual public asg::IAsgTool { ASG_TOOL_INTERFACE(IMuonTPTreeTool) -public: + public: - // used to initialize the required histos - virtual StatusCode RegisterTrees (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools) = 0; + // used to initialize the required histos + virtual StatusCode RegisterTrees (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools) = 0; - // fill the histos - virtual void updateMatch(Probe& probe,ToolHandle <IMuonTPEfficiencyTool> eff_tool) = 0; - virtual void ForgetKnownProbes() = 0; - virtual void fill(Probe& probe,ToolHandle <IMuonTPSelectionTool> sel_tool) = 0; -// virtual void + // fill the histos + virtual void updateMatch(Probe& probe,ToolHandle <IMuonTPEfficiencyTool> & eff_tool) = 0; + virtual void ForgetKnownProbes() = 0; + virtual void fill(Probe& probe,ToolHandle <IMuonTPSelectionTool> & sel_tool) = 0; + // virtual void - /// retrieve booked histograms - virtual std::vector< std::pair<TTree*, std::string> > retrieveBookedTrees() = 0; + /// retrieve booked histograms + virtual std::vector< std::pair<TTree*, std::string> > retrieveBookedTrees() = 0; }; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPEfficiencyTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPEfficiencyTool.h deleted file mode 100644 index 8e985f9fa33..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPEfficiencyTool.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * JPsiMuonTPEfficiencyTool.h - * - * Created on: Sep 01, 2014 - * Author: Maximiliano Sioli - */ - -#ifndef JPSIMUONTPEFFICIENCYTOOL_H_ -#define JPSIMUONTPEFFICIENCYTOOL_H_ - -#include "MuonTPTools/MuonTPEfficiencyTool.h" -class JPsiMuonTPEfficiencyTool : public MuonTPEfficiencyTool{ - ASG_TOOL_CLASS(JPsiMuonTPEfficiencyTool, IMuonTPEfficiencyTool) -public: - JPsiMuonTPEfficiencyTool(std::string name); - - /// Match probes for efficiency calculation - void dRMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const; - bool GoodMatchMuonType(const xAOD::IParticle* probe) const; -private: - bool m_match_MS; - bool m_match_CB; - bool m_match_Medium; - bool m_match_ID; - bool m_match_CaloTag; - bool m_do_IDHits; - -}; - -#endif /* JPSIMUONTPEFFICIENCYTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPPlotTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPPlotTool.h deleted file mode 100644 index 4cc831ff2d2..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPPlotTool.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * JPsiMuonTPPlots.h - * - * Created on: Sep 01, 2014 - * Author: Maximiliano Sioli - */ - -#ifndef JPSIMUONTPPLOTTOOL_H_ -#define JPSIMUONTPPLOTTOOL_H_ -#include "MuonTPTools/IMuonTPPlotTool.h" -#include "MuonTPTools/IMuonTPSelectionTool.h" -#include "MuonTPTools/IMuonTPEfficiencyTool.h" -#include "MuonTPTools/MuonTPPlotTool.h" -#include "AsgTools/AsgTool.h" -#include <map> - -class JPsiMuonTPPlotTool: - public MuonTPPlotTool { - ASG_TOOL_CLASS(JPsiMuonTPPlotTool, IMuonTPPlotTool) - -public: - JPsiMuonTPPlotTool(std::string name); - - virtual std::vector<MuonTPEfficiencyPlotBase*> AddPlots(std::string sDir, bool isMatched); - -protected: - -}; - -#endif /* JPSIMUONTPPLOTTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPSelectionTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPSelectionTool.h deleted file mode 100644 index ca8244fda28..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/JPsiMuonTPSelectionTool.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * JPsiMuonTPSelectionTool.h - * - * Created on: Sep 01, 2014 - * Author: Maximiliano Sioli - */ - -#ifndef JPSIMUONTPSELECTIONTOOL_H_ -#define JPSIMUONTPSELECTIONTOOL_H_ - -/// This is the implementation of the IMuonTPSelectionTool for the Z->mm tag and probe -/// efficiency measurement. -#include "MuonTPTools/MuonTPSelectionTool.h" -#include "AsgTools/AsgTool.h" - -class JPsiMuonTPSelectionTool: - virtual public IMuonTPSelectionTool, - virtual public asg::AsgTool, - public MuonTPSelectionTool{ - ASG_TOOL_CLASS(JPsiMuonTPSelectionTool, IMuonTPSelectionTool) -public: - JPsiMuonTPSelectionTool(std::string myname); - - virtual StatusCode initialize(); - - /// Select Probes - ProbeContainer* selectProbes(const xAOD::MuonContainer*, const xAOD::IParticleContainer*) const; - - /// Get Efficiency Flag - std::string efficiencyFlag() {return m_efficiencyFlag;} - - /// Check if Probe and Tag are the same object - bool isTag(const xAOD::Muon* tag, const xAOD::IParticle* probe) const; - - // helper method to check if the probe is the right type - bool isRightType(const xAOD::IParticle* probe) const; - - private: - - bool m_accept_sameCharge; - bool m_accept_oppCharge; - - bool m_probe_ID_hits; - - double m_tagIsolation; - double m_probeIsolation; - - bool m_IDProbe; - bool m_CaloProbe; - bool m_CBProbe; - bool m_MSProbe; - - double m_deltaPhiCut; - -}; - - -#endif /* JPSIMUONTPSELECTIONTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonIsolTPEfficiencyTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonIsolTPEfficiencyTool.h new file mode 100644 index 00000000000..c12cd78c0c0 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonIsolTPEfficiencyTool.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * MuonIsolTPEfficiencyTool.h + * + * Created on: Aug 31, 2014 + * Author: goblirsc / a.m. + */ + +#ifndef MUONISOLTPEFFICIENCYTOOL_H_ +#define MUONISOLTPEFFICIENCYTOOL_H_ + +#include "MuonTPTools/MuonTPEfficiencyTool.h" + + +class MuonIsolTPEfficiencyTool : public MuonTPEfficiencyTool{ + ASG_TOOL_CLASS(MuonIsolTPEfficiencyTool, IMuonTPEfficiencyTool) + +public: + MuonIsolTPEfficiencyTool(std::string name); + + // Match probes for efficiency calculation + void matchProbes(ProbeContainer*, const xAOD::IParticleContainer*) const; + +private: + + +}; + +#endif /* MUONISOLTPEFFICIENCYTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonRecoTPEfficiencyTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonRecoTPEfficiencyTool.h index 9ea77b5bc44..16a1ddbfe21 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonRecoTPEfficiencyTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonRecoTPEfficiencyTool.h @@ -14,33 +14,37 @@ #include "MuonTPTools/MuonTPEfficiencyTool.h" class MuonRecoTPEfficiencyTool : public MuonTPEfficiencyTool{ - ASG_TOOL_CLASS(MuonRecoTPEfficiencyTool, IMuonTPEfficiencyTool) -public: - MuonRecoTPEfficiencyTool(std::string name); + ASG_TOOL_CLASS(MuonRecoTPEfficiencyTool, IMuonTPEfficiencyTool) + public: + MuonRecoTPEfficiencyTool(std::string name); - /// Match probes for efficiency calculation - void dRMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const; - bool GoodMatchMuonType(const xAOD::IParticle* probe) const; -private: + /// Match probes for efficiency calculation + virtual void matchProbes(ProbeContainer*, const xAOD::IParticleContainer*) const; + void dRMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const; + void ptrMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const; + bool GoodMatchMuonType(const xAOD::IParticle* probe) const; + private: - bool m_match_MS; - bool m_match_CB; - bool m_match_Loose; - bool m_match_Loose_noCT; - bool m_match_Medium; - bool m_match_Tight; - bool m_match_ID; - bool m_match_CaloTag; - bool m_match_MuidCB; - bool m_match_STACO; - bool m_match_MuTag; - bool m_match_MuTagIMO; - bool m_match_MuidSA; - bool m_match_MuGirl; - bool m_match_MuGirlLowBeta; - bool m_match_CaloLikelihood; - bool m_match_ExtrapolateToIP; - bool m_do_IDHits; + bool m_ptrMatching; + bool m_match_MS; + bool m_match_CB; + bool m_match_Loose; + bool m_match_Loose_noCT; + bool m_match_Medium; + bool m_match_Tight; + bool m_match_HighPt; + bool m_match_ID; + bool m_match_CaloTag; + bool m_match_MuidCB; + bool m_match_STACO; + bool m_match_MuTag; + bool m_match_MuTagIMO; + bool m_match_MuidSA; + bool m_match_MuGirl; + bool m_match_MuGirlLowBeta; + bool m_match_CaloLikelihood; + bool m_match_ExtrapolateToIP; + bool m_do_IDHits; }; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPEfficiencyTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPEfficiencyTool.h index c465dbaf6b6..76be7f4899f 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPEfficiencyTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPEfficiencyTool.h @@ -19,9 +19,9 @@ #include "TrigMuonMatching/ITrigMuonMatching.h" class MuonTPEfficiencyTool -: virtual public asg::AsgTool, +: public asg::AsgTool, virtual public IMuonTPEfficiencyTool { - ASG_TOOL_CLASS(MuonTPEfficiencyTool, IMuonTPEfficiencyTool) +// ASG_TOOL_CLASS(MuonTPEfficiencyTool, IMuonTPEfficiencyTool) public: @@ -32,8 +32,8 @@ public: virtual StatusCode initialize(); /// Match probes for efficiency calculation - void matchProbes(ProbeContainer*, const xAOD::IParticleContainer*) const; - + virtual void matchProbes(ProbeContainer*, const xAOD::IParticleContainer*) const =0; + /// dR-based matching virtual void dRMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const; @@ -45,15 +45,22 @@ public: // check for a trigger match (probe side) bool MatchTrigger (const xAOD::IParticle* match, std::string trigger) const; + + // check if the tool represents a nominal matching + bool isNominal() const {return m_isNominal;} + + // return the triger item (if any configured) + std::string triggerItem() {return m_trigger_item;} protected: double m_matchPtCut; double m_matchEtaCut; - bool m_dRMatching; double m_maximumDrCut; unsigned int m_muonAuthor; std::string m_efficiencyFlag; + bool m_isNominal; + std::string m_trigger_item; ToolHandle<CP::IMuonSelectionTool> m_selection_tool; ToolHandle<CP::IMuonEfficiencyScaleFactors> m_sf_tool; bool m_do_sf; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPPlotTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPPlotTool.h index 8a45e27f72c..9a195d1ff4d 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPPlotTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPPlotTool.h @@ -24,43 +24,45 @@ // define the plot classes to add in the HistUtils package class MuonTPPlotTool: - virtual public asg::AsgTool, + public asg::AsgTool, virtual public IMuonTPPlotTool { - ASG_TOOL_CLASS(MuonTPPlotTool, IMuonTPPlotTool) +// ASG_TOOL_CLASS(MuonTPPlotTool, IMuonTPPlotTool) public: - MuonTPPlotTool(std::string name); + MuonTPPlotTool(std::string name); - virtual StatusCode RegisterPlots (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools); + virtual StatusCode RegisterPlots (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools); - virtual std::vector<MuonTPEfficiencyPlotBase*> AddPlots(std::string sDir, bool isMatched); + virtual std::vector<MuonTPEfficiencyPlotBase*> AddPlots(std::string sDir, bool isMatched); virtual std::vector<MuonTPCutFlowBase*> AddCutFlowPlots(std::string sDir); - // fill the histos - virtual void fill(Probe& probe, ToolHandle <IMuonTPSelectionTool> & tp_tool, ToolHandle <IMuonTPEfficiencyTool> eff_tool); - virtual void fillCutFlow (std::string stage, double weight, ToolHandle <IMuonTPSelectionTool> & tp_tool); + // fill the histos + virtual void fill(Probe& probe, ToolHandle <IMuonTPSelectionTool> & tp_tool, ToolHandle <IMuonTPEfficiencyTool> & eff_tool); + virtual void fillCutFlow (std::string stage, double weight, ToolHandle <IMuonTPSelectionTool> & tp_tool); - /// retrieve booked histograms - std::vector<HistData> retrieveBookedHistograms(); + /// retrieve booked histograms + std::vector<HistData> retrieveBookedHistograms(); std::vector<std::pair <TGraph*, std::string> > retrieveBookedGraphs(); - virtual void CalcEff(void); + virtual void CalcEff(void); - virtual ~MuonTPPlotTool(); + virtual ~MuonTPPlotTool(); protected: - std::string m_efficiencyFlag; - std::map<std::string,std::vector<MuonTPEfficiencyPlotBase*> > m_probeTPEffPlots; - std::map<std::string,std::vector<MuonTPEfficiencyPlotBase*> > m_matchTPEffPlots; - std::map<std::string,std::vector<MuonTPEfficiencyPlotBase*> > m_effTPEffPlots; - std::map<std::string,std::vector<MuonTPCutFlowBase*> > m_TPcutFlowPlots; + std::string m_efficiencyFlag; + std::map<std::string,std::vector<MuonTPEfficiencyPlotBase*> > m_probeTPEffPlots; + std::map<std::string,std::vector<MuonTPEfficiencyPlotBase*> > m_matchTPEffPlots; + std::map<std::string,std::vector<MuonTPEfficiencyPlotBase*> > m_effTPEffPlots; + std::map<std::string,std::vector<MuonTPCutFlowBase*> > m_TPcutFlowPlots; bool m_only_A_side; bool m_only_C_side; double m_probe_abseta_min; double m_probe_abseta_max; bool m_doAsymmErrors; + bool m_doEffPlots; + bool m_doProbeMatchPlots; }; #endif /* MUONTPPLOTTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPSelectionTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPSelectionTool.h index a0ffb14d039..bed98f21f97 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPSelectionTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPSelectionTool.h @@ -15,23 +15,16 @@ #include "AsgTools/ToolHandle.h" #include "MuonTPTools/IMuonTPSelectionTool.h" #include "MuonSelectorTools/IMuonSelectionTool.h" -#include "xAODTruth/TruthParticle.h" #include "TrigDecisionTool/TrigDecisionTool.h" #include "TrigMuonMatching/ITrigMuonMatching.h" #include "AsgTools/AsgToolsConf.h" #include "AsgTools/AsgMetadataTool.h" - -// for full athena, we also use the isolation tools -# if defined(ASGTOOL_ATHENA) && !defined(XAOD_ANALYSIS) -#include "RecoToolInterfaces/ITrackIsolationTool.h" -#include "RecoToolInterfaces/ICaloTopoClusterIsolationTool.h" -# endif - +#include "GoodRunsLists/IGoodRunsListSelectionTool.h" class MuonTPSelectionTool -: virtual public asg::AsgTool, +: public asg::AsgTool, virtual public IMuonTPSelectionTool { - ASG_TOOL_CLASS(MuonTPSelectionTool, IMuonTPSelectionTool) +// ASG_TOOL_CLASS(MuonTPSelectionTool, IMuonTPSelectionTool) public: @@ -62,6 +55,9 @@ public: // helper method to select Truth probes bool isFinalStateTruthMuon(const xAOD::IParticle* part) const; + // helper to check if a probe is truth matched + bool isTruthMatched(const xAOD::IParticle* part) const; + // select muons that 'probably' fired the trigger - workaround for 19.1 xAODs without trigger info! bool passDummyTrigger(const xAOD::Muon* tag) const; @@ -73,9 +69,20 @@ public: // apply impact parameter cuts bool PassIPCuts(const xAOD::TrackParticle* probe, double d0cut, double d0signcut, double z0cut) const; + + // apply GRL + bool passGRL(const xAOD::EventInfo* info) const; + + // check if the tool represents a nominal selection + bool isNominal() const {return m_isNominal;} + + // check if the tool is a systematic variation that can not be evaluated using the nominal ntuples + virtual bool notIncludedInNominal() const {return m_isNotPartOfNominal;} virtual void AddCutFlowHist(MuonTPCutFlowBase* hist); virtual void FillCutFlows(std::string step, double weight =1.) const ; + + std::vector<std::string> tagTriggerList() const {return m_tag_Triggers;} protected: @@ -86,19 +93,16 @@ protected: double m_probeEtaCut; double m_highMassWindow; double m_lowMassWindow; + bool m_isNominal; + bool m_isNotPartOfNominal; std::string m_efficiencyFlag; std::vector<std::string> m_tag_Triggers; ToolHandle<CP::IMuonSelectionTool> m_selection_tool; std::vector<MuonTPCutFlowBase*> m_cutFlows; ToolHandle<Trig::TrigDecisionTool> m_trigTool; ToolHandle<Trig::ITrigMuonMatching> m_matchTool; + ToolHandle<IGoodRunsListSelectionTool> m_grlTool; -# if defined(ASGTOOL_ATHENA) && !defined(XAOD_ANALYSIS) - ToolHandle<xAOD::ITrackIsolationTool> m_track_iso_tool; - ToolHandle<xAOD::ICaloTopoClusterIsolationTool> m_calo_iso_tool; - std::vector<xAOD::Iso::IsolationType> m_track_iso_to_run; - std::vector<xAOD::Iso::IsolationType> m_calo_iso_to_run; -# endif }; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPTool.h index 867d21648b8..69149a2817b 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPTool.h @@ -23,7 +23,7 @@ class IMuonTPSelectionTool; class IMuonTPEfficiencyTool; class MuonTPTool -: virtual public asg::AsgTool, +: public asg::AsgTool, virtual public IMuonTPTool { ASG_TOOL_CLASS(MuonTPTool, IMuonTPTool) @@ -44,7 +44,7 @@ class MuonTPTool private: - ServiceHandle<ITHistSvc> m_histSvc; + //ServiceHandle<ITHistSvc> m_histSvc; ToolHandleArray<IMuonTPSelectionTool> m_muonTPSelectionTools; ToolHandleArray<IMuonTPEfficiencyTool> m_muonTPEfficiencyTools; std::string m_efficiencyFlag; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPTreeTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPTreeTool.h index fa401f5ab88..9c762036ca9 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPTreeTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTPTreeTool.h @@ -12,6 +12,7 @@ #ifndef MUONTPTreeTool_H_ #define MUONTPTreeTool_H_ #include "MuonTPTools/IMuonTPTreeTool.h" +#include "TrigDecisionTool/TrigDecisionTool.h" #include "MuonTPTools/IMuonTPSelectionTool.h" #include "MuonTPTools/IMuonTPEfficiencyTool.h" #include "AsgTools/AsgTool.h" @@ -24,39 +25,54 @@ // define the plot classes to add in the HistUtils package class MuonTPTreeTool: - virtual public asg::AsgTool, - virtual public IMuonTPTreeTool { - ASG_TOOL_CLASS(MuonTPTreeTool, IMuonTPTreeTool) +public asg::AsgTool, + virtual public IMuonTPTreeTool { -public: - MuonTPTreeTool(std::string name); + public: + MuonTPTreeTool(std::string name); + virtual ~MuonTPTreeTool(); - virtual StatusCode RegisterTrees (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools); + virtual StatusCode initialize(); + virtual StatusCode RegisterTrees (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools); - virtual void updateMatch(Probe& probe, ToolHandle <IMuonTPEfficiencyTool> eff_tool); - virtual void fill(Probe& probe,ToolHandle <IMuonTPSelectionTool> sel_tool); - virtual void FillCustomStuff(Probe& probe); // can override to fill custom branches + virtual void updateMatch(Probe& probe, ToolHandle <IMuonTPEfficiencyTool> & eff_tool); + virtual void fill(Probe& probe,ToolHandle <IMuonTPSelectionTool> & sel_tool); + virtual void FillCustomStuff(Probe& probe); // can override to fill custom branches + /// retrieve booked histograms + std::vector< std::pair<TTree*, std::string> > retrieveBookedTrees(); - /// retrieve booked histograms - std::vector< std::pair<TTree*, std::string> > retrieveBookedTrees(); + virtual void FillTriggerInfo(); + virtual void FillTagTriggerInfo(Probe & probe); + virtual void InitTree(TTree* tree); + virtual void AddCustomBranches(TTree* tree); // can override to add custom branches - virtual void InitTree(TTree* tree); - virtual void AddCustomBranches(TTree* tree); // can override to add custom branches - - virtual void ForgetKnownProbes(); + virtual void ForgetKnownProbes(); - - - virtual ~MuonTPTreeTool(); -protected: - - - std::string m_efficiencyFlag; - std::map<std::string, std::pair< TTree*, std::string> > m_trees; - std::map<std::string, bool> m_match_flags; - std::map<Probe*, std::map<std::string, bool> > m_match_flags_perProbe; -}; + protected: + + ToolHandle<Trig::TrigDecisionTool> m_trigTool; + + std::string m_efficiencyFlag; + + std::map<std::string, std::pair< TTree*, std::string> > m_trees; + + std::map<std::string, bool> m_match_flags; + std::map<std::string, float> m_scale_factors; + std::map<std::string, float> m_match_dR; + + std::map<std::string, bool> m_triggers; + std::map<std::string, bool> m_tag_trigmatch; + std::map<std::string, float> m_tag_trig_dR; + + std::map<Probe*, std::map<std::string, bool> > m_match_flags_perProbe; + std::map<Probe*, std::map<std::string, float> > m_scale_factors_perProbe; + std::map<Probe*, std::map<std::string, float> > m_match_dR_perProbe; + + bool m_record_SF; + // std::map<Probe*, std::map<std::string, bool> > m_tag_trigmatch_perProbe; + // std::map<Probe*, std::map<std::string, float> > m_tag_trig_dR_perProbe; + }; #endif /* MUONTPTreeTool_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPEfficiencyTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPEfficiencyTool.h index ebd3e7284f6..2ceea312f06 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPEfficiencyTool.h +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPEfficiencyTool.h @@ -16,7 +16,7 @@ // FrameWork includes -#include "GaudiKernel/ServiceHandle.h" +//#include "GaudiKernel/ServiceHandle.h" #include "TrigDecisionTool/TrigDecisionTool.h" @@ -29,12 +29,11 @@ public: // Match probes for efficiency calculation void matchProbes(ProbeContainer*, const xAOD::IParticleContainer*) const; - + private: float m_dR_L1; float m_dR_HLT; - std::string m_trigger_item; }; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPPlotTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPPlotTool.h deleted file mode 100644 index 38429823fdc..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPPlotTool.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * MuonTrigTPPlots.h - * - * Created on: Aug 31, 2014 - * Author: goblirsc /a.m. - */ - -#ifndef MUONTRIGTPPLOTTOOL_H_ -#define MUONTRIGTPPLOTTOOL_H_ -#include "MuonTPTools/IMuonTPPlotTool.h" -#include "MuonTPTools/IMuonTPSelectionTool.h" -#include "MuonTPTools/IMuonTPEfficiencyTool.h" -#include "MuonTPTools/MuonTPPlotTool.h" -#include "AsgTools/AsgTool.h" -#include <map> - -class MuonTrigTPPlotTool: public MuonTPPlotTool -{ - ASG_TOOL_CLASS(MuonTrigTPPlotTool, IMuonTPPlotTool) - -public: - MuonTrigTPPlotTool(std::string name); - - virtual std::vector<MuonTPEfficiencyPlotBase*> AddPlots(std::string sDir, bool isMatched); - virtual std::vector<MuonTPCutFlowBase*> AddCutFlowPlots(std::string sDir); - -protected: - - bool m_do_TPBasic; - bool m_do_Valid; - bool m_apply_SF; -}; - -#endif /* MUONTRIGTPPLOTTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPTreeTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPTreeTool.h deleted file mode 100644 index 0fa4a76e273..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/MuonTrigTPTreeTool.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef MUONTRIGTPTreeTOOL_H_ -#define MUONTRIGTPTreeTOOL_H_ - -#include "MuonTPTools/IMuonTPTreeTool.h" -#include "MuonTPTools/IMuonTPSelectionTool.h" -#include "MuonTPTools/IMuonTPEfficiencyTool.h" -#include "MuonTPTools/MuonTPTreeTool.h" -#include "MuonEfficiencyCorrections/fineEtaPhiBinning.h" -#include "AsgTools/AsgTool.h" -#include <map> - -class MuonTrigTPTreeTool: - public MuonTPTreeTool { // for now, a 1:1 copy - ASG_TOOL_CLASS(MuonTrigTPTreeTool, IMuonTPTreeTool) - -public: - MuonTrigTPTreeTool(std::string name); - - virtual void FillCustomStuff(Probe& probe); // can override to fill custom branches - virtual void AddCustomBranches(TTree* tree); // can override to add custom branches - -protected: - float m_runNumber; - float m_eventNumber; - float m_mu; - float m_mcEventWeight; - float m_pt; - float m_eta; - float m_phi; - float m_ptcone40; - float m_etcone40; - int m_fineEtaPhi; - int m_q; - float m_tagPt; - float m_tagEta; - float m_tagPhi; - float m_mll; - float m_d0; - float m_d0err; - float m_z0; - - fineEtaPhiBinning m_fepb; - -}; - -#endif /* MUONTRIGTPTreeTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPIsolationTreeTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPIsolationTreeTool.h deleted file mode 100644 index 3ba8752c25b..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPIsolationTreeTool.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - - -#ifndef ZMUMUMUONTPISOLATIONTreeTOOL_H_ -#define ZMUMUMUONTPISOLATIONTreeTOOL_H_ -#include "MuonTPTools/IMuonTPTreeTool.h" -#include "MuonTPTools/IMuonTPSelectionTool.h" -#include "MuonTPTools/IMuonTPEfficiencyTool.h" -#include "MuonTPTools/MuonTPTreeTool.h" -#include "MuonEfficiencyCorrections/fineEtaPhiBinning.h" -#include "AsgTools/AsgTool.h" -#include <map> - -class ZmumuMuonTPIsolationTreeTool: - public MuonTPTreeTool { // for now, a 1:1 copy - ASG_TOOL_CLASS(ZmumuMuonTPIsolationTreeTool, IMuonTPTreeTool) - -public: - ZmumuMuonTPIsolationTreeTool(std::string name); - - virtual void FillCustomStuff(Probe& probe); // can override to fill custom branches - virtual void AddCustomBranches(TTree* tree); // can override to add custom branches - -protected: - float m_runNumber; - float m_eventNumber; - float m_mu; - float m_mcEventWeight; - float m_probePt; - float m_probeEta; - float m_probePhi; - int m_fineEtaPhi; - int m_probe_q; - int m_tag_q; - - float m_tagPt; - float m_tagEta; - float m_tagPhi; - - float m_mll; - float m_d0; - float m_d0err; - float m_z0; - -// isolation value - float m_tagiso_neflowisol20; - float m_tagiso_topoetcone20; - float m_tagiso_ptcone20; - float m_tagiso_etcone20; - float m_tagiso_ptvarcone20; - - float m_tagiso_neflowisol30; - float m_tagiso_topoetcone30; - float m_tagiso_ptcone30; - float m_tagiso_etcone30; - float m_tagiso_ptvarcone30; - - float m_tagiso_neflowisol40; - float m_tagiso_topoetcone40; - float m_tagiso_ptcone40; - float m_tagiso_etcone40; - float m_tagiso_ptvarcone40; - - float m_probeiso_neflowisol20; - float m_probeiso_topoetcone20; - float m_probeiso_ptcone20; - float m_probeiso_etcone20; - float m_probeiso_ptvarcone20; - - float m_probeiso_neflowisol30; - float m_probeiso_topoetcone30; - float m_probeiso_ptcone30; - float m_probeiso_etcone30; - float m_probeiso_ptvarcone30; - - float m_probeiso_neflowisol40; - float m_probeiso_topoetcone40; - float m_probeiso_ptcone40; - float m_probeiso_etcone40; - float m_probeiso_ptvarcone40; - - int m_Npvtx; - float m_dPhi; - - fineEtaPhiBinning m_fepb; - -}; - -#endif /* ZMUMUMUONTPISOLATIONTreeTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPTreeTool.h b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPTreeTool.h deleted file mode 100644 index 3a605a4c1b0..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/MuonTPTools/ZmumuMuonTPTreeTool.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - - -#ifndef ZMUMUMUONTPTreeTOOL_H_ -#define ZMUMUMUONTPTreeTOOL_H_ -#include "MuonTPTools/IMuonTPTreeTool.h" -#include "MuonTPTools/IMuonTPSelectionTool.h" -#include "MuonTPTools/IMuonTPEfficiencyTool.h" -#include "MuonTPTools/MuonTPTreeTool.h" -#include "MuonEfficiencyCorrections/fineEtaPhiBinning.h" -#include "MuonPerformanceHistUtils/EtaPhiBinning.h" -#include "AsgTools/AsgTool.h" -#include <map> - -class ZmumuMuonTPTreeTool: - public MuonTPTreeTool { // for now, a 1:1 copy - ASG_TOOL_CLASS(ZmumuMuonTPTreeTool, IMuonTPTreeTool) - -public: - ZmumuMuonTPTreeTool(std::string name); - - virtual void FillCustomStuff(Probe& probe); // can override to fill custom branches - virtual void AddCustomBranches(TTree* tree); // can override to add custom branches - -protected: - float m_runNumber; - float m_eventNumber; - float m_mu; - float m_mcEventWeight; - float m_pt; - float m_eta; - float m_phi; - float m_ptcone40; - float m_etcone40; - int m_fineEtaPhi; - int m_detregion; - int m_q; - float m_tagPt; - float m_tagEta; - float m_tagPhi; - float m_mll; - int m_PV_n; - float m_d0; - float m_d0err; - float m_z0; - - uint8_t m_nBL; - uint8_t m_nPIX; - uint8_t m_nSCT; - uint8_t m_nPIXdead; - uint8_t m_nSCTdead; - uint8_t m_nPIXholes; - uint8_t m_nSCTholes; - uint8_t m_nTRT; - uint8_t m_nTRTout; - - fineEtaPhiBinning m_fepb; - EtaPhiBinning m_epb; - -}; - -#endif /* ZMUMUMUONTPTreeTOOL_H_ */ diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPPlotTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPPlotTool.cxx new file mode 100644 index 00000000000..068a4d0e46b --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPPlotTool.cxx @@ -0,0 +1,56 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * MuonTPPlots.cxx + * + * Created on: Aug 31, 2014 + * Author: goblirsc + */ + +#include "MuonTPTools/DiMuonTPPlotTool.h" +#include "MuonPerformanceHistUtils/ZmumuBasicTPEfficiencyPlots.h" +#include "MuonPerformanceHistUtils/ZmumuTagProbeDileptonPlots.h" +#include "MuonPerformanceHistUtils/ZmumuFineEtaPhiEfficiencyPlots.h" +#include "MuonPerformanceHistUtils/DiLeptonTPEventCutFlowPlots.h" +#include "MuonPerformanceHistUtils/ZmumuDetRegionEfficiencyPlots.h" +#include "MuonPerformanceHistUtils/JPsiTagProbeDileptonPlots.h" +#include "MuonPerformanceHistUtils/JPsiBasicTPEfficiencyPlots.h" +#include "MuonPerformanceHistUtils/MuonTrigTPEfficiencyPlots.h" + +DiMuonTPPlotTool::DiMuonTPPlotTool(std::string name) + : MuonTPPlotTool(name){ + declareProperty("doTrkValidPlots",m_do_Valid=false); + declareProperty("doZmumuKinematicPlots",m_do_TPBasic_Zmm=false); + declareProperty("doJPsiKinematicPlots",m_do_TPBasic_JPsi=false); + declareProperty("doZmumuDileptonPlots",m_do_DiLepton_Zmm=false); + declareProperty("doJPsiDileptonPlots",m_do_DiLepton_JPsi=false); + declareProperty("doFineEtaPhiPlots",m_do_TPFineEtaPhi=false); + declareProperty("doDetectorRegionPlots",m_do_DetRegions=false); + declareProperty("doTrigValidPlots",m_do_TriggerPlots=false); + declareProperty("ApplyScaleFactors",m_apply_SF=false); +} + +std::vector<MuonTPEfficiencyPlotBase*> DiMuonTPPlotTool::AddPlots(std::string sDir, bool isMatched){ + + std::vector<MuonTPEfficiencyPlotBase*> out (0); + if (m_do_Valid) out.push_back( new MuonTPEfficiencyPlots(0, sDir, isMatched)); + if (m_do_TPBasic_Zmm) out.push_back( new ZmumuBasicTPEfficiencyPlots(0, sDir+"/basic_", isMatched,m_apply_SF)); + if (m_do_TPBasic_JPsi) out.push_back( new JPsiBasicTPEfficiencyPlots(0, sDir+"/basic_", isMatched,m_apply_SF)); + if (m_do_TPFineEtaPhi) out.push_back( new ZmumuFineEtaPhiEfficiencyPlots(0, sDir+"/", isMatched,m_apply_SF)); + if (m_do_DiLepton_Zmm) out.push_back( new ZmumuTagProbeDileptonPlots(0, sDir+"/", isMatched,m_apply_SF)); + if (m_do_DiLepton_JPsi) out.push_back( new JPsiTagProbeDileptonPlots(0, sDir+"/", isMatched,m_apply_SF)); + if (m_do_DetRegions) out.push_back(new ZmumuDetRegionEfficiencyPlots(0,sDir+"/",isMatched,m_apply_SF)); + if (m_do_TriggerPlots) out.push_back(new MuonTrigTPEfficiencyPlots(0,sDir+"/",isMatched,m_apply_SF)); + return out; + +} + +std::vector<MuonTPCutFlowBase*> DiMuonTPPlotTool::AddCutFlowPlots(std::string sDir){ + + std::vector<MuonTPCutFlowBase*> out (0); + out.push_back (new DiLeptonTPEventCutFlowPlots(0,sDir)); + return out; + +} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPSelectionTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPSelectionTool.cxx similarity index 59% rename from PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPSelectionTool.cxx rename to PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPSelectionTool.cxx index f8853d68ce9..9382df0f2e2 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPSelectionTool.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPSelectionTool.cxx @@ -3,60 +3,69 @@ */ /* - * ZmumuMuonTPSelectionTool.cxx + * DiMuonTPSelectionTool.cxx * - * Created on: Aug 23, 2014 + * Created on: Jun 18, 2015 * Author: goblirsc */ -#include "MuonTPTools/ZmumuMuonTPSelectionTool.h" -// #include "../MuonTPTools/ZmumuMuonTPSelectionTool.h" +#include "MuonTPTools/DiMuonTPSelectionTool.h" -ZmumuMuonTPSelectionTool::ZmumuMuonTPSelectionTool(std::string myname) -: AsgTool(myname), MuonTPSelectionTool(myname) { +DiMuonTPSelectionTool::DiMuonTPSelectionTool(std::string myname) +: MuonTPSelectionTool(myname) { - declareProperty("UseIDProbes", m_IDProbe = false); - declareProperty("UseMSProbes", m_MSProbe = false); - declareProperty("UseCBProbes", m_CBProbe = false); - declareProperty("UseCaloProbes", m_CaloProbe = false); - declareProperty("UseTruthProbes", m_TruthProbe = false); + declareProperty("UseIDProbes", m_IDProbe = false); + declareProperty("UseMSProbes", m_MSProbe = false); + declareProperty("UseCBProbes", m_CBProbe = false); + declareProperty("UseCaloProbes", m_CaloProbe = false); + declareProperty("UseTruthProbes", m_TruthProbe = false); + declareProperty("UseTruthMatchedProbes", m_TruthMatchedProbe = false); - declareProperty("TagTrackIsoCut", m_tagPtConeIso = 0.2); - declareProperty("ProbeTrackIsoCut", m_probePtConeIso = -1); - declareProperty("TagCaloIsoCut", m_tagEtConeIso = 0.2); - declareProperty("ProbeCaloIsoCut", m_probeEtConeIso = -1); + declareProperty("TagTrackIsoCut", m_tagPtConeIso = 0.2); + declareProperty("ProbeTrackIsoCut", m_probePtConeIso = -1.00); + declareProperty("TagCaloIsoCut", m_tagEtConeIso = 0.2); + declareProperty("ProbeCaloIsoCut", m_probeEtConeIso = -1.00); // for background studies - declareProperty("TagTrackAntiIsoCut", m_tag_antiPtConeIso = -1); - declareProperty("ProbeTrackAntiIsoCut", m_probe_antiPtConeIso = -1); - declareProperty("TagCaloAntiIsoCut", m_tag_antiEtConeIso = -1); - declareProperty("ProbeCaloAntiIsoCut", m_probe_antiEtConeIso = -1); + declareProperty("TagTrackAntiIsoCut", m_tag_antiPtConeIso = -1.00); + declareProperty("ProbeTrackAntiIsoCut", m_probe_antiPtConeIso = -1.00); + declareProperty("TagCaloAntiIsoCut", m_tag_antiEtConeIso = -1.00); + declareProperty("ProbeCaloAntiIsoCut", m_probe_antiEtConeIso = -1.00); declareProperty("AcceptSameCharge", m_accept_sameCharge = false); - declareProperty("AcceptOppCharge", m_accept_oppCharge = true); - - declareProperty("DeltaPhiCut", m_deltaPhiCut = -1.00); - - declareProperty("EfficiencyFlag", m_efficiencyFlag = "IDProbes"); - - declareProperty("DoOnlyAside", m_only_A_side = false); - declareProperty("DoOnlyCside", m_only_C_side = false); - declareProperty("ProbeAbsEtaMin", m_probe_abseta_min = -1.00); - declareProperty("ProbeAbsEtaMax", m_probe_abseta_max = 100.00); - - declareProperty("TagD0Cut", m_tag_d0 = -1); - declareProperty("TagD0SignCut", m_tag_d0Sign = -1); - declareProperty("TagZ0Cut", m_tag_z0 = -1); - declareProperty("ProbeD0Cut", m_probe_d0 = -1); - declareProperty("ProbeD0SignCut", m_probe_d0Sign = -1); - declareProperty("ProbeZ0Cut", m_probe_z0 = -1); - - - declareProperty("ProbeIDHitCut", m_probe_ID_hits = false); + declareProperty("AcceptOppCharge", m_accept_oppCharge = true); + + declareProperty("DeltaPhiCut", m_deltaPhiCut = -1.00); + declareProperty("DeltaEtaCut", m_deltaEtaCut = -1.00); + + declareProperty("EfficiencyFlag", m_efficiencyFlag = "IDProbes"); + + declareProperty("DoOnlyAside", m_only_A_side = false); + declareProperty("DoOnlyCside", m_only_C_side = false); + declareProperty("ProbeAbsEtaMin", m_probe_abseta_min = -1.00); + declareProperty("ProbeAbsEtaMax", m_probe_abseta_max = 100.00); + + declareProperty("TagD0Cut", m_tag_d0 = -1.00); + declareProperty("TagD0SignCut", m_tag_d0Sign = -1.00); + declareProperty("TagZ0Cut", m_tag_z0 = -1.00); + declareProperty("ProbeD0Cut", m_probe_d0 = -1.00); + declareProperty("ProbeD0SignCut", m_probe_d0Sign = -1.00); + declareProperty("ProbeZ0Cut", m_probe_z0 = -1.00); + + declareProperty("ProbeIDHitCut", m_probe_ID_hits = false); + + declareProperty("doProbeChargeSys", m_doProbeChargeSys = false); // Next time you turn this on by default for *EVERYONE*, + declareProperty("ProbeCharge", m_ProbeCharge = "positive"); // at least write an email :) + + declareProperty("UseVeryLooseProbes",m_VeryLooseProbe = false); + declareProperty("UseLooseProbes", m_LooseProbe = false); + declareProperty("UseMediumProbes", m_MediumProbe = false); + declareProperty("UseTightProbes", m_TightProbe = false); + declareProperty("UseHighPtProbes", m_HighPtProbe = false); } -StatusCode ZmumuMuonTPSelectionTool::initialize() +StatusCode DiMuonTPSelectionTool::initialize() { // ATH_CHECK(m_muonSelectionTool.retrieve()); ATH_CHECK(m_selection_tool.retrieve()); @@ -66,11 +75,21 @@ StatusCode ZmumuMuonTPSelectionTool::initialize() //********************************************************************** -ProbeContainer* ZmumuMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer* tags, const xAOD::IParticleContainer* probes) const +ProbeContainer* DiMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer* tags, const xAOD::IParticleContainer* probes) const { - // use m_muonSelectionTool to select muons - ProbeContainer* probeCont = new ProbeContainer(); - FillCutFlows("Processed"); + // use m_muonSelectionTool to select muons + ProbeContainer* probeCont = new ProbeContainer(); + FillCutFlows("Processed"); + + // check GRL + const xAOD::EventInfo* info = 0; + ATH_MSG_DEBUG(""<<evtStore()); + if (evtStore()->retrieve(info, "EventInfo").isFailure()){ + ATH_MSG_FATAL( "Unable to retrieve Event Info" ); + } + if (!passGRL(info)) return probeCont; + FillCutFlows("GRL"); + if(!Event_Trigger()) return probeCont; FillCutFlows("Trigger"); bool have_tag = false; @@ -82,14 +101,14 @@ ProbeContainer* ZmumuMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer FillCutFlows("TagCandidates"); FillCutFlows("TagQuality"); + if (!isFinalStateTruthMuon(probe)) { + continue; + } FillCutFlows("TagPt"); FillCutFlows("TagEta"); FillCutFlows("TagTrigger"); FillCutFlows("TagIP"); FillCutFlows("TagIsolation"); - if (!isFinalStateTruthMuon(probe)) { - continue; - } // Here, we only need to apply the kinematic selection @@ -103,11 +122,47 @@ ProbeContainer* ZmumuMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer FillCutFlows("ProbeInvMass"); FillCutFlows("ProbeCharge"); FillCutFlows("ProbeDeltaPhi"); + FillCutFlows("ProbeDeltaEta"); // in this case, fill the 'tag' slot of the probe with the probe - there is no tag for the truth efficiencies. probeCont->push_back( new Probe(*probe, *probe) ); have_probe = true; } } + + // truth matched muon probes are selected separately (used for truth-closure by isolation and trigger TP) + else if (m_TruthMatchedProbe){ + have_tag = true; + for(auto probe : *probes) { + + FillCutFlows("TagCandidates"); + FillCutFlows("TagQuality"); + if (!isTruthMatched(probe)) { + continue; + } + FillCutFlows("TagPt"); + FillCutFlows("TagEta"); + FillCutFlows("TagTrigger"); + FillCutFlows("TagIP"); + FillCutFlows("TagIsolation"); + + // Here, we only need to apply the kinematic selection + if (!PassProbeKinematics(probe)) continue; + + FillCutFlows("ProbeKinematics"); + FillCutFlows("ProbeQuality"); + FillCutFlows("ProbeQuality"); + FillCutFlows("ProbeIP"); + FillCutFlows("ProbeIsolation"); + FillCutFlows("ProbeInvMass"); + FillCutFlows("ProbeCharge"); + FillCutFlows("ProbeDeltaPhi"); + FillCutFlows("ProbeDeltaEta"); + // in this case, fill the 'tag' slot of the probe with the probe - there is no tag for the truth efficiencies. + probeCont->push_back( new Probe(*probe, *probe) ); + have_probe = true; + } + } + // "Real" Tag&Probe pairs else { // loop over tag container @@ -118,7 +173,6 @@ ProbeContainer* ZmumuMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer // select good muons (combined for the time being) // A muon selection tool should be used, but the tool // should be ASG dual-tool -// if(tag->muonType() != xAOD::Muon::MuonType::Combined) continue; if (m_selection_tool->getQuality(*tag) > xAOD::Muon::Medium) continue; if (!m_selection_tool->passedIDCuts(*tag)) continue; @@ -177,6 +231,30 @@ ProbeContainer* ZmumuMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer double mtp = (tag->p4()+probe->p4()).M(); if(mtp<m_lowMassWindow || mtp>m_highMassWindow) continue; FillCutFlows("ProbeInvMass"); + + if(m_doProbeChargeSys) + { + if(m_ProbeCharge=="positive") + { + // case of a muon probe + const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(probe); + if (muprobe && (muprobe->trackParticle(xAOD::Muon::Primary)->charge() < 0) ) continue; + + // case of an ID probe + const xAOD::TrackParticle* trkprobe = dynamic_cast<const xAOD::TrackParticle*>(probe); + if (trkprobe && (trkprobe->charge() < 0) ) continue; + } + if(m_ProbeCharge=="negative") + { + // case of a muon probe + const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(probe); + if (muprobe && (muprobe->trackParticle(xAOD::Muon::Primary)->charge() > 0) ) continue; + + // case of an ID probe + const xAOD::TrackParticle* trkprobe = dynamic_cast<const xAOD::TrackParticle*>(probe); + if (trkprobe && (trkprobe->charge() > 0) ) continue; + } + } // Charge cut //if(m_oppositeCharge && @@ -203,6 +281,11 @@ ProbeContainer* ZmumuMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer // Delta Phi cut if (DeltaPhiTP(tag,probe) < m_deltaPhiCut) continue; FillCutFlows("ProbeDeltaPhi"); + + // Delta Eta cut + if (fabs(tag->eta()-probe->eta()) < m_deltaEtaCut) continue; + FillCutFlows("ProbeDeltaEta"); + // for each selected probe build a Probe object probeCont->push_back( new Probe(*tag, *probe) ); have_probe = true; @@ -219,7 +302,7 @@ ProbeContainer* ZmumuMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer -bool ZmumuMuonTPSelectionTool::PassTagIsoCuts (const xAOD::Muon* tag) const{ +bool DiMuonTPSelectionTool::PassTagIsoCuts (const xAOD::Muon* tag) const{ float tagiso = 0.0; bool haveIso = tag->isolation(tagiso,xAOD::Iso::ptcone40); if (m_tagPtConeIso > 0 && (!haveIso || tagiso > m_tagPtConeIso * tag->p4().Pt())) return false; @@ -229,7 +312,7 @@ bool ZmumuMuonTPSelectionTool::PassTagIsoCuts (const xAOD::Muon* tag) const{ if (m_tag_antiEtConeIso > 0 && (!haveEtIso || tagiso < m_tag_antiEtConeIso * tag->pt())) return false; return true; } -bool ZmumuMuonTPSelectionTool::PassProbeIsoCuts (const xAOD::IParticle* probe) const{ +bool DiMuonTPSelectionTool::PassProbeIsoCuts (const xAOD::IParticle* probe) const{ // probe iso cut float probeiso = 0.0; float probeEtiso = 0.0; @@ -257,12 +340,12 @@ bool ZmumuMuonTPSelectionTool::PassProbeIsoCuts (const xAOD::IParticle* probe) c return true; } -bool ZmumuMuonTPSelectionTool::isTag(const xAOD::Muon* tag, const xAOD::IParticle* probe) const +bool DiMuonTPSelectionTool::isTag(const xAOD::Muon* tag, const xAOD::IParticle* probe) const { return (tag->p4().DeltaR(probe->p4()) < 0.01); } -bool ZmumuMuonTPSelectionTool::PassProbeIPCuts(const xAOD::IParticle* probe) const{ +bool DiMuonTPSelectionTool::PassProbeIPCuts(const xAOD::IParticle* probe) const{ const xAOD::TrackParticle* tp = 0; const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(probe); @@ -277,7 +360,7 @@ bool ZmumuMuonTPSelectionTool::PassProbeIPCuts(const xAOD::IParticle* probe) con } return PassIPCuts(tp,m_probe_d0, m_probe_d0Sign, m_probe_z0); } -bool ZmumuMuonTPSelectionTool::PassTagIPCuts(const xAOD::Muon* tag) const{ +bool DiMuonTPSelectionTool::PassTagIPCuts(const xAOD::Muon* tag) const{ const xAOD::TrackParticle* tp = tag->primaryTrackParticle(); if (!tp){ @@ -286,7 +369,7 @@ bool ZmumuMuonTPSelectionTool::PassTagIPCuts(const xAOD::Muon* tag) const{ return PassIPCuts(tp,m_tag_d0, m_tag_d0Sign, m_tag_z0); } -bool ZmumuMuonTPSelectionTool::isRightType(const xAOD::IParticle* probe) const{ +bool DiMuonTPSelectionTool::isRightType(const xAOD::IParticle* probe) const{ const xAOD::Muon* muprobe = dynamic_cast <const xAOD::Muon*> (probe); @@ -296,6 +379,29 @@ bool ZmumuMuonTPSelectionTool::isRightType(const xAOD::IParticle* probe) const{ // otherwise, we have to manually pick the right probe + // for VeryLoose/Loose/Medium/Tight selection + if (m_VeryLooseProbe) + { + return (muprobe && m_selection_tool->getQuality(*muprobe) <= xAOD::Muon::VeryLoose); + } + if (m_LooseProbe) + { + return (muprobe && m_selection_tool->getQuality(*muprobe) <= xAOD::Muon::Loose); + } + if (m_MediumProbe) + { + return (muprobe && m_selection_tool->getQuality(*muprobe) <= xAOD::Muon::Medium); + } + if (m_TightProbe) + { + return (muprobe && m_selection_tool->getQuality(*muprobe) <= xAOD::Muon::Tight); + } + if (m_HighPtProbe) + { + return (muprobe && m_selection_tool->passedHighPtCuts(*muprobe)); + } + + // MS probe if we are running on the muon collection if (m_MSProbe){ // static int n_zerophi = 0; @@ -321,7 +427,7 @@ bool ZmumuMuonTPSelectionTool::isRightType(const xAOD::IParticle* probe) const{ } -bool ZmumuMuonTPSelectionTool::PassProbeKinematics (const xAOD::IParticle* probe) const{ +bool DiMuonTPSelectionTool::PassProbeKinematics (const xAOD::IParticle* probe) const{ if(probe->pt() < m_probePtCut) return false; if(fabs(probe->eta()) > m_probeEtaCut) return false; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPTreeTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPTreeTool.cxx new file mode 100644 index 00000000000..2586e0df553 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/DiMuonTPTreeTool.cxx @@ -0,0 +1,437 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * MuonTPTrees.cxx + * + * Created on: Aug 31, 2014 + * Author: goblirsc + */ + +#include "MuonTPTools/DiMuonTPTreeTool.h" +#include "xAODEventInfo/EventInfo.h" +#include "xAODEventShape/EventShape.h" +#include "xAODTracking/VertexContainer.h" +#include "xAODTracking/Vertex.h" +#include "xAODTruth/TruthParticle.h" +#include "xAODJet/JetContainer.h" + +DiMuonTPTreeTool::DiMuonTPTreeTool(std::string name) + : MuonTPTreeTool(name), + m_runNumber(0), + m_eventNumber(0), + m_lumiblock(0), + m_average_mu(-1.), + m_actual_mu(-1), + m_PV_n(-1), + m_mcEventWeight(-1), + m_pt(-1), + m_eta(-1), + m_phi(-1), + m_type(-1), + m_author(-1), + m_quality(-1), + m_fineEtaPhi(-1), + m_detregion(-1), + m_q(-1), + m_d0(-1), + m_d0err(-1), + m_z0(-1), + m_tagPt(-1), + m_tagEta(-1), + m_tagPhi(-1), + m_tag_q(-1), + m_tag_d0(-1), + m_tag_d0err(-1), + m_tag_z0(-1), + m_mll(-1), + m_dPhi(-1), + m_dilep_pt(-1), + m_dilep_tof(-1), + m_tag_deltaR(-1), + m_deltaR(-1), + m_tagiso_neflowisol20(-1), + m_tagiso_topoetcone20(-1), + m_tagiso_ptcone20(-1), + m_tagiso_etcone20(-1), + m_tagiso_ptvarcone20(-1), + + m_tagiso_neflowisol30(-1), + m_tagiso_topoetcone30(-1), + m_tagiso_ptcone30(-1), + m_tagiso_etcone30(-1), + m_tagiso_ptvarcone30(-1), + + m_tagiso_neflowisol40(-1), + m_tagiso_topoetcone40(-1), + m_tagiso_ptcone40(-1), + m_tagiso_etcone40(-1), + m_tagiso_ptvarcone40(-1), + + m_tag_topocore(-1), + + m_probeiso_neflowisol20(-1), + m_probeiso_topoetcone20(-1), + m_probeiso_ptcone20(-1), + m_probeiso_etcone20(-1), + m_probeiso_ptvarcone20(-1), + + m_probeiso_neflowisol30(-1), + m_probeiso_topoetcone30(-1), + m_probeiso_ptcone30(-1), + m_probeiso_etcone30(-1), + m_probeiso_ptvarcone30(-1), + + m_probeiso_neflowisol40(-1), + m_probeiso_topoetcone40(-1), + m_probeiso_ptcone40(-1), + m_probeiso_etcone40(-1), + m_probeiso_ptvarcone40(-1), + + m_probe_topocore(-1), + + m_energyDensity_central(-1), + m_energyDensity_forward(-1) +{ + declareProperty("MuonSelectionTool",m_muon_selection_tool); + declareProperty("AddExtendedIsolation",m_extended_Iso_Info = false); +} + +StatusCode DiMuonTPTreeTool::initialize() +{ + ATH_CHECK(m_muon_selection_tool.retrieve()); + return StatusCode::SUCCESS; + +} +void DiMuonTPTreeTool::FillCustomStuff(Probe& probe){ + + m_energyDensity_central = 0.; + m_energyDensity_forward = 0.; + m_tag_topocore = 0.; + m_probe_topocore = 0.; + + // Primary vertex variables + const xAOD::VertexContainer* primVertices = 0 ; + const xAOD::Vertex* pv = 0; + if(evtStore()->retrieve(primVertices,"PrimaryVertices").isFailure()){ + ATH_MSG_ERROR("Found no PV candidate for IP computation!"); + } + else { + pv = primVertices->at(0); + } + m_PV_n=0; + for (auto vx: *primVertices){ + if (vx->vertexType() == xAOD::VxType::PriVtx || vx->vertexType() == xAOD::VxType::PileUp) ++m_PV_n; + } + + // distance to clostes jet + m_deltaR = 99.; + m_tag_deltaR = 99.; + const xAOD::JetContainer* jets = 0; + if (evtStore()->retrieve(jets,"AntiKt4LCTopoJets").isFailure()){ + ATH_MSG_WARNING( "Unable to retrieve Jet Container" ); + }else{ + // calculate delta R to the closest jet + for(auto jet : *jets) { + float probe_deltaR = probe.probeTrack().p4().DeltaR(jet->p4()); + if (probe_deltaR < m_deltaR) m_deltaR = probe_deltaR; + float tag_deltaR = probe.tagTrack().p4().DeltaR(jet->p4()); + if (tag_deltaR < m_tag_deltaR) m_tag_deltaR = tag_deltaR; + } + if (jets->size()==0) { + m_deltaR=-1; + m_tag_deltaR=-1; + } + } + + // Event shape variables for isolation + const xAOD::EventShape* edShape = 0; + double rho = 0.; + if (evtStore()->retrieve(edShape,"TopoClusterIsoCentralEventShape").isFailure()){ // Returns a boolean, needs to be surrounded with error checks. + ATH_MSG_FATAL( "Unable to retrieve TopoClusterIsoCentralEventShape" ); + } else { + edShape->getDensity(xAOD::EventShape::Density,rho); // Returns a boolean, needs to be surrounded with error checks. + m_energyDensity_central = rho; + } + if (evtStore()->retrieve(edShape,"TopoClusterIsoForwardEventShape").isFailure()){ // Returns a boolean, needs to be surrounded with error checks. + ATH_MSG_FATAL( "Unable to retrieve TopoClusterIsoForwardEventShape" ); + } else { + edShape->getDensity(xAOD::EventShape::Density,rho); // Returns a boolean, needs to be surrounded with error checks. + m_energyDensity_forward = rho; + } + + + int charge = -2; + m_type = 0; + m_author = -1; + m_quality = -1; + const xAOD::Vertex* vx_tag = 0; + const xAOD::Vertex* vx_probe = 0; + // tag muon properties + const xAOD::Muon* mutag = dynamic_cast<const xAOD::Muon*>(&probe.tagTrack()); + int charge2 = -2; + if (mutag) { + charge2 = mutag->trackParticle(xAOD::Muon::Primary)->charge(); + vx_tag = mutag->trackParticle(xAOD::Muon::Primary)->vertex(); + + if (mutag->primaryTrackParticle()){ + m_tag_d0 = mutag->primaryTrackParticle()->d0(); + m_tag_d0err = sqrt(mutag->primaryTrackParticle()->definingParametersCovMatrix()(0,0)); + m_tag_z0 = mutag->primaryTrackParticle()->z0(); + if (pv){ + m_tag_z0 = m_tag_z0 - pv->z() + mutag->primaryTrackParticle()->vz(); + } + } + if (m_extended_Iso_Info){ + bool ok2 = mutag->isolation(m_tagiso_etcone40,xAOD::Iso::topoetcone40); + if (!ok2) m_tagiso_etcone40 = -1; + ok2 = mutag->isolation(m_tagiso_ptcone40,xAOD::Iso::ptcone40); + if (!ok2) m_tagiso_ptcone40 = -1; + ok2 = mutag->isolation(m_tagiso_topoetcone40,xAOD::Iso::topoetcone40); + if (!ok2) m_tagiso_topoetcone40 = -1; + ok2 = mutag->isolation(m_tagiso_ptvarcone40,xAOD::Iso::ptvarcone40); + if (!ok2) m_tagiso_ptvarcone40 = -1; + ok2 = mutag->isolation(m_tagiso_neflowisol40,xAOD::Iso::neflowisol40); + if (!ok2) m_tagiso_neflowisol40 = -1; + + ok2 = mutag->isolation(m_tagiso_etcone30,xAOD::Iso::topoetcone30); + if (!ok2) m_tagiso_etcone30 = -1; + ok2 = mutag->isolation(m_tagiso_ptcone30,xAOD::Iso::ptcone30); + if (!ok2) m_tagiso_ptcone30 = -1; + ok2 = mutag->isolation(m_tagiso_topoetcone30,xAOD::Iso::topoetcone30); + if (!ok2) m_tagiso_topoetcone30 = -1; + ok2 = mutag->isolation(m_tagiso_ptvarcone30,xAOD::Iso::ptvarcone30); + if (!ok2) m_tagiso_ptvarcone30 = -1; + ok2 = mutag->isolation(m_tagiso_neflowisol30,xAOD::Iso::neflowisol30); + if (!ok2) m_tagiso_neflowisol30 = -1; + + ok2 = mutag->isolation(m_tagiso_etcone20,xAOD::Iso::topoetcone20); + if (!ok2) m_tagiso_etcone20 = -1; + ok2 = mutag->isolation(m_tagiso_ptcone20,xAOD::Iso::ptcone20); + if (!ok2) m_tagiso_ptcone20 = -1; + ok2 = mutag->isolation(m_tagiso_topoetcone20,xAOD::Iso::topoetcone20); + if (!ok2) m_tagiso_topoetcone20 = -1; + ok2 = mutag->isolation(m_tagiso_ptvarcone20,xAOD::Iso::ptvarcone20); + if (!ok2) m_tagiso_ptvarcone20 = -1; + ok2 = mutag->isolation(m_tagiso_neflowisol20,xAOD::Iso::neflowisol20); + if (!ok2) m_tagiso_neflowisol20 = -1; + } + } + + + // case of a muon probe + const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(&probe.probeTrack()); + if (muprobe) { + charge = muprobe->trackParticle(xAOD::Muon::Primary)->charge() ; + if (muprobe->primaryTrackParticle()){ + m_d0 = muprobe->primaryTrackParticle()->d0(); + m_d0err = sqrt(muprobe->primaryTrackParticle()->definingParametersCovMatrix()(0,0)); + m_z0 = muprobe->primaryTrackParticle()->z0(); + if (pv){ + m_z0 = m_z0 - pv->z() + muprobe->primaryTrackParticle()->vz(); + } + } + vx_probe = muprobe->trackParticle(xAOD::Muon::Primary)->vertex(); + muprobe->isolationCaloCorrection(m_probe_topocore, xAOD::Iso::topoetcone, xAOD::Iso::coreCone, xAOD::Iso::IsolationCorrectionParameter::coreEnergy); + xAOD::Muon::Quality probe_qual = m_muon_selection_tool->getQuality(*muprobe); + if ( probe_qual == xAOD::Muon::Tight ) m_quality = 0; + else if ( probe_qual == xAOD::Muon::Medium ) m_quality = 1; + else if ( probe_qual == xAOD::Muon::Loose ) m_quality = 2; + else if ( probe_qual == xAOD::Muon::VeryLoose ) m_quality = 3; + + if ( muprobe->author() == xAOD::Muon::unknown ) m_author = 0; + else if ( muprobe->author() == xAOD::Muon::MuidCo ) m_author = 1; + else if ( muprobe->author() == xAOD::Muon::STACO ) m_author = 2; + else if ( muprobe->author() == xAOD::Muon::MuTag ) m_author = 3; + else if ( muprobe->author() == xAOD::Muon::MuTagIMO ) m_author = 4; + else if ( muprobe->author() == xAOD::Muon::MuidSA ) m_author = 5; + else if ( muprobe->author() == xAOD::Muon::MuGirl ) m_author = 6; + else if ( muprobe->author() == xAOD::Muon::MuGirlLowBeta ) m_author = 7; + else if ( muprobe->author() == xAOD::Muon::CaloTag ) m_author = 8; + else if ( muprobe->author() == xAOD::Muon::CaloLikelihood ) m_author = 9; + else if ( muprobe->author() == xAOD::Muon::ExtrapolateMuonToIP ) m_author = 10; + + if ( muprobe->muonType() == xAOD::Muon::Combined ) m_type = 1; // "CB" + else if ( muprobe->muonType() == xAOD::Muon::MuonStandAlone ) m_type = 2; // "SA" + else if ( muprobe->muonType() == xAOD::Muon::SegmentTagged ) m_type = 3; // "ST" + else if ( muprobe->muonType() == xAOD::Muon::CaloTagged ) m_type = 4; // "CT" + + if (m_extended_Iso_Info){ + bool ok = muprobe->isolation(m_probeiso_etcone40,xAOD::Iso::topoetcone40); + if (!ok) m_probeiso_etcone40 = -1; + ok = muprobe->isolation(m_probeiso_ptcone40,xAOD::Iso::ptcone40); + if (!ok) m_probeiso_ptcone40 = -1; + ok = muprobe->isolation(m_probeiso_topoetcone40,xAOD::Iso::topoetcone40); + if (!ok) m_probeiso_topoetcone40 = -1; + ok = muprobe->isolation(m_probeiso_ptvarcone40,xAOD::Iso::ptvarcone40); + if (!ok) m_probeiso_ptvarcone40 = -1; + ok = muprobe->isolation(m_probeiso_neflowisol40,xAOD::Iso::neflowisol40); + if (!ok) m_probeiso_neflowisol40 = -1; + + ok = muprobe->isolation(m_probeiso_etcone30,xAOD::Iso::topoetcone30); + if (!ok) m_probeiso_etcone30 = -1; + ok = muprobe->isolation(m_probeiso_ptcone30,xAOD::Iso::ptcone30); + if (!ok) m_probeiso_ptcone30 = -1; + ok = muprobe->isolation(m_probeiso_topoetcone30,xAOD::Iso::topoetcone30); + if (!ok) m_probeiso_topoetcone30 = -1; + ok = muprobe->isolation(m_probeiso_ptvarcone30,xAOD::Iso::ptvarcone30); + if (!ok) m_probeiso_ptvarcone30 = -1; + ok = muprobe->isolation(m_probeiso_neflowisol30,xAOD::Iso::neflowisol30); + if (!ok) m_probeiso_neflowisol30 = -1; + + ok = muprobe->isolation(m_probeiso_etcone20,xAOD::Iso::topoetcone20); + if (!ok) m_probeiso_etcone20 = -1; + ok = muprobe->isolation(m_probeiso_ptcone20,xAOD::Iso::ptcone20); + if (!ok) m_probeiso_ptcone20 = -1; + ok = muprobe->isolation(m_probeiso_topoetcone20,xAOD::Iso::topoetcone20); + if (!ok) m_probeiso_topoetcone20 = -1; + ok = muprobe->isolation(m_probeiso_ptvarcone20,xAOD::Iso::ptvarcone20); + if (!ok) m_probeiso_ptvarcone40 = -1; + ok = muprobe->isolation(m_probeiso_neflowisol20,xAOD::Iso::neflowisol20); + if (!ok) m_probeiso_neflowisol20 = -1; + } + } + + // case of an ID probe + const xAOD::TrackParticle* trkprobe = dynamic_cast<const xAOD::TrackParticle*>(&probe.probeTrack()); + if (!muprobe && trkprobe){ + charge = trkprobe->charge(); + vx_probe = trkprobe->vertex(); + m_d0 = trkprobe->d0(); + m_d0err = sqrt(trkprobe->definingParametersCovMatrix()(0,0)); + m_z0 = trkprobe->z0(); + // const xAOD::Vertex* vx = trkprobe->vertex(); + if (pv){ + m_z0 = m_z0 - pv->z() + trkprobe->vz(); + } + } + // case of an truth probe: rely on the sign of the pdg ID + const xAOD::TruthParticle* truthtrk = dynamic_cast<const xAOD::TruthParticle*>(&probe.probeTrack()); + if (truthtrk) { + if (truthtrk->charge() > 0) charge = 1.0; + if (truthtrk->charge() < 0) charge = -1.0; + + } + + const xAOD::EventInfo* info = 0; + ATH_MSG_DEBUG(""<<evtStore()); + if (evtStore()->retrieve(info, "EventInfo").isFailure()){ + ATH_MSG_FATAL( "Unable to retrieve Event Info" ); + } + static bool isMC = info->eventType(xAOD::EventInfo::IS_SIMULATION); + + m_runNumber = info->runNumber(); + m_eventNumber = info->eventNumber(); + m_lumiblock = info->lumiBlock(); + m_average_mu = info->averageInteractionsPerCrossing(); + m_actual_mu = info->actualInteractionsPerCrossing(); + m_mcEventWeight = (isMC ? info->mcEventWeight() : 1.00); + m_pt = probe.pt() / 1000.; + m_eta = probe.eta(); + m_phi = probe.phi(); + m_fineEtaPhi = m_fepb.bin(probe.probeTrack().p4()); + m_detregion = m_epb.symmetricBin(probe.probeTrack().p4()); + m_q = charge; + m_tag_q = charge2; + m_tagPt = probe.tagTrack().pt() / 1000.; + m_tagEta = probe.tagTrack().eta(); + m_tagPhi = probe.tagTrack().phi(); + m_mll = (probe.tagTrack().p4()+probe.probeTrack().p4()).M(); + m_dilep_pt = (probe.tagTrack().p4()+probe.probeTrack().p4()).Pt(); + + // if we have a valid decay vertex and primary vertex, compute the time of flight + if (vx_tag && vx_tag == vx_probe && pv){ + TVector3 vvx_tag (vx_tag->x(),vx_tag->y(),vx_tag->z()); + TVector3 vpv (pv->x(),pv->y(),pv->z()); + m_dilep_tof = (vvx_tag - vpv).Perp() * 3096. / m_dilep_pt; + } + else{ + m_dilep_tof = -1; + } + m_dPhi = probe.tagTrack().p4().DeltaPhi(probe.probeTrack().p4()); + + +} +void DiMuonTPTreeTool::AddCustomBranches(TTree* tree){ + + tree->Branch("runNumber",&m_runNumber); + tree->Branch("eventNumber",&m_eventNumber); + tree->Branch("lumiblock",&m_lumiblock); + tree->Branch("average_mu",&m_average_mu); + tree->Branch("actual_mu",&m_actual_mu); + tree->Branch("PV_n",&m_PV_n); + tree->Branch("mcEventWeight",&m_mcEventWeight); + tree->Branch("probe_pt",&m_pt); + tree->Branch("probe_eta",&m_eta); + tree->Branch("probe_phi",&m_phi); + tree->Branch("probe_type",&m_type); + tree->Branch("probe_author",&m_author); + tree->Branch("probe_quality",&m_quality); + tree->Branch("probe_fineEtaPhi",&m_fineEtaPhi); + tree->Branch("probe_detRegion",&m_detregion); + tree->Branch("probe_q",&m_q); + tree->Branch("probe_d0",&m_d0); + tree->Branch("probe_d0err",&m_d0err); + tree->Branch("probe_z0",&m_z0); + tree->Branch("tag_pt",&m_tagPt); + tree->Branch("tag_eta",&m_tagEta); + tree->Branch("tag_phi",&m_tagPhi); + tree->Branch("tag_q",&m_tag_q); + tree->Branch("tag_d0",&m_tag_d0); + tree->Branch("tag_d0err",&m_tag_d0err); + tree->Branch("tag_z0",&m_tag_z0); + tree->Branch("dilep_mll",&m_mll); + tree->Branch("dilep_dphi",&m_dPhi); + tree->Branch("dilep_pt",&m_dilep_pt); + tree->Branch("dilep_tof",&m_dilep_tof); + + tree->Branch("tag_dRJet",&m_tag_deltaR); + tree->Branch("probe_dRJet",&m_deltaR); + + if (m_extended_Iso_Info){ + tree->Branch("tag_neflowisol20",&m_tagiso_neflowisol20); + tree->Branch("tag_topoetcone20",&m_tagiso_topoetcone20); + tree->Branch("tag_ptcone20",&m_tagiso_ptcone20); + tree->Branch("tag_etcone20",&m_tagiso_etcone20); + tree->Branch("tag_ptvarcone20",&m_tagiso_ptvarcone20); + + tree->Branch("tag_neflowisol30",&m_tagiso_neflowisol30); + tree->Branch("tag_topoetcone30",&m_tagiso_topoetcone30); + tree->Branch("tag_ptcone30",&m_tagiso_ptcone30); + tree->Branch("tag_etcone30",&m_tagiso_etcone30); + tree->Branch("tag_ptvarcone30",&m_tagiso_ptvarcone30); + + tree->Branch("tag_neflowisol40",&m_tagiso_neflowisol40); + tree->Branch("tag_topoetcone40",&m_tagiso_topoetcone40); + tree->Branch("tag_ptcone40",&m_tagiso_ptcone40); + tree->Branch("tag_etcone40",&m_tagiso_etcone40); + tree->Branch("tag_ptvarcone40",&m_tagiso_ptvarcone40); + + tree->Branch("tag_topocore",&m_tag_topocore); + + tree->Branch("probe_neflowisol20",&m_probeiso_neflowisol20); + tree->Branch("probe_topoetcone20",&m_probeiso_topoetcone20); + tree->Branch("probe_ptcone20",&m_probeiso_ptcone20); + tree->Branch("probe_etcone20",&m_probeiso_etcone20); + tree->Branch("probe_ptvarcone20",&m_probeiso_ptvarcone20); + + tree->Branch("probe_neflowisol30",&m_probeiso_neflowisol30); + tree->Branch("probe_topoetcone30",&m_probeiso_topoetcone30); + tree->Branch("probe_ptcone30",&m_probeiso_ptcone30); + tree->Branch("probe_etcone30",&m_probeiso_etcone30); + tree->Branch("probe_ptvarcone30",&m_probeiso_ptvarcone30); + + tree->Branch("probe_neflowisol40",&m_probeiso_neflowisol40); + tree->Branch("probe_topoetcone40",&m_probeiso_topoetcone40); + tree->Branch("probe_ptcone40",&m_probeiso_ptcone40); + tree->Branch("probe_etcone40",&m_probeiso_etcone40); + tree->Branch("probe_ptvarcone40",&m_probeiso_ptvarcone40); + + tree->Branch("probe_topocore",&m_probe_topocore); + + tree->Branch("energyDensity_central",&m_energyDensity_central); + tree->Branch("energyDensity_forward",&m_energyDensity_forward); + } + +} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPEfficiencyTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPEfficiencyTool.cxx deleted file mode 100644 index d3b06de8a2e..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPEfficiencyTool.cxx +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * JPsiMuonTPEfficiencyTool.cxx - * - * Created on: Sep 01, 2014 - * Author: Maximiliano Sioli - */ - -#include "MuonTPTools/JPsiMuonTPEfficiencyTool.h" - -JPsiMuonTPEfficiencyTool::JPsiMuonTPEfficiencyTool(std::string myname) -: AsgTool(myname), MuonTPEfficiencyTool(myname) { - declareProperty("MatchToAnyMS",m_match_MS=false); - declareProperty("MatchToCB",m_match_CB=false); - declareProperty("MatchToMedium",m_match_Medium=false); - declareProperty("MatchToID",m_match_ID=false); - declareProperty("MatchToCaloTag",m_match_CaloTag=false); - declareProperty("IDhitCut",m_do_IDHits=true); - -} -void JPsiMuonTPEfficiencyTool::dRMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const -{ - // loop over probes - for(auto probe : *probes) { - double dRMin = 1; - Probe* matchProbe = 0; - - // loop over matches - for(auto match : *matches) { - - // Pt Cut - if(match->pt() < m_matchPtCut) continue; - - // Eta Cut - if(fabs(match->eta()) > m_matchEtaCut) continue; - - // for ID tracks, we need to do this a different way... - xAOD::Muon* matchmuon = dynamic_cast <xAOD::Muon*>(match); - if (matchmuon && m_do_IDHits){ - Root::TAccept matchResult = m_selection_tool->accept(*matchmuon); // we only use the ID cuts for now - if (! matchResult.getCutResult("IDHits")) continue; - } - - if (!GoodMatchMuonType(match)) continue; - - // Calculate dR - double dR = deltaR(probe, match); - if(dR < dRMin) { - dRMin = dR; - matchProbe = probe; - } - } - - // check if a matched probe is found - if(matchProbe && dRMin<m_maximumDrCut) matchProbe->isMatched(true); - } -} -bool JPsiMuonTPEfficiencyTool::GoodMatchMuonType(const xAOD::IParticle* probe) const{ - - const xAOD::Muon* mumatch = dynamic_cast <const xAOD::Muon*> (probe); - - // if the particle is not a muon, assume that the user knows what TrackParticleContainer he is providing! - if (! mumatch) return true; - - // otherwise, we have to manually pick the right probe - - // ID Probe - if (m_match_ID){ - return (mumatch->trackParticle(xAOD::Muon::InnerDetectorTrackParticle) != NULL); - } - // CT Probe - - if (m_match_CaloTag){ - return (mumatch && mumatch->isAuthor(xAOD::Muon::CaloTag) ); - } - // MS Probe - if (m_match_MS){ - return ((mumatch->muonType() == xAOD::Muon::MuonStandAlone || mumatch->muonType() == xAOD::Muon::Combined) && mumatch->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle)!= NULL); - } - // CB probe - if (m_match_CB){ - return (mumatch->muonType() == xAOD::Muon::Combined && mumatch->trackParticle(xAOD::Muon::CombinedTrackParticle) != NULL); - } - if (m_match_Medium){ - bool ok = (mumatch->muonType() == xAOD::Muon::Combined && mumatch->trackParticle(xAOD::Muon::CombinedTrackParticle) != NULL ); - Root::TAccept matchResult = m_selection_tool->accept(*mumatch); // we only use the ID cuts for now - ok &= mumatch->quality()==xAOD::Muon::Medium; - return ok; - } - return false; -} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPPlotTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPPlotTool.cxx deleted file mode 100644 index 258478f108b..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPPlotTool.cxx +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * JPsiMuonTPPlotTool.cxx - * - * Created on: Sep 01, 2014 - * Author: Maximiliano Sioli - */ - -#include "MuonTPTools/JPsiMuonTPPlotTool.h" - -JPsiMuonTPPlotTool::JPsiMuonTPPlotTool(std::string name) - : AsgTool(name),MuonTPPlotTool(name){ -} - -std::vector<MuonTPEfficiencyPlotBase*> JPsiMuonTPPlotTool::AddPlots(std::string sDir, bool isMatched){ - - std::vector<MuonTPEfficiencyPlotBase*> out (0); - out.push_back( new MuonTPEfficiencyPlots(0, sDir, isMatched)); - return out; - -} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPSelectionTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPSelectionTool.cxx deleted file mode 100644 index 79cd31607c4..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/JPsiMuonTPSelectionTool.cxx +++ /dev/null @@ -1,156 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * JPsiMuonTPSelectionTool.cxx - * - * Created on: Sep 01, 2014 - * Author: Maximiliano Sioli - */ - -#include "MuonTPTools/JPsiMuonTPSelectionTool.h" - -JPsiMuonTPSelectionTool::JPsiMuonTPSelectionTool(std::string myname) -: AsgTool(myname), MuonTPSelectionTool(myname) { - - declareProperty("UseIDProbes", m_IDProbe = false); - declareProperty("UseMSProbes", m_MSProbe = false); - declareProperty("UseCBProbes", m_CBProbe = false); - declareProperty("UseCaloProbes", m_CaloProbe = false); - - declareProperty("TagIsoCut", m_tagIsolation = 0.2); - declareProperty("ProbeIsoCut", m_probeIsolation = -1); - - declareProperty("AcceptSameCharge", m_accept_sameCharge = false); - declareProperty("AcceptOppCharge", m_accept_oppCharge = true); - - declareProperty("DeltaPhiCut", m_deltaPhiCut = -1.00); - - declareProperty("EfficiencyFlag", m_efficiencyFlag = "IDProbes"); - - declareProperty("ProbeIDHitCut", m_probe_ID_hits = false); -} - -StatusCode JPsiMuonTPSelectionTool::initialize() -{ - // ATH_CHECK(m_muonSelectionTool.retrieve()); - ATH_CHECK(m_selection_tool.retrieve()); - return StatusCode::SUCCESS; -} - - -//********************************************************************** - -ProbeContainer* JPsiMuonTPSelectionTool::selectProbes(const xAOD::MuonContainer* tags, const xAOD::IParticleContainer* probes) const -{ - // use m_muonSelectionTool to select muons - ProbeContainer* probeCont = new ProbeContainer(); - - // loop over tag container - for(auto tag : *tags) { - - // select good muons (combined for the time being) - // A muon selection tool should be used, but the tool - // should be ASG dual-tool - if(tag->muonType() != xAOD::Muon::MuonType::Combined) continue; - // Could also cut on tag author, likely the same author of the probed efficiency - // if(m_muonTagAuthor!=21 && tag->author()!=m_muonTagAuthor) continue; - - Root::TAccept tagResult = m_selection_tool->accept(*tag); // we only use the ID cuts for now - - if (! tagResult.getCutResult("IDHits")) continue; - // Cut on tag eta, pT - if(tag->pt() < m_tagPtCut) continue; - if(fabs(tag->eta()) > m_tagEtaCut) continue; - - // tag iso cut - float tagiso = 0.; - bool haveIso = tag->isolation(tagiso,xAOD::Iso::ptcone40); - if (m_tagIsolation > 0 && (!haveIso || tagiso > m_tagIsolation * tag->p4().Pt())) continue; - - // for each selected tag, loop over probes - for(auto probe : *probes) { - - // check the probe type - if (!isRightType(probe)) continue; - - // remove the probe track matched to the tag - if(isTag(tag, probe)) continue; - - // select good probe tracks, - // again a selecton ASG duel-tool could be used - // tba - - // Cut on probe eta, pT - if(probe->pt() < m_probePtCut) continue; - if(fabs(probe->eta()) > m_probeEtaCut) continue; - - // ID hits - xAOD::Muon* probemu = dynamic_cast<xAOD::Muon*> (probe); - if (m_probe_ID_hits && probemu) { - Root::TAccept probeResult = m_selection_tool->accept(*probemu); - if (!probeResult.getCutResult("IDHits")) continue; - } - - // probe iso cut - // NYI if (m_probeIsolation > 0 && tag->isolation(xAOD::Iso::ptcone40) > m_probeIsolation * probe->p4().Pt()); - - // Cut on tag-probe invariant mass - double mtp = (tag->p4()+probe->p4()).M(); - if(mtp<m_lowMassWindow || mtp>m_highMassWindow) continue; - - // Charge cut - //if(m_oppositeCharge && - // tag->trackParticle(xAOD::Muon::Primary)->charge() - int cp = ChargeProd(tag,probe); - if (cp == 1 && !m_accept_sameCharge) continue; - if (cp == -1 && !m_accept_oppCharge) continue; // does this work? - - // Delta Phi cut - if (DeltaPhiTP(tag,probe) < m_deltaPhiCut) continue; - // for each selected probe build a Probe object - probeCont->push_back( new Probe(*tag, *probe) ); - } - } - - ATH_MSG_DEBUG("Number of selected probes : " << probeCont->size() ); - - return probeCont; -} -//********************************************************************** - -bool JPsiMuonTPSelectionTool::isTag(const xAOD::Muon* tag, const xAOD::IParticle* probe) const -{ - return (tag->p4().DeltaR(probe->p4()) < 0.01); -} - -bool JPsiMuonTPSelectionTool::isRightType(const xAOD::IParticle* probe) const{ - - const xAOD::Muon* muprobe = dynamic_cast <const xAOD::Muon*> (probe); - - // if the particle is not a muon, assume that the user knows what TrackParticleContainer he is providing! - if (! muprobe) return true; - - // otherwise, we have to manually pick the right probe - - // ID Probe - if (m_IDProbe){ - return (muprobe->trackParticle(xAOD::Muon::InnerDetectorTrackParticle) != NULL); - } - // CT Probe - - if (m_CaloProbe){ - return (muprobe && muprobe->isAuthor(xAOD::Muon::CaloTag) ); - } - // MS Probe - if (m_MSProbe){ - return ((muprobe->muonType() == xAOD::Muon::MuonStandAlone || muprobe->muonType() == xAOD::Muon::Combined) && muprobe->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle)!= NULL); - } - // CB probe - if (m_CBProbe){ - return (muprobe->muonType() == xAOD::Muon::Combined && muprobe->trackParticle(xAOD::Muon::CombinedTrackParticle) != NULL); - } - return false; - -} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonIsolTPEfficiencyTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonIsolTPEfficiencyTool.cxx new file mode 100644 index 00000000000..a0e9dc831ac --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonIsolTPEfficiencyTool.cxx @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * MuonIsolTPEfficiencyTool.cxx + * + * Created on: Aug 31, 2014 + * Author: goblirsc / a.m. + */ + +#include "MuonTPTools/MuonIsolTPEfficiencyTool.h" + +MuonIsolTPEfficiencyTool::MuonIsolTPEfficiencyTool(std::string myname) +: MuonTPEfficiencyTool(myname) +{ + +} + + + +//--------------------------------------------------------- +void MuonIsolTPEfficiencyTool::matchProbes(ProbeContainer* probes, const xAOD::IParticleContainer* ) const +{ + for(auto probe : *probes) + { + // check if the probe is isolated + // then if it is: + probe->isMatched(true); + } +} + diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonRecoTPEfficiencyTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonRecoTPEfficiencyTool.cxx index 63067d864db..0a001846d25 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonRecoTPEfficiencyTool.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonRecoTPEfficiencyTool.cxx @@ -12,37 +12,38 @@ #include "MuonTPTools/MuonRecoTPEfficiencyTool.h" MuonRecoTPEfficiencyTool::MuonRecoTPEfficiencyTool(std::string myname) -: AsgTool(myname), MuonTPEfficiencyTool(myname) { - declareProperty("MatchToAnyMS",m_match_MS=false); - declareProperty("MatchToCB",m_match_CB=false); - declareProperty("MatchToLoose",m_match_Loose=false); - declareProperty("MatchToMedium",m_match_Medium=false); - declareProperty("MatchToLoose_noCaloTag",m_match_Loose_noCT=false); - declareProperty("MatchToTight",m_match_Tight=false); - declareProperty("MatchToID",m_match_ID=false); - declareProperty("MatchToCaloTag",m_match_CaloTag=false); - declareProperty("IDhitCut",m_do_IDHits=true); - - declareProperty("MatchToMuidCB",m_match_MuidCB=false); - declareProperty("MatchToSTACO",m_match_STACO=false); - declareProperty("MatchToMuTag",m_match_MuTag=false); - declareProperty("MatchToMuTagIMO",m_match_MuTagIMO=false); - declareProperty("MatchToMuidSA",m_match_MuidSA=false); - declareProperty("MatchToMuGirl",m_match_MuGirl=false); - declareProperty("MatchToMuGirlLowBeta",m_match_MuGirlLowBeta=false); - declareProperty("MatchToCaloLikelihood",m_match_CaloLikelihood=false); - declareProperty("MatchToExtrapolateToIP",m_match_ExtrapolateToIP=false); + : MuonTPEfficiencyTool(myname) { + declareProperty("ptrMatching", m_ptrMatching = false); + declareProperty("MatchToAnyMS",m_match_MS=false); + declareProperty("MatchToCB",m_match_CB=false); + declareProperty("MatchToLoose",m_match_Loose=false); + declareProperty("MatchToMedium",m_match_Medium=false); + declareProperty("MatchToLoose_noCaloTag",m_match_Loose_noCT=false); + declareProperty("MatchToTight",m_match_Tight=false); + declareProperty("MatchToHighPt",m_match_HighPt=false); + declareProperty("MatchToID",m_match_ID=false); + declareProperty("MatchToCaloTag",m_match_CaloTag=false); + declareProperty("IDhitCut",m_do_IDHits=true); + + declareProperty("MatchToMuidCB",m_match_MuidCB=false); + declareProperty("MatchToSTACO",m_match_STACO=false); + declareProperty("MatchToMuTag",m_match_MuTag=false); + declareProperty("MatchToMuTagIMO",m_match_MuTagIMO=false); + declareProperty("MatchToMuidSA",m_match_MuidSA=false); + declareProperty("MatchToMuGirl",m_match_MuGirl=false); + declareProperty("MatchToMuGirlLowBeta",m_match_MuGirlLowBeta=false); + declareProperty("MatchToCaloLikelihood",m_match_CaloLikelihood=false); + declareProperty("MatchToExtrapolateToIP",m_match_ExtrapolateToIP=false); } void MuonRecoTPEfficiencyTool::dRMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const { // loop over probes - for(auto probe : *probes) { - double dRMin = 1; + double dRMin = 3; Probe* matchProbe = 0; const xAOD::Muon* best_match_muon = NULL; - + probe->dr_match(-1.); // loop over matches for(auto match : *matches) { // Pt Cut @@ -55,13 +56,13 @@ void MuonRecoTPEfficiencyTool::dRMatching(ProbeContainer* probes, const xAOD::IP xAOD::Muon* matchmuon = dynamic_cast <xAOD::Muon*>(match); if (matchmuon && m_do_IDHits){ - if (!m_selection_tool->passedIDCuts(*matchmuon)) continue; + if (!m_selection_tool->passedIDCuts(*matchmuon)) continue; } // ID tracks if (m_match_ID){ - xAOD::TrackParticle *trk = dynamic_cast<xAOD::TrackParticle*>(match); - if(!trk || (m_do_IDHits && !m_selection_tool->passedIDCuts(*trk))) continue; + xAOD::TrackParticle *trk = dynamic_cast<xAOD::TrackParticle*>(match); + if(!trk || (m_do_IDHits && !m_selection_tool->passedIDCuts(*trk))) continue; } // Calculate dR @@ -69,8 +70,8 @@ void MuonRecoTPEfficiencyTool::dRMatching(ProbeContainer* probes, const xAOD::IP // test pointer-level matching! if(dR < dRMin) { - dRMin = dR; - matchProbe = probe; + dRMin = dR; + matchProbe = probe; if (matchmuon) best_match_muon = matchmuon; } } @@ -78,82 +79,167 @@ void MuonRecoTPEfficiencyTool::dRMatching(ProbeContainer* probes, const xAOD::IP // check if a matched probe is found probe->sfweight(1.); probe->isMatched(matchProbe && dRMin<m_maximumDrCut); + probe->dr_match(dRMin); if (m_do_sf && best_match_muon && probe->isMatched()){ - float sf = 1.; - if (m_sf_tool->getEfficiencyScaleFactor(*best_match_muon,sf) == CP::CorrectionCode::Ok){ - probe->sfweight(sf); - } + float sf = 1.; + if (m_sf_tool->getEfficiencyScaleFactor(*best_match_muon,sf) == CP::CorrectionCode::Ok){ + probe->sfweight(sf); + } } } } -bool MuonRecoTPEfficiencyTool::GoodMatchMuonType(const xAOD::IParticle* probe) const{ - const xAOD::Muon* mumatch = dynamic_cast <const xAOD::Muon*> (probe); - // if the particle is not a muon, assume that the user knows what TrackParticleContainer he is providing! - if (! mumatch) return true; +void MuonRecoTPEfficiencyTool::ptrMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const +{ + // loop over probes + for(auto probe : *probes) { + Probe* matchProbe = 0; + const xAOD::Muon* best_match_muon = NULL; - // otherwise, we have to manually pick the right probe + const xAOD::Muon* probemuon = dynamic_cast <const xAOD::Muon*>(&(probe->probeTrack())); + const xAOD::TrackParticle* probetrack = dynamic_cast <const xAOD::TrackParticle*>(&(probe->probeTrack())); + + probe->dr_match(-1.); + // loop over matches + for(auto match : *matches) { - // ID Track - if (m_match_ID){ - return (mumatch->trackParticle(xAOD::Muon::InnerDetectorTrackParticle) != NULL); - } - // CT Match + // Pt Cut + if(match->pt() < m_matchPtCut) continue; + + // Eta Cut + if(fabs(match->eta()) > m_matchEtaCut) continue; + + if (!GoodMatchMuonType(match)) continue; + + xAOD::Muon* matchmuon = dynamic_cast <xAOD::Muon*>(match); + if (matchmuon && m_do_IDHits){ + if (!m_selection_tool->passedIDCuts(*matchmuon)) continue; + } + + // ID tracks + if (m_match_ID){ + xAOD::TrackParticle *trk = dynamic_cast<xAOD::TrackParticle*>(match); + if(!trk || (m_do_IDHits && !m_selection_tool->passedIDCuts(*trk))) continue; + } + + // Probe and Match are xAOD::Muon + if(probemuon && matchmuon && probemuon==matchmuon) { + matchProbe = probe; + best_match_muon = matchmuon; + probe->dr_match(0); + break; + } + + // probe is xAOD::TrackParticle and match is xAOD::Muon + if(probetrack && matchmuon) { + if( probetrack == matchmuon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle ) || + probetrack == matchmuon->trackParticle( xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle ) || + probetrack == matchmuon->trackParticle( xAOD::Muon::MuonSpectrometerTrackParticle ) ) { + matchProbe = probe; + probe->dr_match(0); + best_match_muon = matchmuon; + break; + } + } - if (m_match_CaloTag){ - return (mumatch && m_selection_tool->passedCaloTagQuality(*mumatch) && mumatch->isAuthor(xAOD::Muon::CaloTag) ); - } - // MS Match - if (m_match_MS){ - return ((mumatch->muonType() == xAOD::Muon::MuonStandAlone || mumatch->muonType() == xAOD::Muon::Combined) && mumatch->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle)!= NULL); - } - // CB Match - if (m_match_CB){ - return (mumatch->muonType() == xAOD::Muon::Combined && mumatch->trackParticle(xAOD::Muon::CombinedTrackParticle) != NULL); - } - if (m_match_Loose){ - bool ok = (m_selection_tool->getQuality(*mumatch) <= xAOD::Muon::Loose ); - return ok; - } - if (m_match_Loose_noCT){ - bool ok = (m_selection_tool->getQuality(*mumatch) <= xAOD::Muon::Loose && mumatch->muonType() != xAOD::Muon::CaloTagged ); - return ok; - } - if (m_match_Medium){ - bool ok = (m_selection_tool->getQuality(*mumatch) <= xAOD::Muon::Medium ); - return ok; - } - if (m_match_Tight){ - bool ok = (m_selection_tool->getQuality(*mumatch) <= xAOD::Muon::Tight ); - return ok; - } - if (m_match_MuidCB){ - return (mumatch->isAuthor(xAOD::Muon::MuidCo)); - } - if (m_match_STACO){ - return (mumatch->isAuthor(xAOD::Muon::STACO)); - } - if (m_match_MuTag){ - return (mumatch->isAuthor(xAOD::Muon::MuTag)); - } - if (m_match_MuTagIMO){ - return (mumatch->isAuthor(xAOD::Muon::MuTagIMO)); - } - if (m_match_MuidSA){ - return (mumatch->isAuthor(xAOD::Muon::MuidSA)); - } - if (m_match_MuGirl){ - return (mumatch->isAuthor(xAOD::Muon::MuGirl)); - } - if (m_match_MuGirlLowBeta){ - return (mumatch->isAuthor(xAOD::Muon::MuGirlLowBeta)); - } - if (m_match_CaloLikelihood){ - return (mumatch->isAuthor(xAOD::Muon::CaloLikelihood)); } - if (m_match_ExtrapolateToIP){ - return (mumatch->isAuthor(xAOD::Muon::ExtrapolateMuonToIP)); + + // check if a matched probe is found + probe->sfweight(1.); + probe->isMatched(matchProbe); + if (m_do_sf && best_match_muon && probe->isMatched()){ + float sf = 1.; + if (m_sf_tool->getEfficiencyScaleFactor(*best_match_muon,sf) == CP::CorrectionCode::Ok){ + probe->sfweight(sf); + } } - return false; + } +} + +bool MuonRecoTPEfficiencyTool::GoodMatchMuonType(const xAOD::IParticle* probe) const{ + + const xAOD::Muon* mumatch = dynamic_cast <const xAOD::Muon*> (probe); + + // if the particle is not a muon, assume that the user knows what TrackParticleContainer he is providing! + if (! mumatch) return true; + + // otherwise, we have to manually pick the right probe + + // ID Track + if (m_match_ID){ + return (mumatch->trackParticle(xAOD::Muon::InnerDetectorTrackParticle) != NULL); + } + // CT Match + + if (m_match_CaloTag){ + return (mumatch && m_selection_tool->passedCaloTagQuality(*mumatch) && mumatch->isAuthor(xAOD::Muon::CaloTag) ); + } + // MS Match + if (m_match_MS){ + return ((mumatch->muonType() == xAOD::Muon::MuonStandAlone || mumatch->muonType() == xAOD::Muon::Combined) + && mumatch->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle)!= NULL); + } + // CB Match + if (m_match_CB){ + return (mumatch->muonType() == xAOD::Muon::Combined && mumatch->trackParticle(xAOD::Muon::CombinedTrackParticle) != NULL); + } + if (m_match_Loose){ + return (m_selection_tool->getQuality(*mumatch) <= xAOD::Muon::Loose); + } + if (m_match_Loose_noCT){ + return (m_selection_tool->getQuality(*mumatch) <= xAOD::Muon::Loose && mumatch->muonType() != xAOD::Muon::CaloTagged); + } + if (m_match_Medium){ + return (m_selection_tool->getQuality(*mumatch) <= xAOD::Muon::Medium); + } + if (m_match_Tight){ + return (m_selection_tool->getQuality(*mumatch) <= xAOD::Muon::Tight); + } + if (m_match_HighPt){ + return m_selection_tool->passedHighPtCuts(*mumatch); + } + if (m_match_MuidCB){ + return (mumatch->isAuthor(xAOD::Muon::MuidCo)); + } + if (m_match_STACO){ + return (mumatch->isAuthor(xAOD::Muon::STACO)); + } + if (m_match_MuTag){ + return (mumatch->isAuthor(xAOD::Muon::MuTag)); + } + if (m_match_MuTagIMO){ + return (mumatch->isAuthor(xAOD::Muon::MuTagIMO)); + } + if (m_match_MuidSA){ + return (mumatch->isAuthor(xAOD::Muon::MuidSA)); + } + if (m_match_MuGirl){ + return (mumatch->isAuthor(xAOD::Muon::MuGirl)); + } + if (m_match_MuGirlLowBeta){ + return (mumatch->isAuthor(xAOD::Muon::MuGirlLowBeta)); + } + if (m_match_CaloLikelihood){ + return (mumatch->isAuthor(xAOD::Muon::CaloLikelihood)); + } + if (m_match_ExtrapolateToIP){ + return (mumatch->isAuthor(xAOD::Muon::ExtrapolateMuonToIP)); + } + return false; +} +//********************************************************************** + +void MuonRecoTPEfficiencyTool::matchProbes(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const +{ + if(m_ptrMatching) ptrMatching(probes, matches); + else dRMatching(probes, matches); + + if (msgLvl(MSG::DEBUG)) { + int nmatched=0; + for(auto probe : *probes) + if(probe->isMatched()) + nmatched++; + ATH_MSG_DEBUG("Number of matched probes : " << nmatched ); + } } diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPEfficiencyTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPEfficiencyTool.cxx index 4f01bf586e0..4b217b17397 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPEfficiencyTool.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPEfficiencyTool.cxx @@ -10,18 +10,19 @@ //********************************************************************** MuonTPEfficiencyTool::MuonTPEfficiencyTool(std::string myname) -: AsgTool(myname), m_matchTool("Trig::ITrigMuonMatching/TrigMuonMatching"){ + : AsgTool(myname), m_matchTool("Trig::ITrigMuonMatching/TrigMuonMatching"){ declareProperty("MatchPtCut", m_matchPtCut = 0.0); declareProperty("MatchEtaCut", m_matchEtaCut = 5.0); - declareProperty("dRMatching", m_dRMatching = true); declareProperty("MaximumDrCut", m_maximumDrCut = 0.05); declareProperty("MuonAuthor", m_muonAuthor = 12); // we need a central place for author<->algname mapping! declareProperty("EfficiencyFlag", m_efficiencyFlag = "CBMuons"); + declareProperty("IsNominal", m_isNominal=true); declareProperty("SelectionTool", m_selection_tool); declareProperty("ScaleFactorTool", m_sf_tool); declareProperty("ApplyScaleFactors", m_do_sf = false); declareProperty("TriggerMatchTool", m_matchTool); + declareProperty("TrigItem", m_trigger_item=""); } MuonTPEfficiencyTool::~MuonTPEfficiencyTool() @@ -29,29 +30,21 @@ MuonTPEfficiencyTool::~MuonTPEfficiencyTool() StatusCode MuonTPEfficiencyTool::initialize() { - ATH_CHECK(m_selection_tool.retrieve()); - if (m_do_sf) ATH_CHECK(m_sf_tool.retrieve()); + ATH_CHECK(m_selection_tool.retrieve()); + if (m_do_sf) ATH_CHECK(m_sf_tool.retrieve()); ATH_CHECK(m_matchTool.retrieve()); return StatusCode::SUCCESS; } - //********************************************************************** -void MuonTPEfficiencyTool::matchProbes(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const +void MuonTPEfficiencyTool::matchProbes(ProbeContainer* , const xAOD::IParticleContainer* ) const { - if(m_dRMatching) dRMatching(probes, matches); - - if (msgLvl(MSG::DEBUG)) { - int nmatched=0; - for(auto probe : *probes) - if(probe->isMatched()) - nmatched++; - ATH_MSG_DEBUG("Number of matched probes : " << nmatched ); - } + // do nothing by default } + //********************************************************************** void MuonTPEfficiencyTool::dRMatching(ProbeContainer* probes, const xAOD::IParticleContainer* matches) const @@ -85,19 +78,19 @@ void MuonTPEfficiencyTool::dRMatching(ProbeContainer* probes, const xAOD::IParti // Calculate dR double dR = deltaR(probe, match); if(dR < dRMin) { - dRMin = dR; - matchProbe = probe; - if (mumatch) best_match_muon = mumatch; + dRMin = dR; + matchProbe = probe; + if (mumatch) best_match_muon = mumatch; } } probe->sfweight(1.); // check if a matched probe is found probe->isMatched((matchProbe && dRMin<m_maximumDrCut)); if (m_do_sf && best_match_muon && probe->isMatched()){ - float sf = 1.; - if (m_sf_tool->getEfficiencyScaleFactor(*best_match_muon,sf) == CP::CorrectionCode::Ok){ - probe->sfweight(sf); - } + float sf = 1.; + if (m_sf_tool->getEfficiencyScaleFactor(*best_match_muon,sf) == CP::CorrectionCode::Ok){ + probe->sfweight(sf); + } } } @@ -110,8 +103,8 @@ double MuonTPEfficiencyTool::deltaR(Probe* probe, const xAOD::IParticle* match) } //********************************************************************** - // check for a trigger match (probe side) +// check for a trigger match (probe side) bool MuonTPEfficiencyTool::MatchTrigger (const xAOD::IParticle* match, std::string trigger) const { - return m_matchTool->match(match->eta(),match->phi(), trigger); + return m_matchTool->match(match->eta(),match->phi(), trigger); } diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPPlotTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPPlotTool.cxx index 9c588046de9..f6b232e7540 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPPlotTool.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPPlotTool.cxx @@ -12,189 +12,196 @@ #include "MuonTPTools/MuonTPPlotTool.h" MuonTPPlotTool::MuonTPPlotTool(std::string name) - : AsgTool(name){ - declareProperty("EfficiencyFlag", m_efficiencyFlag = "ZmmTP"); - - declareProperty("DoOnlyAside", m_only_A_side = false); - declareProperty("DoOnlyCside", m_only_C_side = false); - declareProperty("ProbeAbsEtaMin", m_probe_abseta_min = -1.00); - declareProperty("ProbeAbsEtaMax", m_probe_abseta_max = 100.00); - declareProperty("DoAsymmErrorGraphs", m_doAsymmErrors = false); + : AsgTool(name){ + declareProperty("EfficiencyFlag", m_efficiencyFlag = "ZmmTP"); + declareProperty("DoOnlyAside", m_only_A_side = false); + declareProperty("DoOnlyCside", m_only_C_side = false); + declareProperty("ProbeAbsEtaMin", m_probe_abseta_min = -1.00); + declareProperty("ProbeAbsEtaMax", m_probe_abseta_max = 100.00); + declareProperty("DoAsymmErrorGraphs", m_doAsymmErrors = false); + declareProperty("ProduceEfficiencies", m_doEffPlots = false); + declareProperty("ProduceProbeMatchPlots", m_doProbeMatchPlots = true); + } StatusCode MuonTPPlotTool::RegisterPlots (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools){ - // Create histograms - for(auto tpSelTool : probeTools) { - std::string cfdirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag(); - m_TPcutFlowPlots[cfdirs] = AddCutFlowPlots(cfdirs+"/CutFlows"); + // Create histograms + for(auto tpSelTool : probeTools) { + std::string cfdirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag(); + m_TPcutFlowPlots[cfdirs] = AddCutFlowPlots(cfdirs+"/CutFlows"); for (auto plot : m_TPcutFlowPlots[cfdirs]){ plot->initialize(); tpSelTool->AddCutFlowHist(plot); // show this plot to the selection tool, which can then internally fill it } - for(auto tpEffTool : effTools) { - std::string dirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag()+"/"+tpEffTool->efficiencyFlag(); - if (m_probeTPEffPlots.find(dirs) ==m_probeTPEffPlots.end()){ - m_probeTPEffPlots[dirs] = AddPlots(dirs+"/Probes", false); - m_matchTPEffPlots[dirs] = AddPlots(dirs+"/Matches", true); - m_effTPEffPlots[dirs] = AddPlots(dirs+"/Efficiency", true); - - // now we can initialize everything - for (auto plot : m_probeTPEffPlots[dirs]){ - plot->initialize(); - } - for (auto plot : m_matchTPEffPlots[dirs]){ - plot->initialize(); - } - for (auto plot : m_effTPEffPlots[dirs]){ - if (m_doAsymmErrors) { - plot->SetDoAsymmErrors(m_doAsymmErrors); - plot->BookAllAsymmErrors(); + if (m_doProbeMatchPlots) { + for(auto tpEffTool : effTools) { + if (!tpEffTool->isNominal() && !tpSelTool->isNominal()) continue; + std::string dirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag()+"/"+tpEffTool->efficiencyFlag(); + if (m_probeTPEffPlots.find(dirs) ==m_probeTPEffPlots.end()){ + // + m_probeTPEffPlots[dirs] = AddPlots(dirs+"/Probes", false); + m_matchTPEffPlots[dirs] = AddPlots(dirs+"/Matches", true); + // on request, also prepare efficiencies + if (m_doEffPlots) m_effTPEffPlots[dirs] = AddPlots(dirs+"/Efficiency", true); + + // now we can initialize everything + for (auto plot : m_probeTPEffPlots[dirs]){ + plot->initialize(); + } + for (auto plot : m_matchTPEffPlots[dirs]){ + plot->initialize(); } - plot->initialize(); - } - } - } - } + for (auto plot : m_effTPEffPlots[dirs]){ + if (m_doAsymmErrors) { + plot->SetDoAsymmErrors(m_doAsymmErrors); + plot->BookAllAsymmErrors(); + } + plot->initialize(); + } + } + } + } + } return StatusCode::SUCCESS; } std::vector<MuonTPEfficiencyPlotBase*> MuonTPPlotTool::AddPlots(std::string , bool ){ - // here, you can add any MuonTPEfficiencyPlotBase* based plot you like to the output! - // in this base class, we don't add anything - return std::vector<MuonTPEfficiencyPlotBase*>(0); + // here, you can add any MuonTPEfficiencyPlotBase* based plot you like to the output! + // in this base class, we don't add anything + return std::vector<MuonTPEfficiencyPlotBase*>(0); } std::vector<MuonTPCutFlowBase*> MuonTPPlotTool::AddCutFlowPlots(std::string){ - // here, you can add any MuonTPCutFlowBase* based plot you like to the output! - // in this base class, we don't add anything - return std::vector<MuonTPCutFlowBase*>(0); + // here, you can add any MuonTPCutFlowBase* based plot you like to the output! + // in this base class, we don't add anything + return std::vector<MuonTPCutFlowBase*>(0); } - // fill the histos - void MuonTPPlotTool::fill(Probe& probe, ToolHandle <IMuonTPSelectionTool> & tpSelTool, ToolHandle <IMuonTPEfficiencyTool> eff_tool){ +// fill the histos +void MuonTPPlotTool::fill(Probe& probe, ToolHandle <IMuonTPSelectionTool> & tpSelTool, ToolHandle <IMuonTPEfficiencyTool> & eff_tool){ - double feta = fabs(probe.eta()); - if (feta < m_probe_abseta_min) return; - if (feta > m_probe_abseta_max) return; - if (probe.eta() > 0 && m_only_A_side) return; - if (probe.eta() < 0 && m_only_C_side) return; + double feta = fabs(probe.eta()); + if (feta < m_probe_abseta_min) return; + if (feta > m_probe_abseta_max) return; + if (probe.eta() > 0 && m_only_A_side) return; + if (probe.eta() < 0 && m_only_C_side) return; - std::string dirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag()+"/"+eff_tool->efficiencyFlag(); - for (auto plot : m_probeTPEffPlots[dirs]){ - plot->fill(probe); - } - for (auto plot : m_matchTPEffPlots[dirs]){ - plot->fill(probe); - } - } - - // fill the cut flow histos - void MuonTPPlotTool::fillCutFlow(std::string stage, double weight, ToolHandle <IMuonTPSelectionTool> & tpSelTool){ - - std::string dirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag(); - for (auto plot : m_TPcutFlowPlots[dirs]){ - plot->fill(stage, weight); - } - } - /// retrieve booked histograms - std::vector<HistData> MuonTPPlotTool::retrieveBookedHistograms(){ - - std::vector<HistData> histData; - for(auto plots : m_probeTPEffPlots) { - for (auto hist : plots.second){ - std::vector<HistData> histDataTmp = hist->retrieveBookedHistograms(); - histData.insert(histData.end(), histDataTmp.begin(), histDataTmp.end()); - } - } - for(auto plots : m_matchTPEffPlots) { - for (auto hist : plots.second){ - std::vector<HistData> histDataTmp = hist->retrieveBookedHistograms(); - histData.insert(histData.end(), histDataTmp.begin(), histDataTmp.end()); - } - } - for(auto plots : m_effTPEffPlots) { - for (auto hist : plots.second){ - std::vector<HistData> histDataTmp = hist->retrieveBookedHistograms(); - histData.insert(histData.end(), histDataTmp.begin(), histDataTmp.end()); - } - } - for (auto plots: m_TPcutFlowPlots) { - for (auto hist : plots.second){ - std::vector<HistData> histDataTmp = hist->retrieveBookedHistograms(); - histData.insert(histData.end(), histDataTmp.begin(), histDataTmp.end()); - } - } - - return histData; + std::string dirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag()+"/"+eff_tool->efficiencyFlag(); + for (auto plot : m_probeTPEffPlots[dirs]){ + plot->fill(probe); } - std::vector<std::pair <TGraph*, std::string > > MuonTPPlotTool::retrieveBookedGraphs(){ - - std::vector<std::pair <TGraph*, std::string > > graphData; - for(auto plots : m_probeTPEffPlots) { - for (auto hist : plots.second){ - std::vector<std::pair <TGraph*, std::string > > graphDataTmp = hist->retrieveBookedGraphs(); - graphData.insert(graphData.end(), graphDataTmp.begin(), graphDataTmp.end()); - } - } - for(auto plots : m_matchTPEffPlots) { - for (auto hist : plots.second){ - std::vector<std::pair <TGraph*, std::string > > graphDataTmp = hist->retrieveBookedGraphs(); - graphData.insert(graphData.end(), graphDataTmp.begin(), graphDataTmp.end()); - } - } - for(auto plots : m_effTPEffPlots) { - for (auto hist : plots.second){ - std::vector<std::pair <TGraph*, std::string > > graphDataTmp = hist->retrieveBookedGraphs(); - graphData.insert(graphData.end(), graphDataTmp.begin(), graphDataTmp.end()); - } - } - - return graphData; + for (auto plot : m_matchTPEffPlots[dirs]){ + plot->fill(probe); } -void MuonTPPlotTool::CalcEff(void){ +} + +// fill the cut flow histos +void MuonTPPlotTool::fillCutFlow(std::string stage, double weight, ToolHandle <IMuonTPSelectionTool> & tpSelTool){ - for(auto deniter : m_probeTPEffPlots) { - std::vector<MuonTPEfficiencyPlotBase*> denplots = deniter.second; - std::vector<MuonTPEfficiencyPlotBase*> matchplots = m_matchTPEffPlots[deniter.first]; - std::vector<MuonTPEfficiencyPlotBase*> effplots = m_effTPEffPlots[deniter.first]; - for (size_t i = 0; i < denplots.size();++i){ - effplots[i]->EffiDivide(denplots[i],matchplots[i]); - } - } + std::string dirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag(); + for (auto plot : m_TPcutFlowPlots[dirs]){ + plot->fill(stage, weight); + } } +/// retrieve booked histograms +std::vector<HistData> MuonTPPlotTool::retrieveBookedHistograms(){ + + std::vector<HistData> histData; + for(auto plots : m_probeTPEffPlots) { + for (auto hist : plots.second){ + std::vector<HistData> histDataTmp = hist->retrieveBookedHistograms(); + histData.insert(histData.end(), histDataTmp.begin(), histDataTmp.end()); + } + } + for(auto plots : m_matchTPEffPlots) { + for (auto hist : plots.second){ + std::vector<HistData> histDataTmp = hist->retrieveBookedHistograms(); + histData.insert(histData.end(), histDataTmp.begin(), histDataTmp.end()); + } + } + for(auto plots : m_effTPEffPlots) { + for (auto hist : plots.second){ + std::vector<HistData> histDataTmp = hist->retrieveBookedHistograms(); + histData.insert(histData.end(), histDataTmp.begin(), histDataTmp.end()); + } + } + for (auto plots: m_TPcutFlowPlots) { + for (auto hist : plots.second){ + std::vector<HistData> histDataTmp = hist->retrieveBookedHistograms(); + histData.insert(histData.end(), histDataTmp.begin(), histDataTmp.end()); + } + } + return histData; +} +std::vector<std::pair <TGraph*, std::string > > MuonTPPlotTool::retrieveBookedGraphs(){ + + std::vector<std::pair <TGraph*, std::string > > graphData; + for(auto plots : m_probeTPEffPlots) { + for (auto hist : plots.second){ + std::vector<std::pair <TGraph*, std::string > > graphDataTmp = hist->retrieveBookedGraphs(); + graphData.insert(graphData.end(), graphDataTmp.begin(), graphDataTmp.end()); + } + } + for(auto plots : m_matchTPEffPlots) { + for (auto hist : plots.second){ + std::vector<std::pair <TGraph*, std::string > > graphDataTmp = hist->retrieveBookedGraphs(); + graphData.insert(graphData.end(), graphDataTmp.begin(), graphDataTmp.end()); + } + } + for(auto plots : m_effTPEffPlots) { + for (auto hist : plots.second){ + std::vector<std::pair <TGraph*, std::string > > graphDataTmp = hist->retrieveBookedGraphs(); + graphData.insert(graphData.end(), graphDataTmp.begin(), graphDataTmp.end()); + } + } - MuonTPPlotTool::~MuonTPPlotTool(){ - - for(auto plots : m_probeTPEffPlots){ - for (auto plot : plots.second){ - delete plot; - } - } - for(auto plots : m_matchTPEffPlots){ - for (auto plot : plots.second){ - delete plot; - } - } - for(auto plots : m_effTPEffPlots){ - for (auto plot : plots.second){ - delete plot; - } - } - for(auto plots : m_TPcutFlowPlots){ - for (auto plot : plots.second){ - delete plot; - } - } - m_probeTPEffPlots.clear(); - m_matchTPEffPlots.clear(); - m_effTPEffPlots.clear(); - m_TPcutFlowPlots.clear(); + return graphData; +} +void MuonTPPlotTool::CalcEff(void){ + if (!m_doEffPlots) return; + for(auto deniter : m_probeTPEffPlots) { + std::vector<MuonTPEfficiencyPlotBase*> denplots = deniter.second; + std::vector<MuonTPEfficiencyPlotBase*> matchplots = m_matchTPEffPlots[deniter.first]; + std::vector<MuonTPEfficiencyPlotBase*> effplots = m_effTPEffPlots[deniter.first]; + for (size_t i = 0; i < denplots.size();++i){ + effplots[i]->EffiDivide(denplots[i],matchplots[i]); + } } +} + + +MuonTPPlotTool::~MuonTPPlotTool(){ + + for(auto plots : m_probeTPEffPlots){ + for (auto plot : plots.second){ + delete plot; + } + } + for(auto plots : m_matchTPEffPlots){ + for (auto plot : plots.second){ + delete plot; + } + } + for(auto plots : m_effTPEffPlots){ + for (auto plot : plots.second){ + delete plot; + } + } + for(auto plots : m_TPcutFlowPlots){ + for (auto plot : plots.second){ + delete plot; + } + } + m_probeTPEffPlots.clear(); + m_matchTPEffPlots.clear(); + m_effTPEffPlots.clear(); + m_TPcutFlowPlots.clear(); +} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPSelectionTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPSelectionTool.cxx index a4f8aa5379e..aaa99acdc14 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPSelectionTool.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPSelectionTool.cxx @@ -6,53 +6,60 @@ #include "MuonTPTools/MuonTPSelectionTool.h" #include "xAODTracking/VertexContainer.h" -// #include "xAODPrimitives/​tools/​getIsolationCorrectionAccessor.h" +#include "MCTruthClassifier/MCTruthClassifierDefs.h" +// #include "xAODPrimitives/tools/getIsolationCorrectionAccessor.h" +#include "xAODTruth/TruthParticleContainer.h" //********************************************************************** -MuonTPSelectionTool::MuonTPSelectionTool(std::string myname) : AsgTool(myname),m_tag_Triggers(0), m_selection_tool(),m_trigTool("Trig::TrigDecisionTool/TrigDecisionTool"), m_matchTool("Trig::ITrigMuonMatching/TrigMuonMatching"){ - declareProperty("TagPtCut", m_tagPtCut = 20000.0); - declareProperty("TagEtaCut", m_tagEtaCut = 2.5); - declareProperty("ProbePtCut", m_probePtCut = 20000.0); - declareProperty("ProbeEtaCut", m_probeEtaCut = 2.5); - declareProperty("HighMassWindow", m_highMassWindow = 101000.0); - declareProperty("LowMassWindow", m_lowMassWindow = 81000.0); - declareProperty("EfficiencyFlag", m_efficiencyFlag = "IDProbes"); - declareProperty("TagTriggerList", m_tag_Triggers ); - declareProperty("SelectionTool", m_selection_tool); - declareProperty("TriggerMatchTool", m_matchTool); - declareProperty("TriggerDecisionTool", m_trigTool); - - - // track iso recomputation for the full athena release -# if defined(ASGTOOL_ATHENA) && !defined(XAOD_ANALYSIS) - declareProperty("TrackIsolationTool", m_track_iso_tool); - declareProperty("CaloIsolationTool", m_calo_iso_tool); - m_track_iso_to_run.push_back(xAOD::Iso::ptcone40); - m_calo_iso_to_run.push_back(xAOD::Iso::topoetcone40); -# endif +MuonTPSelectionTool::MuonTPSelectionTool(std::string myname) : + AsgTool(myname),m_tag_Triggers(0), + m_selection_tool(), + m_trigTool("Trig::TrigDecisionTool/TrigDecisionTool"), + m_matchTool("Trig::ITrigMuonMatching/TrigMuonMatching"), + m_grlTool("GoodRunsListSelectionTool/GRLTool") +{ + declareProperty("TagPtCut", m_tagPtCut = 20000.0); + declareProperty("TagEtaCut", m_tagEtaCut = 2.5); + declareProperty("ProbePtCut", m_probePtCut = 20000.0); + declareProperty("ProbeEtaCut", m_probeEtaCut = 2.5); + declareProperty("HighMassWindow", m_highMassWindow = 101000.0); + declareProperty("LowMassWindow", m_lowMassWindow = 81000.0); + declareProperty("EfficiencyFlag", m_efficiencyFlag = "IDProbes"); + declareProperty("TagTriggerList", m_tag_Triggers ); + declareProperty("SelectionTool", m_selection_tool); + declareProperty("TriggerDecisionTool", m_trigTool); + declareProperty("TriggerMatchTool", m_matchTool); + declareProperty("IsNominal", m_isNominal=true); + declareProperty("IsNotIncludedInNominal", m_isNotPartOfNominal=false); + declareProperty("GRLTool", m_grlTool, "The private GoodRunsListSelectionTool"); + } StatusCode MuonTPSelectionTool::initialize() { -# if defined(ASGTOOL_ATHENA) && !defined(XAOD_ANALYSIS) - ATH_CHECK(m_track_iso_tool.retrieve()); - ATH_CHECK(m_calo_iso_tool.retrieve()); -# endif - ATH_CHECK(m_selection_tool.retrieve()); - ATH_CHECK(m_trigTool.retrieve()); - ATH_CHECK(m_matchTool.retrieve()); - return StatusCode::SUCCESS; - + + ATH_CHECK(m_selection_tool.retrieve()); + ATH_CHECK(m_trigTool.retrieve()); + ATH_CHECK(m_matchTool.retrieve()); + ATH_CHECK(m_grlTool.retrieve()); + return StatusCode::SUCCESS; } - //********************************************************************** ProbeContainer* MuonTPSelectionTool::selectProbes(const xAOD::MuonContainer* tags, const xAOD::IParticleContainer* probes) const { // use m_muonSelectionTool to select muons ProbeContainer* probeCont = new ProbeContainer(); + + // check GRL + const xAOD::EventInfo* info = 0; + ATH_MSG_DEBUG(""<<evtStore()); + if (evtStore()->retrieve(info, "EventInfo").isFailure()){ + ATH_MSG_FATAL( "Unable to retrieve Event Info" ); + } + if (!passGRL(info)) return probeCont; // loop over tag container for(auto tag : *tags) { @@ -101,160 +108,196 @@ ProbeContainer* MuonTPSelectionTool::selectProbes(const xAOD::MuonContainer* tag } //********************************************************************** +bool MuonTPSelectionTool::passGRL(const xAOD::EventInfo* info) const +{ + if(!info->eventType(xAOD::EventInfo::IS_SIMULATION)){ + if(!m_grlTool->passRunLB(*info)) return false; //checks the GRL and skips to next event if not passing + } + return true; +} + bool MuonTPSelectionTool::isTag(const xAOD::Muon* tag, const xAOD::IParticle* probe) const { return ( tag->p4().DeltaR(probe->p4()) < 0.01); } int MuonTPSelectionTool::ChargeProd (const xAOD::Muon* tag, const xAOD::IParticle* probe) const { - // case of a muon probe - const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(probe); - if (muprobe) { - return muprobe->trackParticle(xAOD::Muon::Primary)->charge() * tag->trackParticle(xAOD::Muon::Primary)->charge(); - } - // case of an ID probe - const xAOD::TrackParticle* trkprobe = dynamic_cast<const xAOD::TrackParticle*>(probe); - if (trkprobe){ - return trkprobe->charge() * tag->trackParticle(xAOD::Muon::Primary)->charge(); - } - return 0; + // case of a muon probe + const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(probe); + if (muprobe) { + return muprobe->trackParticle(xAOD::Muon::Primary)->charge() * tag->trackParticle(xAOD::Muon::Primary)->charge(); + } + // case of an ID probe + const xAOD::TrackParticle* trkprobe = dynamic_cast<const xAOD::TrackParticle*>(probe); + if (trkprobe){ + return trkprobe->charge() * tag->trackParticle(xAOD::Muon::Primary)->charge(); + } + return 0; } double MuonTPSelectionTool::DeltaPhiTP (const xAOD::Muon* tag, const xAOD::IParticle* probe) const{ - return fabs(tag->p4().DeltaPhi(probe->p4())); + return fabs(tag->p4().DeltaPhi(probe->p4())); } double MuonTPSelectionTool::ptcone_trk (const xAOD::IParticle* part, double ) const{ - // this is present in the MUON1 derivation or if our tool already wrote it in a previous iteration - if (part->isAvailable<float>("MUON1_ptcone40")){ - return part->auxdataConst<float>("MUON1_ptcone40"); + // this is present in the MUON1 derivation or if our tool already wrote it in a previous iteration + if (part->isAvailable<float>("MUON1_ptcone40")){ + try{ + return part->auxdataConst<float>("MUON1_ptcone40"); } - else { - // Here, we can manually compute the isolation *if* we are running in full athena. - // In the other cases, we just return a dummy result. - # if defined(ASGTOOL_ATHENA) && !defined(XAOD_ANALYSIS) - xAOD::TrackCorrection corrlist; - corrlist.trackbitset.set(static_cast<unsigned int>(xAOD::Iso::coreTrackPtr)); - xAOD::TrackIsolation resultTrack; - const xAOD::TrackParticle* tp = dynamic_cast<const xAOD::TrackParticle*>(part); - if (!tp || ! m_track_iso_tool->trackIsolation(resultTrack, *tp, m_track_iso_to_run, corrlist,tp->vertex(),0)){ - ATH_MSG_WARNING("Failed to apply the isolation for a particle"); - } - static SG::AuxElement::Decorator< float > ptcone40("MUON1_ptcone40"); - ptcone40(*part) = resultTrack.ptcones.at(0); - return resultTrack.ptcones.at(0); - # else - return -1; - # endif + catch(SG::ExcBadAuxVar failed){ + // sometimes this is missing + ATH_MSG_WARNING("Missing PtCone40 decoration!"); + return -1; } + } + else { + return -1; + } } double MuonTPSelectionTool::etcone_trk (const xAOD::IParticle* part, double ) const{ - if (part->isAvailable<float>("MUON1_topoetcone40")){ - return part->auxdataConst<float>("MUON1_topoetcone40"); + if (part->isAvailable<float>("MUON1_topoetcone40")){ + try{ + return part->auxdataConst<float>("MUON1_topoetcone40"); } - else { - // See above - similar to track isolation - # if defined(ASGTOOL_ATHENA) && !defined(XAOD_ANALYSIS) - xAOD::CaloCorrection Calocorrlist; - Calocorrlist.calobitset.set(static_cast<unsigned int>(xAOD::Iso::coreCone) | static_cast<unsigned int>(xAOD::Iso::pileupCorrection)); - xAOD::CaloIsolation resultCalo; - const xAOD::TrackParticle* tp = dynamic_cast<const xAOD::TrackParticle*>(part); - if (!tp || ! m_calo_iso_tool->caloTopoClusterIsolation(resultCalo, *tp, m_calo_iso_to_run, Calocorrlist)){ - ATH_MSG_WARNING("Failed to apply the isolation for a particle"); - } - static SG::AuxElement::Decorator< float > etcone40("MUON1_topoetcone40"); - etcone40(*part) = resultCalo.etcones.at(0); - return resultCalo.etcones.at(0); - # else - return -1; - # endif + catch(SG::ExcBadAuxVar failed){ + // sometimes this is missing + ATH_MSG_WARNING("Missing EtCone40 decoration!"); + return -1; } + } + return -1; } bool MuonTPSelectionTool::isFinalStateTruthMuon(const xAOD::IParticle* part) const{ - // first, make sure we are actually looping over truth particles! - const xAOD::TruthParticle* truthmu = dynamic_cast <const xAOD::TruthParticle*>(part); - if (!truthmu) return false; + // first, make sure we are actually looping over truth particles! + const xAOD::TruthParticle* truthmu = dynamic_cast <const xAOD::TruthParticle*>(part); + if (!truthmu) return false; - // check PDG ID -// ATH_MSG_INFO("PDG ID"); -// if (!truthmu->isMuon()) return false; + // const xAOD::TruthParticle* muparent = truthmu->parent(0); + if (fabs(truthmu->pdgId()) != 13) return false; + // check the status code + if (truthmu->status() != 1) return false; + + if (truthmu->isAvailable<int>("truthType")){ + try{ + // check the muon type + if (truthmu->auxdata<int>("truthType") != MCTruthPartClassifier::IsoMuon ) return false; // IsoMuon + // check the muon parent + if (truthmu->auxdata<int>("truthOrigin") != MCTruthPartClassifier::ZBoson && truthmu->auxdata<int>("truthOrigin") != MCTruthPartClassifier::CCbarMeson && truthmu->auxdata<int>("truthOrigin") != MCTruthPartClassifier::JPsi ) return false;// ZBoson or CCbarMeson + } + catch(SG::ExcBadAuxVar failed){ + ATH_MSG_WARNING("Missing Truth decorations!"); + } + } + + return true; +} - // check the status code - if (truthmu->status() != 1) return false; - return true; +bool MuonTPSelectionTool::isTruthMatched(const xAOD::IParticle* part) const{ + + // it's an xAOD::Muon + const xAOD::Muon* muon = dynamic_cast<const xAOD::Muon*>(part); + if(muon) { + if(muon->isAvailable<ElementLink<xAOD::TruthParticleContainer> >("truthParticleLink")) { + ElementLink<xAOD::TruthParticleContainer> link = muon->auxdata<ElementLink<xAOD::TruthParticleContainer> >("truthParticleLink"); + if(link.isValid() && (*link)->auxdata<int>("truthType")==MCTruthPartClassifier::IsoMuon) + return true; + } + } + // it's an xAOD::TrackParticle + else{ + const xAOD::TrackParticle* track = dynamic_cast<const xAOD::TrackParticle*>(part); + if(track && track->auxdata<int>("truthType")==MCTruthPartClassifier::IsoMuon) + return true; + } + + return false; } bool MuonTPSelectionTool::passDummyTrigger(const xAOD::Muon* tag) const{ - // until we have real trigger info, we select muons that went into the endcaps and are well above the pt threshold... -// (void)passTagTrigger(tag); - return (fabs(tag->eta()) > 1.1 && tag->pt() > 25000.); + // until we have real trigger info, we select muons that went into the endcaps and are well above the pt threshold... + // (void)passTagTrigger(tag); + return (fabs(tag->eta()) > 1.1 && tag->pt() > 25000.); } bool MuonTPSelectionTool::TagTriggerMatch (const xAOD::Muon* tag) const{ - // nothing requested -> pass through - if (m_tag_Triggers.size() == 0) return true; - // no trigger info --> dummy trigger - if (m_trigTool->getListOfTriggers().size() == 0) { - ATH_MSG_DEBUG("Running with dummy trigger - no triggers found"); - return passDummyTrigger(tag); - } - // require the tag to match one of our triggers - for (auto trig: m_tag_Triggers) { - ATH_MSG_DEBUG("Matching on "<<trig <<": \t"<<m_matchTool->match(tag, trig)); - if (m_matchTool->match(tag, trig)) return true; + // nothing requested -> pass through + if (m_tag_Triggers.size() == 0) return true; + // no trigger info --> dummy trigger + if (m_trigTool->getListOfTriggers().size() == 0) { + ATH_MSG_DEBUG("Running with dummy trigger - no triggers found"); + return passDummyTrigger(tag); + } + // require the tag to match one of our triggers + bool pass = false; + for (auto trig: m_tag_Triggers) { + + ATH_MSG_DEBUG("Matching on "<<trig <<": \t"<<m_matchTool->match(tag, trig)); + bool res = (m_trigTool->isPassed(trig) && m_matchTool->match(tag, trig)); + pass|=res; + + // decorate the tag with the trigger matching outcome, for the ntuples + SG::AuxElement::Decorator<bool> dec_trig ( std::string("trigmatch_")+trig); + dec_trig(*tag) = res; + float dr = -1.; + if (res){ + dr = m_matchTool->minDelR(tag, trig,0.6); } - return false; + SG::AuxElement::Decorator<float> dr_trig ( std::string("trigmatch_dR_")+trig); + dr_trig(*tag) = dr; + } + return pass; } void MuonTPSelectionTool::AddCutFlowHist(MuonTPCutFlowBase* hist){ - m_cutFlows.push_back(hist); + m_cutFlows.push_back(hist); } void MuonTPSelectionTool::FillCutFlows(std::string step, double weight) const{ - for (auto cf : m_cutFlows){ - cf->fill(step.c_str(),weight); - } + for (auto cf : m_cutFlows){ + cf->fill(step.c_str(),weight); + } } bool MuonTPSelectionTool::PassIPCuts(const xAOD::TrackParticle* tp, double d0cut, double d0signcut, double z0cut) const{ - // find the PV - const xAOD::VertexContainer* primVertices = 0 ; - const xAOD::Vertex* pv = 0; - if(evtStore()->retrieve(primVertices,"PrimaryVertices").isFailure()){ - ATH_MSG_ERROR("Found no PV candidate for IP computation!"); - } - else { - pv = primVertices->at(0); - } + // find the PV + const xAOD::VertexContainer* primVertices = 0 ; + const xAOD::Vertex* pv = 0; + if(evtStore()->retrieve(primVertices,"PrimaryVertices").isFailure()){ + ATH_MSG_ERROR("Found no PV candidate for IP computation!"); + } + else { + pv = primVertices->at(0); + } - float d0 = 0; - float d0sign = 0; - float z0 = 0; + float d0 = 0; + float d0sign = 0; + float z0 = 0; - d0 = tp->d0(); - float d0err = sqrt(tp->definingParametersCovMatrix()(0,0)); - d0sign = fabs(d0) / (d0err != 0 ? d0err : 1e-9); - z0 = tp->z0(); - if (pv) z0 += tp->vz() - pv->z(); + d0 = tp->d0(); + float d0err = sqrt(tp->definingParametersCovMatrix()(0,0)); + d0sign = fabs(d0) / (d0err != 0 ? d0err : 1e-9); + z0 = tp->z0(); + if (pv) z0 += tp->vz() - pv->z(); - if (d0cut >= 0 && fabs(d0) > d0cut) return false; - if (d0signcut >= 0 && fabs(d0sign) > d0signcut) return false; - if (z0cut >= 0 && fabs(z0) > z0cut) return false; + if (d0cut >= 0 && fabs(d0) > d0cut) return false; + if (d0signcut >= 0 && fabs(d0sign) > d0signcut) return false; + if (z0cut >= 0 && fabs(z0) > z0cut) return false; - return true; + return true; } bool MuonTPSelectionTool::Event_Trigger (void) const{ - // if we are not requesting a trigger, or if the DS has no trigger info, accept the event - ATH_MSG_DEBUG("Have "<<m_trigTool->getListOfTriggers().size() <<" Triggers"); - if (m_tag_Triggers.size() == 0 || m_trigTool->getListOfTriggers().size() == 0) return true; - // otherwise see if one of our triggers is passed. - for (auto trig: m_tag_Triggers){ - ATH_MSG_DEBUG("Test "<<trig <<": \t"<<m_trigTool->isPassed(trig)); - if (m_trigTool->isPassed(trig)) return true; - } - return false; + // if we are not requesting a trigger, or if the DS has no trigger info, accept the event + ATH_MSG_DEBUG("Have "<<m_trigTool->getListOfTriggers().size() <<" Triggers"); + if (m_tag_Triggers.size() == 0 || m_trigTool->getListOfTriggers().size() == 0) return true; + // otherwise see if one of our triggers is passed. + for (auto trig: m_tag_Triggers){ + ATH_MSG_DEBUG("Test "<<trig <<": \t"<<m_trigTool->isPassed(trig)); + if (m_trigTool->isPassed(trig)) return true; + } + return false; } diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPTool.cxx index 66f9c2d29e9..6bde06b4aa1 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPTool.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPTool.cxx @@ -7,16 +7,19 @@ #include "MuonTPTools/IMuonTPSelectionTool.h" #include "MuonTPTools/IMuonTPEfficiencyTool.h" #include "xAODEventInfo/EventInfo.h" -#include "GaudiKernel/ITHistSvc.h" +//#include "GaudiKernel/ITHistSvc.h" //********************************************************************** MuonTPTool::MuonTPTool(std::string myname) : AsgTool(myname), - m_histSvc("THistSvc", myname), - m_muonTPSelectionTools(), - m_muonTPEfficiencyTools(), - m_inefficient_evts(0) +// m_histSvc("THistSvc", myname), + m_muonTPSelectionTools(), + m_muonTPEfficiencyTools(), + m_inefficient_evts(0), + m_evt(-1), + m_run(-1), + m_centeta(false) { declareProperty("MuonTPSelectionTools", m_muonTPSelectionTools); declareProperty("MuonTPEfficiencyTools", m_muonTPEfficiencyTools); @@ -24,7 +27,6 @@ MuonTPTool::MuonTPTool(std::string myname) declareProperty("TreeTools", m_TPTrees); declareProperty("EfficiencyFlag", m_efficiencyFlag = "JPsiTP"); declareProperty("DumpInefficientEvents", m_dump_inefficient = false); - } @@ -43,7 +45,7 @@ StatusCode MuonTPTool::initialize() ATH_CHECK(m_muonTPEfficiencyTools.retrieve()); ATH_CHECK(m_TPPlots.retrieve()); ATH_CHECK(m_TPTrees.retrieve()); - ATH_CHECK(m_histSvc.retrieve()); + //ATH_CHECK(m_histSvc.retrieve()); if (m_dump_inefficient){ @@ -77,7 +79,7 @@ void MuonTPTool::runTagAndProbe(const xAOD::MuonContainer* tags, const xAOD::IPa const xAOD::EventInfo* info = 0; ATH_MSG_DEBUG(""<<evtStore()); - if (evtStore()->retrieve(info).isFailure()){ + if (evtStore()->retrieve(info, "EventInfo").isFailure()){ ATH_MSG_FATAL( "Unable to retrieve Event Info" ); } @@ -98,6 +100,7 @@ void MuonTPTool::runTagAndProbe(const xAOD::MuonContainer* tags, const xAOD::IPa plots->fillCutFlow("Processed Events",1,tpSelTool); plots->fillCutFlow("Processed Events (Weight)",weight,tpSelTool); } + // Select probes ProbeContainer* probeCont = tpSelTool->selectProbes(tags, probes); @@ -107,21 +110,22 @@ void MuonTPTool::runTagAndProbe(const xAOD::MuonContainer* tags, const xAOD::IPa } } - for(auto probe : *probeCont) - { + for(auto probe : *probeCont) { probe->HasSomeTrigger(false); probe->HasSomeTrigger_HLT(false); - } + } - // Loop on TP efficiencies for each selection - for(auto tpEffTool : m_muonTPEfficiencyTools) - { + // Loop on TP efficiencies for each selection + for(auto tpEffTool : m_muonTPEfficiencyTools){ + // do not run 'double' variations + if (!tpEffTool->isNominal() && !tpSelTool->isNominal()) continue; + // Match probes tpEffTool->matchProbes(probeCont, matches); // Fill efficiency histograms for(auto probe : *probeCont) - { + { if (m_dump_inefficient && !probe->isMatched()){ ineff = true; if (fabs(probe->eta()) > 0.1) m_centeta = false; diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPTreeTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPTreeTool.cxx index fad947bc894..00e2fd045e6 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPTreeTool.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTPTreeTool.cxx @@ -10,100 +10,246 @@ */ #include "MuonTPTools/MuonTPTreeTool.h" -#include <vector> +#include "MuonTPTools/MuonTrigTPEfficiencyTool.h" #include <vector> MuonTPTreeTool::MuonTPTreeTool(std::string name) - : AsgTool(name){ - declareProperty("EfficiencyFlag", m_efficiencyFlag = "ZmmTP"); - + : AsgTool(name), + m_trigTool("Trig::TrigDecisionTool/TrigDecisionTool") +{ + // determines tree names + declareProperty("EfficiencyFlag", m_efficiencyFlag = "ZmmTP"); + // record scale factor info used for closure tests of the CP tools + declareProperty("RecordScaleFactorInfo", m_record_SF = false); + declareProperty("TriggerDecisionTool", m_trigTool); } -StatusCode MuonTPTreeTool::RegisterTrees (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools){ +MuonTPTreeTool::~MuonTPTreeTool() {} +StatusCode MuonTPTreeTool::initialize() +{ + ATH_CHECK(m_trigTool.retrieve()); + return StatusCode::SUCCESS; +} - // Create histograms - for(auto tpSelTool : probeTools) { - std::string cfdirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag(); - m_trees[cfdirs] = std::make_pair (new TTree ((std::string("TPTree_")+tpSelTool->efficiencyFlag()).c_str(),"TP"), cfdirs); - for(auto tpEffTool : effTools) { - if (m_match_flags.find(tpEffTool->efficiencyFlag()) == m_match_flags.end()){ - m_match_flags[tpEffTool->efficiencyFlag()] = false; - } - } - InitTree (m_trees[cfdirs].first); +StatusCode MuonTPTreeTool::RegisterTrees (ToolHandleArray<IMuonTPSelectionTool> & probeTools, ToolHandleArray<IMuonTPEfficiencyTool> & effTools) +{ + // Create histograms + for(auto tpSelTool : probeTools) { + if (tpSelTool->isNominal() || tpSelTool->notIncludedInNominal()){ + std::string cfdirs = m_efficiencyFlag+"/"+tpSelTool->efficiencyFlag(); + m_trees[cfdirs] = std::make_pair (new TTree ((std::string("TPTree_")+tpSelTool->efficiencyFlag()).c_str(),"TP"), cfdirs); + + // add tag trigger matching information + std::vector<std::string> tag_triggers = tpSelTool->tagTriggerList(); + for (auto trig : tag_triggers){ + if (m_tag_trigmatch.find(trig) == m_tag_trigmatch.end()){ + m_tag_trigmatch[trig] = false; + } + if (m_tag_trig_dR.find(trig) == m_tag_trig_dR.end()){ + m_tag_trig_dR[trig] = -1; + } + if (m_triggers.find(trig) == m_triggers.end()){ + m_triggers[trig] = false; + } } + + for(auto tpEffTool : effTools) { + if (m_match_flags.find(tpEffTool->efficiencyFlag()) == m_match_flags.end()){ + m_match_flags[tpEffTool->efficiencyFlag()] = false; + } + if (m_scale_factors.find(tpEffTool->efficiencyFlag()) == m_scale_factors.end()){ + m_scale_factors[tpEffTool->efficiencyFlag()] = 1.0; + } + if (tpEffTool->isNominal()){ + if (m_match_dR.find(tpEffTool->efficiencyFlag()) == m_match_dR.end()){ + m_match_dR[tpEffTool->efficiencyFlag()] = -1.0; + } + } + if (tpEffTool->triggerItem()!="" && + m_triggers.find(tpEffTool->triggerItem()) == m_triggers.end()){ + m_triggers[tpEffTool->triggerItem()] = false; + } + } + + InitTree (m_trees[cfdirs].first); + } + } return StatusCode::SUCCESS; } - // fill the histos - void MuonTPTreeTool::fill(Probe& probe,ToolHandle <IMuonTPSelectionTool> sel_tool){ - std::string cfdirs = m_efficiencyFlag+"/"+sel_tool->efficiencyFlag(); - auto tree = m_trees.find(cfdirs); - if (tree == m_trees.end()){ - ATH_MSG_ERROR("Trying to fill a nonexisting tree!"); - return; + +// fill the histos +void MuonTPTreeTool::fill(Probe& probe,ToolHandle <IMuonTPSelectionTool> & sel_tool) +{ + std::string cfdirs = m_efficiencyFlag+"/"+sel_tool->efficiencyFlag(); + auto tree = m_trees.find(cfdirs); + if (tree == m_trees.end()){ + if (sel_tool->isNominal() || sel_tool->notIncludedInNominal()){ + ATH_MSG_ERROR("Trying to fill a nonexisting tree!"); } - TTree* OutTree = tree->second.first; - auto probe_map = m_match_flags_perProbe.find(&probe); - if (probe_map == m_match_flags_perProbe.end()){ - ATH_MSG_WARNING("Found a probe that doesn't have any match info - intentional?"); - for (auto entry: m_match_flags){ - entry.second = false; - } + return; + } + TTree* OutTree = tree->second.first; + auto probe_map = m_match_flags_perProbe.find(&probe); + if (probe_map == m_match_flags_perProbe.end()){ + ATH_MSG_WARNING("Found a probe that doesn't have any match info - intentional?"); + for (auto entry: m_match_flags){ + entry.second = false; } - else { - for (auto entry: m_match_flags){ - m_match_flags[entry.first] = probe_map->second.at(entry.first); - } + } + else { + for (auto entry: m_match_flags){ + // skip double systematics cases + if (probe_map->second.find(entry.first) == probe_map->second.end()) { + m_match_flags[entry.first] = false; + } + else { + m_match_flags[entry.first] = probe_map->second.at(entry.first); + } } - FillCustomStuff(probe); - OutTree->Fill(); + } + auto probe_sf_map = m_scale_factors_perProbe.find(&probe); + if (probe_sf_map == m_scale_factors_perProbe.end()){ + ATH_MSG_WARNING("Found a probe that doesn't have any SF info - intentional?"); + for (auto entry: m_scale_factors){ + entry.second = 1.00; + } + } + else { + for (auto entry: m_scale_factors){ + if (probe_sf_map->second.find(entry.first) == probe_sf_map->second.end()) { + m_scale_factors[entry.first] = 1.; + } + else { + m_scale_factors[entry.first] = probe_sf_map->second.at(entry.first); + } + } + } + auto probe_dR_map = m_match_dR_perProbe.find(&probe); + if (probe_dR_map == m_match_dR_perProbe.end()){ + ATH_MSG_WARNING("Found a probe that doesn't have any dR info - intentional?"); + for (auto entry: m_match_dR){ + entry.second = 1.00; + } + } + else { + for (auto entry: m_match_dR){ + if (probe_dR_map->second.find(entry.first) == probe_dR_map->second.end()) { + m_match_dR[entry.first] = -1.; + } + else { + m_match_dR[entry.first] = probe_dR_map->second.at(entry.first); + } + } + } + FillTriggerInfo(); + FillTagTriggerInfo(probe); + FillCustomStuff(probe); + OutTree->Fill(); - } -void MuonTPTreeTool::FillCustomStuff(Probe & ){ - // do nothing in the default version -} -void MuonTPTreeTool::AddCustomBranches(TTree*){ - // do nothing in the default version - // in 'your' version, do tree->Branch("something",&m_something); in here } +void MuonTPTreeTool::FillTriggerInfo() +{ + for (auto trig : m_triggers) + m_triggers[trig.first] = m_trigTool->isPassed(trig.first); +} -void MuonTPTreeTool::updateMatch(Probe& probe,ToolHandle <IMuonTPEfficiencyTool> eff_tool){ - - if (m_match_flags_perProbe.find(&probe) == m_match_flags_perProbe.end()){ - m_match_flags_perProbe[&probe] = std::map<std::string, bool>() ; +void MuonTPTreeTool::FillTagTriggerInfo(Probe & probe) +{ + const xAOD::Muon* tagmuon = dynamic_cast <const xAOD::Muon*>(&(probe.tagTrack())); + // tag is not a muon: happens for truth probes + if (!tagmuon) return; + for (auto trigstatus : m_tag_trigmatch){ + std::string trigkey = trigstatus.first; + if (tagmuon->isAvailable<bool>(std::string("trigmatch_")+trigkey)){ + m_tag_trigmatch[trigkey] = tagmuon->auxdata<bool>(std::string("trigmatch_")+trigkey); } - m_match_flags_perProbe[&probe][eff_tool->efficiencyFlag()] = probe.isMatched(); - + else{ + ATH_MSG_WARNING("Missing tag trigger matching info for chain "<<trigkey<<"!"); + m_tag_trigmatch[trigkey] = false; + } + } + for (auto trigstatus : m_tag_trig_dR){ + std::string trigkey = trigstatus.first; + if (tagmuon->isAvailable<float>(std::string("trigmatch_dR_")+trigkey)){ + m_tag_trig_dR[trigkey] = tagmuon->auxdata<float>(std::string("trigmatch_dR_")+trigkey); + } + else{ + ATH_MSG_WARNING("Missing tag trigger dR info for chain "<<trigkey<<"!"); + m_tag_trig_dR[trigkey] = -1.; + } + } } -void MuonTPTreeTool::ForgetKnownProbes(void){ - m_match_flags_perProbe.clear(); +void MuonTPTreeTool::FillCustomStuff(Probe & ){ + // do nothing in the default version } - -void MuonTPTreeTool::InitTree(TTree* tree){ - for (auto flag : m_match_flags){ - tree->Branch((std::string("matched_")+flag.first).c_str(), &(m_match_flags[flag.first])); - } - AddCustomBranches(tree); +void MuonTPTreeTool::AddCustomBranches(TTree*){ + // do nothing in the default version + // in 'your' version, do tree->Branch("something",&m_something); in here } - /// retrieve booked trees - std::vector<std::pair<TTree*, std::string> > MuonTPTreeTool::retrieveBookedTrees(){ - std::vector<std::pair<TTree*, std::string> > OutTrees; - for (auto tree: m_trees){ - OutTrees.push_back(tree.second); - } - return OutTrees; +void MuonTPTreeTool::updateMatch(Probe& probe,ToolHandle <IMuonTPEfficiencyTool> & eff_tool) +{ + if (m_match_flags_perProbe.find(&probe) == m_match_flags_perProbe.end()){ + m_match_flags_perProbe[&probe] = std::map<std::string, bool>() ; } + if (m_scale_factors_perProbe.find(&probe) == m_scale_factors_perProbe.end()){ + m_scale_factors_perProbe[&probe] = std::map<std::string, float>() ; + } + if (m_match_dR_perProbe.find(&probe) == m_match_dR_perProbe.end()){ + m_match_dR_perProbe[&probe] = std::map<std::string, float>() ; + } + m_match_flags_perProbe[&probe][eff_tool->efficiencyFlag()] = probe.isMatched(); + m_scale_factors_perProbe[&probe][eff_tool->efficiencyFlag()] = probe.sfweight(); + m_match_dR_perProbe[&probe][eff_tool->efficiencyFlag()] = probe.dr_match(); - MuonTPTreeTool::~MuonTPTreeTool(){ +} +void MuonTPTreeTool::ForgetKnownProbes(void) +{ + m_match_flags_perProbe.clear(); + m_match_dR_perProbe.clear(); + m_scale_factors_perProbe.clear(); +} + +void MuonTPTreeTool::InitTree(TTree* tree) +{ + // fill the match flags + for (auto flag : m_match_flags){ + tree->Branch((std::string("probe_matched_")+flag.first).c_str(), &(m_match_flags[flag.first])); + if (m_record_SF) tree->Branch((std::string("probe_scale_factor_")+flag.first).c_str(), &(m_scale_factors[flag.first])); + } + for (auto flag : m_match_dR){ + tree->Branch((std::string("probe_dRMatch_")+flag.first).c_str(), &(m_match_dR[flag.first])); + } + // also fill in the tag trigger info + for (auto bla : m_tag_trig_dR){ + tree->Branch((std::string("tag_matched_")+bla.first).c_str(),&(m_tag_trigmatch[bla.first])); + tree->Branch((std::string("tag_dRMatch_")+bla.first).c_str(),&(m_tag_trig_dR[bla.first])); } + // add branches for event triggers + for (auto bla : m_triggers) { + tree->Branch(bla.first.c_str(),&(m_triggers[bla.first])); + } + + AddCustomBranches(tree); +} + +/// retrieve booked trees +std::vector<std::pair<TTree*, std::string> > MuonTPTreeTool::retrieveBookedTrees() +{ + std::vector<std::pair<TTree*, std::string> > OutTrees; + for (auto tree: m_trees){ + OutTrees.push_back(tree.second); + } + return OutTrees; +} + diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPEfficiencyTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPEfficiencyTool.cxx index 56e3e09a5a7..42f0d6d4fcc 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPEfficiencyTool.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPEfficiencyTool.cxx @@ -12,11 +12,10 @@ #include "MuonTPTools/MuonTrigTPEfficiencyTool.h" MuonTrigTPEfficiencyTool::MuonTrigTPEfficiencyTool(std::string myname) -: AsgTool(myname), MuonTPEfficiencyTool(myname) +: MuonTPEfficiencyTool(myname) { declareProperty("dR_L1", m_dR_L1 = 0.2); declareProperty("dR_HLT", m_dR_HLT= 0.25); - declareProperty("TrigItem", m_trigger_item=""); } @@ -31,45 +30,61 @@ void MuonTrigTPEfficiencyTool::matchProbes(ProbeContainer* probes, const xAOD::I const xAOD::Muon* matchmuon = dynamic_cast<const xAOD::Muon*>(&(probe->probeTrack())); if (!matchmuon) - { + { ATH_MSG_WARNING("Running trigger efficiency on something that is not a muon!"); continue; } - // Pt Cut - if(matchmuon->pt() < m_matchPtCut) continue; - // Eta Cut + // Pt Cut + if(matchmuon->pt() < m_matchPtCut) continue; + // Eta Cut if(fabs(matchmuon->eta()) > m_matchEtaCut) continue; + + probe->SetCurrentTrigger(m_trigger_item); - probe->SetCurrentTrigger(m_trigger_item); - - // L1 trigger matching - if ( m_trigger_item.find("L1_")!=std::string::npos && m_trigger_item != "L1_AllTriggers") - { - bool trigmatchL1 = m_matchTool->matchL1(matchmuon,m_trigger_item, m_dR_L1); + probe->dr_match(-1.); + // L1 trigger matching + if ( m_trigger_item.find("L1_")==0 && m_trigger_item != "L1_AllTriggers") + { + bool trigmatchL1 = false; + try{ + trigmatchL1 = m_matchTool->matchL1(matchmuon,m_trigger_item, m_maximumDrCut); + } + catch(SG::ExcNoAuxStore){ + ATH_MSG_WARNING("Unable to read trigger info for L1 matching to "<<m_trigger_item); + trigmatchL1 = false; + } probe->isMatched(trigmatchL1); + best_dR_L1 = m_matchTool->minDelRL1(matchmuon,m_trigger_item,10.); + probe->dr_match(best_dR_L1); if(!trigmatchL1) continue; probe->HasSomeTrigger(true); - best_dR_L1 = m_matchTool->minDelRL1(matchmuon,m_trigger_item); probe->dRL1 = best_dR_L1; } - if (m_trigger_item == "L1_AllTriggers") - { + if (m_trigger_item == "L1_AllTriggers"){ probe->isMatched(probe->HasSomeTrigger()); } - // HLT trigger matching - if ( m_trigger_item.find("HLT_")!=std::string::npos && m_trigger_item != "HLT_AllTriggers") - { - bool match_HLT_trig = m_matchTool->match(matchmuon->eta(), matchmuon->phi(), m_trigger_item); + // HLT trigger matching + if ( m_trigger_item.find("HLT_")==0 && m_trigger_item != "HLT_AllTriggers") + { + bool match_HLT_trig = false; + try{ + match_HLT_trig = m_matchTool->match(matchmuon->eta(), matchmuon->phi(), m_trigger_item,m_maximumDrCut); + } + catch(SG::ExcNoAuxStore){ + ATH_MSG_WARNING("Unable to read trigger info for HLT matching to "<<m_trigger_item); + match_HLT_trig = false; + } probe->isMatched(match_HLT_trig); + best_dR_HLT = m_matchTool->minDelR(matchmuon,m_trigger_item,10.); + probe->dr_match(best_dR_HLT); if (!match_HLT_trig) continue; probe->HasSomeTrigger_HLT(true); - best_dR_HLT = m_matchTool->minDelR(matchmuon,m_trigger_item); - probe->dRHLT = best_dR_HLT; + probe->dRHLT = best_dR_HLT; } - if (m_trigger_item == "HLT_AllTriggers") - { + if (m_trigger_item == "HLT_AllTriggers") + { probe->isMatched(probe->HasSomeTrigger_HLT()); } } diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPPlotTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPPlotTool.cxx deleted file mode 100644 index 89788d6d50c..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPPlotTool.cxx +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * MuonTrigTPPlotTool.cxx - * - * Created on: Aug 31, 2014 - * Author: goblirsc / a.m. - */ - -#include "MuonTPTools/MuonTrigTPPlotTool.h" -//#include "MuonPerformanceHistUtils/ZmumuBasicTPEfficiencyPlots.h" -#include "MuonPerformanceHistUtils/MuonTrigTPEfficiencyPlots.h" -//#include "MuonPerformanceHistUtils/ZmumuTagProbeDileptonPlots.h" -#include "MuonPerformanceHistUtils/ZmumuTPEventCutFlowPlots.h" - -MuonTrigTPPlotTool::MuonTrigTPPlotTool(std::string name) - : AsgTool(name),MuonTPPlotTool(name) -{ - declareProperty("doTrkValidPlots", m_do_Valid = false); - declareProperty("doBasicKinematicPlots", m_do_TPBasic = true); - declareProperty("ApplyScaleFactors", m_apply_SF = false); -} - - - -//-------------------------------------------------------------------------------- -std::vector<MuonTPEfficiencyPlotBase*> MuonTrigTPPlotTool::AddPlots(std::string sDir, bool isMatched) -{ - std::vector<MuonTPEfficiencyPlotBase*> out (0); - if (m_do_Valid) out.push_back( new MuonTPEfficiencyPlots( 0, sDir, isMatched)); - if (m_do_TPBasic) out.push_back( new MuonTrigTPEfficiencyPlots(0, sDir, isMatched,m_apply_SF)); - return out; -} - - - -//-------------------------------------------------------------------------------- -std::vector<MuonTPCutFlowBase*> MuonTrigTPPlotTool::AddCutFlowPlots(std::string sDir) -{ - std::vector<MuonTPCutFlowBase*> out (0); - out.push_back (new ZmumuTPEventCutFlowPlots(0,sDir)); - return out; -} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPTreeTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPTreeTool.cxx deleted file mode 100644 index 36cd4f552fc..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/MuonTrigTPTreeTool.cxx +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * MuonTPTrees.cxx - * - * Created on: Aug 31, 2014 - * Author: goblirsc / a.m. - */ - -#include "MuonTPTools/MuonTrigTPTreeTool.h" -#include "xAODEventInfo/EventInfo.h" -#include "xAODTracking/VertexContainer.h" - -MuonTrigTPTreeTool::MuonTrigTPTreeTool(std::string name) - : AsgTool(name),MuonTPTreeTool(name){} - -void MuonTrigTPTreeTool::FillCustomStuff(Probe& probe) -{ - - const xAOD::VertexContainer* primVertices = 0 ; - const xAOD::Vertex* pv = 0; - if(evtStore()->retrieve(primVertices,"PrimaryVertices").isFailure()){ - ATH_MSG_ERROR("Found no PV candidate for IP computation!"); - } - else { - pv = primVertices->at(0); - } - int charge = 0; - // case of a muon probe - charge = -2; - m_ptcone40 = -1; - m_etcone40 = -1; -// const xAOD::VertexContainer* vxc (" - const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(&probe.probeTrack()); - if (muprobe) - { - charge = muprobe->trackParticle(xAOD::Muon::Primary)->charge() ; - bool ok = muprobe->isolation(m_etcone40,xAOD::Iso::topoetcone40); - if (!ok) m_etcone40 = -1; - ok = muprobe->isolation(m_ptcone40,xAOD::Iso::ptcone40); - if (!ok) m_ptcone40 = -1; - if (muprobe->primaryTrackParticle()) - { - m_d0 = muprobe->primaryTrackParticle()->d0(); - m_d0err = sqrt(muprobe->primaryTrackParticle()->definingParametersCovMatrix()(0,0)); - m_z0 = muprobe->primaryTrackParticle()->z0(); - if (pv) - { - m_z0 = m_z0 - pv->z() + muprobe->primaryTrackParticle()->vz(); - } - } - } - // case of an ID probe - const xAOD::TrackParticle* trkprobe = dynamic_cast<const xAOD::TrackParticle*>(&probe.probeTrack()); - if (!muprobe && trkprobe) - { - charge = trkprobe->charge(); - if (trkprobe->isAvailable<float>("TopoEtCone40")) - { - m_etcone40 = trkprobe->auxdataConst<float>("TopoEtCone40"); - } - else - { - m_etcone40 = -1.; - } - if (trkprobe->isAvailable<float>("PtCone40")) - { - m_ptcone40 = trkprobe->auxdataConst<float>("PtCone40"); - } - else - { - m_ptcone40 = -1.; - } - m_d0 = trkprobe->d0(); - m_d0err = sqrt(trkprobe->definingParametersCovMatrix()(0,0)); - m_z0 = trkprobe->z0(); -// const xAOD::Vertex* vx = trkprobe->vertex(); - if (pv){ - m_z0 = m_z0 - pv->z() + trkprobe->vz(); - } - } - - const xAOD::EventInfo* info = 0; - ATH_MSG_DEBUG(""<<evtStore()); - if (evtStore()->retrieve(info).isFailure()) - { - ATH_MSG_FATAL( "Unable to retrieve Event Info" ); - } - static bool isMC = info->eventType(xAOD::EventInfo::IS_SIMULATION); - - m_runNumber = info->runNumber(); - m_eventNumber = info->eventNumber(); - m_mu = info->averageInteractionsPerCrossing(); - m_mcEventWeight = (isMC ? info->mcEventWeight() : 1.00); - m_pt = probe.pt() / 1000.; - m_eta = probe.eta(); - m_phi = probe.phi(); - m_fineEtaPhi = m_fepb.bin(probe.probeTrack().p4()); - m_q = charge; - m_tagPt = probe.tagTrack().pt() / 1000.; - m_tagEta = probe.tagTrack().eta(); - m_tagPhi = probe.tagTrack().phi(); - m_mll = (probe.tagTrack().p4()+probe.probeTrack().p4()).M(); - - -} -void MuonTrigTPTreeTool::AddCustomBranches(TTree* tree) -{ - tree->Branch("runNumber", &m_runNumber); - tree->Branch("eventNumber", &m_eventNumber); - tree->Branch("mu", &m_mu); - tree->Branch("mcEventWeight",&m_mcEventWeight); - tree->Branch("pt", &m_pt); - tree->Branch("eta", &m_eta); - tree->Branch("phi", &m_phi); - tree->Branch("d0", &m_d0); - tree->Branch("d0err", &m_d0err); - tree->Branch("z0", &m_z0); - tree->Branch("ptcone40", &m_ptcone40); - tree->Branch("etcone40", &m_etcone40); - tree->Branch("fineEtaPhi", &m_fineEtaPhi); - tree->Branch("q", &m_q); - tree->Branch("tagPt", &m_tagPt); - tree->Branch("tagEta", &m_tagEta); - tree->Branch("tagPhi", &m_tagPhi); - tree->Branch("mll", &m_mll); -} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPIsolationTreeTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPIsolationTreeTool.cxx deleted file mode 100644 index 8fc015ea54b..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPIsolationTreeTool.cxx +++ /dev/null @@ -1,227 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * MuonTPTrees.cxx - * - * Created on: Aug 31, 2014 - * Author: goblirsc - */ - -#include "MuonTPTools/ZmumuMuonTPIsolationTreeTool.h" -#include "xAODEventInfo/EventInfo.h" -#include "xAODTracking/VertexContainer.h" - -ZmumuMuonTPIsolationTreeTool::ZmumuMuonTPIsolationTreeTool(std::string name) - : AsgTool(name),MuonTPTreeTool(name){ -} - -void ZmumuMuonTPIsolationTreeTool::FillCustomStuff(Probe& probe){ - - const xAOD::VertexContainer* primVertices = 0 ; - const xAOD::Vertex* pv = 0; - if(evtStore()->retrieve(primVertices,"PrimaryVertices").isFailure()){ - ATH_MSG_ERROR("Found no PV candidate for IP computation!"); - } - else { - pv = primVertices->at(0); - } - - m_Npvtx = primVertices->size(); - - m_dPhi = fabs(probe.tagTrack().p4().DeltaPhi(probe.probeTrack().p4())); - - int charge = 0; - // case of a muon probe - charge = -2; -// const xAOD::VertexContainer* vxc (" - const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(&probe.probeTrack()); - if (muprobe) { - charge = muprobe->trackParticle(xAOD::Muon::Primary)->charge() ; - bool ok = muprobe->isolation(m_probeiso_etcone40,xAOD::Iso::topoetcone40); - if (!ok) m_probeiso_etcone40 = -1; - ok = muprobe->isolation(m_probeiso_ptcone40,xAOD::Iso::ptcone40); - if (!ok) m_probeiso_ptcone40 = -1; - ok = muprobe->isolation(m_probeiso_topoetcone40,xAOD::Iso::topoetcone40); - if (!ok) m_probeiso_topoetcone40 = -1; - ok = muprobe->isolation(m_probeiso_ptvarcone40,xAOD::Iso::ptvarcone40); - if (!ok) m_probeiso_ptvarcone40 = -1; - ok = muprobe->isolation(m_probeiso_neflowisol40,xAOD::Iso::neflowisol40); - if (!ok) m_probeiso_neflowisol40 = -1; - - ok = muprobe->isolation(m_probeiso_etcone30,xAOD::Iso::topoetcone30); - if (!ok) m_probeiso_etcone30 = -1; - ok = muprobe->isolation(m_probeiso_ptcone30,xAOD::Iso::ptcone30); - if (!ok) m_probeiso_ptcone30 = -1; - ok = muprobe->isolation(m_probeiso_topoetcone30,xAOD::Iso::topoetcone30); - if (!ok) m_probeiso_topoetcone30 = -1; - ok = muprobe->isolation(m_probeiso_ptvarcone30,xAOD::Iso::ptvarcone30); - if (!ok) m_probeiso_ptvarcone30 = -1; - ok = muprobe->isolation(m_probeiso_neflowisol30,xAOD::Iso::neflowisol30); - if (!ok) m_probeiso_neflowisol30 = -1; - - ok = muprobe->isolation(m_probeiso_etcone20,xAOD::Iso::topoetcone20); - if (!ok) m_probeiso_etcone20 = -1; - ok = muprobe->isolation(m_probeiso_ptcone20,xAOD::Iso::ptcone20); - if (!ok) m_probeiso_ptcone20 = -1; - ok = muprobe->isolation(m_probeiso_topoetcone20,xAOD::Iso::topoetcone20); - if (!ok) m_probeiso_topoetcone20 = -1; - ok = muprobe->isolation(m_probeiso_ptvarcone20,xAOD::Iso::ptvarcone20); - if (!ok) m_probeiso_ptvarcone40 = -1; - ok = muprobe->isolation(m_probeiso_neflowisol20,xAOD::Iso::neflowisol20); - if (!ok) m_probeiso_neflowisol20 = -1; - - if (muprobe->primaryTrackParticle()){ - m_d0 = muprobe->primaryTrackParticle()->d0(); - m_d0err = sqrt(muprobe->primaryTrackParticle()->definingParametersCovMatrix()(0,0)); - m_z0 = muprobe->primaryTrackParticle()->z0(); - if (pv){ - m_z0 = m_z0 - pv->z() + muprobe->primaryTrackParticle()->vz(); - } - } - } - - - const xAOD::Muon* mutag = dynamic_cast<const xAOD::Muon*>(&probe.tagTrack()); - - int charge2 = 0; - charge2 = -2; - - if (mutag) { - charge2 = mutag->trackParticle(xAOD::Muon::Primary)->charge() ; - - bool ok2 = mutag->isolation(m_tagiso_etcone40,xAOD::Iso::topoetcone40); - if (!ok2) m_tagiso_etcone40 = -1; - ok2 = mutag->isolation(m_tagiso_ptcone40,xAOD::Iso::ptcone40); - if (!ok2) m_tagiso_ptcone40 = -1; - ok2 = mutag->isolation(m_tagiso_topoetcone40,xAOD::Iso::topoetcone40); - if (!ok2) m_tagiso_topoetcone40 = -1; - ok2 = mutag->isolation(m_tagiso_ptvarcone40,xAOD::Iso::ptvarcone40); - if (!ok2) m_tagiso_ptvarcone40 = -1; - ok2 = mutag->isolation(m_tagiso_neflowisol40,xAOD::Iso::neflowisol40); - if (!ok2) m_tagiso_neflowisol40 = -1; - - ok2 = mutag->isolation(m_tagiso_etcone30,xAOD::Iso::topoetcone30); - if (!ok2) m_tagiso_etcone30 = -1; - ok2 = mutag->isolation(m_tagiso_ptcone30,xAOD::Iso::ptcone30); - if (!ok2) m_tagiso_ptcone30 = -1; - ok2 = mutag->isolation(m_tagiso_topoetcone30,xAOD::Iso::topoetcone30); - if (!ok2) m_tagiso_topoetcone30 = -1; - ok2 = mutag->isolation(m_tagiso_ptvarcone30,xAOD::Iso::ptvarcone30); - if (!ok2) m_tagiso_ptvarcone30 = -1; - ok2 = mutag->isolation(m_tagiso_neflowisol30,xAOD::Iso::neflowisol30); - if (!ok2) m_tagiso_neflowisol30 = -1; - - ok2 = mutag->isolation(m_tagiso_etcone20,xAOD::Iso::topoetcone20); - if (!ok2) m_tagiso_etcone20 = -1; - ok2 = mutag->isolation(m_tagiso_ptcone20,xAOD::Iso::ptcone20); - if (!ok2) m_tagiso_ptcone20 = -1; - ok2 = mutag->isolation(m_tagiso_topoetcone20,xAOD::Iso::topoetcone20); - if (!ok2) m_tagiso_topoetcone20 = -1; - ok2 = mutag->isolation(m_tagiso_ptvarcone20,xAOD::Iso::ptvarcone20); - if (!ok2) m_tagiso_ptvarcone20 = -1; - ok2 = mutag->isolation(m_tagiso_neflowisol20,xAOD::Iso::neflowisol20); - if (!ok2) m_tagiso_neflowisol20 = -1; - } - - // case of an ID probe - const xAOD::TrackParticle* trkprobe = dynamic_cast<const xAOD::TrackParticle*>(&probe.probeTrack()); - if (!muprobe && trkprobe){ - charge = trkprobe->charge(); - if (trkprobe->isAvailable<float>("TopoEtCone40")){ - m_probeiso_etcone40 = trkprobe->auxdataConst<float>("TopoEtCone40"); - } - else { - m_probeiso_etcone40 = -1.; - } - if (trkprobe->isAvailable<float>("PtCone40")){ - m_probeiso_ptcone40 = trkprobe->auxdataConst<float>("PtCone40"); - } - else { - m_probeiso_ptcone40 = -1.; - } - m_d0 = trkprobe->d0(); - m_d0err = sqrt(trkprobe->definingParametersCovMatrix()(0,0)); - m_z0 = trkprobe->z0(); -// const xAOD::Vertex* vx = trkprobe->vertex(); - if (pv){ - m_z0 = m_z0 - pv->z() + trkprobe->vz(); - } - } - - const xAOD::EventInfo* info = 0; - ATH_MSG_DEBUG(""<<evtStore()); - if (evtStore()->retrieve(info).isFailure()){ - ATH_MSG_FATAL( "Unable to retrieve Event Info" ); - } - static bool isMC = info->eventType(xAOD::EventInfo::IS_SIMULATION); - - m_runNumber = info->runNumber(); - m_eventNumber = info->eventNumber(); - m_mu = info->averageInteractionsPerCrossing(); - m_mcEventWeight = (isMC ? info->mcEventWeight() : 1.00); - m_probePt = probe.pt() / 1000.; - m_probeEta = probe.eta(); - m_probePhi = probe.phi(); - - m_fineEtaPhi = m_fepb.bin(probe.probeTrack().p4()); - m_probe_q = charge; - m_tag_q = charge2; - m_tagPt = probe.tagTrack().pt() / 1000.; - m_tagEta = probe.tagTrack().eta(); - m_tagPhi = probe.tagTrack().phi(); - m_mll = (probe.tagTrack().p4()+probe.probeTrack().p4()).M(); - - -} -void ZmumuMuonTPIsolationTreeTool::AddCustomBranches(TTree* tree){ - - tree->Branch("runNumber",&m_runNumber); - tree->Branch("eventNumber",&m_eventNumber); - tree->Branch("mu",&m_mu); - tree->Branch("mcEventWeight",&m_mcEventWeight); - tree->Branch("tag_pt",&m_tagPt); - tree->Branch("tag_eta",&m_tagEta); - tree->Branch("tag_phi",&m_tagPhi); - tree->Branch("tagiso_neflowisol20",&m_tagiso_neflowisol20); - tree->Branch("tagiso_topoetcone20",&m_tagiso_topoetcone20); - tree->Branch("tagiso_etcone20",&m_tagiso_etcone20); - tree->Branch("tagiso_ptcone20",&m_tagiso_ptcone20); - tree->Branch("tagiso_ptvarcone20",&m_tagiso_ptvarcone20); - tree->Branch("tagiso_neflowisol30",&m_tagiso_neflowisol30); - tree->Branch("tagiso_topoetcone30",&m_tagiso_topoetcone30); - tree->Branch("tagiso_etcone30",&m_tagiso_etcone30); - tree->Branch("tagiso_ptcone30",&m_tagiso_ptcone30); - tree->Branch("tagiso_ptvarcone30",&m_tagiso_ptvarcone30); - tree->Branch("tagiso_neflowisol40",&m_tagiso_neflowisol40); - tree->Branch("tagiso_topoetcone40",&m_tagiso_topoetcone40); - tree->Branch("tagiso_etcone40",&m_tagiso_etcone40); - tree->Branch("tagiso_ptcone40",&m_tagiso_ptcone40); - tree->Branch("tagiso_ptvarcone40",&m_tagiso_ptvarcone40); - tree->Branch("probe_pt",&m_probePt); - tree->Branch("probe_eta",&m_probeEta); - tree->Branch("probe_phi",&m_probePhi); - tree->Branch("probeiso_neflowisol20",&m_probeiso_neflowisol20); - tree->Branch("probeiso_topoetcone20",&m_probeiso_topoetcone20); - tree->Branch("probeiso_etcone20",&m_probeiso_etcone20); - tree->Branch("probeiso_ptcone20",&m_probeiso_ptcone20); - tree->Branch("probeiso_ptvarcone20",&m_probeiso_ptvarcone20); - tree->Branch("probeiso_neflowisol30",&m_probeiso_neflowisol30); - tree->Branch("probeiso_topoetcone30",&m_probeiso_topoetcone30); - tree->Branch("probeiso_etcone30",&m_probeiso_etcone30); - tree->Branch("probeiso_ptcone30",&m_probeiso_ptcone30); - tree->Branch("probeiso_ptvarcone30",&m_probeiso_ptvarcone30); - tree->Branch("probeiso_neflowisol40",&m_probeiso_neflowisol40); - tree->Branch("probeiso_topoetcone40",&m_probeiso_topoetcone40); - tree->Branch("probeiso_etcone40",&m_probeiso_etcone40); - tree->Branch("probeiso_ptcone40",&m_probeiso_ptcone40); - tree->Branch("probeiso_ptvarcone40",&m_probeiso_ptvarcone40); - tree->Branch("d0",&m_d0); - tree->Branch("d0err",&m_d0err); - tree->Branch("z0",&m_z0); - tree->Branch("fineEtaPhi",&m_fineEtaPhi); - tree->Branch("tag_q",&m_tag_q); - tree->Branch("probe_q",&m_probe_q); - tree->Branch("mll",&m_mll); -} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPPlotTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPPlotTool.cxx deleted file mode 100644 index 4776eb2bcd2..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPPlotTool.cxx +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * MuonTPPlots.cxx - * - * Created on: Aug 31, 2014 - * Author: goblirsc - */ - -#include "MuonTPTools/ZmumuMuonTPPlotTool.h" -#include "MuonPerformanceHistUtils/ZmumuBasicTPEfficiencyPlots.h" -#include "MuonPerformanceHistUtils/ZmumuTagProbeDileptonPlots.h" -#include "MuonPerformanceHistUtils/ZmumuFineEtaPhiEfficiencyPlots.h" -#include "MuonPerformanceHistUtils/ZmumuTPEventCutFlowPlots.h" -#include "MuonPerformanceHistUtils/ZmumuDetRegionEfficiencyPlots.h" - -ZmumuMuonTPPlotTool::ZmumuMuonTPPlotTool(std::string name) - : AsgTool(name),MuonTPPlotTool(name){ - declareProperty("doTrkValidPlots",m_do_Valid=false); - declareProperty("doBasicKinematicPlots",m_do_TPBasic=true); - declareProperty("doDileptonPlots",m_do_DiLepton=true); - declareProperty("doFineEtaPhiPlots",m_do_TPFineEtaPhi=false); - declareProperty("doDetectorRegionPlots",m_do_DetRegions=false); - declareProperty("ApplyScaleFactors",m_apply_SF=false); -} - -std::vector<MuonTPEfficiencyPlotBase*> ZmumuMuonTPPlotTool::AddPlots(std::string sDir, bool isMatched){ - - std::vector<MuonTPEfficiencyPlotBase*> out (0); - if (m_do_Valid) out.push_back( new MuonTPEfficiencyPlots(0, sDir, isMatched)); - if (m_do_TPBasic) out.push_back( new ZmumuBasicTPEfficiencyPlots(0, sDir, isMatched,m_apply_SF)); - if (m_do_TPFineEtaPhi) out.push_back( new ZmumuFineEtaPhiEfficiencyPlots(0, sDir, isMatched,m_apply_SF)); - if (m_do_DiLepton) out.push_back( new ZmumuTagProbeDileptonPlots(0, sDir, isMatched,m_apply_SF)); - if (m_do_DetRegions) out.push_back(new ZmumuDetRegionEfficiencyPlots(0,sDir,isMatched,m_apply_SF)); - return out; - -} - -std::vector<MuonTPCutFlowBase*> ZmumuMuonTPPlotTool::AddCutFlowPlots(std::string sDir){ - - std::vector<MuonTPCutFlowBase*> out (0); - out.push_back (new ZmumuTPEventCutFlowPlots(0,sDir)); - return out; - -} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPTreeTool.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPTreeTool.cxx deleted file mode 100644 index ef6785c6a21..00000000000 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/Root/ZmumuMuonTPTreeTool.cxx +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - * MuonTPTrees.cxx - * - * Created on: Aug 31, 2014 - * Author: goblirsc - */ - -#include "MuonTPTools/ZmumuMuonTPTreeTool.h" -#include "xAODEventInfo/EventInfo.h" -#include "xAODTracking/VertexContainer.h" -#include "xAODTracking/Vertex.h" -#include "xAODTruth/TruthParticle.h" - -ZmumuMuonTPTreeTool::ZmumuMuonTPTreeTool(std::string name) - : AsgTool(name),MuonTPTreeTool(name){ -} - -void ZmumuMuonTPTreeTool::FillCustomStuff(Probe& probe){ - - const xAOD::VertexContainer* primVertices = 0 ; - const xAOD::Vertex* pv = 0; - if(evtStore()->retrieve(primVertices,"PrimaryVertices").isFailure()){ - ATH_MSG_ERROR("Found no PV candidate for IP computation!"); - } - else { - pv = primVertices->at(0); - } - m_PV_n=0; - for (auto vx: *primVertices){ - if (vx->vertexType() == xAOD::VxType::PriVtx || vx->vertexType() == xAOD::VxType::PileUp) ++m_PV_n; - } - int charge = 0; - // case of a muon probe - charge = -2; - m_ptcone40 = -1; - m_etcone40 = -1; -// const xAOD::VertexContainer* vxc (" - const xAOD::Muon* muprobe = dynamic_cast<const xAOD::Muon*>(&probe.probeTrack()); - if (muprobe) { - charge = muprobe->trackParticle(xAOD::Muon::Primary)->charge() ; - bool ok = muprobe->isolation(m_etcone40,xAOD::Iso::topoetcone40); - if (!ok) m_etcone40 = -1; - ok = muprobe->isolation(m_ptcone40,xAOD::Iso::ptcone40); - if (!ok) m_ptcone40 = -1; - if (muprobe->primaryTrackParticle()){ - m_d0 = muprobe->primaryTrackParticle()->d0(); - m_d0err = sqrt(muprobe->primaryTrackParticle()->definingParametersCovMatrix()(0,0)); - m_z0 = muprobe->primaryTrackParticle()->z0(); - if (pv){ - m_z0 = m_z0 - pv->z() + muprobe->primaryTrackParticle()->vz(); - } - muprobe->primaryTrackParticle()->summaryValue(m_nBL, xAOD::numberOfBLayerHits); - muprobe->primaryTrackParticle()->summaryValue(m_nPIX, xAOD::numberOfPixelHits); - muprobe->primaryTrackParticle()->summaryValue(m_nPIXholes, xAOD::numberOfPixelHoles); - muprobe->primaryTrackParticle()->summaryValue(m_nPIXdead, xAOD::numberOfPixelDeadSensors); - muprobe->primaryTrackParticle()->summaryValue(m_nSCT, xAOD::numberOfSCTHits ); - muprobe->primaryTrackParticle()->summaryValue(m_nSCTholes, xAOD::numberOfSCTHoles ); - muprobe->primaryTrackParticle()->summaryValue(m_nSCTdead, xAOD::numberOfSCTDeadSensors ); - muprobe->primaryTrackParticle()->summaryValue(m_nTRT, xAOD::numberOfTRTHits ); - muprobe->primaryTrackParticle()->summaryValue(m_nTRTout, xAOD::numberOfTRTOutliers ); - } - } - // case of an ID probe - const xAOD::TrackParticle* trkprobe = dynamic_cast<const xAOD::TrackParticle*>(&probe.probeTrack()); - if (!muprobe && trkprobe){ - charge = trkprobe->charge(); - if (trkprobe->isAvailable<float>("MUON1_topoetcone40")){ - m_etcone40 = trkprobe->auxdataConst<float>("MUON1_topoetcone40"); - } - else { - m_etcone40 = -1.; - } - if (trkprobe->isAvailable<float>("MUON1_ptcone40")){ - m_ptcone40 = trkprobe->auxdataConst<float>("MUON1_ptcone40"); - } - else { - m_ptcone40 = -1.; - } - m_d0 = trkprobe->d0(); - m_d0err = sqrt(trkprobe->definingParametersCovMatrix()(0,0)); - m_z0 = trkprobe->z0(); -// const xAOD::Vertex* vx = trkprobe->vertex(); - if (pv){ - m_z0 = m_z0 - pv->z() + trkprobe->vz(); - } - trkprobe->summaryValue(m_nBL, xAOD::numberOfBLayerHits); - trkprobe->summaryValue(m_nPIX, xAOD::numberOfPixelHits); - trkprobe->summaryValue(m_nPIXholes, xAOD::numberOfPixelHoles); - trkprobe->summaryValue(m_nPIXdead, xAOD::numberOfPixelDeadSensors); - trkprobe->summaryValue(m_nSCT, xAOD::numberOfSCTHits ); - trkprobe->summaryValue(m_nSCTholes, xAOD::numberOfSCTHoles ); - trkprobe->summaryValue(m_nSCTdead, xAOD::numberOfSCTDeadSensors ); - trkprobe->summaryValue(m_nTRT, xAOD::numberOfTRTHits ); - trkprobe->summaryValue(m_nTRTout, xAOD::numberOfTRTOutliers ); - } - // case of an truth probe: rely on the sign of the pdg ID - const xAOD::TruthParticle* truthtrk = dynamic_cast<const xAOD::TruthParticle*>(&probe.probeTrack()); - if (truthtrk) { - if (truthtrk->charge() > 0) charge = 1.0; - if (truthtrk->charge() < 0) charge = -1.0; - } - - const xAOD::EventInfo* info = 0; - ATH_MSG_DEBUG(""<<evtStore()); - if (evtStore()->retrieve(info).isFailure()){ - ATH_MSG_FATAL( "Unable to retrieve Event Info" ); - } - static bool isMC = info->eventType(xAOD::EventInfo::IS_SIMULATION); - - m_runNumber = info->runNumber(); - m_eventNumber = info->eventNumber(); - m_mu = info->averageInteractionsPerCrossing(); - m_mcEventWeight = (isMC ? info->mcEventWeight() : 1.00); - m_pt = probe.pt() / 1000.; - m_eta = probe.eta(); - m_phi = probe.phi(); - m_fineEtaPhi = m_fepb.bin(probe.probeTrack().p4()); - m_detregion = m_epb.symmetricBin(probe.probeTrack().p4()); - m_q = charge; - m_tagPt = probe.tagTrack().pt() / 1000.; - m_tagEta = probe.tagTrack().eta(); - m_tagPhi = probe.tagTrack().phi(); - m_mll = (probe.tagTrack().p4()+probe.probeTrack().p4()).M(); - - -} -void ZmumuMuonTPTreeTool::AddCustomBranches(TTree* tree){ - - tree->Branch("runNumber",&m_runNumber); - tree->Branch("eventNumber",&m_eventNumber); - tree->Branch("mu",&m_mu); - tree->Branch("mcEventWeight",&m_mcEventWeight); - tree->Branch("pt",&m_pt); - tree->Branch("eta",&m_eta); - tree->Branch("phi",&m_phi); - tree->Branch("d0",&m_d0); - tree->Branch("d0err",&m_d0err); - tree->Branch("z0",&m_z0); - tree->Branch("ptcone40",&m_ptcone40); - tree->Branch("etcone40",&m_etcone40); - tree->Branch("fineEtaPhi",&m_fineEtaPhi); - tree->Branch("detRegion",&m_detregion); - tree->Branch("q",&m_q); - tree->Branch("tagPt",&m_tagPt); - tree->Branch("tagEta",&m_tagEta); - tree->Branch("tagPhi",&m_tagPhi); - tree->Branch("mll",&m_mll); - tree->Branch("PV_n",&m_PV_n); - - tree->Branch("nBL",&m_nBL); - tree->Branch("nPIX",&m_nPIX); - tree->Branch("nSCT",&m_nSCT); - tree->Branch("nPIXdead",&m_nPIXdead); - tree->Branch("nSCTdead",&m_nSCTdead); - tree->Branch("nSCTholes",&m_nSCTholes); - tree->Branch("nPIXholes",&m_nPIXholes); - tree->Branch("nTRT",&m_nTRT); - tree->Branch("nTRTout",&m_nTRTout); - -} diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/cmt/Makefile.RootCore b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/cmt/Makefile.RootCore index 9662d437040..e03bf3ccedf 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/cmt/Makefile.RootCore +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/cmt/Makefile.RootCore @@ -12,7 +12,7 @@ PACKAGE_OBJFLAGS = -DASGTOOL_STANDALONE -DASGTOOL_NOTEVENT PACKAGE_LDFLAGS = PACKAGE_BINFLAGS = PACKAGE_LIBFLAGS = -PACKAGE_DEP = AsgTools +PACKAGE_DEP = AsgTools xAODBase xAODMuon xAODTruth MuonPerformanceHistUtils MuonEfficiencyCorrections MuonSelectorTools TrigMuonMatching TrigDecisionTool ElectronIsolationSelection TrigConfL1Data TrigDecisionInterface TrigConfxAOD GoodRunsLists PACKAGE_TRYDEP = PACKAGE_CLEAN = PACKAGE_NOGRID = diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/cmt/requirements b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/cmt/requirements index 46c35675ee3..3813162c20f 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/cmt/requirements +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/cmt/requirements @@ -7,20 +7,25 @@ public use AtlasPolicy AtlasPolicy-* use AsgTools AsgTools-* Control/AthToolSupport use xAODMuon xAODMuon-* Event/xAOD -use xAODTruth xAODTruth-* Event/xAOD use xAODBase xAODBase-* Event/xAOD use MuonPerformanceHistUtils MuonPerformanceHistUtils-* PhysicsAnalysis/MuonID/MuonPerformanceAnalysis use MuonEfficiencyCorrections MuonEfficiencyCorrections-* PhysicsAnalysis/MuonID/MuonIDAnalysis use MuonSelectorTools MuonSelectorTools-* PhysicsAnalysis/MuonID use TrigDecisionTool TrigDecisionTool-* Trigger/TrigAnalysis -use TrigMuonMatching TrigMuonMatching-* Trigger/TrigAnalysis +use TrigMuonMatching TrigMuonMatching-* Trigger/TrigAnalysis use AtlasROOT AtlasROOT-* External -use_ifndef pplist="XAOD_ANALYSIS" pkg="Reconstruction/RecoTools/RecoToolInterfaces" +use GoodRunsLists GoodRunsLists-* DataQuality +# Put this back in once available +## use IsolationSelection IsolationSelection-* PhysicsAnalysis/AnalysisCommon private use GaudiInterface GaudiInterface-* External use xAODEventInfo xAODEventInfo-* Event/xAOD -use xAODTracking xAODTracking-* Event/xAOD +use xAODEventShape xAODEventShape-* Event/xAOD +use xAODTracking xAODTracking-* Event/xAOD +use xAODJet xAODJet-* Event/xAOD +use xAODTruth xAODTruth-* Event/xAOD +use MCTruthClassifier MCTruthClassifier-* PhysicsAnalysis end_private public diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/CreateSF.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/CreateSF.py new file mode 100644 index 00000000000..4b22eaf687a --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/CreateSF.py @@ -0,0 +1,266 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +import Histos +import Utils +import ROOT +import DSConfig +import Utils +from Defs import * +ROOT.gROOT.Macro("rootlogon.C") +ROOT.gROOT.SetStyle("ATLAS") +ROOT.gROOT.SetBatch(1) +from array import array +from PlotUtils import PlotUtils + +hists_final = [] + +# this creates a 3d binning, with x = fineetaphi, y = pt (constant), z = charge (based on posq and negq histos) +def build_3d_composite(period, raw_posq, raw_negq, jpsibins_low, jpsibins_up, jpsisys=[], isMC=False): + + bins_for_hist = [abin for abin in jpsibins_low+[jpsibins_up[-1]]] + nptbins = len(bins_for_hist)-1 + ptbins = array('d',bins_for_hist) + + fineetaphibins = [] + for i in range(1,raw_posq.GetNbinsX()+1): + fineetaphibins.append(raw_posq.GetXaxis().GetBinLowEdge(i)) + fineetaphibins.append(raw_posq.GetXaxis().GetBinUpEdge(raw_posq.GetNbinsX())) + fineetaphibins = array('d',fineetaphibins) + + qbins = [-2.,0.,2.] + nqbins = len(qbins)-1 + qbins = array('d',qbins) + + mcNaming = "" + if isMC: + mcNaming = "_MC" + # then create the histo + if len(jpsisys)>0: + histoname = "%s_sys_3dized_%s%s"%(raw_posq.GetName(),period,mcNaming) + else: + histoname = "%s_3dized_%s%s"%(raw_posq.GetName(),period,mcNaming) + h3d = ROOT.TH3F(histoname,raw_posq.GetTitle(),raw_posq.GetNbinsX(),fineetaphibins,nptbins,ptbins,nqbins,qbins) + + # and fill it! + if len(jpsisys)>0: + for t in range(1,h3d.GetNbinsX()+1): + sys_p = raw_posq.GetBinContent(t) + sys_n = raw_negq.GetBinContent(t) + for u in range(1,h3d.GetNbinsY()+1): + h3d.SetBinContent(t,u,h3d.GetZaxis().FindBin(-1.),ROOT.sqrt(sys_n*sys_n+ROOT.pow(jpsisys[u-1],2))) + h3d.SetBinError(t,u,h3d.GetZaxis().FindBin(-1.),ROOT.sqrt(sys_n*sys_n+ROOT.pow(jpsisys[u-1],2))) + h3d.SetBinContent(t,u,h3d.GetZaxis().FindBin(1.),ROOT.sqrt(sys_p*sys_p+ROOT.pow(jpsisys[u-1],2))) + h3d.SetBinError(t,u,h3d.GetZaxis().FindBin(1.),ROOT.sqrt(sys_p*sys_p+ROOT.pow(jpsisys[u-1],2))) + + else: + for t in range(1,h3d.GetNbinsX()+1): + val_p = raw_posq.GetBinContent(t) + err_p = raw_posq.GetBinError(t) + val_n = raw_negq.GetBinContent(t) + err_n = raw_negq.GetBinError(t) + for u in range(1,h3d.GetNbinsY()+1): + h3d.SetBinContent(t,u,h3d.GetZaxis().FindBin(-1.),val_n) + h3d.SetBinError(t,u,h3d.GetZaxis().FindBin(-1.),err_n) + h3d.SetBinContent(t,u,h3d.GetZaxis().FindBin(1.),val_p) + h3d.SetBinError(t,u,h3d.GetZaxis().FindBin(1.),err_p) + + return h3d + + + +def createPeriod (outfile,period,probe,match,Data,MC): + + ptlow = [0., 4.5, 7., 10., 15.] + ptup = [4.5, 7., 10., 15., 1e15] + jpsisys = [0.06, 0.015, 0.005, 0.0025, 0.00] + + # for pre-recommendations, copy negative eta bins of transition region to positive ones (use doPreRecEtaCopy=True): + testpos = Histos.TPFinalSysHistos("testpos",probe,match,DetRegions.All,"fineEtaPhi",infiles=[["MC",MC],["Data",Data]],charge="pos",corr = True,doPreRecEtaCopy=False,useAsymEff=True).HistoSets + testneg = Histos.TPFinalSysHistos("testneg",probe,match,DetRegions.All,"fineEtaPhi",infiles=[["MC",MC],["Data",Data]],charge="neg",corr = True,doPreRecEtaCopy=False,useAsymEff=True).HistoSets + + # fill data and MC efficiency and SF + h_data_eff_p = testpos["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency] + h_mc_eff_p = testpos["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] + h_sf_p = testpos["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF] + + data_eff_sys_1D_p = testpos[Systematics.All][0] + mc_eff_sys_1D_p = testpos[Systematics.All][1] + sf_sys_1D_p = testpos[Systematics.All][2] + + h_data_eff_n = testneg["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency] + h_mc_eff_n = testneg["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] + h_sf_n = testneg["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF] + + data_eff_sys_1D_n = testneg[Systematics.All][0] + mc_eff_sys_1D_n = testneg[Systematics.All][1] + sf_sys_1D_n = testneg[Systematics.All][2] + + # convert TGraphAsymmErrors to TH1 for scale factor files + if h_data_eff_p.InheritsFrom("TGraphAsymmErrors"): + h_data_eff_p = Utils.ConvertTGraphAsymmErrors(h_data_eff_p) + h_mc_eff_p = Utils.ConvertTGraphAsymmErrors(h_mc_eff_p) + h_sf_p = Utils.ConvertTGraphAsymmErrors(h_sf_p) + data_eff_sys_1D_p = Utils.ConvertTGraphAsymmErrors(data_eff_sys_1D_p) + mc_eff_sys_1D_p = Utils.ConvertTGraphAsymmErrors(mc_eff_sys_1D_p) + sf_sys_1D_p = Utils.ConvertTGraphAsymmErrors(sf_sys_1D_p) + if h_data_eff_n.InheritsFrom("TGraphAsymmErrors"): + h_data_eff_n = Utils.ConvertTGraphAsymmErrors(h_data_eff_n) + h_mc_eff_n = Utils.ConvertTGraphAsymmErrors(h_mc_eff_n) + h_sf_n = Utils.ConvertTGraphAsymmErrors(h_sf_n) + data_eff_sys_1D_n = Utils.ConvertTGraphAsymmErrors(data_eff_sys_1D_n) + mc_eff_sys_1D_n = Utils.ConvertTGraphAsymmErrors(mc_eff_sys_1D_n) + sf_sys_1D_n = Utils.ConvertTGraphAsymmErrors(sf_sys_1D_n) + + + data_eff_3d = build_3d_composite(period, h_data_eff_p, h_data_eff_n, ptlow, ptup) + mc_eff_3d = build_3d_composite(period, h_mc_eff_p, h_mc_eff_n, ptlow, ptup, isMC=True) + sf_3d = build_3d_composite(period, h_sf_p, h_sf_n, ptlow, ptup) + data_eff_sys_3d = build_3d_composite(period, data_eff_sys_1D_p, data_eff_sys_1D_n, ptlow, ptup, jpsisys) + mc_eff_sys_3d = build_3d_composite(period, mc_eff_sys_1D_p, mc_eff_sys_1D_n, ptlow, ptup, jpsisys, isMC=True) + sf_sys_3d = build_3d_composite(period, sf_sys_1D_p, sf_sys_1D_n, ptlow, ptup, jpsisys) + + # the systematics tool provides relative errors, so multiply + data_eff_sys_3d.Multiply(data_eff_3d) + mc_eff_sys_3d.Multiply(mc_eff_3d) + sf_sys_3d.Multiply(sf_3d) + + # assign axis names that the SF tool knows how to interpret + data_eff_3d.GetXaxis().SetTitle("fine etaphi bin") + data_eff_3d.GetYaxis().SetTitle("p_{T} [GeV]") + data_eff_3d.GetZaxis().SetTitle("charge") + + mc_eff_3d.GetXaxis().SetTitle("fine etaphi bin") + mc_eff_3d.GetYaxis().SetTitle("p_{T} [GeV]") + mc_eff_3d.GetZaxis().SetTitle("charge") + + sf_3d.GetXaxis().SetTitle("fine etaphi bin") + sf_3d.GetYaxis().SetTitle("p_{T} [GeV]") + sf_3d.GetZaxis().SetTitle("charge") + + data_eff_sys_3d.GetXaxis().SetTitle("fine etaphi bin") + data_eff_sys_3d.GetYaxis().SetTitle("p_{T} [GeV]") + data_eff_sys_3d.GetZaxis().SetTitle("charge") + + mc_eff_sys_3d.GetXaxis().SetTitle("fine etaphi bin") + mc_eff_sys_3d.GetYaxis().SetTitle("p_{T} [GeV]") + mc_eff_sys_3d.GetZaxis().SetTitle("charge") + + sf_sys_3d.GetXaxis().SetTitle("fine etaphi bin") + sf_sys_3d.GetYaxis().SetTitle("p_{T} [GeV]") + sf_sys_3d.GetZaxis().SetTitle("charge") + + outfile.WriteTObject(data_eff_3d,"Eff_%s"%(period)) + outfile.WriteTObject(mc_eff_3d,"MC_Eff_%s"%(period)) + outfile.WriteTObject(sf_3d,"SF_%s"%(period)) + outfile.WriteTObject(data_eff_sys_3d,"Eff_sys_%s"%(period)) + outfile.WriteTObject(mc_eff_sys_3d,"MC_Eff_sys_%s"%(period)) + outfile.WriteTObject(sf_sys_3d,"SF_sys_%s"%(period)) + +def createCTPeriod (outfile,period,probe,Data,MC): + + test = Histos.TPFinalSysHistos("test",probe,Matches.Calo,DetRegions.All,"CaloTag2D",infiles=[["MC",MC],["Data",Data]],charge=None,corr = True).HistoSets + + # fill data and MC efficiency and SF + h_data_eff = test["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency] + h_mc_eff = test["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] + h_sf = test["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF] + + data_eff_sys_2D = test[Systematics.All][0] + mc_eff_sys_2D = test[Systematics.All][1] + sf_sys_2D = test[Systematics.All][2] + + # do not need to convert TGraphAsymmErrors to TH1 for scale factor files since CaloTag2D is 2D and thus not using TGraphAsymmErrors + + # the systematics tool provides relative errors, so multiply + data_eff_sys_2D.Multiply(h_data_eff) + mc_eff_sys_2D.Multiply(h_mc_eff) + sf_sys_2D.Multiply(h_sf) + + # assign axis names that the SF tool knows how to interpret + h_data_eff.GetXaxis().SetTitle("#eta") + h_data_eff.GetYaxis().SetTitle("p_{T} [GeV]") + + h_mc_eff.GetXaxis().SetTitle("#eta") + h_mc_eff.GetYaxis().SetTitle("p_{T} [GeV]") + + h_sf.GetXaxis().SetTitle("#eta") + h_sf.GetYaxis().SetTitle("p_{T} [GeV]") + + data_eff_sys_2D.GetXaxis().SetTitle("#eta") + data_eff_sys_2D.GetYaxis().SetTitle("p_{T} [GeV]") + mc_eff_sys_2D.GetXaxis().SetTitle("#eta") + mc_eff_sys_2D.GetYaxis().SetTitle("p_{T} [GeV]") + sf_sys_2D.GetXaxis().SetTitle("#eta") + sf_sys_2D.GetYaxis().SetTitle("p_{T} [GeV]") + + outfile.WriteTObject(h_data_eff,"Eff_%s"%(period)) + outfile.WriteTObject(h_mc_eff,"MC_Eff_%s"%(period)) + outfile.WriteTObject(h_sf,"SF_%s"%(period)) + outfile.WriteTObject(data_eff_sys_2D,"Eff_sys_%s"%(period)) + outfile.WriteTObject(mc_eff_sys_2D,"MC_Eff_sys_%s"%(period)) + outfile.WriteTObject(sf_sys_2D,"SF_sys_%s"%(period)) + + + +if __name__ == "__main__": + + # -------------------------- + # In principle all you have to setup is defined here + # -------------------------- + # MC input file + InputZmumu = DSConfig.Zmumu_mc15 + + TypesToRun = [ + ["Medium",Probes.Calo, Matches.Medium], + ["Tight",Probes.Calo, Matches.Tight], + ["Loose",Probes.Calo, Matches.LooseNoCalo], + ["Calo",Probes.MStoMu, Matches.Calo], + ] + + periods = [ + ["All",20322.,DSConfig.Data_periodB] + ] + + # name of the overall period the SF file is about + filePeriod = "2015" + ## -------------------------- + + + for Type in TypesToRun: + + muonTypeName = Type[0] + Probe = Type[1] + Match = Type[2] + if Match == Matches.Calo: + ofile = ROOT.TFile("CaloTag_%s_SF.root"%(filePeriod),"RECREATE") + else: + ofile = ROOT.TFile("MuonsChain_%s_%s_SF.root"%(muonTypeName,filePeriod),"RECREATE") + + ofile.cd() + + # Create luminosity tree + LumiDataTree = ROOT.TTree('LumiData','Lumi Data') + + # Create branches in the tree + period = ROOT.std.string("init") + LumiDataTree.Branch("Period",period) + lumi = array( 'f', [0] * len(periods) ) + LumiDataTree.Branch( 'IntLumi', lumi, 'IntLumi/F' ) + + for p in periods: + period = ROOT.std.string(p[0]) + lumi[0] = p[1] + LumiDataTree.SetBranchAddress("Period",period) + LumiDataTree.Fill() + + DataInput = p[2] + # get the actual histograms per perdiod/runNumber + if Match == Matches.Calo: + createCTPeriod(outfile=ofile,period=period,probe=Probe,Data=DataInput,MC=InputZmumu) + else: + createPeriod(outfile=ofile,period=period,probe=Probe,match=Match,Data=DataInput,MC=InputZmumu) + + + ofile.WriteTObject(LumiDataTree) + ofile.Close() + diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/DSConfig.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/DSConfig.py new file mode 100644 index 00000000000..e7ab7fdb0c4 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/DSConfig.py @@ -0,0 +1,23 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + + +import ROOT +# utility class for DS meta info +class DSconfig: + def __init__(self,lumi=20300.,XS=1.,nEvents=-1,colour=None,label="",filepath=""): + self.Lumi = lumi + self.Colour=colour + self.Label = label + self.Filepath = filepath + self.XS = XS + self.nEvents = nEvents + + +Data_periodB = DSconfig(lumi=3900.,XS=1.,nEvents=-1,colour=ROOT.kBlack,label="Data",filepath="/ptmp/mpp/niko/MCP/GridOutput/150520/data12_8TeV.physics_Muons.periodB.root") + + +Data_15_firstWeek = DSconfig(lumi=0.220,XS=1.,nEvents=-1,colour=ROOT.kBlack,label="Data 2015",filepath="/ptmp/mpp/goblirsc/MCP2014/GridOut/2015-06-09-Data15_v1b/Data15.root") + + +# mc15_13TeV.361107.PowhegPythia8EvtGen_AZNLOCTEQ6L1_Zmumu.e3601_r6633_r6264 +Zmumu_mc15 = DSconfig(Data_periodB.Lumi,XS=1100.,nEvents=3294358,colour=ROOT.kRed,label="Z#rightarrow#mu#mu MC15",filepath="/afs/ipp-garching.mpg.de/home/g/goblirsc/analysis/TP_Rearrangement/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonPerformanceAlgs/share/muontp.root") diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Defs.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Defs.py new file mode 100644 index 00000000000..6a26657c3ea --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Defs.py @@ -0,0 +1,79 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +# definitions for the offline Zmumu analysis +import ROOT, math +import HistoDefs + +class Analysis: + Z_Reco = "ZmumuTPReco" + Z_Isol = "ZmumuTPIsol" + Z_Trig = "ZmumuTPTrig" + JP_Reco = "JPsiTPReco" + JP_Isol = "JPsiTPIsol" + JP_Trig = "JPsiTPTrig" + + +class ChargeProducts: + OC="OC" + SC="SC" + OC_AntiIso="OCAntiIso" + SC_AntiIso="SCAntiIso" + +class Probes: + ID = "IDProbes" + Calo = "CaloProbes" + MStoID = "MSProbes_ID" + MStoMu = "MSProbes_Muon" + TruthToID = "TruthProbes_ID" + TruthToMu = "TruthProbes_Muon" + +class DetRegions: + All="All" + noCrack="noCrack" + Crack="Crack" + Barrel="Barrel" + Transition="Transition" + Endcap="Endcap" + CSC="CSC" + +class Matches: + Calo ="CaloTaggedMuons" + CB ="CombinedMuons" + Loose ="LooseMuons" + LooseNoCalo ="LooseMuons_noCaloTag" + Medium ="MediumMuons" + Tight ="TightMuons" + ID ="IDTracks" + ID_noMCP ="IDTracks_noMCP" + +class PlotKinds: + Probes="Probes" + Matches="Matches" + Efficiency="Efficiency" + +class HistoKinds: + Efficiency="Efficiency" + DataEfficiency="Data Efficiency" + MCEfficiency="MC Efficiency" + TruthEfficiency="Truth Efficiency" + SF="ScaleFactor" + TruthSF="Truth ScaleFactor" + MCTruthSF="MC/Truth ScaleFactor" + +class Systematics: + dR="dR" + truth="Truth" + BG="BG" + Det="DetectorRun1" + All="Total" + +ExtraCuts = { + DetRegions.All: "", + DetRegions.Crack: "abs(eta) < 0.1", + DetRegions.noCrack: "abs(eta) > 0.1", + DetRegions.Barrel: "abs(eta) > 0.1 && abs(eta) < 1.1", + DetRegions.Transition: "abs(eta) > 1.1 && abs(eta) < 1.3", + DetRegions.Endcap: "abs(eta) > 1.3 && abs(eta) < 2.0", + DetRegions.CSC: "abs(eta) > 2.0 && abs(eta) < 2.5", +} + diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/EffPlots.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/EffPlots.py new file mode 100644 index 00000000000..edd5f8f1eab --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/EffPlots.py @@ -0,0 +1,818 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +import Histos +import ROOT +import DSConfig +import Utils +from Defs import * +from PlotUtils import PlotUtils +ROOT.gROOT.Macro("rootlogon.C") +ROOT.gROOT.SetStyle("ATLAS") +ROOT.gROOT.SetBatch(1) +import sys + +histos = [] +eff_axis_ranges = [] +sf_axis_ranges = [] + +def draw2D (histo, var, probe, match, region, conf_Data, histoKind, corr, LumiScale, analysis=Analysis.Z_Reco): + + pu = PlotUtils() + pu.Size = 0.06*(1-pu.VerticalCanvasSplit) + pu.Lumi = conf_Data.Lumi/1000. + + + can = ROOT.TCanvas("Eff_%s_%s_%s_%s_%s"%(match,var,probe,region,histoKind.replace(" ","")),"Efficiencies",600,600) + can.cd() + + histos.append(can) + histo.GetZaxis().SetTitle(histoKind) + + if HistoKinds.SF in histoKind: + ROOT.gStyle.SetPalette(55) + histo.GetZaxis().SetRangeUser(0.85,1.15) + else: + ROOT.gStyle.SetPalette(54) + histo.GetZaxis().SetRangeUser(0.80,1.01) + + histo.Draw("colz l") + #histo.Draw("same TEXT") + + can.SetTopMargin(0.15) + can.SetRightMargin(0.2) + can.SetLeftMargin(0.12) + histo.GetYaxis().SetTitleOffset(0.7*histo.GetYaxis().GetTitleOffset()) + histo.GetZaxis().SetTitleOffset(1.5*histo.GetZaxis().GetTitleOffset()) + # need to find a better way to do this: + histo.GetZaxis().SetLabelSize(histo.GetYaxis().GetLabelSize()) + histo.GetZaxis().SetTitleSize(histo.GetYaxis().GetTitleSize()) + + pu.DrawAtlas(can.GetLeftMargin(),0.92) + pu.DrawLumiSqrtS(can.GetLeftMargin(),0.87) + pu.DrawTarget(match,1-can.GetRightMargin(),0.92,31) + pu.DrawSource(probe,1-can.GetRightMargin(),0.87,31) + + if (not corr) and (probe == Probes.ID or probe == Probes.Calo): + pu.DrawTLatex(can.GetLeftMargin()+0.02,can.GetBottomMargin()+0.02,"ID eff. #font[62]{not} applied") + + corrstr = "" + if (not corr) and (probe == Probes.ID or probe == Probes.Calo): + corrstr = "_noIDCorr" + nEventsFileName = "" + nEventsStr = "" + if LumiScale != -1: + nEventsFileName = "_%03d"%nEventsFileNameInt + nEventsStr = ("_%.4fipb"%LumiScale).replace(".","pt") + + can.SaveAs ("Plots/Eff_%s_%s_%s_%s_%s%s%s.pdf"%(match,var,probe,region,histoKind.replace(" ",""),corrstr,nEventsFileName)) + + if HistoKinds.SF in histoKind: + pu.DrawTLatex(0.5,0.96,"%s SF%s vs %s for %s probes in %s %s"%(match,corrstr,var,probe,region,nEventsStr),pu.Size*(1-pu.VerticalCanvasSplit),52,21) + else: + pu.DrawTLatex(0.5,0.96,"%s Effi%s vs %s for %s probes in %s %s"%(match,corrstr,var,probe,region,nEventsStr),pu.Size*(1-pu.VerticalCanvasSplit),52,21) + + can.SaveAs("Plots/AllEffPlots.pdf") + +def doEffPlots1D (hists_final, var, probe, match, region, conf_Data, conf_Zmumu, LumiScale, corr = True, syshisto = None, analysis=Analysis.Z_Reco): + + # check if 2 sets of histos are available -> compare them + if len(hists_final)>1: + h_ref = hists_final[1].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency] + ratio2 = hists_final[1].Histos[HistoKinds.SF][HistoKinds.SF] + if match in Matches.ID: + h_ref_mc = hists_final[1].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] + else: + h_ref = None + + h_data = hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency] + h_mc = hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] + h_truth = hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.TruthEfficiency] + ratio = hists_final[0].Histos[HistoKinds.SF][HistoKinds.SF] + ratiotruth = hists_final[0].Histos[HistoKinds.SF][HistoKinds.TruthSF] + + ###### + # used for styling histo (when TGraphAsymmErrors are used) + h_styling = HistoDefs.initHisto(var)[0].Clone("stylingHisto") + # from print in Histos.py: + h_styling.GetXaxis().SetTitleSize(0.0500000007451) + h_styling.GetXaxis().SetTitleOffset(1.39999997616) + h_styling.GetXaxis().SetLabelSize(0.0500000007451) + h_styling.GetXaxis().SetLabelOffset(0.00499999988824) + h_styling.GetYaxis().SetTitleSize(0.0500000007451) + h_styling.GetYaxis().SetTitleOffset(1.39999997616) + h_styling.GetYaxis().SetLabelSize(0.0500000007451) + h_styling.GetYaxis().SetLabelOffset(0.00499999988824) + + h_styling_ratio = h_styling.Clone("stylingHistoRatio") + h_styling_ratio.GetYaxis().SetTitle("Data/MC") + + h_styling.GetYaxis().SetTitle("Efficiency") + ###### + + ############## + if var == "DetRegions": + # for week-1 data (DetRegions plot) + h_styling.SetLabelOffset(0.025, "X") + h_styling.GetXaxis().SetRangeUser(1,11) + for i in range(1,Utils.GetNbins(h_styling)-1): + h_styling.GetXaxis().SetBinLabel(i,"") + h_styling.GetXaxis().SetTitle("") + + h_styling_ratio.SetLabelOffset(0.025, "X") + h_styling_ratio.GetXaxis().SetRangeUser(1,11) + h_styling_ratio.GetXaxis().SetTitleOffset(h_styling_ratio.GetXaxis().GetTitleOffset()*1.1) + ############## + + pu = PlotUtils() + pu.Size = 0.06 + pu.Lumi = conf_Data.Lumi/1000. + pu.SqrtS = 13 + + # for evolution plots + nEventsStr = "" + if LumiScale != -1: + nEventsStr = ("_%.3fipb"%LumiScale).replace(".","pt") + if var == "DetRegions": + can,p1,p2 = pu.Prepare2PadCanvas("Eff_%s_%s_%s_%s%s"%(match,var,probe,region,nEventsStr),width=1000, height=800) + else: + can,p1,p2 = pu.Prepare2PadCanvas("Eff_%s_%s_%s_%s%s"%(match,var,probe,region,nEventsStr)) + + can.cd() + p1.Draw() + histos.append(p1) + histos.append(p2) + histos.append(can) + p1.cd() + + + # plotting style: + h_data.SetLineColor(ROOT.kBlack) + h_data.SetMarkerColor(ROOT.kBlack) + h_data.SetMarkerStyle(ROOT.kFullDotLarge) + if h_ref != None: + h_ref.SetLineColor(ROOT.kOrange-2) + h_ref.SetMarkerColor(ROOT.kOrange-2) + h_ref.SetMarkerStyle(ROOT.kFullSquare) + h_ref.SetTitle(hists_final[1].Name) + # for comparing Matches.ID to Matches.ID_noMCP + if match in Matches.ID: + h_ref.SetTitle(Matches.ID_noMCP) + h_ref_mc.SetTitle("%s MC"%(Matches.ID_noMCP)) + + h_mc.SetLineColor(ROOT.kRed-7) + h_mc.SetMarkerColor(ROOT.kRed-7) + h_mc.SetMarkerStyle(ROOT.kOpenCircle) + h_mc.SetTitle(conf_Zmumu.Label) + + h_truth.SetLineColor(ROOT.kBlue-7) + h_truth.SetMarkerColor(ROOT.kBlue-7) + h_truth.SetMarkerStyle(ROOT.kOpenSquare) + h_truth.SetTitle("Truth MC") + h_data.SetTitle(conf_Data.Label) + + ratio.SetLineColor(ROOT.kGreen-8) + ratio.SetFillColor(ratio.GetLineColor()) + ratio.SetMarkerColor(ROOT.kBlack) + ratio.SetMarkerStyle(ROOT.kFullDotLarge) + + if h_ref != None: + ratio2.SetLineColor(h_ref.GetLineColor()) + ratio2.SetMarkerColor(h_ref.GetMarkerColor()) + ratio2.SetMarkerStyle(ROOT.kOpenSquare) + else: + ratio2 = None + + ratiotruth.SetLineColor(h_truth.GetLineColor()) + ratiotruth.SetMarkerColor(h_truth.GetMarkerColor()) + ratiotruth.SetMarkerStyle(ROOT.kOpenSquare) + ratiotruth.SetTitle("Truth MC") + + ###### + # labels and axis ranges + pu.AdaptLabelsTopPad([h_styling, h_truth, h_data, h_mc]) + # for creating evolution plots, SetFancyAxisRanges_Eff has to be fixed + #if False: + if LumiScale != -1: + if len(eff_axis_ranges)<1: + eff_axis_ranges.append(pu.SetFancyAxisRanges_Eff([h_data,h_mc], maxmin = 1.05)) + pu.SetFancyAxisRanges_Eff([h_styling], maxmin = eff_axis_ranges[0][0][0], fixRange=True) + #print eff_axis_ranges + else: + eff_axis_ranges.append(pu.SetFancyAxisRanges_Eff([h_data,h_mc], maxmin = eff_axis_ranges[0][0][0], fixRange=True)) + pu.SetFancyAxisRanges_Eff([h_styling], maxmin = eff_axis_ranges[0][0][0], fixRange=True) + #print eff_axis_ranges + else: + eff_axis_ranges.append(pu.SetFancyAxisRanges_Eff([h_data,h_mc], maxmin = 1.05)) + pu.SetFancyAxisRanges_Eff([h_styling], maxmin = eff_axis_ranges[0][0][0], fixRange=True) + del eff_axis_ranges[:] + ###### + + h_styling.Draw("AXIS") + if h_mc.InheritsFrom("TGraphAsymmErrors"): + h_mc.Draw("sameP") + else: + h_mc.Draw("same") + + if h_ref == None: + #h_truth.Draw("same") + h_truth.GetYaxis().SetTitle("Efficiency") + if h_ref != None: + if h_mc.InheritsFrom("TGraphAsymmErrors"): + h_ref.Draw("sameP") + else: + h_ref.Draw("same") + # for comparing Matches.ID to Matches.ID_noMCP + if match in Matches.ID: + h_ref_mc.Draw("same") + if h_mc.InheritsFrom("TGraphAsymmErrors"): + h_data.Draw("sameP") + else: + h_data.Draw("same") + + pu.DrawAtlas(0.19,0.4) + + if LumiScale != -1: + lumi=LumiScale*InputData.Lumi + pu.DrawLumiSqrtSEvolution(0.19,0.32,lumi=lumi) + else: + pu.DrawLumiSqrtS(0.19,0.32) + if h_ref != None: + # for comparing Matches.ID to Matches.ID_noMCP + if match in Matches.ID: + pu.DrawLegend([(h_data,"PL"), (h_ref,"PL"), (h_mc,"PL"), (h_ref_mc,"PL")],0.69,0.08,0.89,0.33) + else: + pu.DrawLegend([(h_data,"PL"), (h_ref,"PL"), (h_mc,"PL")],0.69,0.08,0.89,0.33) + else: + #pu.DrawLegend([(h_data,"PL"), (h_mc,"PL"), (h_truth,"PL")],0.69,0.08,0.89,0.33) + pu.DrawLegend([(h_data,"PL"), (h_mc,"PL")],0.55,0.32,1-ROOT.gPad.GetRightMargin(),0.47) + + #pu.DrawSource(probe,0.69,0.36) + pu.DrawTarget(match,0.19,0.24) + if (not corr) and (probe == Probes.ID or probe == Probes.Calo): + pu.DrawTLatex(0.19,0.16,"ID eff. #font[62]{not} applied") + + + p2.cd() + p2.SetGridy() + + ###### + # labels and axis ranges + pu.AdaptLabelsBottomPad([h_styling_ratio,ratiotruth,ratio]) + if syshisto != None: + ratioWithTotalSys = ratio.Clone("%s_TotalSys"%(ratio.GetName())) + # put the following into SetFancyAxisRanges_SF in order to consider the systematic bands + ratioWithTotalSysAxis = ratio.Clone("%s_TotalSysForFancyAxisRanges"%(ratio.GetName())) + if not ratio.InheritsFrom("TGraphAsymmErrors"): + ratioWithTotalSys.SetDirectory(0) + ratioWithTotalSysAxis.SetDirectory(0) + nbins = Utils.GetNbins(ratioWithTotalSys) + for i in range (0, nbins): + if ratio.InheritsFrom("TGraphAsymmErrors"): + ratioWithTotalSys.SetPointEYhigh(i,ROOT.sqrt(ratioWithTotalSys.GetErrorYhigh(i)**2.+(ratioWithTotalSys.GetY()[i]*syshisto.GetY()[i])**2.)) + ratioWithTotalSys.SetPointEYlow(i,ROOT.sqrt(ratioWithTotalSys.GetErrorYlow(i)**2.+(ratioWithTotalSys.GetY()[i]*syshisto.GetY()[i])**2.)) + #Currently not used in SetFancyAxisRanges_SF + ratioWithTotalSysAxis.SetPoint(i,ratioWithTotalSysAxis.GetX()[i],ratio.GetY()[i]+ratioWithTotalSys.GetErrorYlow(i)) + else: + ratioWithTotalSys.SetBinError(i,ROOT.sqrt(ratioWithTotalSys.GetBinError(i)*ratioWithTotalSys.GetBinError(i)+ratioWithTotalSys.GetBinContent(i)*syshisto.GetBinContent(i)*ratioWithTotalSys.GetBinContent(i)*syshisto.GetBinContent(i))) + #Currently not used in SetFancyAxisRanges_SF + ratioWithTotalSysAxis.SetBinContent(i,ratio.GetBinContent(i)+ratioWithTotalSys.GetBinError(i)) + # for creating evolution plots, SetFancyAxisRanges_SF has to be fixed + #if False: + if LumiScale != -1: + if len(sf_axis_ranges)<1: + if syshisto != None: + sf_axis_ranges.append(pu.SetFancyAxisRanges_SF([ratio,ratioWithTotalSys,ratioWithTotalSysAxis],minmax = 0.8, maxmin = 1.2)) + pu.SetFancyAxisRanges_SF([h_styling_ratio], minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True) + else: + sf_axis_ranges.append(pu.SetFancyAxisRanges_SF([ratio],minmax = 0.8, maxmin = 1.2)) + pu.SetFancyAxisRanges_SF([h_styling_ratio], minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True) + #print sf_axis_ranges + else: + if syshisto != None: + sf_axis_ranges.append(pu.SetFancyAxisRanges_SF([ratio,ratioWithTotalSys,ratioWithTotalSysAxis],minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True)) + pu.SetFancyAxisRanges_SF([h_styling_ratio], minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True) + else: + sf_axis_ranges.append(pu.SetFancyAxisRanges_SF([ratio],minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True)) + pu.SetFancyAxisRanges_SF([h_styling_ratio], minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True) + #print sf_axis_ranges + else: + if syshisto != None: + sf_axis_ranges.append(pu.SetFancyAxisRanges_SF([ratio,ratioWithTotalSys],minmax = 0.8, maxmin = 1.2)) + pu.SetFancyAxisRanges_SF([h_styling_ratio], minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True) + else: + sf_axis_ranges.append(pu.SetFancyAxisRanges_SF([ratio],minmax = 0.8, maxmin = 1.2)) + pu.SetFancyAxisRanges_SF([h_styling_ratio], minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True) + #print sf_axis_ranges + del sf_axis_ranges[:] + ###### + + h_styling_ratio.Draw("AXIS") + if syshisto != None: + ratioWithTotalSys.SetFillColor(ROOT.kOrange-3) + ratioWithTotalSys.SetLineColor(ROOT.kOrange-3) + if h_mc.InheritsFrom("TGraphAsymmErrors"): + ratioWithTotalSys.Draw("same2") + ratio.Draw("same2") + else: + ratioWithTotalSys.Draw("E2") + ratio.Draw("E2 same") + else: + if h_mc.InheritsFrom("TGraphAsymmErrors"): + ratio.Draw("same2") + else: + ratio.Draw("E2 same") + + if h_ref == None: + #ratiotruth.Draw("same") + pass + if ratio2 != None: + ratio2.Draw("same") + if h_mc.InheritsFrom("TGraphAsymmErrors"): + ratio.Draw("sameP") + else: + ratio.Draw("same") + + + ROOT.gPad.RedrawAxis() + corrstr = "" + if (not corr) and (probe == Probes.ID or probe == Probes.Calo): + corrstr = "_noIDCorr" + nEventsFileName = "" + nEventsStr = "" + if LumiScale != -1: + nEventsFileName = "_%04d"%nEventsFileNameInt + nEventsStr = ("_%.3fipb"%LumiScale).replace(".","pt") + p1.cd() + #pu.DrawTLatex(1-can.GetRightMargin(),0.94,"%.0f Zs"%(nMax),0.04,52,31) + can.cd() + can.Print("Plots/test.gif+10") + + can.SaveAs ("Plots/Eff_%s_%s_%s_%s%s%s.pdf"%(match,var,probe,region,corrstr,nEventsFileName)) + p1.cd() + + pu.DrawTLatex(0.5,0.94,"%s Effi%s vs %s for %s probes in %s %s"%(match,corrstr,var,probe,region,nEventsStr),0.04,52,22) + + can.SaveAs("Plots/AllEffPlots.pdf") + + +def doSFValidation1D (hists_final, var, probe, match, region, conf_Data, corr = True, syshisto = None, analysis=Analysis.Z_Reco): + + + # check if 2 sets of histos are available -> compare them + if len(hists_final)<2: + return + + h_mc_SF = hists_final[1].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] + ratio_SF = hists_final[1].Histos[HistoKinds.SF][HistoKinds.SF] + + pu = PlotUtils() + pu.Size = 0.06 + pu.Lumi = conf_Data.Lumi/1000. + + can,p1,p2 = pu.Prepare2PadCanvas("SF_Valid_%s_%s_%s_%s"%(match,var,probe,region)) + can.cd() + + p1.Draw() + + histos.append(p1) + histos.append(p2) + histos.append(can) + p1.cd() + + + # used for styling histo when TGraphAsymmErrors are used + h_styling = HistoDefs.initHisto(var)[0].Clone("stylingHisto") + # from print in Histos.py: + h_styling.GetXaxis().SetTitleSize(0.0500000007451) + h_styling.GetXaxis().SetTitleOffset(1.39999997616) + h_styling.GetXaxis().SetLabelSize(0.0500000007451) + h_styling.GetXaxis().SetLabelOffset(0.00499999988824) + h_styling.GetYaxis().SetTitleSize(0.0500000007451) + h_styling.GetYaxis().SetTitleOffset(1.39999997616) + h_styling.GetYaxis().SetLabelSize(0.0500000007451) + h_styling.GetYaxis().SetLabelOffset(0.00499999988824) + + h_styling_ratio = h_styling.Clone("stylingHisto") + + h_styling.GetYaxis().SetTitle("Efficiency") + + h_data = hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency] + h_mc = hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] + ratio = hists_final[0].Histos[HistoKinds.SF][HistoKinds.SF] + + #h_mc.SetFillColor(ROOT.kRed-7) + h_data.SetLineColor(ROOT.kBlack) + h_data.SetMarkerColor(ROOT.kBlack) + h_data.SetMarkerStyle(ROOT.kFullDotLarge) + + h_mc_SF.SetFillColor(ROOT.kBlue-7) + h_mc_SF.SetMarkerColor(ROOT.kBlue-7) + h_mc_SF.SetLineColor(ROOT.kBlue-7) + h_mc_SF.SetMarkerSize(1.25 * h_mc_SF.GetMarkerSize()) + h_mc_SF.SetMarkerStyle(ROOT.kOpenSquare) + h_mc_SF.SetTitle("MC after SF") + + #h_mc.SetFillColor(ROOT.kRed-7) + h_mc.SetLineColor(ROOT.kRed-7) + h_mc.SetMarkerColor(ROOT.kRed-7) + h_mc.SetMarkerStyle(ROOT.kOpenCircle) + h_mc.SetTitle("MC before SF") + + h_data.SetTitle(conf_Data.Label) + + ratio.SetLineColor(h_mc.GetLineColor()) + ratio.SetMarkerColor(h_mc.GetMarkerColor()) + ratio.SetMarkerStyle(h_mc.GetMarkerStyle()) + ratio.SetTitle("MC before SF") + + ratio_SF.SetLineColor(h_mc_SF.GetLineColor()) + ratio_SF.SetMarkerSize(1.25 * ratio_SF.GetMarkerSize()) + ratio_SF.SetMarkerColor(h_mc_SF.GetMarkerColor()) + ratio_SF.SetMarkerStyle(h_mc_SF.GetMarkerStyle()) + ratio_SF.SetTitle("MC after SF") + + pu.AdaptLabelsTopPad([h_styling,h_data,h_mc,h_mc_SF]) + eff_axis_ranges.append(pu.SetFancyAxisRanges_Eff([h_data,h_mc,h_mc_SF], maxmin = 1.05)) + pu.SetFancyAxisRanges_Eff([h_styling], maxmin = eff_axis_ranges[0][0][0], fixRange=True) + del eff_axis_ranges[:] + + h_styling.Draw("AXIS") + if h_data.InheritsFrom("TGraphAsymmErrors"): + h_mc.Draw("sameP") + h_mc_SF.Draw("sameP") + h_data.Draw("sameP") + else: + h_mc.Draw("same") + h_mc_SF.Draw("same") + h_data.Draw("same") + + pu.DrawAtlas(0.19,0.4) + pu.DrawLumiSqrtS(0.19,0.32) + pu.DrawLegend([(h_data,"PL"), (h_mc,"PL"), (h_mc_SF,"PL")],0.69,0.08,0.89,0.33) + + pu.DrawSource(probe,0.69,0.36) + pu.DrawTarget(match,0.19,0.24) + if (not corr) and (probe == Probes.ID or probe == Probes.Calo): + pu.DrawTLatex(0.19,0.16,"ID eff. #font[62]{not} applied") + p2.cd() + + p2.SetGridy() + + pu.AdaptLabelsBottomPad([h_styling_ratio,ratio_SF,ratio]) + h_styling_ratio.GetYaxis().SetTitle("Data/MC") + + sf_axis_ranges.append(pu.SetFancyAxisRanges_SF([ratio_SF,ratio],minmax = 0.9, maxmin = 1.1)) + pu.SetFancyAxisRanges_SF([h_styling_ratio], minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True) + del sf_axis_ranges[:] + + + if syshisto != None: + ratioWithTotalSys = ratio.Clone("%s_TotalSys"%(ratio.GetName())) + if not ratio.InheritsFrom("TGraphAsymmErrors"): + ratioWithTotalSys.SetDirectory(0) + nbins = ratioWithTotalSys.GetNbinsX()+1 + for i in range (1, nbins): + ratioWithTotalSys.SetBinError(i,ROOT.sqrt(ratioWithTotalSys.GetBinError(i)*ratioWithTotalSys.GetBinError(i)+ratioWithTotalSys.GetBinContent(i)*syshisto.GetBinContent(i)*ratioWithTotalSys.GetBinContent(i)*syshisto.GetBinContent(i))) + ratioWithTotalSys.SetFillColor(ROOT.kOrange-3) + ratioWithTotalSys.SetLineColor(ROOT.kOrange-3) + ratio.SetFillColor(ROOT.kGreen-8) + ratio.SetLineColor(ROOT.kGreen-8) + ratio.SetMarkerColor(ROOT.kBlack) + ratio.SetMarkerStyle(ROOT.kFullDotLarge) + h_styling_ratio.Draw("AXIS") + if ratio.InheritsFrom("TGraphAsymmErrors"): + ratioWithTotalSys.Draw("same2") + ratio.Draw("same2") + else: + ratioWithTotalSys.Draw("E2 same") + ratio.Draw("E2 same") + else: + h_styling_ratio.Draw("AXIS") + if ratio.InheritsFrom("TGraphAsymmErrors"): + ratio.Draw("sameP") + else: + ratio.Draw("same") + + if ratio.InheritsFrom("TGraphAsymmErrors"): + ratio_SF.Draw("sameP") + else: + ratio_SF.Draw("same") + ROOT.gPad.RedrawAxis() + chi2_prev = 0. + chi2_now = 0. + for a in range (1,Utils.GetNbins(ratio)): + if ratio.InheritsFrom("TGraphAsymmErrors"): + chi2_prev = chi2_prev + (ratio.GetY()[a] - 1.)**2 / ratio.GetN() + chi2_now = chi2_now + (ratio_SF.GetY()[a] - 1.)**2 / ratio_SF.GetN() + else: + chi2_prev = chi2_prev + (ratio.GetBinContent(a) - 1.)**2 / ratio.GetNbinsX() + chi2_now = chi2_now + (ratio_SF.GetBinContent(a) - 1.)**2 / ratio_SF.GetNbinsX() + chi2_prev = math.sqrt(chi2_prev) + chi2_now = math.sqrt(chi2_now) + pu.DrawTLatex(0.19, 0.5, " #frac{<(SF -1)>}{#sqrt{N_{bins}}}: %.4f before SF, %.4f after"%(chi2_prev, chi2_now)) + corrstr = "" + if (not corr) and (probe == Probes.ID or probe == Probes.Calo): + corrstr = "_noIDCorr" + can.SaveAs ("Plots/SFValid_%s_%s_%s_%s%s.pdf"%(match,var,probe,region,corrstr)) + p1.cd() + ROOT.gPad.RedrawAxis() + + pu.DrawTLatex(0.5,0.94,"%s Effi%s vs %s for %s probes in %s"%(match,corrstr,var,probe,region),0.04,52,22) + + can.SaveAs("Plots/AllEffPlots.pdf") + +def doEffPlots2D (hists_final, var, probe, match, region, conf_Data, conf_Zmumu, LumiScale, corr = True, analysis=Analysis.Z_Reco): + + # check if 2 sets of histos are available -> how to plot a comparison in 2D? + if len(hists_final)>1: + print "Error: Currently no 2D comparison between 2 different datasets possible!" + sys.exit(1) + + + h_data = hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency] + h_mc = hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] + h_truth = hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.TruthEfficiency] + + ratiodata = hists_final[0].Histos[HistoKinds.SF][HistoKinds.SF] + ratiotruth = hists_final[0].Histos[HistoKinds.SF][HistoKinds.TruthSF] + + draw2D (h_data, var, probe, match, region, conf_Data, HistoKinds.DataEfficiency, corr, LumiScale) + draw2D (h_mc, var, probe, match, region, conf_Data, HistoKinds.MCEfficiency, corr, LumiScale) + draw2D (h_truth, var, probe, match, region, conf_Data, HistoKinds.TruthEfficiency, corr, LumiScale) + + draw2D (ratiodata, var, probe, match, region, conf_Data, HistoKinds.SF, corr, LumiScale) + draw2D (ratiotruth, var, probe, match, region, conf_Data, HistoKinds.TruthSF, corr, LumiScale) + +def doEffPlots (var, probe, match, region, conf_Data, conf_Zmumu, inputComparison = None, corr = True, includeSys = True, doClosure = False, LumiScale=-1, doPreRecEtaCopy=False, analysis=Analysis.Z_Reco): + + infiles = [ + ["MC",conf_Zmumu], + ["Data",conf_Data] + ] + + hists_final = [] + + # for pre-recommendations, copy negative eta bins of transition region to positive ones (use doPreRecEtaCopy=True): + if includeSys: + # with systematic uncertainty bands: + test = Histos.TPFinalSysHistos("test",probe,match,region,var,infiles,charge=None,corr=corr,doClosure=doClosure,LumiScale=LumiScale,doPreRecEtaCopy=doPreRecEtaCopy, analysis=analysis).HistoSets + syshisto = test[Systematics.All][0] + hists_final.append(test["Nominal"]) + else: + # faster (without systematic uncertainty bands): + hists_final.append(Histos.TPFinalHistos("test",probe,match,region,var,infiles,corr=corr,doClosure=doClosure,LumiScale=LumiScale,doPreRecEtaCopy=doPreRecEtaCopy, analysis=analysis)) + syshisto = None + + + if inputComparison != None: + infiles2 = [ + ["MC",conf_Zmumu], + ["Data",inputComparison] + ] + hists_final.append(Histos.TPFinalHistos(inputComparison.Label,probe,match,region,var,infiles2,corr=corr,doClosure=doClosure, analysis=analysis)) + + if hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency].InheritsFrom("TH2"): + doEffPlots2D (hists_final, var, probe, match, region, conf_Data, conf_Zmumu, LumiScale, corr, analysis=analysis) + else: + doEffPlots1D (hists_final, var, probe, match, region, conf_Data, conf_Zmumu, LumiScale, corr, syshisto, analysis=analysis) + + +def doSysPlot(probe,match,region,var,infiles,charge=None,corr = True, doPreRecEtaCopy=False): + + testpos = Histos.TPFinalSysHistos("testpos",probe,match,region,var,infiles,charge,corr,doPreRecEtaCopy=doPreRecEtaCopy).HistoSets + + # used for styling histo when TGraphAsymmErrors are used + h_styling = HistoDefs.initHisto(var)[0].Clone("stylingHisto") + # from print in Histos.py: + h_styling.GetXaxis().SetTitleSize(0.0500000007451) + h_styling.GetXaxis().SetTitleOffset(1.39999997616) + h_styling.GetXaxis().SetLabelSize(0.0500000007451) + h_styling.GetXaxis().SetLabelOffset(0.00499999988824) + h_styling.GetYaxis().SetTitleSize(0.0500000007451) + h_styling.GetYaxis().SetTitleOffset(1.39999997616) + h_styling.GetYaxis().SetLabelSize(0.0500000007451) + h_styling.GetYaxis().SetLabelOffset(0.00499999988824) + h_styling.GetYaxis().SetTitle("Relative Systematic uncertainty (%)") + + h_truth_sys_sf = testpos[Systematics.truth][2] + h_dR_sys_sf = testpos[Systematics.dR][2] + h_BG_sys_sf = testpos[Systematics.BG][2] + h_Det_sys_sf = testpos[Systematics.Det][2] + h_total_sys_sf = testpos[Systematics.All][2] + + h_stat_sf = testpos["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF] + + if h_stat_sf.InheritsFrom("TGraphAsymmErrors"): + for i in range (0,Utils.GetNbins(h_stat_sf)): + maxError = max(h_stat_sf.GetErrorYhigh(i),h_stat_sf.GetErrorYlow(i)) + try: + h_stat_sf.SetPoint(i,h_stat_sf.GetX()[i],maxError/h_stat_sf.GetY()[i]) + except ZeroDivisionError: + h_stat_sf.SetPoint(i,h_stat_sf.GetX()[i],0.) + h_total_sys_sf.SetPoint(i,h_total_sys_sf.GetX()[i],math.sqrt(h_total_sys_sf.GetY()[i]**2. + h_stat_sf.GetY()[i]**2.)) + else: + for i in range (1,Utils.GetNbins(h_stat_sf)): + try: + h_stat_sf.SetBinContent(i,h_stat_sf.GetBinError(i)/h_stat_sf.GetBinContent(i)) + except ZeroDivisionError: + h_stat_sf.SetBinContent(i,0.) + h_total_sys_sf.SetBinContent(i,math.sqrt(h_total_sys_sf.GetBinContent(i)*h_total_sys_sf.GetBinContent(i) + h_stat_sf.GetBinContent(i)*h_stat_sf.GetBinContent(i))) + + if h_stat_sf.InheritsFrom("TGraphAsymmErrors"): + for i in range (0,Utils.GetNbins(h_stat_sf)): + h_truth_sys_sf.SetPoint(i,h_truth_sys_sf.GetX()[i],h_truth_sys_sf.GetY()[i]*100.) + h_dR_sys_sf.SetPoint(i,h_dR_sys_sf.GetX()[i],h_dR_sys_sf.GetY()[i]*100.) + h_BG_sys_sf.SetPoint(i,h_BG_sys_sf.GetX()[i],h_BG_sys_sf.GetY()[i]*100.) + h_Det_sys_sf.SetPoint(i,h_Det_sys_sf.GetX()[i],h_Det_sys_sf.GetY()[i]*100.) + h_total_sys_sf.SetPoint(i,h_total_sys_sf.GetX()[i],h_total_sys_sf.GetY()[i]*100.) + h_stat_sf.SetPoint(i,h_stat_sf.GetX()[i],h_stat_sf.GetY()[i]*100.) + else: + for i in range (1,Utils.GetNbins(h_truth_sys_sf)): + h_truth_sys_sf.SetBinContent(i, h_truth_sys_sf.GetBinContent(i)*100.) + h_dR_sys_sf.SetBinContent(i, h_dR_sys_sf.GetBinContent(i)*100.) + h_BG_sys_sf.SetBinContent(i, h_BG_sys_sf.GetBinContent(i)*100.) + h_Det_sys_sf.SetBinContent(i, h_Det_sys_sf.GetBinContent(i)*100.) + h_total_sys_sf.SetBinContent(i, h_total_sys_sf.GetBinContent(i)*100.) + h_stat_sf.SetBinContent(i, h_stat_sf.GetBinContent(i)*100.) + + pu = PlotUtils() + pu.Size = 0.06 * (1 - pu.VerticalCanvasSplit) + pu.Lumi = infiles[1][1].Lumi / 1000. + + can = ROOT.TCanvas("Sys_%s_%s_%s_%s" % (probe, match, var, charge), "Systematics", 800, 800) + can.cd() + can.SetLeftMargin(0.15) + + can.SetLogy(1) + + + + valuesForYRange = [] + if h_total_sys_sf.InheritsFrom("TGraphAsymmErrors"): + for i in range (0,Utils.GetNbins(h_total_sys_sf)): + valuesForYRange.append(h_total_sys_sf.GetY()[i]) + ymin = min(valuesForYRange) + ymax = max(valuesForYRange) + else: + ymin = h_total_sys_sf.GetMinimum() + ymax = h_total_sys_sf.GetMaximum() + + h_styling.Draw("AXIS") + h_styling.SetMinimum(1.0e-3) + h_styling.SetMaximum(ymax*1e3) + + + h_total_sys_sf.SetLineColor(ROOT.kBlack) + h_total_sys_sf.GetYaxis().SetTitle("Relative Systematic uncertainty (%)") + h_total_sys_sf.SetLineWidth(4) + + + h_stat_sf.SetLineColor(ROOT.kMagenta+1) + h_stat_sf.SetLineWidth(2) + + + h_truth_sys_sf.SetLineColor(ROOT.kBlue) + h_truth_sys_sf.SetLineWidth(2) + h_truth_sys_sf.SetMarkerColor(h_truth_sys_sf.GetLineColor()) + h_truth_sys_sf.SetMarkerStyle(24) + + + + h_dR_sys_sf.SetMarkerStyle(25) + h_dR_sys_sf.SetLineWidth(2) + h_dR_sys_sf.SetLineColor(ROOT.kGreen+1) + h_dR_sys_sf.SetMarkerColor(h_dR_sys_sf.GetLineColor()) + + + h_BG_sys_sf.SetLineWidth(2) + h_BG_sys_sf.SetMarkerStyle(26) + h_BG_sys_sf.SetLineColor(ROOT.kRed) + h_BG_sys_sf.SetMarkerColor(h_BG_sys_sf.GetLineColor()) + + + h_Det_sys_sf.SetLineWidth(2) + h_Det_sys_sf.SetMarkerStyle(26) + h_Det_sys_sf.SetLineColor(ROOT.kOrange-3) + h_Det_sys_sf.SetMarkerColor(h_Det_sys_sf.GetLineColor()) + + + if h_stat_sf.InheritsFrom("TGraphAsymmErrors"): + h_total_sys_sf.Draw("LX same") + h_stat_sf.Draw("LX same") + h_truth_sys_sf.Draw("LX same") + h_dR_sys_sf.Draw("LX same") + h_BG_sys_sf.Draw("LX same") + h_Det_sys_sf.Draw("LX same") + else: + h_total_sys_sf.Draw("HIST l same") + h_stat_sf.Draw("HIST l same") + h_truth_sys_sf.Draw("HIST l same") + h_dR_sys_sf.Draw("HIST l same") + h_BG_sys_sf.Draw("HIST l same") + h_Det_sys_sf.Draw("HIST l same") + + leg = ROOT.TLegend(.45, .68, .95, .85) + leg.SetFillStyle(0) + leg.SetBorderSize(0) + leg.SetTextFont(42) + leg.SetNColumns(2) + leg.AddEntry(h_truth_sys_sf, "Truth Closure", "l") + leg.AddEntry(h_dR_sys_sf, "Match #DeltaR", "l") + leg.AddEntry(h_BG_sys_sf, "Background", "l") + leg.AddEntry(h_Det_sys_sf, "MC14 vs MC15", "l") + leg.AddEntry(h_stat_sf, "Statistics", "l") + leg.AddEntry(h_total_sys_sf, "Total", "l") + leg.Draw() + + + pu.DrawAtlas(can.GetLeftMargin(), 0.91) + pu.DrawLumiSqrtS(can.GetLeftMargin(), 0.87) + pu.DrawTarget(match, 1 - can.GetRightMargin(), 0.92, 31) + pu.DrawSource(probe, 1 - can.GetRightMargin(), 0.87, 31) + if charge != None: + qlabel = 'charge: %s' % (charge) + pu.DrawTLatex(1 - can.GetRightMargin(), 0.82, qlabel, size=pu.Size, align=31) + histlabel = HistoKinds.SF + pu.DrawTLatex(can.GetLeftMargin(), 0.82, histlabel, size=pu.Size) + + if charge != None: + can.SaveAs ("Plots/Sys_%s_%s_%s_%s_%s.pdf" % (probe, match, region, var, charge)) + else: + can.SaveAs ("Plots/Sys_%s_%s_%s_%s.pdf" % (probe, match, region, var)) + + pu.DrawTLatex(0.5,0.94,"Systematics %s vs %s for %s probes in %s"%(match,var,probe,region),0.04,52,22) + can.SaveAs("Plots/AllEffPlots.pdf") + +if __name__ == "__main__": + + # what we want to run on: + InputData = DSConfig.Zmumu_mc15 + InputZmumu = DSConfig.Zmumu_mc15 + + dummy = ROOT.TCanvas("dummy","dummy",800,800) + dummy.SaveAs("Plots/AllEffPlots.pdf[") + + # variables we want to plot: + # NOTE: 'fineEtaPhi' is 1D while 'etaphiFine' is 2D + + + ####### + # systematics plots: + ####### + #doSysPlot(Probes.Calo,Matches.Medium, DetRegions.All, "eta", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + #doSysPlot(Probes.Calo,Matches.Medium, DetRegions.All, "fineEtaPhi", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True, doPreRecEtaCopy=True) + #doSysPlot(Probes.Calo,Matches.Medium, DetRegions.All, "pt", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + #doSysPlot(Probes.Calo,Matches.Medium, DetRegions.noCrack, "pt", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + + #doSysPlot(Probes.Calo,Matches.Tight, DetRegions.All, "eta", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + #doSysPlot(Probes.Calo,Matches.Tight, DetRegions.All, "fineEtaPhi", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True, doPreRecEtaCopy=True) + #doSysPlot(Probes.Calo,Matches.Tight, DetRegions.All, "pt", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + #doSysPlot(Probes.Calo,Matches.Tight, DetRegions.noCrack, "pt", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + + #doSysPlot(Probes.Calo,Matches.LooseNoCalo, DetRegions.All, "eta", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + #doSysPlot(Probes.Calo,Matches.LooseNoCalo, DetRegions.All, "fineEtaPhi", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True, doPreRecEtaCopy=True) + #doSysPlot(Probes.Calo,Matches.LooseNoCalo, DetRegions.All, "pt", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + #doSysPlot(Probes.Calo,Matches.LooseNoCalo, DetRegions.noCrack, "pt", infiles=[["MC",InputZmumu],["Data",InputData]],charge=None,corr = True) + + + + ####### + # efficiency plots: + ####### + #doEffPlots ("phi", Probes.Calo, Matches.LooseNoCalo, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("eta", Probes.Calo,Matches.LooseNoCalo, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("pt", Probes.Calo, Matches.LooseNoCalo,DetRegions.All, InputData, InputZmumu) + #doEffPlots ("pt", Probes.Calo, Matches.LooseNoCalo,DetRegions.noCrack, InputData, InputZmumu) + #doEffPlots ("DetRegions", Probes.Calo,Matches.LooseNoCalo, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("etaTemp", Probes.Calo,Matches.LooseNoCalo, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("etaphiFine", Probes.Calo,Matches.LooseNoCalo, DetRegions.All, InputData, InputZmumu, includeSys = False, doPreRecEtaCopy=False) + #doEffPlots ("fineEtaPhi", Probes.Calo,Matches.LooseNoCalo, DetRegions.All, InputData, InputZmumu, doPreRecEtaCopy=False) + + #doEffPlots ("phi", Probes.MStoMu,Matches.Calo, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("eta", Probes.MStoMu,Matches.Calo, DetRegions.All, InputData, InputZmumu, includeSys = False) + #doEffPlots ("pt", Probes.MStoMu,Matches.Calo, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("pt", Probes.MStoMu,Matches.Calo, DetRegions.Crack, InputData, InputZmumu) + #doEffPlots ("DetRegions", Probes.MStoMu,Matches.Calo, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("etaphiFine", Probes.MStoMu,Matches.Calo, DetRegions.All, InputData, InputZmumu, includeSys = False) + #doEffPlots ("CaloTag2D", Probes.MStoMu, Matches.Calo, DetRegions.All, InputData, InputZmumu, includeSys = False) + + doEffPlots ("phi", Probes.Calo, Matches.Medium, DetRegions.All, InputData, InputZmumu, analysis=Analysis.Z_Reco) + doEffPlots ("eta", Probes.Calo, Matches.Medium,DetRegions.All, InputData, InputZmumu, analysis=Analysis.Z_Reco) + doEffPlots ("pt", Probes.Calo, Matches.Medium,DetRegions.All, InputData, InputZmumu, analysis=Analysis.Z_Reco) + doEffPlots ("pt", Probes.Calo, Matches.Medium,DetRegions.noCrack, InputData, InputZmumu, analysis=Analysis.Z_Reco) + doEffPlots ("DetRegions", Probes.Calo,Matches.Medium, DetRegions.All, InputData, InputZmumu, analysis=Analysis.Z_Reco) + doEffPlots ("etaTemp", Probes.Calo,Matches.Medium, DetRegions.All, InputData, InputZmumu, analysis=Analysis.Z_Reco) + doEffPlots ("etaphiFine", Probes.Calo,Matches.Medium, DetRegions.All, InputData, InputZmumu, includeSys = False, doPreRecEtaCopy=False, analysis=Analysis.Z_Reco) + doEffPlots ("fineEtaPhi", Probes.Calo,Matches.Medium, DetRegions.All, InputData, InputZmumu, doPreRecEtaCopy=False, analysis=Analysis.Z_Reco) + + #doEffPlots ("phi", Probes.Calo, Matches.Tight, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("eta", Probes.Calo, Matches.Tight,DetRegions.All, InputData, InputZmumu) + #doEffPlots ("pt", Probes.Calo, Matches.Tight,DetRegions.All, InputData, InputZmumu) + #doEffPlots ("pt", Probes.Calo, Matches.Tight,DetRegions.noCrack, InputData, InputZmumu) + #doEffPlots ("DetRegions", Probes.Calo,Matches.Tight, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("etaTemp", Probes.Calo,Matches.Tight, DetRegions.All, InputData, InputZmumu) + #doEffPlots ("etaphiFine", Probes.Calo,Matches.Tight, DetRegions.All, InputData, InputZmumu, includeSys = False, doPreRecEtaCopy=False) + #doEffPlots ("fineEtaPhi", Probes.Calo,Matches.Tight, DetRegions.All, InputData, InputZmumu, doPreRecEtaCopy=False) + + + dummy.SaveAs("Plots/AllEffPlots.pdf]") diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/HistoDefs.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/HistoDefs.py new file mode 100644 index 00000000000..5b97590bf01 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/HistoDefs.py @@ -0,0 +1,229 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +from Defs import * +import sys +import math, ROOT, itertools, os.path +from array import array + +# TH2Poly for fine eta-phi binning +def TPFineEtaPhiHist(name,title): + histo = ROOT.TH2Poly() + histo.SetName(name) + histo.SetTitle(title) + + barrelECTrans = 1.19 + + # etabins used in 2012 analysis: + #etabins = [-2.75,-2.18,-1.95,-1.74,-1.52,-1.37,-1.05,-0.84,-0.63,-0.42,-0.21,0.,0.21,0.42,0.63,0.84,1.05,1.37,1.52,1.74,1.95,2.18,2.75] + etabins = [0.15,0.3,0.45,0.6,0.75,0.9,1.05,barrelECTrans,1.35,1.5,1.65,1.8,1.95,2.1,2.25,2.5] + etabins = sorted([0.]+etabins+[-binX for binX in etabins]) + + phiSectorBarrel = [-2.905,-2.59,-2.12,-1.805,-1.335,-1.02,-0.55,-0.235,0.235,0.55,1.02,1.335,1.805,2.12,2.59,2.905] + phiSectorEC = [-3.011,-2.487,-2.225,-1.702,-1.440,-0.916,-0.655,-0.131,0.131,0.655,0.916,1.440,1.702,2.225,2.487,3.011] + + # we go like this when adding the bins: + # + # ^ ^ ^ + # | | | + # x-------> + + #correct behavior for the bin around pi: one common bin at +pi and -pi instead of 2! + for etaCurrent, etaNext in zip (etabins, etabins [1:] ): + for phiBarrelCurrent, phiBarrelNext, phiECCurrent, phiECNext in zip (phiSectorBarrel, phiSectorBarrel [1:], phiSectorEC, phiSectorEC [1:] ): + + # if we pass the threshold, different treatment + if (etaCurrent < -barrelECTrans) and (etaNext > -barrelECTrans):#first threshold passage + # + # + # here, we do: + # |1.19 + # 1 2 + # 3 4 + # 6 5 + # 8 |7 + # + x = array('d',[etaCurrent, -barrelECTrans, -barrelECTrans, etaNext, etaNext, -barrelECTrans, -barrelECTrans, etaCurrent]) + y = array('d',[phiECNext, phiECNext, phiBarrelNext, phiBarrelNext, phiBarrelCurrent, phiBarrelCurrent, phiECCurrent, phiECCurrent]) + binNumber = histo.AddBin(8,x,y) + #print '(etaCurrent < -barrelECTrans) and (etaNext > -barrelECTrans), etaCurrent: %s, etaNext: %s. bin: %s'%(etaCurrent, etaNext,binNumber) + elif (etaCurrent < barrelECTrans) and (etaNext > barrelECTrans):# second threshold passage + # + # + # here, we do: + # |1.19 + # |3 4 + # 1 2 + # 8 7 + # |6 5 + # + x = array('d',[etaCurrent, barrelECTrans, barrelECTrans, etaNext, etaNext, barrelECTrans, barrelECTrans, etaCurrent]) + y = array('d',[phiBarrelNext, phiBarrelNext, phiECNext, phiECNext, phiECCurrent, phiECCurrent, phiBarrelCurrent, phiBarrelCurrent]) + binNumber = histo.AddBin(8,x,y) + #print '(etaCurrent < barrelECTrans) and (etaNext > barrelECTrans), etaCurrent: %s, etaNext: %s. bin: %s'%(etaCurrent, etaNext,binNumber) + else:#normal case + # + # + # here, we do: + # + # 1 2 + # + # 4 3 + # + if (etaNext <= -barrelECTrans) or (etaCurrent >= barrelECTrans): + phiCurrent = phiECCurrent + phiNext = phiECNext + else: + phiCurrent = phiBarrelCurrent + phiNext = phiBarrelNext + + x = array('d',[etaCurrent, etaNext, etaNext, etaCurrent]) + y = array('d',[phiNext, phiNext, phiCurrent, phiCurrent]) + binNumber = histo.AddBin(4,x,y) + #print 'else, etaCurrent: %s, etaNext: %s. bin: %s'%(etaCurrent, etaNext,binNumber) + + # finally, the -pi / pi bin! + phiBarrelLast = phiSectorBarrel[-1] + phiECLast = phiSectorEC[-1] + + # here, we fill like this: + # and of course if we have no threshold + # we don't have 6,7,10,11 + # + # 4.........................3 <- +pi + # ' ' + # ' ' + # 5.......6 ' + # 7................8' 8,9 are actually *on* the vertical double line of course! + # '' and exactly along the line 2-3. + # '' + # '' + # '' this line has 0 width and is aligned with the other bin + # '' edges, so we don't see it on the histo! + # '' drawn twice here just to clarify that we go along that + # '' way twice + # 10...............9' + # 12......11 ' + # ' array ' + # ' ' + # 1.........................2 <- -pi + if math.fabs(etaCurrent) > barrelECTrans: + phiedge = phiECLast + else: + phiedge = phiBarrelLast + if math.fabs(etaNext) > barrelECTrans: + phiedger = phiECLast + else: + phiedger = phiBarrelLast + + if (etaCurrent <= -barrelECTrans) and (etaNext >= -barrelECTrans): + xe = array('d',[etaCurrent, etaNext, etaNext, etaCurrent,etaCurrent,-barrelECTrans,-barrelECTrans,etaNext,etaNext,-barrelECTrans,-barrelECTrans,etaCurrent]) + ye = array('d',[-math.pi,-math.pi,math.pi,math.pi,phiedge,phiedge,phiedger,phiedger,-phiedger,-phiedger,-phiedge,-phiedge]) + binNumber = histo.AddBin(12,xe,ye) + #print '(etaCurrent <= -barrelECTrans) and (etaNext >= -barrelECTrans), etaCurrent: %s, etaNext: %s. bin: %s'%(etaCurrent, etaNext,binNumber) + elif (etaCurrent <= barrelECTrans) and (etaNext >= barrelECTrans): + xe = array('d',[etaCurrent, etaNext, etaNext, etaCurrent,etaCurrent,barrelECTrans,barrelECTrans,etaNext,etaNext,barrelECTrans,barrelECTrans,etaCurrent]) + ye = array('d',[-math.pi,-math.pi,math.pi,math.pi,phiedge,phiedge,phiedger,phiedger,-phiedger,-phiedger,-phiedge,-phiedge]) + binNumber = histo.AddBin(12,xe,ye) + #print '(etaCurrent <= barrelECTrans) and (etaNext >= barrelECTrans), etaCurrent: %s, etaNext: %s. bin: %s'%(etaCurrent, etaNext,binNumber) + else: + xe5 = array('d',[etaCurrent,etaNext,etaNext,etaCurrent,etaCurrent,etaNext,etaNext,etaCurrent]) + ye5 = array('d',[-math.pi,-math.pi,math.pi,math.pi,phiedge,phiedger,-phiedger,-phiedge]) + binNumber = histo.AddBin(8,xe5,ye5) + #print 'else2, etaCurrent: %s, etaNext: %s. bin: %s'%(etaCurrent, etaNext,binNumber) + return histo + + + + +# list of already created histograms +HistoSetups = { "mll" : "mll" } + +# return histogram definition in the following way: +# [ROOT.TH1F("pt_template","pt;p_{T} [GeV];Probes",len(PtBins)-1,array.array("f",PtBins)),"pt",""] +def initHisto(name): + + + CaloTagEtaBins = [-2.5,-2,-1.8,-1.6,-1.5,-1.1,-0.15,0.15,1.1,1.5,1.6,1.8,2,2.5] + CaloTagPtBins = [15,20,30,40,50,60,70,90,1e15] + PtBins = [10,15,20,25,30,35,40,50,65,80,100] + #etaBins = [-2.5, -1.1,-0.2,0.2,1.1,2.5] + etaBins = [-2.5, 2.5] + + # 1D + if name == "DetRegions": + histo = ROOT.TH1F("DetRegions_template","DetRegions;Detector Region;Probes",12,-0.5,11.5) + histo.GetXaxis().SetBinLabel(1,"unknown") + histo.GetXaxis().SetBinLabel(2,"Barrel large") + histo.GetXaxis().SetBinLabel(3,"Barrel small") + histo.GetXaxis().SetBinLabel(4,"Barrel overlap") + histo.GetXaxis().SetBinLabel(5,"Feet") + histo.GetXaxis().SetBinLabel(6,"Transition") + histo.GetXaxis().SetBinLabel(7,"Endcap large") + histo.GetXaxis().SetBinLabel(8,"Endcap small") + histo.GetXaxis().SetBinLabel(9,"BEE") + histo.GetXaxis().SetBinLabel(10,"Forward large") + histo.GetXaxis().SetBinLabel(11,"Forward small") + histo.GetXaxis().SetBinLabel(12,"Crack") + histo.SetDirectory(0) + HistoSetups[name] = name + return [histo,"detRegion",""] + elif name == "mll": + HistoSetups[name] = name + return [ROOT.TH1F("mll_template","mll;m_{ll} [GeV];TP Pairs",8,80000,100000),"mll",""] + elif name == "pt": + HistoSetups[name] = name + return [ROOT.TH1F("pt_template","pt;p_{T} [GeV];Probes",len(PtBins)-1,array("f",PtBins)),"pt",""] + elif name == "eta": + HistoSetups[name] = name + return [ROOT.TH1F("eta_template","eta;#eta;Probes",20,-2.5,2.5),"eta",""] + elif name == "etaTemp": + HistoSetups[name] = name + return [ROOT.TH1F("etaTemp_template","eta;#eta;Probes",len(etaBins)-1,array("f",etaBins)),"eta",""] + elif name == "phi": + HistoSetups[name] = name + return [ROOT.TH1F("phi_template","phi;#phi;Probes",20,-math.pi,math.pi),"phi",""] + elif name == "d0": + HistoSetups[name] = name + return [ROOT.TH1F("d0_template","d0;d_{0} [mm];Probes",20,-0.2,0.2),"d0",""] + elif name == "z0": + HistoSetups[name] = name + return [ROOT.TH1F("z0_template","z0;z_{0} [mm];Probes",20,-0.2,0.2),"z0",""] + elif name == "z_pt": + HistoSetups[name] = name + return [ROOT.TH1F("z_pt_template","z_pt;p_{T}(Z) [GeV];TP Pairs",100,0,200),"1",""] + elif name == "fineEtaPhi": + HistoSetups[name] = name + return [ROOT.TH1F("fineEtaPhi_template","fineEtaPhi;fine (#eta,#phi) bin;Probes",352,-175.5,176.5),"fineEtaPhi",""] + elif name == "fineEtaPhi_negq": + HistoSetups[name] = name + return [ROOT.TH1F("fineEtaPhi_negq_template","fineEtaPhi_negq;fine (#eta,#phi) bin;Probes",352,-175.5,176.5),"fineEtaPhi_negq",""] + elif name == "fineEtaPhi_posq": + HistoSetups[name] = name + return [ROOT.TH1F("fineEtaPhi_posq_template","fineEtaPhi_posq;fine (#eta,#phi) bin;Probes",352,-175.5,176.5),"fineEtaPhi_posq",""] + elif name == "DetRegions_Aside": + HistoSetups[name] = name + return [ROOT.TH1F("DetRegions_Aside_template","DetRegions_Aside;Detector Region;Probes",14,-0.5,13.5),"detRegion","abs(eta) > 0"] + elif name == "DetRegions_Cside": + HistoSetups[name] = name + return [ROOT.TH1F("DetRegions_Cside_template","DetRegions_Cside;Detector Region;Probes",14,-0.5,13.5),"detRegion","abs(eta) < 0"] + + # 2D + elif name == "etaphi": + HistoSetups[name] = name + return [ROOT.TH2F("etaphi_template","etaphi;#eta;#phi",30,-2.5,2.5,32,-math.pi,math.pi),"phi : eta",""] + elif name == "etapt": + HistoSetups[name] = name + return [ROOT.TH2F("etapt_template","etapt;#eta;p_{T} [GeV]",20,-2.5,2.5,10,10,120),"pt : eta",""] + elif name == "CaloTag2D": + HistoSetups[name] = name + return [ROOT.TH2F("CaloTag2D_template","CaloTag2D;#eta;p_{T} [GeV]",len(CaloTagEtaBins)-1,array("f",CaloTagEtaBins), len(CaloTagPtBins)-1, array("f",CaloTagPtBins)),"pt : eta",""] + elif name == "ptmll": + HistoSetups[name] = name + return [ROOT.TH2F("ptmll_template","ptmll;p_{T} [GeV];m_{ll} [GeV]",10,10,120,20,80000,100000),"mll : pt",""] + elif name == "etaphiFine": + HistoSetups[name] = name + return [TPFineEtaPhiHist("etaphiFine_template","etaphiFine;#eta;#phi;Efficiency"),"phi : eta",""] + + else: + print "Histogram not defined!" + return None diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Histos.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Histos.py new file mode 100644 index 00000000000..e4d1a9ea611 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Histos.py @@ -0,0 +1,715 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +from Defs import * +import Utils +import ROOT +import math +import DSConfig +import HistoDefs +graphList = [] + +## This class provides the basic functionality to read individual histos +class TPHisto: + + ## normal init: based on conent parameters + def __init__ (self, name,probe,match,region,chargeprod,kind,var, histo=None,infile=None,doClosure=False,LumiScale=-1,useAsymEff=True,analysis=Analysis.Z_Reco): + self.Name = name + self.Analysis = analysis + self.Probe = probe + self.Match = match + self.Region = region + self.ChargeProd = chargeprod + self.Kind = kind + self.Var = var + self.Histo = histo + self.Infile = infile + self.DoClosure = doClosure + self.LumiScale = LumiScale + self.UseAsymEff = useAsymEff + + if self.Histo == None and self.Infile != None: + self.Load() + + ## create instance from an existing histo + @classmethod + def FromHist (out,name,h_in,fin=0): + if h_in == None: + return + fname = h_in.GetName() + Args = fname.split("_") + kindcand = Args[5] + kind = "" + for cand in [bla for bla in PlotKinds.__dict__.keys() if not "__" in bla ]: + if cand in kindcand: + kind = cand + var = kindcand.split(cand)[-1] + hcl = h_in.Clone("Cl_"+name+"_"+h_in.GetName()) + + return out(name=name,probe = Args[0],region=Args[2], chargeprod = Args[3],match=Args[4],kind=kind,var=var,histo=hcl,infile=fin) + + + # Utility methods for I/O purposes + def GetPlotName (self): + #return "_".join([self.Probe,self.Probe,self.Region,self.ChargeProd,self.Match,self.Kind])+self.Var + return "_".join([self.Probe,self.Region,self.Probe,self.ChargeProd,self.Match,self.Kind])+self.Var + def GetTreeName(self): + return "_".join(["TPTree",self.Probe,self.ChargeProd]) + def GetCFName (self): + #return "_".join([self.Probe,self.Probe,self.Region,self.ChargeProd,self.Match,self.Kind])+self.Var + return "_".join([self.Probe,DetRegions.All,self.Probe,self.ChargeProd,"CutFlowsMainSelection"]) + def GetTreePath(self): + return "%s/Trees/"%self.Analysis+"_".join([self.Probe,self.ChargeProd]) + def GetPlotPath(self): + return "/".join([self.Analysis,self.Probe+"_"+self.Region,self.Probe+"_"+self.ChargeProd,self.Match,self.Kind]) + def GetFullPath(self): + return self.GetPlotPath()+"/"+self.GetPlotName() + def GetCFPath(self): + return "/".join([self.Analysis,self.Probe+"_"+DetRegions.All,self.Probe+"_"+self.ChargeProd,"CutFlows"]) + def GetFullTreePath(self): + return self.GetTreePath()+"/"+self.GetTreeName() + def GetFullCFPath(self): + return self.GetCFPath()+"/"+self.GetCFName() + # Write the histo to a file + def Write(self, File = None, Dir = None): + if File == None: + File = self.Infile + if Dir == None: + Dir = self.GetPlotPath() + if not File == None or self.Histo == None: + dir = ROOT.gDirectory.GetName() + File.cd() + subdirs = Dir.split("/") + for subdir in subdirs: + if not ROOT.gDirectory.GetDirectory(subdir,False): + ROOT.gDirectory.mkdir(subdir) + if not ROOT.gDirectory.cd(subdir): + print "Writing failed - unable to walk through directory structure "+dir + self.Histo.Write() + File.cd("") + # Load the histo from a file + def Load(self, File=None, Dir=None): + if (self.UseAsymEff) and not ":" in HistoDefs.initHisto(self.Var)[1]: + if self.Kind == PlotKinds.Efficiency: + graph = ROOT.TGraphAsymmErrors() + graph.SetName(self.Name+"graph") + self.Histo = graph + graphList.append(graph) + return + if File == None: + File = self.Infile + if Dir == None: + Dir = self.GetPlotPath() + h = File.Get(Dir+"/"+self.GetPlotName()) + if h == None or self.DoClosure or self.LumiScale!=-1: + self.ExtractFromTree(File,LumiScale=self.LumiScale) + else: + self.ExtractDirect(File) + def ExtractDirect (self,File=None,Dir=None): + if File == None: + File = self.Infile + if Dir == None: + Dir = self.GetPlotPath() + h = File.Get(Dir+"/"+self.GetPlotName()) + if h == None or not hasattr(h,"GetNbinsX"): + print "Unable to load histo "+Dir+"/"+self.GetPlotName() + else: + self.Histo = h.Clone("Cl_"+self.Name+"_"+h.GetName()) + if self.Var == "DetRegions": + #h2 = HistoSetups["DetRegions"][0].Clone(self.Histo.GetName()+"2") + h2 = HistoDefs.initHisto("DetRegions")[0].Clone(self.Histo.GetName()+"2") + h2.GetXaxis().SetTitleSize(self.Histo.GetXaxis().GetTitleSize()) + h2.GetXaxis().SetTitleOffset(self.Histo.GetXaxis().GetTitleOffset()) + h2.GetXaxis().SetLabelSize(self.Histo.GetXaxis().GetLabelSize()) + h2.GetXaxis().SetLabelOffset(self.Histo.GetXaxis().GetLabelOffset()) + h2.GetYaxis().SetTitleSize(self.Histo.GetYaxis().GetTitleSize()) + h2.GetYaxis().SetTitleOffset(self.Histo.GetYaxis().GetTitleOffset()) + h2.GetYaxis().SetLabelSize(self.Histo.GetYaxis().GetLabelSize()) + h2.GetYaxis().SetLabelOffset(self.Histo.GetYaxis().GetLabelOffset()) + h2.GetXaxis().SetTitle(self.Histo.GetXaxis().GetTitle()) + h2.GetYaxis().SetTitle(self.Histo.GetYaxis().GetTitle()) + for i in range (1, self.Histo.GetNbinsX()+1): + if (i > h2.GetNbinsX()): + h2.SetBinContent(h2.GetNbinsX(),h2.GetBinContent(h2.GetNbinsX())+self.Histo.GetBinContent(i)) + h2.SetBinError(h2.GetNbinsX(),math.sqrt(h2.GetBinError(h2.GetNbinsX())**2+self.Histo.GetBinError(i)**2)) + else: + h2.SetBinContent(i,self.Histo.GetBinContent(i)) + h2.SetBinError(i,self.Histo.GetBinError(i)) + + self.Histo = h2 + self.Histo.SetDirectory(0) + print "Note: Reading %s directly"%self.GetPlotName() + #print "Got a plot with %i bins"%self.Histo.GetNbinsX() + def PassesCuts(self, tree, eventNumber, cutlist=[]): + + weight = 1. + # get current event and check cuts + tree.GetEntry(eventNumber) + for cut in cutlist: + if "weight" in cut: + #print "event %s: weight %s: %s"%(eventNumber,cut,getattr(tree,cut)) + weight = weight*float(getattr(tree,cut)) + if cut != "1": + if ">=" in cut or "<=" in cut: + print "%s in cuts currently not supported, take </> instead"%cut + if ">" in cut: + if "abs[" in cut: + cut = cut.replace("abs[", "") + if math.fabs(getattr(tree,cut.split(">")[0])) <= float(cut.split(">")[1]): + return 0. + else: + if getattr(tree,cut.split(">")[0]) <= float(cut.split(">")[1]): + return 0. + elif "<" in cut: + if "abs[" in cut: + cut = cut.replace("abs[", "") + if math.fabs(getattr(tree,cut.split("<")[0])) >= float(cut.split("<")[1]): + return 0. + else: + if getattr(tree,cut.split("<")[0]) >= float(cut.split("<")[1]): + return 0. + else: + #print "event %s: cut %s: %s"%(eventNumber,cut,getattr(tree,cut)) + if getattr(tree,cut) != 1: + return 0. + + return weight + + # reverse engineer from the existing histo + def ExtractFromTree(self, File=None, Dir=None, LumiScale=-1): + #if not self.Var in HistoDefs.HistoSetups.iterkeys(): + ##if not self.Var in HistoDefs.Histonames.iterkeys(): + #print "Unsupported histo requested from tree: %s"%(self.Var) + #self.Histo = None + #return + if File == None: + File = self.Infile + if Dir == None: + Dir = self.GetTreePath() + + h = HistoDefs.initHisto(self.Var)[0].Clone(self.GetPlotName()) + if h == None: + print "Unsupported histo requested from tree: %s"%(self.Var) + return + print Dir+"/"+self.GetTreeName() + # what to do here: TH2F plots need PlotKinds.Efficiency! +# if self.Kind != PlotKinds.Efficiency: + + t = File.Get(Dir+"/"+self.GetTreeName()) + try: + ntodo = t.GetEntries() + if LumiScale > 0: + ntodo = int(ntodo * LumiScale) + except: + print "Failed to load %s"%self.GetTreeName() + throw + #h = HistoSetups[self.Var][0].Clone(self.GetPlotName()) + h.Sumw2() + h.GetXaxis().SetLabelSize(0.05) + h.GetXaxis().SetTitleSize(0.05) + h.GetXaxis().SetTitleOffset(1.4) + h.GetYaxis().SetLabelSize(0.05) + h.GetYaxis().SetTitleSize(0.05) + h.GetYaxis().SetTitleOffset(1.4) + + tmpVar = self.Var + + cuts = "(%s) * (%s)"%(HistoDefs.initHisto(self.Var)[2], ExtraCuts[self.Region]) + #cuts = "(%s) * (%s)"%(HistoSetups[self.Var][2], ExtraCuts[self.Region]) + if len((self.Var).split('_'))>1: + if "posq" in ((self.Var).split('_'))[1]: + cuts = "(%s) * ( q > 0)"%cuts + elif "negq" in ((self.Var).split('_'))[1]: + cuts = "(%s) * ( q < 0)"%cuts + else: + print 'Error: During reading from tree, unknown variable detected: %s'%(((self.Var).split('_'))[1]) + tmpVar = ((self.Var).split('_'))[0] + + #if not "Truth" in self.Probe: + if not h.InheritsFrom("TH2"): + h.GetYaxis().SetTitle("Probes") + if self.Kind == PlotKinds.Matches: + cuts = "(%s) * (matched_%s)"%(cuts,self.Match) + #print cuts + if self.DoClosure: + if cuts != "": + cuts = "(%s) * (scale_factor_%s)"%(cuts,self.Match) + else: + cuts = "scale_factor_%s"%(self.Match) + #print cuts + if not h.InheritsFrom("TH2"): + h.GetYaxis().SetTitle("Matched Probes") + cuts = cuts.replace("()","(1)") + #print " ++++++++ Cuts are %s ++++++++++++++++"%cuts + if LumiScale==-1: + #t.Project(self.GetPlotName(),HistoSetups[tmpVar][1],cuts) + t.Project(self.GetPlotName(),HistoDefs.initHisto(tmpVar)[1],cuts) + else: + #if ":" in HistoSetups[tmpVar][1]: + if ":" in HistoDefs.initHisto(tmpVar)[1]: + print "Using LumiScale in 2D histos currently not supported! Running without LumiScale instead." + #t.Project(self.GetPlotName(),HistoSetups[tmpVar][1],cuts) + t.Project(self.GetPlotName(),HistoDefs.initHisto(tmpVar)[1],cuts) + else: + cuts = cuts.replace(" ", "") + # adjust abs() naming in order to use it later + cuts = cuts.replace("abs(", "abs[") + cuts = cuts.replace("(","") + cuts = cuts.replace(")","") + cutlist = cuts.split("*") + cutlist = filter(lambda a: a != "1", cutlist) + + nentries = t.GetEntries() + if nentries==0: + print "Empty files!" + + curEvt = 0 + for event in t: + if curEvt>ntodo: + print "Max Number of events=%i reached!"%ntodo + break + else: + + #binno = getattr(t,HistoSetups[tmpVar][1]) + binno = getattr(t,HistoDefs.initHisto(tmpVar)[1]) + #if HistoSetups[tmpVar][1] == "detRegion" and binno > 11: + if HistoDefs.initHisto(tmpVar)[1] == "detRegion" and binno > 11: + binno = 11 + h.Fill(binno,self.PassesCuts(t,curEvt,cutlist)) + if curEvt % 5000 == 0: + print "Event number %d out of %d " % (curEvt, nentries) + curEvt += 1 + + print "Note: Reading %s from the TP tree"%self.GetPlotName() + + h.SetDirectory(0) + #h.Print() + self.Histo = h + +# this guy provides a whole set of matching histos +class TPHistoSet: + def __init__(self,name,probe,match,region,var,infile=None,doClosure=False,LumiScale=-1,useAsymEff=True,analysis=Analysis.Z_Reco): + self.Histos={} + self.Name = name + self.Analysis = analysis + self.Infile = infile + self.Probe = probe + self.Match = match + self.Region = region + self.Var = var + self.DoClosure = doClosure + self.LumiScale = LumiScale + self.UseAsymEff = useAsymEff + + print '\nCreating TPHistoSet %s for %s'%(name,infile) + for CP in [bla for bla in ChargeProducts.__dict__.keys() if not "__" in bla]: + self.Histos[CP] = {} + if (self.Probe == Probes.TruthToID or self.Probe == Probes.TruthToMu) and ("SC" in CP or "AntiIso" in CP): + continue + for Kind in [bla for bla in PlotKinds.__dict__.keys() if not "__" in bla]: + self.Histos[CP][Kind] = TPHisto(name=name,probe=probe,match=match,region=region,var=var,chargeprod = getattr(ChargeProducts,CP), kind=getattr(PlotKinds,Kind), infile=infile,histo=None,doClosure=self.DoClosure,LumiScale=self.LumiScale,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + #self.UpdateEff() + def UpdateEff(self): + Utils.EffDivide(self.Histos[ChargeProducts.OC][PlotKinds.Matches].Histo,self.Histos[ChargeProducts.OC][PlotKinds.Probes].Histo,self.Histos[ChargeProducts.OC][PlotKinds.Efficiency].Histo) + + def ApplyIDeff (self, ideff=None): + if ideff!= None: + for k,v in self.Histos.iteritems(): + if v["Efficiency"].Histo.InheritsFrom("TH2Poly"): + Utils.PolyMultiply(v["Efficiency"].Histo,ideff.Histos[k]["Efficiency"].Histo,v["Efficiency"].Histo) + elif v["Efficiency"].Histo.InheritsFrom("TGraphAsymmErrors"): + Utils.GraphMultiply(v["Efficiency"].Histo,ideff.Histos[k]["Efficiency"].Histo,v["Efficiency"].Histo) + else: + v["Efficiency"].Histo.Multiply(ideff.Histos[k]["Efficiency"].Histo) + + # Data-driven background correction procedure + def DataDrivenBG (self,SignalMC=[],IrredMC=[],RedMC=[], SysVar = ""): + # produce a clone of the original + #print "Producing a background template with fraction %.3f%% of entries"%(self.LumiScale*100.) + Bkg = TPHistoSet("BackgroundTemplateFrom"+self.Name,self.Probe,self.Match,self.Region,self.Var,self.Infile,doClosure=False, LumiScale=self.LumiScale,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + # and update its contents + for CP in [ChargeProducts.OC, ChargeProducts.SC]: + for thing in ["Probes","Matches"]: + h_bkg = Bkg.Histos[CP][thing].Histo + if h_bkg == None: + Bkg.Histos[CP][thing] = self.Histos[ChargeProducts.SC][thing].Histo.Clone("bkg_from"+self.Histos[ChargeProducts.SC][thing].GetName()) + h_bkg = Bkg.Histos[CP][thing].Histo + # Start out with an empty histogram + h_bkg.Reset("") + + # a) Take the same-charge distribution from data + h_bkg.Add(self.Histos[ChargeProducts.SC][thing].Histo,1.) + + # b) Subtract any irreducibe same-charge pairs (they are taken from MC) + for subtractme in SignalMC+IrredMC: # subtract irreducibe same sign + h_bkg.Add(subtractme.Histos[ChargeProducts.SC][thing].Histo,-1.00) + # c) Correct the OC version for a non-unity OC/SC ratio in QCD using MC or anti-isolated data + if CP == ChargeProducts.OC and not self.Probe == Probes.ID: + qcdOC = TPHisto(name="qcdOCtmp",probe=self.Probe,match=self.Match,region=self.Region,var="mll",chargeprod=ChargeProducts.OC_AntiIso, kind=thing, infile=self.Infile, histo=None, doClosure=False,useAsymEff=False,analysis=self.Analysis) + n_qcdOC = qcdOC.Histo.Integral(1,qcdOC.Histo.GetXaxis().FindBin(80e3)) + qcdOC.Histo.Integral(qcdOC.Histo.GetXaxis().FindBin(100e3),qcdOC.Histo.GetNbinsX()) + qcdSC = TPHisto(name="qcdOCtmp",probe=self.Probe,match=self.Match,region=self.Region,var="mll",chargeprod=ChargeProducts.SC_AntiIso, kind=thing, infile=self.Infile, histo=None, doClosure=False,useAsymEff=False,analysis=self.Analysis) + n_qcdSC = qcdSC.Histo.Integral(1,qcdSC.Histo.GetXaxis().FindBin(80e3)) + qcdSC.Histo.Integral(qcdSC.Histo.GetXaxis().FindBin(100e3),qcdSC.Histo.GetNbinsX()) + if n_qcdSC == 0: + scale = 1 + else: + scale = n_qcdOC / n_qcdSC + if SysVar == "up": + scale = 1 + 2.*(scale - 1) + if SysVar == "down": + scale = 1 + #print "BG scale is %.3f / %.3f = %.3f"%(n_qcdOC, n_qcdSC, scale) + h_bkg.Scale(scale) + # that's it! + return Bkg + + def ScaleToData(self,data): + dataint = data.Histos[ChargeProducts.OC][PlotKinds.Probes].Histo.Integral() + myint = self.Histos[ChargeProducts.OC][PlotKinds.Probes].Histo.Integral() + scale = dataint / myint + #print "Scale via norm: %.4f"%scale + for CP in [bla for bla in ChargeProducts.__dict__.keys() if not "__" in bla]: + for thing in ["Probes","Matches"]: + self.Histos[CP][thing].Histo.Scale(scale) + def ApplyXSScale(self,xs,nsample=-1,lumi=20300.): + if nsample < 0: + if self.Infile == None: + print "Error: Please provide either the number of MC events or a valid iput file with a cut flow if you want to do XS weighting" + cf = self.Histos[ChargeProducts.OC][PlotKinds.Matches].GetFullCFPath() + #print cf + hcf = self.Infile.Get(cf) + nsample = float(hcf.GetBinContent(1)) + #print "nsample %.2f"%nsample + scale = xs * lumi / nsample + #print "xs is %.2f, lumi is %.4f"%(xs,lumi) + #print "XS scale is %.4f"%scale + for CP in [bla for bla in ChargeProducts.__dict__.keys() if not "__" in bla]: + for thing in ["Probes","Matches"]: + self.Histos[CP][thing].Histo.Scale(scale) + + def SubtractBG(self,Backgrounds=[]): + if self.Probe == Probes.TruthToID or self.Probe == Probes.TruthToMu: + return + for CP in [bla for bla in ChargeProducts.__dict__.keys() if not "__" in bla]: + for thing in ["Probes","Matches"]: + tosub = self.Histos[CP][thing].Histo + for BG in Backgrounds: + subthis = BG.Histos[CP][thing].Histo + tosub.Add(subthis,-1.) + #print 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ' + #print CP + #print thing + #print BG + #print '\n\n\n\n' + #for i in range(1, Utils.GetNbins(subthis)): + #print subthis.GetBinContent(i), subthis.GetBinError(i) + +class TPFinalHistos: + def __init__(self,name,probe,match,region,var,infiles,corr = True,sysVar = "",doClosure=False,LumiScale=-1,doPreRecEtaCopy=False,useAsymEff=True,analysis=Analysis.Z_Reco): + self.Histos={} + self.Name = name + self.Analysis = analysis + self.Probe = probe + self.Match = match + self.Region = region + self.Var = var + self.Infiles = infiles + self.Corr = corr + self.SysVar = sysVar + self.DoClosure = doClosure + self.LumiScale = LumiScale + self.DoPreRecEtaCopy = doPreRecEtaCopy + self.UseAsymEff = useAsymEff + + self.Histos[HistoKinds.Efficiency] = {} + self.Histos[HistoKinds.SF] = {} + self.Histos[PlotKinds.Probes] = {} + + #print 'Creating TPHistoSet for %s'%(infiles[0][0]) + MCHists = TPHistoSet(infiles[0][0],var=var,probe=probe,match = match, region = region, infile = ROOT.TFile(infiles[0][1].Filepath,"READ"), doClosure=self.DoClosure,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + MCHistsScaled = TPHistoSet(infiles[0][0],var=var,probe=probe,match = match, region = region, infile = ROOT.TFile(infiles[0][1].Filepath,"READ"), doClosure=self.DoClosure,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + + #print 'Creating TPHistoSet for %s'%(infiles[1][0]) + DataHists = TPHistoSet(infiles[1][0],var=var,probe=probe,match = match, region = region, infile = ROOT.TFile(infiles[1][1].Filepath,"READ"), LumiScale=self.LumiScale,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + + # scale MCHists first, since it is used in SubtractBG + MCHistsScaled.ScaleToData(DataHists) + #TODO: reinclude ApplyXSScale? + #MCHists.ApplyXSScale(infiles[0][1].XS, infiles[0][1].nEvents, infiles[0][1].Lumi) + BkgDataHists = DataHists.DataDrivenBG(SignalMC=[MCHistsScaled],SysVar = sysVar) + DataHists.SubtractBG([BkgDataHists]) + + + #print 'Creating TPHistoSet for %s Truth'%(infiles[0][0]) + if Matches.ID in match: + Truth = TPHistoSet("Truth",var=var,probe=Probes.TruthToID,match = match, region = region, infile = ROOT.TFile(infiles[0][1].Filepath,"READ"), doClosure=False,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + else: + Truth = TPHistoSet("Truth",var=var,probe=Probes.TruthToMu,match = match, region = region, infile = ROOT.TFile(infiles[0][1].Filepath,"READ"), doClosure=False,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + + #print 'DataHists.UpdateEff()' + DataHists.UpdateEff() + #print 'MCHists.UpdateEff()' + MCHists.UpdateEff() + #print 'Truth.UpdateEff()' + Truth.UpdateEff() + + + # Apply the ID eff if we have to + if corr and (probe == Probes.ID or probe == Probes.Calo): + if "dRUp" in match: + match = "%s_dRUp"%(Matches.ID) + elif "dRDown" in match: + match = "%s_dRDown"%(Matches.ID) + else: + match=Matches.ID + DataIDHists = TPHistoSet("DataID", var=var, probe=Probes.MStoID, match=match, region=region, infile=ROOT.TFile(infiles[1][1].Filepath, "READ"),useAsymEff=self.UseAsymEff,analysis=self.Analysis) + MCIDHists = TPHistoSet("MCID", var=var, probe=Probes.MStoID, match=match, region=region, infile=ROOT.TFile(infiles[0][1].Filepath, "READ"), doClosure=False,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + MCIDHistsScaled = TPHistoSet("MCID", var=var, probe=Probes.MStoID, match=match, region=region, infile=ROOT.TFile(infiles[0][1].Filepath, "READ"), doClosure=False,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + #TODO: reinclude ApplyXSScale? + #MCIDHists.ApplyXSScale(infiles[0][1].XS, infiles[0][1].nEvents, infiles[0][1].Lumi) + MCIDHistsScaled.ScaleToData(DataIDHists) + DataIDHists.SubtractBG([DataIDHists.DataDrivenBG(SignalMC=[MCIDHistsScaled],SysVar = sysVar)]) + MCIDHists.UpdateEff() + DataIDHists.UpdateEff() + + DataHists.ApplyIDeff(DataIDHists) + MCHists.ApplyIDeff(MCIDHists) + + + # fill probe histos: + self.Histos[PlotKinds.Probes]["Data"] = DataHists.Histos[ChargeProducts.OC][PlotKinds.Probes].Histo + self.Histos[PlotKinds.Probes]["MC"] = MCHistsScaled.Histos[ChargeProducts.OC][PlotKinds.Probes].Histo + self.Histos[PlotKinds.Probes]["Bkg"] = BkgDataHists.Histos[ChargeProducts.OC][PlotKinds.Probes].Histo + h_model = self.Histos[PlotKinds.Probes]["MC"].Clone('%s_model'%(self.Histos[PlotKinds.Probes]["MC"].GetName())) + h_dataVsModel = self.Histos[PlotKinds.Probes]["Data"].Clone('%s_DataVsModel'%(self.Histos[PlotKinds.Probes]["Data"].GetName())) + if not self.Histos[PlotKinds.Probes]["MC"].InheritsFrom("TGraphAsymmErrors"): + h_model.SetDirectory(0) + h_dataVsModel.SetDirectory(0) + h_model.Add(self.Histos[PlotKinds.Probes]["MC"],self.Histos[PlotKinds.Probes]["Bkg"],1.,1.) + self.Histos[PlotKinds.Probes]["Model"] = h_model + if self.Histos[PlotKinds.Probes]["MC"].InheritsFrom("TH2Poly"): + Utils.PolyDivide(self.Histos[PlotKinds.Probes]["Data"],self.Histos[PlotKinds.Probes]["Model"],h_dataVsModel) + elif self.Histos[PlotKinds.Probes]["MC"].InheritsFrom("TGraphAsymmErrors"): + Utils.GraphDivide(self.Histos[PlotKinds.Probes]["Data"],self.Histos[PlotKinds.Probes]["Model"],h_dataVsModel) + else: + h_dataVsModel.Divide(self.Histos[PlotKinds.Probes]["Data"],self.Histos[PlotKinds.Probes]["Model"],1.,1.) + self.Histos[PlotKinds.Probes]["DataVsModel"] = h_dataVsModel + + # fill efficiency histos: + h_data = DataHists.Histos[ChargeProducts.OC][PlotKinds.Efficiency].Histo + self.Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency] = h_data + h_mc = MCHists.Histos[ChargeProducts.OC][PlotKinds.Efficiency].Histo + h_mc.SetName(h_mc.GetName().replace('Efficiency','MCEfficiency')) + self.Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency] = h_mc + h_truth = Truth.Histos[ChargeProducts.OC][PlotKinds.Efficiency].Histo + h_truth.SetName(h_truth.GetName().replace('Efficiency','TruthEfficiency')) + self.Histos[HistoKinds.Efficiency][HistoKinds.TruthEfficiency] = h_truth + + # for pre-recommendations, copy negative eta bins of transition region to positive ones: + if self.DoPreRecEtaCopy: + Utils.CopyEtaBins(h_data) + Utils.CopyEtaBins(h_mc) + Utils.CopyEtaBins(h_truth) + + # replace 'MCEfficiency' since it was added to h_mc above + ratio = h_mc.Clone(h_mc.GetName().replace('MCEfficiency','SF')) + ratiotruth = h_truth.Clone(h_mc.GetName().replace('MCEfficiency','SFTruth')) + ratiotruthMC = h_truth.Clone(h_mc.GetName().replace('MCEfficiency','SFMCByTruth')) + if not h_mc.InheritsFrom("TGraphAsymmErrors"): + ratio.SetDirectory(0) + ratiotruth.SetDirectory(0) + ratiotruthMC.SetDirectory(0) + + if h_mc.InheritsFrom("TH2Poly"): + Utils.PolyDivide(h_data,h_mc,ratio) + Utils.PolyDivide(h_data,h_truth,ratiotruth) + Utils.PolyDivide(h_mc,h_truth,ratiotruthMC) + elif h_mc.InheritsFrom("TGraphAsymmErrors"): + Utils.GraphDivide(h_data,h_mc,ratio) + Utils.GraphDivide(h_data,h_truth,ratiotruth) + Utils.GraphDivide(h_mc,h_truth,ratiotruthMC) + else: + ratio.Divide(h_data,h_mc,1.,1.) + ratiotruth.Divide(h_data,h_truth,1.,1.) + ratiotruthMC.Divide(h_mc,h_truth,1.,1.) + + + for hist in [ratio,ratiotruth,ratiotruthMC]: + for i in range(0, Utils.GetNbins(hist)): + if hist.InheritsFrom("TGraphAsymmErrors"): + if hist.GetErrorYhigh(i)>1.0: + hist.SetPointEYhigh(i,1.0) + if hist.GetErrorYlow(i)>1.0: + hist.SetPointEYlow(i,1.0) + else: + if hist.GetBinError(i)>1.0: + hist.SetBinError(i,1.0) + + # fill scale factor histos: + self.Histos[HistoKinds.SF][HistoKinds.SF] = ratio + self.Histos[HistoKinds.SF][HistoKinds.TruthSF] = ratiotruth + self.Histos[HistoKinds.SF][HistoKinds.MCTruthSF] = ratiotruthMC + + +class TPFinalSysHistos: + def __init__(self,name,probe,match,region,var,infiles,charge=None,corr=True,doClosure=False,LumiScale=-1,doPreRecEtaCopy=False,useAsymEff=True,analysis = Analysis.Z_Reco): + self.HistoSets={} + self.Name = name + self.Probe = probe + self.Match = match + self.Region = region + self.Var = var + self.Infiles = infiles + self.Charge = charge + self.Corr = corr + self.Analysis = analysis + self.DoClosure = doClosure + self.LumiScale = LumiScale + self.DoPreRecEtaCopy = doPreRecEtaCopy + self.UseAsymEff = useAsymEff + + print '\nCreating TPFinalSysHistos for %s%s'%(var,charge) + # fill nominal TPFinalHistos first, since they are needed for systematic evaluation + self.HistoSets["Nominal"] = self.CreateTPFinalHistos (self.Name,self.Probe,self.Match,self.Region,self.Var,self.Infiles,None,self.Charge,self.Corr,analysis=self.Analysis) + + for syst in [bla for bla in Systematics.__dict__.keys() if not "__" in bla ]: + if Systematics.All != getattr(Systematics,syst): + print '\n\n\nSystematic: %s'%getattr(Systematics,syst) + self.HistoSets[getattr(Systematics,syst)] = self.CreateTPFinalHistos (self.Name+"_"+syst,self.Probe,self.Match,self.Region,self.Var,self.Infiles,syst,self.Charge,self.Corr,analysis=self.Analysis) + + # fill total systematics histos -> Clone dR syst and add others in quadrature + totalSys = [] + for hist in self.HistoSets[Systematics.dR]: + totalSys.append( hist.Clone(hist.GetName().replace(Systematics.dR,Systematics.All)) ) + self.HistoSets[Systematics.All] = totalSys + + # use add_in_quadrature(hist_add_to, hist_add_this) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][0],self.HistoSets[Systematics.truth][0]) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][0],self.HistoSets[Systematics.BG][0]) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][0],self.HistoSets[Systematics.Det][0]) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][1],self.HistoSets[Systematics.truth][1]) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][1],self.HistoSets[Systematics.BG][1]) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][1],self.HistoSets[Systematics.Det][1]) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][2],self.HistoSets[Systematics.truth][2]) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][2],self.HistoSets[Systematics.BG][2]) + Utils.add_in_quadrature(self.HistoSets[Systematics.All][2],self.HistoSets[Systematics.Det][2]) + + def CreateTPFinalHistos (self,name,probe,match,region,var,infiles,syst,charge,corr,analysis=Analysis.Z_Reco): + + if syst != None: + if Systematics.dR == getattr(Systematics,syst): + TPFinalHistos_dRup = self.CreateTPHistos(name,probe,match,region,var,infiles,"dRUp",charge,corr) + TPFinalHistos_dRDown = self.CreateTPHistos(name,probe,match,region,var,infiles,"dRDown",charge,corr) + # compare with nominal: + h_dR_sys_data_eff = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], TPFinalHistos_dRup.Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], TPFinalHistos_dRDown.Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], "dR", 1.) + h_dR_sys_mc_eff = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], TPFinalHistos_dRup.Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], TPFinalHistos_dRDown.Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], "dR", 1.) + h_dR_sys_sf = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF], TPFinalHistos_dRup.Histos[HistoKinds.SF][HistoKinds.SF], TPFinalHistos_dRDown.Histos[HistoKinds.SF][HistoKinds.SF], "dR", 1.) + return [h_dR_sys_data_eff, h_dR_sys_mc_eff, h_dR_sys_sf] + elif Systematics.truth == getattr(Systematics,syst): + h_truth_sys_data_eff = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.TruthEfficiency], self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], "truth", 1.) + h_truth_sys_mc_eff = h_truth_sys_data_eff + h_truth_sys_sf = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.SF][HistoKinds.TruthSF], self.HistoSets["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF], self.HistoSets["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF], "truth", 0.5) + return [h_truth_sys_data_eff, h_truth_sys_mc_eff, h_truth_sys_sf] + elif Systematics.BG == getattr(Systematics,syst): + TPFinalHistos_BGUp = self.CreateTPHistos(name,probe,match,region,var,infiles,"BGUp",charge,corr) + TPFinalHistos_BGDown = self.CreateTPHistos(name,probe,match,region,var,infiles,"BGDown",charge,corr) + # compare with nominal: + h_BG_sys_data_eff = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], TPFinalHistos_BGUp.Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], TPFinalHistos_BGDown.Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], "BG", 1.) + h_BG_sys_mc_eff = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], TPFinalHistos_BGUp.Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], TPFinalHistos_BGDown.Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], "BG", 1.) + h_BG_sys_sf = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF], TPFinalHistos_BGUp.Histos[HistoKinds.SF][HistoKinds.SF], TPFinalHistos_BGDown.Histos[HistoKinds.SF][HistoKinds.SF], "BG", 1.) + return [h_BG_sys_data_eff, h_BG_sys_mc_eff, h_BG_sys_sf] + elif Systematics.Det == getattr(Systematics,syst): + # detector systematic compares MC14 vs MC15 + if "MC14" in infiles[0][1].Label: + #print "use %s for detector systematic evaluation"%DSConfig.Zmumu_mc15.Filepath + TPFinalHistos_MC15 = self.CreateTPHistos(name,probe,match,region,var,[["MC",DSConfig.Zmumu_mc15],self.Infiles[1]],None,charge,corr,doPreRecCopy=False) + else: + #print "use %s for detector systematic evaluation"%DSConfig.Zmumu_r20_1_3_3.Filepath + TPFinalHistos_MC15 = self.CreateTPHistos(name,probe,match,region,var,[["MC",DSConfig.Zmumu_mc15],self.Infiles[1]],None,charge,corr,doPreRecCopy=False) + # compare with MC14: + h_Det_sys_data_eff = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], TPFinalHistos_MC15.Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], TPFinalHistos_MC15.Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency], "Det", 1.) + h_Det_sys_mc_eff = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], TPFinalHistos_MC15.Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], TPFinalHistos_MC15.Histos[HistoKinds.Efficiency][HistoKinds.MCEfficiency], "Det", 1.) + h_Det_sys_sf = Utils.sysCompare(self.HistoSets["Nominal"].Histos[HistoKinds.SF][HistoKinds.SF], TPFinalHistos_MC15.Histos[HistoKinds.SF][HistoKinds.SF], TPFinalHistos_MC15.Histos[HistoKinds.SF][HistoKinds.SF], "Det", 1.) + return [h_Det_sys_data_eff, h_Det_sys_mc_eff, h_Det_sys_sf] + else: + print 'CreateTPFinalHistos() was called with unknown systematic type: %s! Abort!'%(syst) + return None + else: + return self.CreateTPHistos(name,probe,match,region,var,infiles,syst,charge,corr) + + def CreateTPHistos (self,name,probe,match,region,var,infiles,syst,charge,corr,doPreRecCopy=True): + + if charge != None: + if "pos" in charge: + var = var+"_posq" + elif "neg" in charge: + var = var+"_negq" + else: + print "Error: charge %s not recognized!"%(charge) + return None + + BGvar = "" + if syst == "BGUp": + BGvar = "up" + elif syst == "BGDown": + BGvar = "down" + + if syst == "dRUp": + match = "%s_dRUp"%(match) + elif syst == "dRDown": + match = "%s_dRDown"%(match) + + name = 'hists_%s_%s_%s_%s'%(var, probe, match, syst) + + if not doPreRecCopy: + print 'doing MC15 systematic: set doPreRecCopy to False' + return TPFinalHistos(name,probe,match,region,var,infiles,sysVar = BGvar,doClosure=self.DoClosure,LumiScale=self.LumiScale,doPreRecEtaCopy=False,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + else: + return TPFinalHistos(name,probe,match,region,var,infiles,sysVar = BGvar,doClosure=self.DoClosure,LumiScale=self.LumiScale,doPreRecEtaCopy=self.DoPreRecEtaCopy,useAsymEff=self.UseAsymEff,analysis=self.Analysis) + + +########## some testing code ############## +if __name__ == "__main__": + bla = TPHisto (name="Test",probe = Probes.ID, match = Matches.Medium, region = DetRegions.All, kind = PlotKinds.Efficiency, var = "eta", chargeprod = ChargeProducts.OC) + + + #print bla.GetFullPath() + #print bla.GetFullTreePath() + + import ROOT + #f = ROOT.TFile.Open("/afs/ipp-garching.mpg.de/home/g/goblirsc/analysis/TP_nightly/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonPerformanceAlgs/run/test.merge.root","READ") + + #bla.ExtractFromTree(f) + + #bla2 = TPHisto (name="Test",probe = Probes.ID, match = Matches.Medium, region = DetRegions.All, kind = PlotKinds.Efficiency, var = "eta", chargeprod = ChargeProducts.OC,infile=ROOT.TFile.Open("/afs/ipp-garching.mpg.de/home/g/goblirsc/analysis/TP_nightly/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonPerformanceAlgs/run/test.merge.root","READ")) + + + #print f.Get(bla.GetFullTreePath()) + + ##print [bla for bla in Matches.__dict__.keys() if not "__" in bla ] + #import ROOT + #moo = ROOT.TH1F(bla.GetPlotName(),bla.GetFullPath(),100,0,1) + #hist2 = TPHisto.FromHist("TestMC2",moo,None) + #print hist2.GetPlotName() + #print hist2.Histo.GetName() + #hist2.Write(ROOT.TFile("out.root","RECREATE"),"Test/Dir/Structure") + + #bla.Load(ROOT.TFile("out.root","READ"),"Test/Dir/Structure") + #print bla.Histo + + + + ## Larger scale test + infile = ROOT.TFile("/afs/ipp-garching.mpg.de/home/g/goblirsc/analysis/TP_nightly/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonPerformanceAlgs/run/test.merge.root") + aset = TPHistoSet("Blah",probe=Probes.ID, match = Matches.Medium, region = DetRegions.All, var = "etaphi", infile = infile,analysis=self.Analysis) + can = ROOT.TCanvas() + can.cd() + ROOT.gStyle.SetPalette(54) + ROOT.gPad.SetRightMargin(0.2) + aset.Histos[ChargeProducts.OC][PlotKinds.Efficiency].Histo.Draw("COLZ") + #can.SaveAs("test.pdf") + #for kind,hist in aset.Histos["OC"].iteritems(): + #hist.Histo.Add(aset.Histos["SC"][kind].Histo,-1) + #aset.UpdateEff() + ##aset.Histos["OC"]["Probes"].Histo.Draw() + #aset.Histos["OC"]["Efficiency"].Histo.Draw() + can.SaveAs("Plots/test.pdf") + diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/PlotUtils.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/PlotUtils.py new file mode 100644 index 00000000000..c53d86c3276 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/PlotUtils.py @@ -0,0 +1,281 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +import ROOT, math +from Defs import * + +class PlotUtils: + def __init__(self,size=0.042,status="Internal", lumi = "20.3", sqrts = "13"): + self.Status = status + self.Size = size + self.Lumi = lumi # in fb^-1 + self.SqrtS = sqrts + self.VerticalCanvasSplit = 0.4 + self.Objects = [] + + def DrawTLatex(self, x,y,text,size=0.042,font=42,align=11): + tex = ROOT.TLatex() + tex.SetTextAlign(align) + tex.SetTextSize(size) + tex.SetTextFont(font) + tex.SetNDC() + self.Objects.append(tex) + tex.DrawLatex(x,y,text) + + def DrawAtlas(self, x,y,align=11): + self.DrawTLatex(x,y,"#font[72]{ATLAS} %s"%self.Status,self.Size,42,align) + def DrawLumiSqrtS(self,x,y,align=11,lumi="20.3"): + if self.Lumi < 0.001: + lumiToPrint = "%.1f"%(self.Lumi*1e6) + self.DrawTLatex(x,y,"#sqrt{s} = %s TeV, %s nb^{-1}"%(self.SqrtS, lumiToPrint),self.Size,42,align) + elif self.Lumi < 1.: + lumiToPrint = "%.1f"%(self.Lumi*1e3) + self.DrawTLatex(x,y,"#sqrt{s} = %s TeV, %s pb^{-1}"%(self.SqrtS, lumiToPrint),self.Size,42,align) + else: + lumiToPrint = "%.1f"%(self.Lumi) + self.DrawTLatex(x,y,"#sqrt{s} = %s TeV, %s fb^{-1}"%(self.SqrtS, lumiToPrint),self.Size,42,align) + def DrawLumiSqrtSEvolution(self,x,y,align=11,lumi="20.3"): + self.DrawTLatex(x,y,"#sqrt{s} = %s TeV, %s pb^{-1}"%(self.SqrtS,lumi),self.Size,42,align) + def DrawSource(self,probe,x,y,align=11): + text = "" + if probe == Probes.ID: + text = "ID Probes" + if probe == Probes.Calo: + text = "CaloTag Probes" + if probe == Probes.MStoID or probe == Probes.MStoMu: + text = "MS Probes" + if probe == Probes.TruthToID or probe == Probes.TruthToMu: + text = "Truth Efficiencies" + self.DrawTLatex(x,y,text,self.Size,52,align) + def DrawTarget(self,match,x,y,align=11): + text = "" + if match == Matches.Calo: + text = "CaloTag Muons" + if match == Matches.CB: + text = "Combined Muons" + if match == Matches.Loose: + text = "Loose Muons" + if match == Matches.LooseNoCalo: + text = "Loose Muons (no CaloTag)" + if match == Matches.Medium: + text = "Medium Muons" + if match == Matches.Tight: + text = "Tight Muons" + if match == Matches.ID: + text = "ID Tracks" + self.DrawTLatex(x,y,text,self.Size,42,align) + + def DrawLegend (self,histos,x1,y1,x2,y2): + leg = ROOT.TLegend(x1,y1,x2,y2) + self.Objects.append(leg) + leg.SetFillStyle(0) + leg.SetBorderSize(0) + leg.SetTextFont(42) + for histo in histos: + #if histo.GetFillColor() != ROOT.kBlack: + #leg.AddEntry(histo,histo.GetTitle(),"F") + #else: + leg.AddEntry(histo[0],histo[0].GetTitle(),histo[1]) + leg.Draw() + + def Prepare2PadCanvas(self, cname, width=800, height=800): + can = ROOT.TCanvas(cname,cname,width,height) + self.Objects.append(can) + p1 = ROOT.TPad("p1_"+cname,cname,0.0,self.VerticalCanvasSplit,1.0,1.0) + p2 = ROOT.TPad("p2_"+cname,cname,0.0,0.0,1.0,self.VerticalCanvasSplit) + p1.SetBottomMargin(0) + p1.SetTopMargin(0.09) + p2.Draw() + p2.SetTopMargin(0) + p2.SetBottomMargin(0.4) + p2.SetGridy() + self.Objects.append(can) + self.Objects.append(p1) + self.Objects.append(p2) + can.cd() + p1.Draw() + p2.Draw() + return [can,p1,p2] + + def AdaptLabelsTopPad (self,histos): + labelscalefact = 1. / (1. - self.VerticalCanvasSplit) + for hist in histos: + hist.GetXaxis().SetTitleSize(labelscalefact * hist.GetXaxis().GetTitleSize()) + hist.GetYaxis().SetTitleSize(labelscalefact * hist.GetYaxis().GetTitleSize()) + hist.GetXaxis().SetLabelSize(labelscalefact * hist.GetXaxis().GetLabelSize()) + hist.GetYaxis().SetLabelSize(labelscalefact * hist.GetYaxis().GetLabelSize()) + hist.GetXaxis().SetTitleOffset(1./labelscalefact * hist.GetXaxis().GetTitleOffset()) + hist.GetYaxis().SetTitleOffset(1./labelscalefact * hist.GetYaxis().GetTitleOffset()) + + def AdaptLabelsBottomPad (self,histos): + labelscalefact = 1. / (self.VerticalCanvasSplit) + for hist in histos: + hist.GetXaxis().SetTitleSize(labelscalefact * hist.GetXaxis().GetTitleSize()) + hist.GetYaxis().SetTitleSize(labelscalefact * hist.GetYaxis().GetTitleSize()) + hist.GetXaxis().SetLabelSize(labelscalefact * hist.GetXaxis().GetLabelSize()) + hist.GetYaxis().SetLabelSize(labelscalefact * hist.GetYaxis().GetLabelSize()) + #hist.GetXaxis().SetTitleOffset(1./labelscalefact * hist.GetXaxis().GetTitleOffset()) + hist.GetYaxis().SetTitleOffset(1.1/labelscalefact * hist.GetYaxis().GetTitleOffset()) + + def SetFancyAxisRanges_SF (self,histos,minmax=1.0,maxmin=0.9,fixRange=False): + ymin = maxmin + ymax = minmax + + finalRanges = [] + + if fixRange: + for histo in histos: + histo.GetYaxis().SetRangeUser(ymin - (0.5 * abs(1. - ymin)),ymax + 0.5 * abs(ymax - 1)) + #histo.GetYaxis().SetRangeUser(0.925,1.075) + #histo.GetYaxis().SetRangeUser(0.4,1.6) + histo.GetYaxis().SetNdivisions(3,ROOT.kTRUE) + # not yet clear yet how to apply this on the y-axis only + ROOT.TGaxis.SetMaxDigits(3) + finalRanges.append([ymin,ymax]) + else: + + for histo in histos: + if histo.InheritsFrom("TGraphAsymmErrors"): + if (ROOT.TMath.MaxElement(histo.GetN(),histo.GetY())<1.4) and (ROOT.TMath.MaxElement(histo.GetN(),histo.GetY()) > ymax): + ymax = ROOT.TMath.MaxElement(histo.GetN(),histo.GetY()) + if (ROOT.TMath.MinElement(histo.GetN(),histo.GetY())>0.6) and (ROOT.TMath.MinElement(histo.GetN(),histo.GetY()) < ymin): + ymin = ROOT.TMath.MinElement(histo.GetN(),histo.GetY()) + else: + if histo.GetMaximum(1.4) > ymax: + ymax = histo.GetMaximum(1.4) + if histo.GetMinimum(0.6) < ymin: + ymin = histo.GetMinimum(0.6) + + GoodStops = [0.0,0.3,0.4,0.5,0.65,0.7,0.75,0.8,0.9,0.95,0.98,0.99,0.995,1.005,1.01,1.02,1.05,1.1,1.2,1.25,1.3,1.35,1.5,1.6,1.7,1.72] + + ymaxl = [p for p in GoodStops if p + 0.5 * abs(p - 1) > ymax] + if len (ymaxl) > 0: + ymax = ymaxl[0] + yminl = [p for p in GoodStops if p- 0.5 * abs(p - 1) < ymin ] + if len (yminl) > 0: + ymin = yminl[-1] + + ymin = 1. - max (abs(1.-ymax), abs(1.-ymin)) + ymax = 1. + (1.-ymin) + + for histo in histos: + histo.GetYaxis().SetRangeUser(ymin - (0.5 * abs(1. - ymin)),ymax + 0.5 * abs(ymax - 1)) + histo.GetYaxis().SetNdivisions(3,ROOT.kTRUE) + # not yet clear yet how to apply this on the y-axis only + ROOT.TGaxis.SetMaxDigits(3) + finalRanges.append([ymin,ymax]) + return finalRanges + + def SetFancyAxisRanges_SF_Probes (self,histos,minmax=1.0,maxmin=0.9,fixRange=False): + ymin = maxmin + ymax = minmax + + finalRanges = [] + + if fixRange: + if ymin < .334: + histo.GetYaxis().SetRangeUser(ymin - 0.05,ymax + 0.05) + else: + for histo in histos: + histo.GetYaxis().SetRangeUser(ymin - (0.5 * abs(1. - ymin)),ymax + 0.5 * abs(ymax - 1)) + histo.GetYaxis().SetNdivisions(3,ROOT.kTRUE) + # show exponent (smaller numbers) but shift it away + histo.GetXaxis().SetNoExponent(ROOT.kFALSE) + # not yet clear yet how to apply this on the y-axis only + ROOT.TGaxis.SetMaxDigits(3) + ROOT.TGaxis.SetExponentOffset(1.) + finalRanges.append([ymin,ymax]) + else: + for histo in histos: + histo.GetXaxis().SetNoExponent(ROOT.kTRUE) + if histo.InheritsFrom("TGraphAsymmErrors"): + if (ROOT.TMath.MaxElement(histo.GetN(),histo.GetY())<1.9) and (ROOT.TMath.MaxElement(histo.GetN(),histo.GetY()) > ymax): + ymax = ROOT.TMath.MaxElement(histo.GetN(),histo.GetY()) + if (ROOT.TMath.MinElement(histo.GetN(),histo.GetY())>0.1) and (ROOT.TMath.MinElement(histo.GetN(),histo.GetY()) < ymin): + ymin = ROOT.TMath.MinElement(histo.GetN(),histo.GetY()) + else: + if histo.GetMaximum(1.9) > ymax: + ymax = histo.GetMaximum(1.9) + if histo.GetMinimum(0.1) < ymin: + ymin = histo.GetMinimum(0.1) + + GoodStops = [0.0,0.1,0.3,0.4,0.5,0.65,0.7,0.75,0.8,0.9,0.95,0.98,0.99,0.995,1.005,1.01,1.02,1.05,1.1,1.2,1.25,1.3,1.35,1.5,1.6,1.7,1.9,1.72] + + ymaxl = [p for p in GoodStops if p + 0.5 * abs(p - 1) > ymax] + if len (ymaxl) > 0: + ymax = ymaxl[0] + yminl = [p for p in GoodStops if p- 0.5 * abs(p - 1) < ymin ] + if len (yminl) > 0: + ymin = yminl[-1] + + ymin = 1. - max (abs(1.-ymax), abs(1.-ymin)) + ymax = 1. + (1.-ymin) + + for histo in histos: + histo.GetYaxis().SetRangeUser(ymin - (0.5 * abs(1. - ymin)),ymax + 0.5 * abs(ymax - 1)) + histo.GetYaxis().SetNdivisions(3,ROOT.kTRUE) + # not yet clear yet how to apply this on the y-axis only + #ROOT.TGaxis.SetMaxDigits(2) + finalRanges.append([ymin,ymax]) + return finalRanges + + def SetFancyAxisRanges_Eff (self,histos,isSym=False,maxmin=0.9,fixRange=False): + ymin = maxmin + finalRanges = [] + + if fixRange: + for histo in histos: + histo.GetYaxis().SetRangeUser(ymin,1.001) + histo.GetYaxis().SetNdivisions(4) + histo.GetXaxis().SetNoExponent(ROOT.kTRUE) + finalRanges.append([ymin]) + else: + for histo in histos: + histo.GetXaxis().SetNoExponent(ROOT.kTRUE) + if histo.InheritsFrom("TGraphAsymmErrors"): + if (ROOT.TMath.MinElement(histo.GetN(),histo.GetY())>0.4) and (ROOT.TMath.MinElement(histo.GetN(),histo.GetY()) < ymin): + ymin = ROOT.TMath.MinElement(histo.GetN(),histo.GetY()) + else: + if histo.GetMinimum(0.4) < ymin: + ymin = histo.GetMinimum(0.4) + + GoodStops = [0.01,0.401,0.501,0.601,0.701,0.801,0.851,0.931] + + yminl = [p for p in GoodStops if p < ymin] + if len (yminl) > 0: + ymin = yminl[-1] + + for histo in histos: + histo.GetYaxis().SetRangeUser(ymin,1.001) + histo.GetYaxis().SetNdivisions(4) + finalRanges.append([ymin]) + + return finalRanges + + def SetFancyAxisRanges (self,histos,maxmin=0.2,minmax=1.01,fixRange=False): + ymin = maxmin + ymax = minmax + finalRanges = [] + + if fixRange: + for histo in histos: + histo.GetYaxis().SetRangeUser(ymin,ymax) + + else: + for histo in histos: + if histo.GetMinimum(0.4) < ymin: + ymin = histo.GetMinimum(0.4) + if histo.GetMaximum()>ymax: + ymax = histo.GetMaximum()*1.5 + + GoodStops = [0.01,0.401,0.501,0.601,0.701,0.801,0.901] + + yminl = [p for p in GoodStops if p < ymin] + if len (yminl) > 0: + ymin = yminl[-1] + + for histo in histos: + histo.GetYaxis().SetRangeUser(ymin,ymax) + finalRanges.append([ymin,ymax]) + + return finalRanges + diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/ProbePlots.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/ProbePlots.py new file mode 100644 index 00000000000..c67067f94d3 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/ProbePlots.py @@ -0,0 +1,254 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +import Histos +import ROOT +import DSConfig +import Utils +import sys +from Defs import * +from PlotUtils import PlotUtils +ROOT.gROOT.Macro("rootlogon.C") +ROOT.gROOT.SetStyle("ATLAS") +ROOT.gROOT.SetBatch(1) + +histos = [] +eff_axis_ranges = [] +sf_axis_ranges = [] + +def draw2D (hist, var, probe, match, region, conf_Data): + + pu = PlotUtils() + pu.Size = 0.06*(1-pu.VerticalCanvasSplit) + pu.Lumi = conf_Data.Lumi/1000. + + ROOT.gStyle.SetPalette(54) + + can = ROOT.TCanvas("ProbeCheck_%s_%s_%s_%s"%(var,probe,region,hist[0]),PlotKinds.Probes,800,600) + can.cd() + can.SetTopMargin(0.15) + can.SetRightMargin(0.2) + can.SetLeftMargin(0.12) + + if "DataSM" in hist[0]: + hist[1].GetZaxis().SetTitle("Data/SM") + else: + hist[1].GetZaxis().SetTitle(PlotKinds.Probes+" "+hist[0]) + + hist[1].Draw("colz") + hist[1].GetYaxis().SetTitleOffset(0.7*hist[1].GetYaxis().GetTitleOffset()) + hist[1].GetZaxis().SetTitleOffset(1.5*hist[1].GetZaxis().GetTitleOffset()) + # need to find a better way to do this: + hist[1].GetZaxis().SetLabelSize(hist[1].GetYaxis().GetLabelSize()) + hist[1].GetZaxis().SetTitleSize(hist[1].GetYaxis().GetTitleSize()) + + pu.DrawAtlas(can.GetLeftMargin(),0.92) + pu.DrawLumiSqrtS(can.GetLeftMargin(),0.87) + #pu.DrawTarget(match,1-can.GetRightMargin(),0.92,31) + pu.DrawSource(probe,1-can.GetRightMargin(),0.87,31) + + can.SaveAs ("Plots/ProbeCheck_%s_%s_%s_%s.pdf"%(var,probe,region,hist[0])) + + pu.DrawTLatex(0.5,0.94,"%s for %s probes in %s %s"%(var,probe,region,hist[0]),0.04,52,22) + + can.SaveAs("Plots/AllProbePlots.pdf") + +def doProbePlots1D (hists_final, var, probe, match, region, conf_Data, conf_Zmumu, log): + + if len(hists_final)>1: + print 'Error: Something went wrong in TPFinalHistos()!' + sys.exit(1) + else: + h_data = hists_final[0].Histos[PlotKinds.Probes]["Data"] + h_bkg = hists_final[0].Histos[PlotKinds.Probes]["Bkg"] + h_mc = hists_final[0].Histos[PlotKinds.Probes]["MC"] + h_model = hists_final[0].Histos[PlotKinds.Probes]["Model"] + ratio = hists_final[0].Histos[PlotKinds.Probes]["DataVsModel"] + + ###### + # used for styling histo (when TGraphAsymmErrors are used) + h_styling = HistoDefs.initHisto(var)[0].Clone("stylingHisto") + # from print in Histos.py: + h_styling.GetXaxis().SetTitleSize(0.0500000007451) + h_styling.GetXaxis().SetTitleOffset(1.39999997616) + h_styling.GetXaxis().SetLabelSize(0.0500000007451) + h_styling.GetXaxis().SetLabelOffset(0.00499999988824) + h_styling.GetYaxis().SetTitleSize(0.0500000007451) + h_styling.GetYaxis().SetTitleOffset(1.39999997616) + h_styling.GetYaxis().SetLabelSize(0.0500000007451) + h_styling.GetYaxis().SetLabelOffset(0.00499999988824) + + h_styling_ratio = h_styling.Clone("stylingHistoRatio") + h_styling_ratio.GetYaxis().SetTitle("Data/SM") + + h_styling.GetYaxis().SetTitle("Probes") + ###### + + pu = PlotUtils() + pu.Size = 0.06 + pu.Lumi = conf_Data.Lumi/1000. + pu.SqrtS = 13 + + can,p1,p2 = pu.Prepare2PadCanvas("ProbeCheck_%s_%s_%s"%(var,probe,region)) + can.cd() + p1.Draw() + histos.append(p1) + histos.append(p2) + histos.append(can) + p1.cd() + + + # plotting style: + h_data.SetMarkerStyle(ROOT.kFullDotLarge) + h_data.SetLineColor(ROOT.kBlack) + h_data.SetMarkerColor(h_data.GetLineColor()) + h_data.SetTitle(conf_Data.Label) + ratio.SetMarkerStyle(ROOT.kFullDotLarge) + ratio.SetLineColor(h_data.GetLineColor()) + ratio.SetMarkerColor(h_data.GetLineColor()) + h_bkg.SetLineColor(ROOT.kOrange-2) + h_bkg.SetFillColor(h_bkg.GetLineColor()) + h_bkg.SetTitle("Data-driven Background") + h_mc.SetLineColor(ROOT.kBlue-9) + h_mc.SetFillColor(h_mc.GetLineColor()) + h_mc.SetTitle(conf_Zmumu.Label) + + if (log): + p1.SetLogy() + + stk = ROOT.THStack("Stack","Stack") + stk.Add(h_bkg) + stk.Add(h_mc) + stk.Draw("HIST") + + ###### + # labels and axis ranges + pu.AdaptLabelsTopPad([h_styling,stk.GetHistogram(),h_data,h_bkg,h_mc]) + eff_axis_ranges.append(pu.SetFancyAxisRanges([stk.GetHistogram(), h_data, h_bkg, h_mc])) + pu.SetFancyAxisRanges([h_styling], minmax = eff_axis_ranges[0][0][1], maxmin = eff_axis_ranges[0][0][0], fixRange=True) + ###### + + h_styling.Draw("AXIS") + + if(log): + stk.SetMinimum(5e-1) + stk.GetHistogram().SetMaximum(1e3*stk.GetMaximum()) + + stk.Draw("sameHIST") + h_data.Draw("same") + + pu.DrawAtlas(0.19,0.83) + pu.DrawLumiSqrtS(0.19,0.76) + pu.DrawLegend([(h_data,"PL"), (h_mc,"F"), (h_bkg,"F")],0.6,0.6,0.89,0.89) + + p2.cd() + p2.SetGridy() + + ###### + # labels and axis ranges + pu.AdaptLabelsBottomPad([h_styling_ratio,ratio]) + sf_axis_ranges.append(pu.SetFancyAxisRanges_SF_Probes([ratio])) + pu.SetFancyAxisRanges_SF_Probes([h_styling_ratio], minmax = sf_axis_ranges[0][0][1], maxmin = sf_axis_ranges[0][0][0], fixRange=True) + ###### + + h_styling_ratio.Draw("AXIS") + ratio.Draw("same") + + can.SaveAs ("Plots/ProbeCheck_%s_%s_%s.pdf"%(var,probe,region)) + p1.cd() + + pu.DrawTLatex(0.5,0.94,"%s for %s probes in %s"%(var,probe,region),0.04,52,22) + + can.SaveAs("Plots/AllProbePlots.pdf") + +def doProbePlots2D (hists_final, var, probe, match, region, conf_Data, conf_Zmumu, log): + + if len(hists_final)>1: + print 'Error: Something went wrong in TPFinalHistos()!' + sys.exit(1) + else: + h_data = hists_final[0].Histos[PlotKinds.Probes]["Data"] + h_bkg = hists_final[0].Histos[PlotKinds.Probes]["Bkg"] + h_mc = hists_final[0].Histos[PlotKinds.Probes]["MC"] + h_model = hists_final[0].Histos[PlotKinds.Probes]["Model"] + ratio = hists_final[0].Histos[PlotKinds.Probes]["DataVsModel"] + + + draw2D (["Data",h_data], var, probe, match, region, conf_Data) + draw2D (["SM",h_model], var, probe, match, region, conf_Data) + draw2D (["DataSM",ratio], var, probe, match, region, conf_Data) + +def doProbePlots (var, probe, region, conf_Data, conf_Zmumu, log=True): + + match = Matches.Medium + if probe == Probes.MStoMu: + match = Matches.Calo + + infiles = [ + ["MC",conf_Zmumu], + ["Data",conf_Data] + ] + + hists_final = [] + + # faster (without systematic uncertainty bands): + hists_final.append(Histos.TPFinalHistos("test",probe,match,region,var,infiles,useAsymEff=False)) + + if hists_final[0].Histos[HistoKinds.Efficiency][HistoKinds.DataEfficiency].InheritsFrom("TH2"): + doProbePlots2D (hists_final, var, probe, match, region, conf_Data, conf_Zmumu, log) + else: + doProbePlots1D (hists_final, var, probe, match, region, conf_Data, conf_Zmumu, log) + + +if __name__ == "__main__": + + # what we want to run on: + InputData = DSConfig.Data_15_firstWeek + InputZmumu = DSConfig.Zmumu_mc15 + + dummy = ROOT.TCanvas("dummy","dummy",800,800) + dummy.SaveAs("Plots/AllProbePlots.pdf[") + + # variables we want to plot: + #doProbePlots ("etaphiFine", Probes.ID, DetRegions.All, InputData, InputZmumu, log=False) + #doProbePlots ("mll", Probes.ID, DetRegions.All, InputData, InputZmumu, log=False) + #doProbePlots ("pt", Probes.ID, DetRegions.All, InputData, InputZmumu) + #doProbePlots ("eta", Probes.ID, DetRegions.All, InputData, InputZmumu) + #doProbePlots ("d0", Probes.ID, DetRegions.All, InputData, InputZmumu) + #doProbePlots ("z0", Probes.ID, DetRegions.All, InputData, InputZmumu) + + doProbePlots ("etaphiFine", Probes.Calo, DetRegions.All, InputData, InputZmumu, log=False) + doProbePlots ("mll", Probes.Calo, DetRegions.All, InputData, InputZmumu, log=False) + doProbePlots ("pt", Probes.Calo, DetRegions.All, InputData, InputZmumu) + doProbePlots ("eta", Probes.Calo, DetRegions.All, InputData, InputZmumu) + doProbePlots ("d0", Probes.Calo, DetRegions.All, InputData, InputZmumu) + doProbePlots ("z0", Probes.Calo, DetRegions.All, InputData, InputZmumu) + + #doProbePlots ("etaphiFine", Probes.MStoMu, DetRegions.All, InputData, InputZmumu, log=False) + #doProbePlots ("mll", Probes.MStoMu, DetRegions.All, InputData, InputZmumu, log=False) + #doProbePlots ("pt", Probes.MStoMu, DetRegions.All, InputData, InputZmumu) + #doProbePlots ("eta", Probes.MStoMu, DetRegions.All, InputData, InputZmumu) + #doProbePlots ("d0", Probes.MStoMu, DetRegions.All, InputData, InputZmumu) + #doProbePlots ("z0", Probes.MStoMu, DetRegions.All, InputData, InputZmumu) + + #doProbePlots ("etaphiFine", Probes.ID, DetRegions.noCrack, InputData, InputZmumu, log=False) + #doProbePlots ("mll", Probes.ID, DetRegions.noCrack, InputData, InputZmumu, log=False) + #doProbePlots ("pt", Probes.ID, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("eta", Probes.ID, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("d0", Probes.ID, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("z0", Probes.ID, DetRegions.noCrack, InputData, InputZmumu) + + #doProbePlots ("etaphiFine", Probes.Calo, DetRegions.noCrack, InputData, InputZmumu, log=False) + #doProbePlots ("mll", Probes.Calo, DetRegions.noCrack, InputData, InputZmumu, log=False) + #doProbePlots ("pt", Probes.Calo, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("eta", Probes.Calo, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("d0", Probes.Calo, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("z0", Probes.Calo, DetRegions.noCrack, InputData, InputZmumu) + + #doProbePlots ("etaphiFine", Probes.MStoMu, DetRegions.noCrack, InputData, InputZmumu, log=False) + #doProbePlots ("mll", Probes.MStoMu, DetRegions.noCrack, InputData, InputZmumu, log=False) + #doProbePlots ("pt", Probes.MStoMu, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("eta", Probes.MStoMu, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("d0", Probes.MStoMu, DetRegions.noCrack, InputData, InputZmumu) + #doProbePlots ("z0", Probes.MStoMu, DetRegions.noCrack, InputData, InputZmumu) + + dummy.SaveAs("Plots/AllProbePlots.pdf]") diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/TestRecoSF.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/TestRecoSF.py new file mode 100644 index 00000000000..637c9e5ce15 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/TestRecoSF.py @@ -0,0 +1,71 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +################################################### +# Simple macro to test reco SF files +# 20.6.2015, goblirsc<at>cern.ch +################################################### + +import ROOT +import os +import commands +import math +import sys + +ROOT.gROOT.Macro("rootlogon.C") +ROOT.gROOT.SetStyle("ATLAS") +ROOT.gROOT.SetBatch(1) +def GetHistos(histo, histosys, biny, binz): + hname = histo.GetName()+"_%i_%i"%(biny,binz) + hproj = histo.ProjectionX(hname,biny,biny,binz,binz) + hproj.SetDirectory(0) + hproj_sys = histosys.ProjectionX(hname+"Sys",biny,biny,binz,binz) + hproj_sys.SetDirectory(0) + for k in range (hproj_sys.GetNbinsX()+1): + hproj.SetBinContent(k,hproj.GetBinContent(k) + 0.1 * (biny - 1)) + syserr = hproj_sys.GetBinContent(k) + hproj_sys.SetBinContent(k,hproj.GetBinContent(k)) + hproj_sys.SetBinError(k,syserr) + + + return [hproj, hproj_sys] + +def DrawCheckPlot(histo, histo_sys): + plots = [] + hname = histo.GetName() + for h in range (1,histo.GetNbinsZ()+1): + can = ROOT.TCanvas("can_%i"%h,"can",800,600) + can.cd() + leg = ROOT.TLegend(0.1,0.75,0.8,0.95) + leg.SetBorderSize(0) + leg.SetNColumns(3) + leg.SetFillStyle(0) + first = True + colours = [ROOT.kBlue-1, ROOT.kGreen-2, ROOT.kRed-2,ROOT.kOrange-3,ROOT.kCyan, ROOT.kMagenta+1] + for g in range (1,histo.GetNbinsY()+1): + subhistos = GetHistos(histo,histo_sys,g,h) + subhistos[0].SetMarkerStyle(ROOT.kDot) + subhistos[1].SetFillColor(colours[g]) + plots.append(subhistos) + if first: + subhistos[1].GetYaxis().SetRangeUser(0.9,2.) + subhistos[1].Draw("E2") + first = False + else: + subhistos[1].Draw("E2same") + subhistos[0].Draw("same") + if g < histo.GetNbinsY(): + leg.AddEntry(subhistos[1],"%.1f GeV < pt < %.1f GeV"%(histo.GetYaxis().GetBinLowEdge(g),(histo.GetYaxis().GetBinUpEdge(g)))) + else: + leg.AddEntry(subhistos[1],"%.1f GeV < pt"%(histo.GetYaxis().GetBinLowEdge(g))) + chargesuff = "_posq" + leg.Draw() + if histo.GetZaxis().GetBinCenter(h) < 0: + chargesuff = "_negq" + can.SaveAs("Plots/SF_Check_%s%s.pdf"%(hname,chargesuff)) + +if __name__ == "__main__": + inf = sys.argv[-1] + rf = ROOT.TFile.Open(inf,"READ") + hsf = rf.Get("SF_All") + hsys = rf.Get("SF_sys_All") + DrawCheckPlot(hsf,hsys) \ No newline at end of file diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Utils.py b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Utils.py new file mode 100644 index 00000000000..1d6996a5762 --- /dev/null +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/macros/Utils.py @@ -0,0 +1,253 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +import math, ROOT +import inspect +from array import array + + +## use PrintFrame() for debugging +def PrintFrame(): + callerframerecord = inspect.stack()[1] # 0 represents this line + # 1 represents line at caller + frame = callerframerecord[0] + info = inspect.getframeinfo(frame) + #print info.filename # __FILE__ -> Test.py + #print info.function # __FUNCTION__ -> Main + print info.lineno + +## Some utility methods used for the Z TP +def CalcEff (probes,matches): + t = probes[0] + dt = probes[1] + h = matches[0] + dh = matches[1] + #print "++++++++++++++++++ got %.4f +/- %.4f trials, %.5f / %.4f matches"%(t,dt,h,dh) + if t == 0: + return [1.0,1.0] + #t = 1 + m = t - h + #print "dt = %.4f, dh = %.4f"%(dt,dh) + dm = math.sqrt(abs(dt*dt-dh*dh)) + #print " ++++++++++++++++++ and got %.4f +/- %.4f misses"%(m,dm) + eff = h/t + deff = math.sqrt(abs(((h*dm)**2+(m*dh)**2)/(t**4))) + #print " ++++++++++++++++++ Eff is %.4f +/- %.4f"%(eff,deff) + #print "%.0f / %.0f -> %.4f"%(h,t,eff) + return [eff,deff] + +def CalcEffAsym (probes,matches): + t = probes[0] + dt = probes[1] + h = matches[0] + dh = matches[1] + #print "++++++++++++++++++ got %.4f +/- %.4f trials, %.5f / %.4f matches"%(t,dt,h,dh) + if t == 0: + return [1.0,0.0,1.0] + #t = 1 + m = t - h + #print "dt = %.4f, dh = %.4f"%(dt,dh) + dm = math.sqrt(abs(dt*dt-dh*dh)) + #print " ++++++++++++++++++ and got %.4f +/- %.4f misses"%(m,dm) + eff = h/t + deff = math.sqrt(abs(((h*dm)**2+(m*dh)**2)/(t**4))) + + # use equation (11) from page 49 of https://cds.cern.ch/record/1247341/files/ATL-COM-PHYS-2010-124.pdf + N = t + if N == 0.: + N = 1. + sigmaPos = (2.*eff+1./N+math.sqrt(4.*eff*(1.-eff)/N+1./N**2))/(2.+2./N)-eff + sigmaNeg = (2.*eff+1./N-math.sqrt(4.*eff*(1.-eff)/N+1./N**2))/(2.+2./N)-eff + + #print " ++++++++++++++++++ asym Eff is %.4f + %.4f %.4f"%(eff,sigmaPos,sigmaNeg) + return [eff,sigmaPos,abs(sigmaNeg)] + +def EffDivide (num,den,eff): + nbinsNum = GetNbins(num) + #print 'in EffDivide: numerator has %s bins'%nbinsNum + #print num.GetBinContent(0) + for i in range (0, nbinsNum): + #print "bin %s: num: %s, den: %s"%(i, num.GetBinContent(i), den.GetBinContent(i)) + if (num.GetBinContent(i) > den.GetBinContent(i)): + num.SetBinContent(i,den.GetBinContent(i)) + + if eff.InheritsFrom("TGraphAsymmErrors"): + for i in range (0, nbinsNum): + effiAsym = CalcEffAsym([den.GetBinContent(i),den.GetBinError(i)], [num.GetBinContent(i),num.GetBinError(i)]) + eff.SetPoint(eff.GetN(),num.GetBinCenter(i),effiAsym[0]) + #print "bin %s: up: %s, down: %s"%(i, effiAsym[1], effiAsym[2]) + eff.SetPointEYhigh(eff.GetN()-1, effiAsym[1]) + eff.SetPointEYlow(eff.GetN()-1, effiAsym[2]) + eff.SetPointEXhigh(eff.GetN()-1, num.GetBinWidth(i)/2.) + eff.SetPointEXlow(eff.GetN()-1, num.GetBinWidth(i)/2.) + else: + for i in range (0, nbinsNum): + effi = CalcEff([den.GetBinContent(i),den.GetBinError(i)], [num.GetBinContent(i),num.GetBinError(i)]) + eff.SetBinContent(i,effi[0]) + eff.SetBinError(i,effi[1]) + +## Some utility methods for algebra in root +def PolyDivide (num,den,ratio): + nbins = GetNbins(num) + for i in range (1, nbins): + if 0.!=den.GetBinContent(i): + ratio.SetBinContent(i,num.GetBinContent(i)/den.GetBinContent(i)) + ratio.SetBinError(i,math.sqrt((num.GetBinError(i)/den.GetBinContent(i))**2.+(den.GetBinError(i)*num.GetBinContent(i)/den.GetBinContent(i)**2.)**2.)) + else: + ratio.SetBinContent(i,0.) + ratio.SetBinError(i,0.) + +def PolyMultiply (fac1,fac2,res): + nbins = GetNbins(fac1) + for i in range (1, nbins): + res.SetBinContent(i,fac1.GetBinContent(i)*fac2.GetBinContent(i)) + res.SetBinError(i,math.sqrt((fac2.GetBinError(i)*fac1.GetBinContent(i))**2.+(fac1.GetBinError(i)*fac2.GetBinContent(i))**2.)) + +def GraphDivide (num,den,ratio): + nPoints = GetNbins(num) + for i in range (0, nPoints): + if 0.!=den.GetY()[i]: + ratio.SetPoint(i,num.GetX()[i],num.GetY()[i]/den.GetY()[i]) + ratio.SetPointEYhigh(i,math.sqrt((num.GetErrorYhigh(i)/den.GetY()[i])**2.+(den.GetErrorYhigh(i)*num.GetY()[i]/den.GetY()[i]**2.)**2.)) + ratio.SetPointEYlow(i,math.sqrt((num.GetErrorYlow(i)/den.GetY()[i])**2.+(den.GetErrorYlow(i)*num.GetY()[i]/den.GetY()[i]**2.)**2.)) + else: + ratio.SetPoint(i,num.GetX()[i],0.) + ratio.SetPointEYhigh(i,0.) + ratio.SetPointEYlow(i,0.) + +def GraphMultiply (fac1,fac2,res): + nPoints = GetNbins(fac1) + for i in range (0, nPoints): + res.SetPoint(i,fac1.GetX()[i],fac1.GetY()[i]*fac2.GetY()[i]) + res.SetPointEYhigh(i,math.sqrt((fac2.GetErrorYhigh(i)*fac1.GetY()[i])**2.+(fac1.GetErrorYhigh(i)*fac2.GetY()[i])**2.)) + res.SetPointEYlow(i,math.sqrt((fac2.GetErrorYlow(i)*fac1.GetY()[i])**2.+(fac1.GetErrorYlow(i)*fac2.GetY()[i])**2.)) + +def GetNbins(histo): + nbins = 0 + if histo.InheritsFrom("TH2Poly"): + nbins = histo.GetNumberOfBins()+1 + elif histo.InheritsFrom("TH2"): + nbins = (histo.GetNbinsX()+2)*(histo.GetNbinsY()+2) + elif histo.InheritsFrom("TH1"): + nbins = histo.GetNbinsX()+2 + elif histo.InheritsFrom("TGraphAsymmErrors"): + nbins = histo.GetN() + else: + print "GetNbins(): no supported histogram type!" + return -1 + + return nbins + +def ConvertTGraphAsymmErrors(graph): + nPoints = GetNbins(graph) + binCenters = [] + for i in range (0, nPoints): + binCenters.append(graph.GetX()[i]) + + histo = ROOT.TH1F(graph.GetName(),graph.GetName(),len(binCenters)-1,array("f",binCenters)) + histo.SetDirectory(0) + + for i in range (0, nPoints): + histo.SetBinContent(i,graph.GetY()[i]) + maxError = max(graph.GetErrorYhigh(i),graph.GetErrorYlow(i)) + histo.SetBinError(i,maxError) + return histo + + +## Some utility methods for systematics evaluation +def fill_sys_bin (binNumber, h_nom, h_up, h_down, h_sys, weight): + if h_nom.InheritsFrom("TGraphAsymmErrors"): + nom_val = h_nom.GetY()[binNumber] + up_val = h_up.GetY()[binNumber] + down_val = h_down.GetY()[binNumber] + else: + nom_val = h_nom.GetBinContent(binNumber) + up_val = h_up.GetBinContent(binNumber) + down_val = h_down.GetBinContent(binNumber) + + sup = math.fabs(up_val - nom_val) + sdown = math.fabs(down_val - nom_val) +# print 'bin: %s nom_val: %s sup: %s, sdown: %s'%(binNumber,nom_val,sup,sdown) + + # for now, we symmetrize using the larger of the deviations + if (nom_val == 0): + nom_val = 0.001 + smax = ROOT.TMath.Max(sup,sdown)/nom_val * weight + + if h_nom.InheritsFrom("TGraphAsymmErrors"): + statYhigh = h_nom.GetErrorYhigh(binNumber)/nom_val * weight + statYlow = h_nom.GetErrorYlow(binNumber)/nom_val * weight + + h_sys.SetPoint(binNumber,h_sys.GetX()[binNumber],smax) + h_sys.SetPointEYhigh(binNumber,statYhigh) + h_sys.SetPointEYlow(binNumber,statYlow) + else: + stat = h_nom.GetBinError(binNumber)/nom_val * weight + + h_sys.SetBinContent(binNumber,smax) + h_sys.SetBinError(binNumber,stat) + +def sysCompare(h_nom, h_up, h_down, sysType, weight): + sys = h_nom.Clone('%s_sys_%s'%(h_nom.GetName(),sysType)) + if not sys.InheritsFrom("TGraphAsymmErrors"): + sys.SetDirectory(0) + + nbins = GetNbins(sys) + + for ibin in range(0,nbins): + fill_sys_bin(ibin,h_nom,h_up,h_down,sys,weight) + + return sys + +def add_in_quadrature(hist_add_to, hist_add_this): + # loop over the bins - here we need the actual types + nbins = GetNbins(hist_add_to) + + for k in range(0,nbins): + if hist_add_to.InheritsFrom("TGraphAsymmErrors"): + sys = hist_add_to.GetY()[k] + add_sys = hist_add_this.GetY()[k] + sys = ROOT.sqrt(sys*sys+add_sys*add_sys) + hist_add_to.SetPoint(k,hist_add_to.GetX()[k],sys) + else: + sys = hist_add_to.GetBinContent(k) + add_sys = hist_add_this.GetBinContent(k) + sys = ROOT.sqrt(sys*sys+add_sys*add_sys) + hist_add_to.SetBinContent(k,sys) + +def CopyEtaBins(hist): + nbins = GetNbins(hist) + #print '\n\n\n\n\n\n\nin CopyEtaBins\n\n\n\n\n\n\n' + #print nbins + + if hist.InheritsFrom("TGraphAsymmErrors"): + print 'TODO: CopyEtaBins for graphs' + else: + # fineEtaPhiBinning has 352 bins (22 eta bins, 16 phi bins each) + # abseta >= 1.05 and abseta < 1.37 -> etabin = -6*16 (negative eta), etabin = 5*16 (positive eta) + if nbins == 354: + for k in range(0,nbins): + # k=1 equals bin -11*16+1 = -175 + #print k-176 + # copy bins (from -95 to -80) to (81 to 96), this means 81-96 to 257-272 + if k in [257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272]: + hist.SetBinContent(k,hist.GetBinContent(k-176)) + hist.SetBinError(k,hist.GetBinError(k-176)) + #print k + + # TPFineEtaPhiHist binning + if nbins == 513: + for k in range(0,nbins): + #print k + ## copy bins (for 1.35<abs(eta)<1.5), this means 97-112 to 401-416 + # copy bins (for 1.19<abs(eta)<1.35), this means 113-128 to 385-400 + # copy bins (for 1.05<abs(eta)<1.19), this means 129-144 to 369-384 + #if (k > 400 and k < 417): + #hist.SetBinContent(k,hist.GetBinContent(k-304)) + #hist.SetBinError(k,hist.GetBinError(k-304)) + if (k > 384 and k < 401): + hist.SetBinContent(k,hist.GetBinContent(k-272)) + hist.SetBinError(k,hist.GetBinError(k-272)) + if (k > 368 and k < 385): + hist.SetBinContent(k,hist.GetBinContent(k-240)) + hist.SetBinError(k,hist.GetBinError(k-240)) + \ No newline at end of file diff --git a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/src/components/MuonTPTools_entries.cxx b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/src/components/MuonTPTools_entries.cxx index 682865ecad6..bedd339300b 100644 --- a/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/src/components/MuonTPTools_entries.cxx +++ b/PhysicsAnalysis/MuonID/MuonPerformanceAnalysis/MuonTPTools/src/components/MuonTPTools_entries.cxx @@ -1,56 +1,56 @@ // MuonTPTools_entries.cxx #include "MuonTPTools/MuonTPTool.h" + #include "MuonTPTools/MuonTPSelectionTool.h" +#include "MuonTPTools/DiMuonTPSelectionTool.h" + #include "MuonTPTools/MuonTPEfficiencyTool.h" -#include "MuonTPTools/ZmumuMuonTPPlotTool.h" -#include "MuonTPTools/MuonTPPlotTool.h" -#include "MuonTPTools/MuonTPTreeTool.h" -#include "MuonTPTools/ZmumuMuonTPTreeTool.h" -#include "MuonTPTools/ZmumuMuonTPIsolationTreeTool.h" -#include "MuonTPTools/ZmumuMuonTPSelectionTool.h" #include "MuonTPTools/MuonRecoTPEfficiencyTool.h" #include "MuonTPTools/MuonTrigTPEfficiencyTool.h" -#include "MuonTPTools/MuonTrigTPPlotTool.h" -#include "MuonTPTools/MuonTrigTPTreeTool.h" -#include "MuonTPTools/JPsiMuonTPPlotTool.h" -#include "MuonTPTools/JPsiMuonTPSelectionTool.h" -#include "MuonTPTools/JPsiMuonTPEfficiencyTool.h" +#include "MuonTPTools/MuonIsolTPEfficiencyTool.h" + +#include "MuonTPTools/MuonTPPlotTool.h" +#include "MuonTPTools/DiMuonTPPlotTool.h" + +#include "MuonTPTools/MuonTPTreeTool.h" +#include "MuonTPTools/DiMuonTPTreeTool.h" + #include "GaudiKernel/DeclareFactoryEntries.h" DECLARE_TOOL_FACTORY(MuonTPTool) -DECLARE_TOOL_FACTORY(MuonTPSelectionTool) -DECLARE_TOOL_FACTORY(MuonTPEfficiencyTool) -DECLARE_TOOL_FACTORY(ZmumuMuonTPSelectionTool) -DECLARE_TOOL_FACTORY(MuonTPPlotTool) -DECLARE_TOOL_FACTORY(MuonTPTreeTool) -DECLARE_TOOL_FACTORY(ZmumuMuonTPPlotTool) -DECLARE_TOOL_FACTORY(ZmumuMuonTPTreeTool) -DECLARE_TOOL_FACTORY(ZmumuMuonTPIsolationTreeTool) + +// DECLARE_TOOL_FACTORY(MuonTPSelectionTool) +DECLARE_TOOL_FACTORY(DiMuonTPSelectionTool) + +// DECLARE_TOOL_FACTORY(MuonTPEfficiencyTool) DECLARE_TOOL_FACTORY(MuonRecoTPEfficiencyTool) DECLARE_TOOL_FACTORY(MuonTrigTPEfficiencyTool) -DECLARE_TOOL_FACTORY(MuonTrigTPPlotTool) -DECLARE_TOOL_FACTORY(MuonTrigTPTreeTool) -DECLARE_TOOL_FACTORY(JPsiMuonTPSelectionTool) -DECLARE_TOOL_FACTORY(JPsiMuonTPPlotTool) -DECLARE_TOOL_FACTORY(JPsiMuonTPEfficiencyTool) +DECLARE_TOOL_FACTORY(MuonIsolTPEfficiencyTool) + +// DECLARE_TOOL_FACTORY(MuonTPPlotTool) +DECLARE_TOOL_FACTORY(DiMuonTPPlotTool) +// DECLARE_TOOL_FACTORY(JPsiMuonTPPlotTool) + +// DECLARE_TOOL_FACTORY(MuonTPTreeTool) +DECLARE_TOOL_FACTORY(DiMuonTPTreeTool) DECLARE_FACTORY_ENTRIES(MuonTPTools) { DECLARE_TOOL(MuonTPTool) - DECLARE_TOOL(MuonTPSelectionTool) - DECLARE_TOOL(MuonTPEfficiencyTool) - DECLARE_TOOL(ZmumuMuonTPSelectionTool) - DECLARE_TOOL(ZmumuMuonTPPlotTool) - DECLARE_TOOL(ZmumuMuonTPTreeTool) - DECLARE_TOOL(ZmumuMuonTPIsolationTreeTool) + +// DECLARE_TOOL(MuonTPSelectionTool) + DECLARE_TOOL(DiMuonTPSelectionTool) + +// DECLARE_TOOL(MuonTPEfficiencyTool) DECLARE_TOOL(MuonRecoTPEfficiencyTool) DECLARE_TOOL(MuonTrigTPEfficiencyTool) - DECLARE_TOOL(MuonTrigTPPlotTool) - DECLARE_TOOL(MuonTrigTPTreeTool) - DECLARE_TOOL(MuonTPPlotTool) - DECLARE_TOOL(MuonTPTreeTool) - DECLARE_TOOL(JPsiMuonTPSelectionTool) - DECLARE_TOOL(JPsiMuonTPPlotTool) - DECLARE_TOOL(JPsiMuonTPEfficiencyTool) + DECLARE_TOOL(MuonIsolTPEfficiencyTool) + +// DECLARE_TOOL(MuonTPPlotTool) + DECLARE_TOOL(DiMuonTPPlotTool) + +// DECLARE_TOOL(MuonTPTreeTool) + DECLARE_TOOL(DiMuonTPTreeTool) + } -- GitLab