diff --git a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/CMakeLists.txt b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/CMakeLists.txt index 5963f3b0a3b48794c88103b07ca966421751a38f..f66377acc4698afa16361d8be73dfd72ba3e78bd 100644 --- a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/CMakeLists.txt +++ b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/CMakeLists.txt @@ -1,12 +1,23 @@ # The name of the package: atlas_subdir( FTagAnalysisInterfaces ) +# The dependencies of the package: +atlas_depends_on_subdirs( + PUBLIC + Control/AthToolSupport/AsgTools + Event/xAOD/xAODBTagging + Event/xAOD/xAODJet + PhysicsAnalysis/AnalysisCommon/PATCore + PhysicsAnalysis/AnalysisCommon/PATInterfaces + PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface + PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency ) + # Component(s) in the package: atlas_add_library( FTagAnalysisInterfacesLib FTagAnalysisInterfaces/*.h INTERFACE PUBLIC_HEADERS FTagAnalysisInterfaces - LINK_LIBRARIES AsgTools xAODBTagging xAODJet PATCoreLib CalibrationDataInterfaceLib PATInterfaces xAODBTaggingEfficiencyLib ) + LINK_LIBRARIES AsgTools xAODBTagging xAODJet PATCoreLib CalibrationDataInterfaceLib ) atlas_add_dictionary( FTagAnalysisInterfacesDict FTagAnalysisInterfaces/FTagAnalysisInterfacesDict.h diff --git a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/FTagAnalysisInterfacesDict.h b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/FTagAnalysisInterfacesDict.h index 82af707e72e1ff200b8e202825c581992107b215..8a00bd1d5312c8757bc0f95d16b9e04250354f5f 100644 --- a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/FTagAnalysisInterfacesDict.h +++ b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/FTagAnalysisInterfacesDict.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ @@ -15,5 +15,6 @@ #include "FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h" #include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h" #include "FTagAnalysisInterfaces/IBTaggingTruthTaggingTool.h" +#include "FTagAnalysisInterfaces/IBTaggingEigenVectorRecompositionTool.h" #endif // FTAGANALYSISINTERFACES_FTAGANALYSISINTERFACESDICT_H diff --git a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h index 106f523b0decde966b92e42d989ea5c7eff10688..18cd37db05233cc780771e903bb401ef7710beca 100644 --- a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h +++ b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h @@ -1,7 +1,7 @@ // Dear emacs, this is -*- c++ -*- /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// @@ -76,6 +76,8 @@ class IBTaggingEfficiencyTool : virtual public CP::ISystematicsTool { // this merely passes on the request to the underlying CDI object (listSystematics() cannot be used here, as corresponding CP::SystematicVariation objects may not exist) virtual std::map<std::string, std::vector<std::string> > listScaleFactorSystematics(bool named = false) const = 0; + + virtual CP::CorrectionCode getEigenRecompositionCoefficientMap(const std::string &label, std::map<std::string, std::map<std::string, float>> & coefficientMap) = 0; }; #endif // CPIBTAGGINGEFFICIENCYTOOL_H diff --git a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingEigenVectorRecompositionTool.h b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingEigenVectorRecompositionTool.h new file mode 100644 index 0000000000000000000000000000000000000000..711f0a436a0b531e3dc4eeefc1b1d9474b55c385 --- /dev/null +++ b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingEigenVectorRecompositionTool.h @@ -0,0 +1,63 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// IBTaggingEfficiencyTool.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +/** +@class BTaggingEigenVectorRecompositionTool +Tool to help retrieving(from CDI) and providing coefficents values which +could be used for expressing eigen vector NPs by linear combination of +original uncertainty NPs in workspace level of the physics analysis. +Then eigenvector uncertainties are replaced by original uncertainties. +Replacement could help us correlate uncertainties between analyses +which are using different tagger algorighthms. +@author Y. Ke, Q. Buat +@contact yake@cern.ch, qbuat@cern.ch +**/ +#ifndef CPIBTAGGINGEIGENVECTORRECOMPOSITIONTOOL_H +#define CPIBTAGGINGEIGENVECTORRECOMPOSITIONTOOL_H + +#include "AsgTools/IAsgTool.h" +#include "PATInterfaces/ISystematicsTool.h" +#include "PATInterfaces/CorrectionCode.h" +#include "PATInterfaces/SystematicCode.h" +#include "PATInterfaces/SystematicSet.h" + +#include <vector> +#include <map> + +class IBTaggingEigenVectorRecompositionTool : virtual public CP::ISystematicsTool { + + /// Declare the interface that the class provides + ASG_TOOL_INTERFACE( IBTagEigenVectorRecompositionTool ) + + public: + /** + * Return a vector which contains a list of original vector uncertainties names. + * vector list is for the chosen flavour label. The order of the names is the same + * as the coefficient values given by getCoefficients() + **/ + virtual std::vector<std::string> getListOfOriginalNuisanceParameters(const std::string& label) const = 0; + /** + * Produce a coefficient map contains only eigenvectors that is showing in + * eigenIdxList and return it to user. If given empty evIdxList, the function + * returns a full map. Produced map is for the chosen flavour label. + **/ + virtual std::map<std::string, std::map<std::string, float>> getCoefficientMap(const std::string& label, const std::vector<unsigned int> eigenIdxList = std::vector<unsigned int>()) const = 0; + /** + * Returns a vector contains the coefficients value of the chosen label + * and the chosen eigenvector. The order of the value is the same as + * the order of original uncertainty names given by + * getListOfOriginalNuisanceParameters() + **/ + virtual std::vector<float> getCoefficients(const std::string & label, const unsigned int evIdx) const = 0; + // Return number of eigenvectors used for the chosen label. + virtual int getNumEigenVectors(const std::string & label) const = 0; + +}; + +#endif // CPIBTAGGINGEIGENVECTORRECOMPOSITIONTOOL_H diff --git a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingSelectionTool.h b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingSelectionTool.h index 4a2962e9912563c1402f153ccd3e30d85a2a4ea3..01f249278c851d790a114d67409cecc6f1a7bc79 100644 --- a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingSelectionTool.h +++ b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/IBTaggingSelectionTool.h @@ -1,7 +1,7 @@ // Dear emacs, this is -*- c++ -*- /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/selection.xml b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/selection.xml index 0ca83586057e2ac71082c4616505608f9d868646..da7589e410ea809716db296417f176b935a6e4ba 100644 --- a/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/selection.xml +++ b/PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces/FTagAnalysisInterfaces/selection.xml @@ -3,4 +3,5 @@ <class name="IBTaggingEfficiencyTool" /> <class name="IBTaggingSelectionTool" /> <class name="IBTaggingTruthTaggingTool" /> + <class name="IBTaggingEigenVectorRecompositionTool" /> </lcgdict> diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CMakeLists.txt b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CMakeLists.txt index 4fb473ce926d96247f45ac7182f85274e0cfacf0..1901242e9dea21f80be95642d9eb30b6369670d6 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CMakeLists.txt +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CMakeLists.txt @@ -31,3 +31,4 @@ atlas_add_library( CalibrationDataInterfaceLib # Install files from the package: atlas_install_joboptions( share/*.py ) + diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataBackend.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataBackend.h index 9e3a745a7da7846c8aa286aae6508833f3139a2d..7da15c5882ca096efdd0234a089c80caf694bc17 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataBackend.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataBackend.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataContainer.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataContainer.h index 1b922479b4f8d784871fe3abfab466e072e9e763..7de76d26c6a5b46f6485b440b75172a258c8801f 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataContainer.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataContainer.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataEigenVariations.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataEigenVariations.h index c2eb5e166a586c1c497779d48004f24de5a09618..9f9b8a3bb7a3c4d88255b71ea393b5b1f589e59d 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataEigenVariations.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataEigenVariations.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ ////////////////////////////////////////////////////////////////////// @@ -87,6 +87,10 @@ namespace Analysis /** matrix to remove unecessary rows and columns from covariance */ TMatrixD getJacobianReductionMatrix() const; + /** Eigenvector recomposition method.*/ + bool EigenVectorRecomposition(const std::string label, + std::map<std::string, std::map<std::string, float>> &coefficientMap) const; + private: /** container object containing the basic information */ const CalibrationDataHistogramContainer* m_cnt; diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceBase.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceBase.h index a35c2462babf9f241d6fb880ecce6c160c52c7ab..5e83f573253c044de4878317ea46ce5f0a2ac98b 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceBase.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceBase.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceROOT.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceROOT.h index 215d1e03076b70be74e9f8ccce7b15cfe574b549..96311d58e5b5d47bc8a90b31aa3ff3f2469196b4 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceROOT.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceROOT.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// @@ -98,11 +98,8 @@ namespace Analysis const std::map<std::string, std::vector<std::string> >& EffNames, const std::map<std::string, std::vector<std::string> >& excludeFromEV, const std::map<std::string, Analysis::EVReductionStrategy> EVReductions, - - bool useEV = true, - bool useMCMCSF = true, - bool useTopologyRescaling = false, - bool useRecommendedEVExclusions = false, + bool useEV = true, bool useMCMCSF = true, + bool useTopologyRescaling = false, bool useRecommendedEVExclusions = false, bool verbose = true); /** default constructor for PROOF object retrieval */ @@ -306,6 +303,20 @@ namespace Analysis // ------------------------------------------------------------------------------------------ + /** run EigenVector Recomposition method */ + CalibrationStatus runEigenVectorRecomposition(const std::string& author, + const std::string& label, + const std::string& OP, + unsigned int mapindex = 0); + + CalibrationStatus runEigenVectorRecomposition(const std::string& label, + unsigned int mapindex = 0); + + /** Get Eigenvector recomposition map after running runEigenVectorRecomposition()*/ + std::map<std::string, std::map<std::string, float>> getEigenVectorRecompositionCoefficientMap(); + + // ------------------------------------------------------------------------------------------ + // Utilities /** retrieve the MC efficiency (central values) object for the given flavour label and operating point. @@ -439,6 +450,11 @@ namespace Analysis // ------------------------------------------------------------------------------------------ + // map storing coefficient calculated by EigenRecomposition. + std::map<std::string, std::map<std::string, float>> m_coefficientMap; + + // ------------------------------------------------------------------------------------------ + // Bounds checking functionality /** |eta| bounds and strategy for dealing with out-of-bounds conditions */ diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceTester.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceTester.h index b6172af5ea224ca0ece92b351d3f37750246a532..7f0856e26bca383d955a36e6264cabfb69821a73 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceTester.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceTester.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceTool.h index 30bc56ac344381a02730acd7e7e46b512f2d5d0c..d0a1e87e9f6c1839835e4528e3073cc803722da5 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceTool.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInterfaceTool.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// @@ -56,7 +56,7 @@ namespace Analysis verify that the aliasing is appropriate! DB representation (all residing under a common root folder): - .../\<jet author\>/\<tagger\>/\<operating point\>/\<flavour\>/\<object name\> + .../<jet author>/<tagger>/<operating point>/<flavour>/<object name> @author Frank Filthaut <F.Filthaut@science.ru.nl> */ diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInternals.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInternals.h index b057529a26bce0cd28f921f242804c1f7c6e0589..779779c40eb7087596ffde95b751a555c9dc3bb7 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInternals.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataInternals.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ ////////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataUpdater.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataUpdater.h index 5b721f27f8a24bb4998d48d0903ad4b539e9265a..0cda9c22e6e745b0b4a654780f6d576eaa2e519f 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataUpdater.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataUpdater.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataUtilities.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataUtilities.h index 4c334edf114e1e402a9581a114686cb28b3a87ea..e9d74cc6a14a0d67c996e1b17a089398393d4d6d 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataUtilities.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataUtilities.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ // CalibrationDataUtilities.h, (c) ATLAS Detector software diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataVariables.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataVariables.h index 8fb1b49ff84da94a5d3a95db114d4511b8b27f6c..f548030e07e2956d5a3cf1cea2ad3fa871e7b04c 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataVariables.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/CalibrationDataVariables.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/ICalibrationDataInterfaceTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/ICalibrationDataInterfaceTool.h index acb43e2034ded557a4d5aa4577d028118c02e552..f813f04639257a5c9e33b6fac5afd371abc06c61 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/ICalibrationDataInterfaceTool.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/CalibrationDataInterface/ICalibrationDataInterfaceTool.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataBackend.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataBackend.cxx index 3505ea574d3595c52a3331af0afd40b6d743481c..4e2cc51d005895134696342cc4cb3f6aa8b1eb5e 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataBackend.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataBackend.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataContainer.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataContainer.cxx index 5688046d1392ce14befae3cfd57653cd1ad062f6..a4282a8e0e9b9c1ce05cc070d82be6fb21427df1 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataContainer.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataContainer.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataEigenVariations.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataEigenVariations.cxx index 31375312c8240a29323360ea85055ddead9ff2c8..2210f43fa510939f31e1492d516a6135ca2afb3d 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataEigenVariations.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataEigenVariations.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////////// @@ -23,6 +23,7 @@ #include "TDecompSVD.h" #include "TMatrixDSymEigen.h" #include "TROOT.h" +#include "TFile.h" using Analysis::CalibrationDataEigenVariations; using Analysis::CalibrationDataInterface::split; @@ -1040,3 +1041,134 @@ CalibrationDataEigenVariations::isExtrapolationVariation(unsigned int nameIndex) return (m_namedExtrapolation == int(nameIndex)); } + +//________________________________________________________________________________ +bool +CalibrationDataEigenVariations::EigenVectorRecomposition(const std::string label, + std::map<std::string, std::map<std::string, float>> &coefficientMap) const +{ + // Calculating eigen vector recomposition coefficient map and pass to + // user by reference. Return true if method success. Return false and + // will not modify coefficientMap if function failed. + // + // label: flavour label + // coefficientMap: (reference to) coefficentMap which will be used as return value. + if (! m_initialized) const_cast<CalibrationDataEigenVariations*>(this)->initialize(); + + std::vector<TH1*> originSF_hvec; + std::vector<TH1*> eigenSF_hvec; + + // Retrieving information for calculation + std::vector<string>fullUncList = m_cnt->listUncertainties(); + std::vector<string> uncList; + for (unsigned int t = 0; t < fullUncList.size(); ++t) { + // entries that should never be included + if (fullUncList[t] == "comment" || fullUncList[t] == "result" || + fullUncList[t] == "combined" || fullUncList[t] == "statistics" || + fullUncList[t] == "systematics" || fullUncList[t] == "MCreference" || + fullUncList[t] == "MChadronisation" || fullUncList[t] == "extrapolation" || + fullUncList[t] == "ReducedSets" || fullUncList[t] == "excluded_set") continue; + // entries that can be excluded if desired + if (m_namedIndices.find(fullUncList[t]) != m_namedIndices.end()) continue; + + TH1* hunc = dynamic_cast<TH1*>(m_cnt->GetValue(fullUncList[t].c_str())); + + Int_t nx = hunc->GetNbinsX(); + Int_t ny = hunc->GetNbinsY(); + Int_t nz = hunc->GetNbinsZ(); + Int_t bin = 0; + bool retain = false; // Retain the histogram? + + // discard empty histograms + // Read all bins without underflow&overflow + for(Int_t binx = 1; binx <= nx; binx++) + for(Int_t biny = 1; biny <= ny; biny++) + for(Int_t binz = 1; binz <= nz; binz++){ + bin = hunc->GetBin(binx, biny, binz); + if (fabs(hunc->GetBinContent(bin)) > 1E-20){ + retain = true; + break; + } + }// end hist bin for-loop + if (!retain){ + std::cout<<"Eigenvector Recomposition: Empty uncertainty "<<fullUncList.at(t)<<" is discarded."<<std::endl; + continue; // discard the vector + } + + uncList.push_back(fullUncList.at(t)); + originSF_hvec.push_back(hunc); + } + + TH1* nom = dynamic_cast<TH1*>(m_cnt->GetValue("result")); // Nominal SF hist + int dim = nom->GetDimension(); + Int_t nx = nom->GetNbinsX(); + Int_t ny = nom->GetNbinsY(); + Int_t nz = nom->GetNbinsZ(); + Int_t nbins = nx; + if(dim > 1) nbins *= ny; + if(dim > 2) nbins *= nz; + TMatrixD matSF(uncList.size(), nbins); + Int_t col = 0; // mark the column number + // Fill the Delta SF Matrix + for(unsigned int i = 0; i < uncList.size(); i++){ + col = 0; + // Loop all bins except underflow&overflow bin + for(int binz = 1; binz <= nz; binz++) + for(int biny = 1; biny <= ny; biny++) + for(int binx = 1; binx <= nx; binx++){ + Int_t bin = originSF_hvec.at(i)->GetBin(binx, biny, binz); + TMatrixDRow(matSF,i)[col] = originSF_hvec[i]->GetBinContent(bin); + col++; + } + } + + // get eigen vectors of scale factors. Note that this is not the original eigen-vector. + int nEigen = getNumberOfEigenVariations(); + TH1* up = nullptr; + TH1* down = nullptr; + for (int i = 0; i < nEigen; i++){ + if (!getEigenvectorVariation(i, up, down)){ + std::cerr<<"EigenVectorRecomposition: Error on retrieving eigenvector "<<i<<std::endl; + return false; + } + //Need uncertainty value so subtract central calibration here. + up->Add(nom, -1); + eigenSF_hvec.push_back(up); + } + TMatrixD matEigen(nEigen, nbins); + + // Fill the Eigen Matrix + for(int i = 0; i < nEigen; i++){ + col = 0; + // Read 300 bins without underflow&overflow + for(int binz = 1; binz <= nz; binz++) + for(int biny = 1; biny <= ny; biny++) + for(int binx = 1; binx <= nx; binx++){ + Int_t bin = eigenSF_hvec.at(i)->GetBin(binx, biny, binz); + TMatrixDRow(matEigen,i)[col] = eigenSF_hvec[i]->GetBinContent(bin); + col++; + } + } + + // Sanity check: + TMatrixD matEigenOriginal = matEigen; + TMatrixD matEigenTranspose = matEigen; + matEigenTranspose = matEigenTranspose.T(); + TMatrixD matOriginalTimesTranspose = matEigenOriginal*matEigenTranspose; + TMatrixD matEigenInvert = matEigenTranspose*matOriginalTimesTranspose.Invert(); + //(matEigenOriginal*matEigenInvert).DrawClone("colz"); // This should give us an identity matrix + + TMatrixD matCoeff = matSF*matEigenInvert; + int nRows = matCoeff.GetNrows(); + int nCols = matCoeff.GetNcols(); + std::map<std::string, float> temp_map; + for (int col = 0; col < nCols; col++){ + temp_map.clear(); + for(int row = 0; row < nRows; row++){ + temp_map[uncList[row]] = TMatrixDRow(matCoeff, row)[col]; + } + coefficientMap["Eigen_"+label+"_"+std::to_string(col)] = temp_map; + } + + return true; +} diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataInterfaceBase.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataInterfaceBase.cxx index 70341de9510ceaebb9aaf58ddca238464c7f46e2..2acf618b10da806872f961376835a5d2775a8357 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataInterfaceBase.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataInterfaceBase.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataInterfaceROOT.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataInterfaceROOT.cxx index e541ff01dcebd2c2ca7dce1be60486adda47f529..8a1b5fd518fd11b7a039ecfa059554218b0bc67c 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataInterfaceROOT.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataInterfaceROOT.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ ////////////////////////////////////////////////////////////////////////////////////////////// @@ -394,7 +394,6 @@ Analysis::CalibrationDataInterfaceROOT::CalibrationDataInterfaceROOT(const strin for (auto const& flavour : flavours) { m_excludeFromCovMatrix[flavour] = to_exclude; } - for (auto const& flavour : flavours) { test = "excludeFrom"; test += flavour; test += "CovMatrix"; to_exclude = split(env.GetValue(test.c_str(), "")); @@ -2158,6 +2157,72 @@ Analysis::CalibrationDataInterfaceROOT::getShiftedScaleFactors (const std::strin shifted->Add(hunc, sigmas); return shifted; } +//====================== run EigenVectorRecomposition method =========================== +Analysis::CalibrationStatus +Analysis::CalibrationDataInterfaceROOT::runEigenVectorRecomposition (const std::string& author, + const std::string& label, + const std::string& OP, + unsigned int mapIndex){ + // run eigen vector recomposition method. If success, stored the retrieved coefficient map + // in m_coefficientMap and return success. Otherwise return error and keep m_coefficientMap + // untouched. + // author: jet collection name + // label: jet flavour label + // OP: tagger working point + // mapIndex: index to the MC efficiency map to be used. Should be 0? + // Todo: What is mapindex? + // Todo: Check the way xAODBTaggingTool initialize CDI. Check if that is the as how we are initialize CDI. + if(!m_runEigenVectorMethod) { + cerr << "runEigenVectorRecomposition: Recomposition need to be ran with CalibrationDataInterfaceRoot initialized in eigenvector mode" << endl; + return Analysis::kError; + } + + unsigned int indexSF; + if (! retrieveCalibrationIndex (label, OP, author, true, indexSF, mapIndex)) { + cerr << "runEigenVectorRecomposition: unable to find SF calibration for object " + << fullName(author, OP, label, true) << endl; + return Analysis::kError; + } + + return runEigenVectorRecomposition (label, indexSF); +} + +Analysis::CalibrationStatus +Analysis::CalibrationDataInterfaceROOT::runEigenVectorRecomposition (const std::string& label, + unsigned int indexSF){ + // run eigen vector recomposition method. If success, stored the retrieved coefficient map + // in m_coefficientMap and return success. Otherwise return error and keep m_coefficientMap + // untouched. + // label: jet flavour label + // indexSF: index to scale factor calibration object + CalibrationDataContainer* container = m_objects[indexSF]; + if (! container) { + cerr << "runEigenVectorRecomposition: error retrieving container!" << endl; + return Analysis::kError; + } + + // Retrieve eigenvariation + const CalibrationDataEigenVariations* eigenVariation=m_eigenVariationsMap[container]; + if (! eigenVariation) { + cerr << "runEigenVectorRecomposition: Could not retrieve eigenvector variation, while it should have been there." << endl; + return Analysis::kError; + } + // Doing eigenvector recomposition + std::map<std::string, std::map<std::string, float>> coefficientMap; + if(!eigenVariation->EigenVectorRecomposition(label, coefficientMap)) + return Analysis::kError; + + m_coefficientMap = coefficientMap; + return Analysis::kSuccess; +} + +std::map<std::string, std::map<std::string, float>> +Analysis::CalibrationDataInterfaceROOT::getEigenVectorRecompositionCoefficientMap(){ + if(m_coefficientMap.empty()) + cerr << "getCoefficientMap: Call runEigenVectorRecomposition() before retrieving coefficient map! " <<endl; + return m_coefficientMap; +} + //====================== put some utility functions here =================================== diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataUtilities.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataUtilities.cxx index a0be063407b3094e0a6f67ca609c892bfdcbdc6d..d35793012794ff77cc3e0744f6f8929524a492df 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataUtilities.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/CalibrationDataUtilities.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/LinkDef.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/LinkDef.h index 5324dd345f25dde217198782598b570456ff1010..7fb4c793f1f21f50034144e1d742eaaed7939b58 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/LinkDef.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/Root/LinkDef.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "CalibrationDataInterface/CalibrationDataVariables.h" diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/src/components/CalibrationDataInterface_entries.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/src/components/CalibrationDataInterface_entries.cxx index 3958b728c9306cca846707a930439c695a67365d..6d2329172cd0b96fe9c6b7df7dd5ef3c9d6fe5e4 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/src/components/CalibrationDataInterface_entries.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/CalibrationDataInterface/src/components/CalibrationDataInterface_entries.cxx @@ -1,3 +1,5 @@ + + #include "CalibrationDataInterface/CalibrationDataInterfaceTool.h" #include "CalibrationDataInterface/CalibrationDataUpdater.h" #include "CalibrationDataInterface/CalibrationDataInterfaceTester.h" diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/CMakeLists.txt b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/CMakeLists.txt index 59ad17fb61f2600c0180b0fe90630cba18d3f9da..2d6618ffc57ea37daf080361679fe7a122eaa970 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/CMakeLists.txt +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/CMakeLists.txt @@ -3,6 +3,7 @@ # Declare the package name: atlas_subdir( xAODBTaggingEfficiency ) + # External dependencies: find_package( ROOT COMPONENTS Core Hist RIO ) @@ -11,15 +12,16 @@ atlas_add_library( xAODBTaggingEfficiencyLib xAODBTaggingEfficiency/*.h Root/*.cxx PUBLIC_HEADERS xAODBTaggingEfficiency INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} - LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools xAODBTagging + LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools AsgMessagingLib xAODBTagging PATCoreAcceptLib PATInterfaces CalibrationDataInterfaceLib FTagAnalysisInterfacesLib - PRIVATE_LINK_LIBRARIES PathResolver ) + PRIVATE_LINK_LIBRARIES PathResolver AsgMessagingLib ) + if( NOT XAOD_STANDALONE ) atlas_add_component( xAODBTaggingEfficiency src/*.h src/*.cxx src/components/*.cxx - LINK_LIBRARIES xAODJet CalibrationDataInterfaceLib AthenaBaseComps + LINK_LIBRARIES AsgMessagingLib xAODJet CalibrationDataInterfaceLib AthenaBaseComps GaudiKernel FTagAnalysisInterfacesLib xAODBTaggingEfficiencyLib ) endif() @@ -28,15 +30,23 @@ atlas_add_dictionary( xAODBTaggingEfficiencyDict xAODBTaggingEfficiency/selection.xml LINK_LIBRARIES xAODBTaggingEfficiencyLib ) -# Executable(s) in the package: -if( XAOD_STANDALONE ) +# Executable(s) in the package (to be built only under AthAnalysis or in stand-alone mode): +if( XAOD_ANALYSIS OR XAOD_STANDALONE ) atlas_add_executable( BTaggingEfficiencyToolTester util/BTaggingEfficiencyToolTester.cxx LINK_LIBRARIES xAODBTaggingEfficiencyLib ) - atlas_add_executable( BTaggingSelectionToolTester + atlas_add_executable( BTaggingEigenVectorRecompositionToolTester + util/BTaggingEigenVectorRecompositionToolTester.cxx + LINK_LIBRARIES xAODBTaggingEfficiencyLib ) + + atlas_add_executable( BTaggingSelectionToolTester util/BTaggingSelectionToolTester.cxx LINK_LIBRARIES AsgMessagingLib xAODJet xAODBTagging xAODBTaggingEfficiencyLib ) + + atlas_add_executable( BTaggingTruthTaggingTester + util/BTaggingTruthTaggingTester.cxx + LINK_LIBRARIES AsgMessagingLib xAODJet xAODBTagging xAODBTaggingEfficiencyLib FTagAnalysisInterfacesLib ) endif() # Install files from the package: diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingEfficiencyTool.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingEfficiencyTool.cxx index 7082d2dd9803c302c004c12d2f65fe2188034bf2..6191e9cac88b7e09cf6ee98797141b96e9f32455 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingEfficiencyTool.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingEfficiencyTool.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "xAODBTaggingEfficiency/BTaggingEfficiencyTool.h" @@ -490,7 +490,7 @@ StatusCode BTaggingEfficiencyTool::initialize() { ATH_CHECK( m_selectionTool.setProperty("JetAuthor", m_jetAuthor) ); ATH_CHECK( m_selectionTool.setProperty("MinPt", m_minPt) ); ATH_CHECK( m_selectionTool.retrieve() ); - } + } // if the user decides to ignore these errors, at least make her/him aware of this if (m_ignoreOutOfValidityRange) { @@ -942,6 +942,33 @@ BTaggingEfficiencyTool::listScaleFactorSystematics(bool named) const { return uncertainties; } +CorrectionCode +BTaggingEfficiencyTool::getEigenRecompositionCoefficientMap(const std::string &label, std::map<std::string, std::map<std::string, float>> & coefficientMap){ + // Calling EigenVectorRecomposition method in CDI and retrieve recomposition map. + // If success, coefficientMap would be filled and return ok. + // If failed, return error. + // label : flavour label + // coefficientMap: store returned coefficient map. + if (! m_initialised) { + ATH_MSG_ERROR("BTaggingEfficiencyTool has not been initialised"); + return CorrectionCode::Error; + } + if(label.compare("B") != 0 && + label.compare("C") != 0 && + label.compare("T") != 0 && + label.compare("Light") != 0){ + ATH_MSG_ERROR("Flavour label is illegal! Label need to be B,C,T or Light."); + return CorrectionCode::Error; + } + CalibrationStatus status = m_CDI->runEigenVectorRecomposition(m_jetAuthor, label, m_OP); + if (status != Analysis::kSuccess){ + ATH_MSG_ERROR("Failure running EigenVectorRecomposition Method."); + return CorrectionCode::Error; + } + coefficientMap = m_CDI->getEigenVectorRecompositionCoefficientMap(); + return CorrectionCode::Ok; +} + // WARNING the behaviour of future calls to getEfficiency and friends are modified by this // method - it indicates which systematic shifts are to be applied for all future calls SystematicCode BTaggingEfficiencyTool::applySystematicVariation( const SystematicSet & systConfig) { diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingEigenVectorRecompositionTool.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingEigenVectorRecompositionTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6a80f5835f5f6556443d02d934c860f058a66ce4 --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingEigenVectorRecompositionTool.cxx @@ -0,0 +1,233 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "xAODBTaggingEfficiency/BTaggingEigenVectorRecompositionTool.h" + + +BTaggingEigenVectorRecompositionTool::BTaggingEigenVectorRecompositionTool( const std::string & name) : + asg::AsgTool( name ) +{ + declareProperty("BTaggingEfficiencyTool", m_btageffTool); +} + +BTaggingEigenVectorRecompositionTool::~BTaggingEigenVectorRecompositionTool() +{ + +} + +// Initialize BtaggingEfficiencyTool handle and retrieve coefficient map for +// all flavours. Also initialize vectors which contains all original sources +// uncertainties' names. One vector for each flavour. +StatusCode BTaggingEigenVectorRecompositionTool::initialize() +{ + ATH_MSG_INFO("Hello BTaggingEigenVectorRecompositionTool user... initializing"); + ATH_CHECK(m_btageffTool.retrieve()); + + if (m_btageffTool.empty()) { + ATH_MSG_ERROR("Failed to retrieve BTaggingEfficiencyTool handle"); + return StatusCode::FAILURE; + } + CP::CorrectionCode code1 = m_btageffTool->getEigenRecompositionCoefficientMap("B", m_coefficientMapB); + CP::CorrectionCode code2 = m_btageffTool->getEigenRecompositionCoefficientMap("C", m_coefficientMapC); + CP::CorrectionCode code3 = m_btageffTool->getEigenRecompositionCoefficientMap("T", m_coefficientMapT); + CP::CorrectionCode code4 = m_btageffTool->getEigenRecompositionCoefficientMap("Light", m_coefficientMapLight); + + if(code1 != CP::CorrectionCode::Ok) { + ATH_MSG_ERROR("Failed to retrieve coefficient map of B"); + return StatusCode::FAILURE; + } + if(code2 != CP::CorrectionCode::Ok) { + ATH_MSG_ERROR("Failed to retrieve coefficient map of C"); + return StatusCode::FAILURE; + } + if(code3 != CP::CorrectionCode::Ok) { + ATH_MSG_ERROR("Failed to retrieve coefficient map of T"); + return StatusCode::FAILURE; + } + if(code4 != CP::CorrectionCode::Ok) { + ATH_MSG_ERROR("Failed to retrieve coefficient map of Light"); + return StatusCode::FAILURE; + } + + std::map<std::string, std::map<std::string, float>>::iterator outter; + + outter = m_coefficientMapB.begin(); + for (std::map<std::string, float>::iterator inner=outter->second.begin(); + inner!=outter->second.end(); ++inner){ + m_NPnameListB.push_back(inner->first); + } + outter = m_coefficientMapC.begin(); + for (std::map<std::string, float>::iterator inner=outter->second.begin(); + inner!=outter->second.end(); ++inner){ + m_NPnameListC.push_back(inner->first); + } + outter = m_coefficientMapT.begin(); + for (std::map<std::string, float>::iterator inner=outter->second.begin(); + inner!=outter->second.end(); ++inner){ + m_NPnameListT.push_back(inner->first); + } + outter = m_coefficientMapLight.begin(); + for (std::map<std::string, float>::iterator inner=outter->second.begin(); + inner!=outter->second.end(); ++inner){ + m_NPnameListLight.push_back(inner->first); + } + + return StatusCode::SUCCESS; + +} + +// Return a vector which contains a list of original vector uncertainties names. +// vector list is for the chosen flavour label. The order of the names is the same +// as the coefficient values given by getCoefficients() +std::vector<std::string> BTaggingEigenVectorRecompositionTool::getListOfOriginalNuisanceParameters(const std::string & label) const +{ + ATH_MSG_INFO("getListOfOriginalNuisanceParameters()"); + + std::vector<std::string> dummy; + if(label.compare("B") == 0) + return m_NPnameListB; + else if(label.compare("C") == 0) + return m_NPnameListC; + else if(label.compare("T") == 0) + return m_NPnameListT; + else if(label.compare("Light") == 0) + return m_NPnameListLight; + else{ + ATH_MSG_ERROR("Label is illegal! Available label: B, C, T and Light."); + return dummy; + } + + return dummy; +} + +// Produce a coefficient map contains only eigenvectors that is showing in +// eigenIdxList and return it to user. If given empty evIdxList, the function +// returns a full map. Produced map is for the chosen flavour label. +std::map<std::string, std::map<std::string, float>> BTaggingEigenVectorRecompositionTool::getCoefficientMap(const std::string & label, const std::vector<unsigned int> evIdxList) const +{ + ATH_MSG_INFO("getCoefficientMap()"); + + std::map<std::string, std::map<std::string, float>> fullMap; + if(label.compare("B") == 0) + fullMap = m_coefficientMapB; + else if(label.compare("C") == 0) + fullMap = m_coefficientMapC; + else if(label.compare("T") == 0) + fullMap = m_coefficientMapT; + else if(label.compare("Light") == 0) + fullMap = m_coefficientMapLight; + else{ + ATH_MSG_ERROR("Label is illegal! Available label: B, C, T and Light."); + return fullMap; + } + + std::vector<std::string> evNameList; + for(unsigned int i : evIdxList){ + // Note: This eigenvector name convention has to be same with that in CalibrationDataEigenVariations. One way to avoid the naming convention is to change coefficient map structure into: map<unsigned int, map<string, float>> + evNameList.push_back("Eigen_"+label+"_"+std::to_string(i)); + } + + std::map<std::string, std::map<std::string, float>> resultMap; + for (std::map<std::string, std::map<std::string, float>>::iterator iter = fullMap.begin(); + iter != fullMap.end(); ++iter){ + if (evNameList.end() != std::find(evNameList.begin(), evNameList.end(), iter->first) || + evNameList.empty()) + resultMap[iter->first] = iter->second; + } + return resultMap; +} + +// Returns a vector contains the coefficients value of the chosen label +// and the chosen eigenvector. The order of the value is the same as +// the order of original uncertainty names given by +// getListOfOriginalNuisanceParameters() +std::vector<float> BTaggingEigenVectorRecompositionTool::getCoefficients(const std::string & label, const unsigned int evIdx) const +{ + ATH_MSG_INFO("getCoefficients()"); + std::vector<float> coefficients; // dummy to be replaced + std::map<std::string, std::map<std::string, float>> fullMap; + std::vector<std::string> NPnameList; + if(label.compare("B") == 0){ + fullMap = m_coefficientMapB; + NPnameList = m_NPnameListB; + } + else if(label.compare("C") == 0){ + fullMap = m_coefficientMapC; + NPnameList = m_NPnameListC; + } + else if(label.compare("T") == 0){ + fullMap = m_coefficientMapT; + NPnameList = m_NPnameListT; + } + else if(label.compare("Light") == 0){ + fullMap = m_coefficientMapLight; + NPnameList = m_NPnameListLight; + } + else{ + ATH_MSG_ERROR("Label is illegal! Available label: B, C, T and Light."); + return coefficients; + } + + std::string evName = "Eigen_"+label+"_"+std::to_string(evIdx); + if(fullMap.count(evName) <= 0){ + ATH_MSG_ERROR("Cannot find " << evName <<" in Eigen Vector coefficient map."); + return coefficients; + } + + std::map<std::string, float> oneEVmap = fullMap[evName]; + for(std::string NPname : NPnameList){ + coefficients.push_back(oneEVmap[NPname]); + } + return coefficients; +} + +// Return number of eigenvectors used for the chosen label. +int BTaggingEigenVectorRecompositionTool::getNumEigenVectors(const std::string & label)const{ + std::map<std::string, std::map<std::string, float>> fullMap; + if(label.compare("B") == 0) + fullMap = m_coefficientMapB; + else if(label.compare("C") == 0) + fullMap = m_coefficientMapC; + else if(label.compare("T") == 0) + fullMap = m_coefficientMapT; + else if(label.compare("Light") == 0) + fullMap = m_coefficientMapLight; + else{ + ATH_MSG_ERROR("Label is illegal! Available label: B, C, T and Light."); + return -1; + } + return fullMap.size(); +} + +// this returns a list of eigen vector systematics supported by the btaggingEfficiency tool handle +CP::SystematicSet BTaggingEigenVectorRecompositionTool::affectingSystematics() const { + return m_btageffTool->affectingSystematics(); +} + +// it indicates which systematic shifts are to be applied for all future calls +// no systematics for now, proxy for later +CP::SystematicCode BTaggingEigenVectorRecompositionTool::applySystematicVariation( const CP::SystematicSet & systConfig ) +{ + for (auto syst : systConfig) { + CP::SystematicSet myset; + ATH_MSG_WARNING("applySystematicVariation was called for " << syst.name() << " but BTaggingEigenVectorRecompositionTool does not apply Systematic Variations"); + //the truth tagging tool provides results for all possible systematic variations in its results objects, the user does not need to call each one seperatly. + } + return CP::SystematicCode::Ok; +} + +// returns true if the argument systematic is supported by the +// btaggingEfficiency tool handle +bool BTaggingEigenVectorRecompositionTool::isAffectedBySystematic( const CP::SystematicVariation & systematic ) const +{ + CP::SystematicSet sys = affectingSystematics(); + return sys.find(systematic) != sys.end(); +} + +// subset of Eigenvector systeamtics that are recommended by the +// btaggingEfficiency tool handle +CP::SystematicSet BTaggingEigenVectorRecompositionTool::recommendedSystematics() const { + return affectingSystematics(); +} diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingSelectionTool.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingSelectionTool.cxx index 6d4310cbb62a0696a2812c75e663f9df4f7855d2..d6fecd87342ec32d0d51455ab1b27efb3e77aafc 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingSelectionTool.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingSelectionTool.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "xAODBTaggingEfficiency/BTaggingSelectionTool.h" @@ -195,6 +195,7 @@ void BTaggingSelectionTool::ExtractTaggerProperties(taggerproperties &tagger, st } } + CorrectionCode BTaggingSelectionTool::getTaggerWeight( const xAOD::Jet& jet, double & tagweight, bool useVetoWP) const{ taggerproperties localtagger; @@ -238,7 +239,7 @@ CorrectionCode BTaggingSelectionTool::getTaggerWeight( const xAOD::Jet& jet, dou return CorrectionCode::Ok; } - else if(taggerName.find("DL1") != string::npos){ + else if(taggerName.find("DL1") != string::npos){ double dl1_pb(-10.); double dl1_pc(-10.); @@ -296,7 +297,7 @@ CorrectionCode BTaggingSelectionTool::getTaggerWeight( double pb, double pc, dou tagweight = -100.; if( taggerName.find("DL1") != string::npos ){ - bool valid_input = (!std::isnan(pu) && pb>0 && pc>0 && pu>0); + bool valid_input = (!std::isnan(pu) && pb>=0 && pc>=0 && pu>=0); if (!valid_input){ if(m_ErrorOnTagWeightFailure){ @@ -309,9 +310,10 @@ CorrectionCode BTaggingSelectionTool::getTaggerWeight( double pb, double pc, dou } if(OP.find("CTag") != string::npos){ - tagweight = log( pc/(localtagger.fraction*pb+(1.-localtagger.fraction)*pu) ); - }else{ - tagweight = log( pb/(localtagger.fraction*pc+(1.-localtagger.fraction)*pu) ); + tagweight = log(pc / (localtagger.fraction * pb + (1. - localtagger.fraction) * pu)); + } + else{ + tagweight = log(pb / (localtagger.fraction * pc + (1. - localtagger.fraction) * pu) ); } return CorrectionCode::Ok; @@ -326,20 +328,18 @@ CorrectionCode BTaggingSelectionTool::getTaggerWeight( double pb, double pc, dou asg::AcceptData BTaggingSelectionTool::accept( const xAOD::IParticle* p ) const { - // Reset the result: - asg::AcceptData acceptData(&m_acceptinfo); // Check if this is a jet: if( p->type() != xAOD::Type::Jet ) { ATH_MSG_ERROR( "accept(...) Function received a non-jet" ); - return acceptData; + return asg::AcceptData (&m_acceptinfo); } // Cast it to a jet: const xAOD::Jet* jet = dynamic_cast< const xAOD::Jet* >( p ); if( ! jet ) { ATH_MSG_FATAL( "accept(...) Failed to cast particle to jet" ); - return acceptData; + return asg::AcceptData (&m_acceptinfo); } // Let the specific function do the work: @@ -347,7 +347,7 @@ asg::AcceptData BTaggingSelectionTool::accept( const xAOD::IParticle* p ) const } asg::AcceptData BTaggingSelectionTool::accept( const xAOD::Jet& jet ) const { - asg::AcceptData acceptData(&m_acceptinfo); + asg::AcceptData acceptData (&m_acceptinfo); if (! m_initialised) { ATH_MSG_ERROR("BTaggingSelectionTool has not been initialised"); @@ -375,7 +375,6 @@ asg::AcceptData BTaggingSelectionTool::accept( const xAOD::Jet& jet ) const { double weight_mv2cl100(-10.); const xAOD::BTagging* btag = xAOD::BTaggingUtilities::getBTagging( jet ); - if ((!btag)){ ATH_MSG_ERROR("Failed to retrieve the BTagging information"); } @@ -421,7 +420,8 @@ asg::AcceptData BTaggingSelectionTool::accept( const xAOD::Jet& jet ) const { asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double tag_weight) const { - asg::AcceptData acceptData(&m_acceptinfo); + + asg::AcceptData acceptData (&m_acceptinfo); if (! m_initialised) { ATH_MSG_ERROR("BTaggingSelectionTool has not been initialised"); @@ -430,7 +430,7 @@ asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double tag_ eta = std::fabs(eta); - if (! checkRange(pT, eta, acceptData)) + if (! checkRange(pT, eta,acceptData)) return acceptData; // After initialization, either m_tagger.spline or m_tagger.constcut should be non-zero @@ -443,8 +443,8 @@ asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double tag_ if ( tag_weight < cutvalue ){ return acceptData; } + acceptData.setCutResult( "WorkingPoint", true ); - // Return the result: return acceptData; } @@ -453,7 +453,7 @@ asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double tag_ asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double weight_mv2cl100, double weight_mv2c100) const { - asg::AcceptData acceptData(&m_acceptinfo); + asg::AcceptData acceptData (&m_acceptinfo); if (! m_initialised) { ATH_MSG_ERROR("BTaggingSelectionTool has not been initialised"); @@ -462,7 +462,7 @@ asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double weig eta = std::fabs(eta); - if (! checkRange(pT, eta, acceptData)) + if (! checkRange(pT, eta,acceptData)) return acceptData; // After initialization, either m_tagger.spline or m_tagger.constcut should be non-zero @@ -511,7 +511,7 @@ asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double weig asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double pb, double pc, double pu) const { - asg::AcceptData acceptData(&m_acceptinfo); + asg::AcceptData acceptData (&m_acceptinfo); if (! m_initialised) { ATH_MSG_ERROR("BTaggingSelectionTool has not been initialised"); @@ -520,7 +520,7 @@ asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double pb, eta = std::fabs(eta); - if (! checkRange(pT, eta, acceptData)) + if (! checkRange(pT, eta,acceptData)) return acceptData; // After initialization, either m_tagger.spline or m_tagger.constcut should be non-zero @@ -550,6 +550,8 @@ asg::AcceptData BTaggingSelectionTool::accept(double pT, double eta, double pb, int BTaggingSelectionTool::getQuantile( const xAOD::IParticle* p ) const { // Check if this is a jet: + + if( p->type() != xAOD::Type::Jet ) { ATH_MSG_ERROR( "accept(...) Function received a non-jet" ); return -1; @@ -581,7 +583,7 @@ int BTaggingSelectionTool::getQuantile( const xAOD::Jet& jet ) const{ } -int BTaggingSelectionTool::getQuantile(double pT, double eta, double weight_mv2) const +int BTaggingSelectionTool::getQuantile(double pT, double eta, double weight_mv2 ) const { if (! m_initialised) { ATH_MSG_ERROR("BTaggingSelectionTool has not been initialised"); @@ -593,29 +595,28 @@ int BTaggingSelectionTool::getQuantile(double pT, double eta, double weight_mv2) // returns 3 if between 77% and 70% // returns 2 if between 85% and 77% // returns 1 if between 100% and 85% - // returns 0 if smaller than -1e4-> should never happen - // return -1 if bigger than 1e4 or not in b-tagging acceptance + // return -1 not in b-tagging acceptance ////////////////////// int bin_index(-1); - - asg::AcceptData acceptData(&m_acceptinfo); - if (! checkRange(pT, eta, acceptData)) return bin_index; + asg::AcceptData acceptData (&m_acceptinfo); + if (! checkRange(pT, eta,acceptData)) return bin_index; // If in b-tagging acceptance, cont.tagging - for (int i=0; i<=5; ++i) { + for (int i=1; i<=5; ++i) { if (weight_mv2 < m_continuouscuts[i]) { bin_index = i; break; } + else if (weight_mv2 >= m_continuouscuts[5]){ + bin_index = 5; + break; + } } - - if (0==bin_index) ATH_MSG_ERROR("B-tagging weight is smaller than 1e-4, this shouldn't happen!"); - return bin_index; } -bool BTaggingSelectionTool::checkRange(double pT, double eta, asg::AcceptData& acceptData) const +bool BTaggingSelectionTool::checkRange(double pT, double eta,asg::AcceptData& acceptData) const { // Do the |eta| cut: if( eta > m_maxEta ) { diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingTruthTaggingTool.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingTruthTaggingTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..584461fa8c6955215701b52c4d8dc344e1fcd0fd --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/BTaggingTruthTaggingTool.cxx @@ -0,0 +1,1310 @@ +#include "xAODBTaggingEfficiency/BTaggingTruthTaggingTool.h" +#include "xAODBTaggingEfficiency/BTaggingEfficiencyTool.h" +#include "xAODBTagging/BTagging.h" +#include "xAODBTagging/BTaggingUtilities.h" +#include "CalibrationDataInterface/CalibrationDataInterfaceROOT.h" +#include "CalibrationDataInterface/CalibrationDataContainer.h" +#include "PATInterfaces/SystematicRegistry.h" +#include "PathResolver/PathResolver.h" +#include "PATCore/AcceptData.h" + +#include "TFile.h" + +#include <algorithm> +#include <numeric> + +using std::string; + +using CP::CorrectionCode; +using CP::SystematicSet; +using CP::SystematicVariation; +using CP::SystematicCode; +using CP::SystematicRegistry; + +using Analysis::Uncertainty; +using Analysis::CalibrationDataVariables; +using Analysis::CalibrationDataContainer; +using Analysis::CalibResult; +using Analysis::CalibrationStatus; +using Analysis::Total; +using Analysis::SFEigen; +using Analysis::SFNamed; +using Analysis::None; + +using xAOD::IParticle; + + +BTaggingTruthTaggingTool::BTaggingTruthTaggingTool( const std::string & name) + : asg::AsgTool( name ), + m_effTool ("BTaggingEfficiencyTool/effTool", this), + m_selTool ("BTaggingSelectionTool/selTool", this) + { + + m_initialised = false; + + + // properties of BTaggingTruthTaggingTool + declareProperty( "IgnoreScaleFactors", m_ignoreSF=true, "ignore scale factors in computation of TRF weight"); + declareProperty( "UsePermutations", m_usePerm=true, "if the chosen permutation is used, a reweighting is applied to the TRF weight for systematics"); + declareProperty( "UseQuantile", m_useQuntile=true, "if the chosen quantile is used, a reweighting is applied to the TRF weight for systematics"); + declareProperty( "UseSystematics", m_useSys=false, "will the results contain all systematic variations, or just the nominal"); + declareProperty( "MaxNtagged", m_nbtag=2, "what is the maximal possible number of tagged jets"); + + // properties of BtaggingSelectionTool + declareProperty( "MaxEta", m_maxEta = 2.5 ); + declareProperty( "MinPt", m_minPt = 20000 /*MeV*/); + declareProperty( "MaxRangePt", m_maxRangePt = 1000000 /*MeV*/); + + // properties of BTaggingEfficiencyTool + declareProperty("TaggerName", m_taggerName="MV2c10", "tagging algorithm name as specified in CDI file"); + declareProperty("OperatingPoint", m_OP="FixedCutBEff_77", "operating point as specified in CDI file"); + declareProperty("JetAuthor", m_jetAuthor="AntiKt4EMTopoJets", "jet collection & JVF/JVT specification in CDI file"); + declareProperty("ScaleFactorFileName", m_SFFile = "xAODBTaggingEfficiency/13TeV/2016-20_7-13TeV-MC15-CDI-July12_v1.root", "name of the official scale factor calibration CDI file (uses PathResolver)"); + declareProperty("UseDevelopmentFile", m_useDevFile = false, "specify whether or not to use the (PathResolver) area for temporary scale factor calibration CDI files"); + declareProperty("EfficiencyFileName", m_EffFile = "", "name of optional user-provided MC efficiency CDI file"); + declareProperty("ScaleFactorBCalibration", m_SFBName = "default", "name of b-jet scale factor calibration object"); + declareProperty("ScaleFactorCCalibration", m_SFCName = "default", "name of c-jet scale factor calibration object"); + declareProperty("ScaleFactorTCalibration", m_SFTName = "default", "name of tau-jet scale factor calibration object"); + declareProperty("ScaleFactorLightCalibration", m_SFLightName = "default", "name of light-flavour jet scale factor calibration object"); + declareProperty("EigenvectorReductionB", m_EVReductionB = "Loose", "b-jet scale factor Eigenvector reduction strategy; choose between 'Loose', 'Medium', 'Tight'"); + declareProperty("EigenvectorReductionC", m_EVReductionC = "Loose", "c-jet scale factor Eigenvector reduction strategy; choose between 'Loose', 'Medium', 'Tight'"); + declareProperty("EigenvectorReductionLight", m_EVReductionLight = "Loose","light-flavour jet scale factor Eigenvector reduction strategy; choose between 'Loose', 'Medium', 'Tight'"); + declareProperty("EfficiencyBCalibrations", m_EffBName = "default", "(semicolon-separated) name(s) of b-jet efficiency object(s)"); + declareProperty("EfficiencyCCalibrations", m_EffCName = "default", "(semicolon-separated) name(s) of c-jet efficiency object(s)"); + declareProperty("EfficiencyTCalibrations", m_EffTName = "default", "(semicolon-separated) name(s) of tau-jet efficiency object(s)"); + declareProperty("EfficiencyLightCalibrations", m_EffLightName = "default", "(semicolon-separated) name(s) of light-flavour-jet efficiency object(s)"); + declareProperty("ExcludeFromEigenVectorTreatment", m_excludeFromEV = "", "(semicolon-separated) names of uncertainties to be excluded from eigenvector decomposition (if used)"); + declareProperty("SystematicsStrategy", m_systStrategy = "SFEigen", "name of systematics model; presently choose between 'SFEigen' and 'Envelope'"); + declareProperty("ConeFlavourLabel", m_coneFlavourLabel = true, "specify whether or not to use the cone-based flavour labelling instead of the default ghost association based labelling"); + declareProperty("OldConeFlavourLabel", m_oldConeFlavourLabel = false, "when using cone-based flavour labelling, specify whether or not to use the (deprecated) Run-1 legacy labelling"); + declareProperty("CutBenchmark", m_cutBenchmark = "FixedCutBEff_70", "if you want to run in continuous you need to fix a benchmark - it does something only if running in Continuous OP"); + declareProperty("ExcludeSpecificEigens", m_excludeEV = "" , "(semicolon-separated) names of Eigens you want to exclude. in case of continuous some eigenvectors can be ignored to make the computation faster"); + declareProperty("StoreOnlyUpVariations", m_doOnlyUpVariations = false , "If set to true it processes only the __1up b-tagging variations. It speeds up the computation in case of symmetric variations."); + declareProperty("doDirectTagging", m_doDirectTag = false , "If set to true it also computes and stores the direct tagging choice and the related SFs for each jet"); +} + +StatusCode BTaggingTruthTaggingTool::setEffMapIndex(const std::string& flavour, unsigned int index){ + ANA_CHECK_SET_TYPE (StatusCode); + + ANA_CHECK(m_effTool->setMapIndex(flavour, index)); + if(m_useQuntile && !m_continuous){ + for(unsigned int iop=0; iop<m_availableOP.size(); iop++){ + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)]->setMapIndex(flavour, index)); + } + } + return StatusCode::SUCCESS; +} + +void BTaggingTruthTaggingTool::setUseSystematics(bool useSystematics){ + ATH_MSG_DEBUG("setting the use of systematics to: " <<useSystematics); + m_useSys = useSystematics; + ATH_MSG_DEBUG(" m_useSys = " << m_useSys); +} + +SystematicSet BTaggingTruthTaggingTool::affectingSystematics() const { + return m_effTool->affectingSystematics(); +} + +SystematicCode BTaggingTruthTaggingTool::applySystematicVariation( const CP::SystematicSet & systConfig ) +{ + for (auto syst : systConfig) { + CP::SystematicSet myset; + ATH_MSG_WARNING("applySystematicVariation was called for " << syst.name() << " but BTaggingTruthTaggingTool does not apply Systematic Variations"); + //the truth tagging tool provides results for all possible systematic variations in its results objects, the user does not need to call each one seperatly. + } + return SystematicCode::Ok; +} + +bool BTaggingTruthTaggingTool::isAffectedBySystematic( const CP::SystematicVariation & systematic ) const +{ + SystematicSet sys = affectingSystematics(); + return sys.find( systematic) != sys.end(); +} + +SystematicSet BTaggingTruthTaggingTool::recommendedSystematics() const { + return affectingSystematics(); +} + +StatusCode BTaggingTruthTaggingTool::initialize() { + + ANA_CHECK_SET_TYPE (StatusCode); + + m_initialised = true; + + ANA_CHECK(m_selTool.setProperty("MaxEta", m_maxEta)); + ANA_CHECK(m_selTool.setProperty("MaxRangePt", m_maxRangePt)); + ANA_CHECK(m_selTool.setProperty("MinPt", m_minPt)); + ANA_CHECK(m_selTool.setProperty("TaggerName", m_taggerName)); + ANA_CHECK(m_selTool.setProperty("OperatingPoint", m_OP)); + ANA_CHECK(m_selTool.setProperty("JetAuthor", m_jetAuthor)); + ANA_CHECK(m_selTool.setProperty("FlvTagCutDefinitionsFileName", m_SFFile)); + ANA_CHECK(m_selTool.initialize()); + + ANA_CHECK(m_effTool.setProperty("MinPt", m_minPt)); + ANA_CHECK(m_effTool.setProperty("TaggerName", m_taggerName)); + ANA_CHECK(m_effTool.setProperty("OperatingPoint", m_OP)); + ANA_CHECK(m_effTool.setProperty("JetAuthor", m_jetAuthor)); + ANA_CHECK(m_effTool.setProperty("ScaleFactorFileName", m_SFFile )); + ANA_CHECK(m_effTool.setProperty("UseDevelopmentFile", m_useDevFile )); + ANA_CHECK(m_effTool.setProperty("EfficiencyFileName", m_EffFile )); + ANA_CHECK(m_effTool.setProperty("ScaleFactorBCalibration", m_SFBName )); + ANA_CHECK(m_effTool.setProperty("ScaleFactorCCalibration", m_SFCName )); + ANA_CHECK(m_effTool.setProperty("ScaleFactorTCalibration", m_SFTName )); + ANA_CHECK(m_effTool.setProperty("ScaleFactorLightCalibration", m_SFLightName )); + ANA_CHECK(m_effTool.setProperty("EigenvectorReductionB", m_EVReductionB )); + ANA_CHECK(m_effTool.setProperty("EigenvectorReductionC", m_EVReductionC )); + ANA_CHECK(m_effTool.setProperty("EigenvectorReductionLight", m_EVReductionLight )); + ANA_CHECK(m_effTool.setProperty("EfficiencyBCalibrations", m_EffBName )); + ANA_CHECK(m_effTool.setProperty("EfficiencyCCalibrations", m_EffCName )); + ANA_CHECK(m_effTool.setProperty("EfficiencyTCalibrations", m_EffTName )); + ANA_CHECK(m_effTool.setProperty("EfficiencyLightCalibrations", m_EffLightName )); + ANA_CHECK(m_effTool.setProperty("ExcludeFromEigenVectorTreatment", m_excludeFromEV )); + ANA_CHECK(m_effTool.setProperty("SystematicsStrategy", m_systStrategy )); + ANA_CHECK(m_effTool.setProperty("ConeFlavourLabel", m_coneFlavourLabel )); + ANA_CHECK(m_effTool.setProperty("OldConeFlavourLabel", m_oldConeFlavourLabel )); + + ANA_CHECK(m_effTool.initialize()); + + m_continuous = false; + + if(m_OP.find("FlatBEff") != std::string::npos){ + m_availableOP.resize(m_availableOP_fixEff.size()); + m_availableOP=m_availableOP_fixEff; + } + else if(m_OP.find("FixedCutBEff") != std::string::npos){ + m_availableOP.resize(m_availableOP_fixCut.size()); + m_availableOP=m_availableOP_fixCut; + } + else if(m_OP.find("Continuous") != std::string::npos){ + ATH_MSG_INFO("You are running in Continuous and you choosed " << m_cutBenchmark <<" as benchmark" ); + m_continuous = true; + m_availableOP.resize(m_availableOP_fixCut.size()); + m_availableOP=m_availableOP_fixCut; + } + else if(m_useQuntile){ + ATH_MSG_ERROR(m_OP << " not in the list of available OPs"); + return StatusCode::FAILURE; + } + + if(m_continuous){ + m_OperatingPoint_index = find(m_availableOP.begin(), m_availableOP.end(), m_cutBenchmark) - m_availableOP.begin(); + } + else{ + if(m_useQuntile){ + m_OperatingPoint_index = find(m_availableOP.begin(), m_availableOP.end(), m_OP) - m_availableOP.begin(); + if(m_OperatingPoint_index >= m_availableOP.size()) { + ATH_MSG_ERROR(m_OP << " not in the list of available OPs"); + return StatusCode::FAILURE; + } + } + } + + m_eff_syst.clear(); + m_sys_name.clear(); + CP::SystematicSet def_set; + m_eff_syst.push_back(def_set); + m_sys_name.push_back("Nominal"); + + if(m_useSys){ + std::vector<std::string> excludeEV_vector; + if(m_excludeEV != "") + excludeEV_vector = split(m_excludeEV, ';'); + CP::SystematicSet systs = m_effTool->affectingSystematics(); + for (const auto & syst : systs) { + CP::SystematicSet myset; + string s = syst.name(); + if(m_doOnlyUpVariations && s.find("__1down") !=string::npos) continue; + if(std::any_of(excludeEV_vector.begin(), excludeEV_vector.end(), [&s](const std::string& str) { return str.find(s) != std::string::npos; })) continue; + + myset.insert(syst); + if(m_excludeEV != "") + ATH_MSG_INFO("Adding systematic " << syst.name() << "to the list "); + else + ATH_MSG_DEBUG("Adding systematic " << syst.name() << "to the list "); + m_eff_syst.push_back(myset); + m_sys_name.push_back(syst.name()); + } + } + if(m_useQuntile == true || m_continuous == true){ + ATH_MSG_INFO("m_useQuntile true"); + + //open the CDI file to get the cutvalues for all working points. + TString pathtofile = PathResolverFindCalibFile(m_SFFile); + m_inf = TFile::Open(pathtofile, "read"); + m_binEdges.clear(); + + for(unsigned int iop=0; iop<m_availableOP.size(); iop++){ + + if(!m_continuous){ + std::string toolname = name()+"_eff_"+m_availableOP.at(iop); + + m_effTool_allOP[m_availableOP.at(iop)] = asg::AnaToolHandle<IBTaggingEfficiencyTool>("BTaggingEfficiencyTool/"+toolname,this); + + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("OperatingPoint", m_availableOP.at(iop))); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("TaggerName", m_taggerName)); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("JetAuthor", m_jetAuthor)); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("ScaleFactorFileName", m_SFFile )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("UseDevelopmentFile", m_useDevFile )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("EfficiencyFileName", m_EffFile )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("ScaleFactorBCalibration", m_SFBName )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("ScaleFactorCCalibration", m_SFCName )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("ScaleFactorTCalibration", m_SFTName )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("ScaleFactorLightCalibration", m_SFLightName )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("EigenvectorReductionB", m_EVReductionB )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("EigenvectorReductionC", m_EVReductionC )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("EigenvectorReductionLight", m_EVReductionLight )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("EfficiencyBCalibrations", m_EffBName )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("EfficiencyCCalibrations", m_EffCName )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("EfficiencyTCalibrations", m_EffTName )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("EfficiencyLightCalibrations", m_EffLightName )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("ExcludeFromEigenVectorTreatment", m_excludeFromEV )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("SystematicsStrategy", m_systStrategy )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("ConeFlavourLabel", m_coneFlavourLabel )); + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].setProperty("OldConeFlavourLabel", m_oldConeFlavourLabel )); + + ANA_CHECK(m_effTool_allOP[m_availableOP.at(iop)].initialize()); + + if(m_OP.find("FixedCutBEff")!= std::string::npos){ + TString cutname = m_taggerName+"/"+m_jetAuthor+"/"+m_availableOP.at(iop)+"/cutvalue"; + float cutval = ((TVector*) m_inf->Get(cutname))[0](0); + m_binEdges.push_back(cutval); + } //FCBEff + } //!Continuous + + else{ + if(m_cutBenchmark.find("FixedCutBEff")!= std::string::npos){ + TString cutname = m_taggerName+"/"+m_jetAuthor+"/"+m_availableOP.at(iop)+"/cutvalue"; + float cutval = ((TVector*) m_inf->Get(cutname))[0](0); + m_binEdges.push_back(cutval); + } //FCBEff + } //Continuous + } //loop + } //quantile + + return StatusCode::SUCCESS; +} + + +StatusCode BTaggingTruthTaggingTool::setJets(TRFinfo &trfinf,std::vector<double>& pt, std::vector<double>& eta, std::vector<int>& flav, std::vector<double>& tagw){ + ANA_CHECK_SET_TYPE (StatusCode); + if(pt.size()!=eta.size() || pt.size()!=flav.size() || pt.size()!=tagw.size()){ + ATH_MSG_ERROR( "Vectors of pt, eta, flav and tagw should have same size" ); + return StatusCode::FAILURE; + } + + std::vector<Analysis::CalibrationDataVariables>* vars = new std::vector<Analysis::CalibrationDataVariables>(0); + for(unsigned int i =0; i<pt.size(); i++){ + Analysis::CalibrationDataVariables vars_appo; + if (!fillVariables(pt.at(i), eta.at(i), tagw.at(i), vars_appo)){ + ATH_MSG_ERROR("unable to fill variables"); + return StatusCode::FAILURE; + } + vars->push_back(vars_appo); + } + + ANA_CHECK(setJets(trfinf,flav, vars)); + delete vars; + return StatusCode::SUCCESS; +} + +StatusCode BTaggingTruthTaggingTool::setJets(TRFinfo &trfinf,const xAOD::JetContainer& jets){ + ANA_CHECK_SET_TYPE (StatusCode); + std::vector<int> flav; + std::vector<Analysis::CalibrationDataVariables>* vars = new std::vector<Analysis::CalibrationDataVariables>(0); + for(const auto jet : jets) { + Analysis::CalibrationDataVariables vars_appo; + if (!fillVariables(*jet, vars_appo)){ + ATH_MSG_ERROR("unable to fill variables"); + return StatusCode::FAILURE; + } + + vars->push_back(vars_appo); + flav.push_back(jetFlavourLabel(*jet)); + } + + ANA_CHECK(setJets(trfinf,flav, vars)); + delete vars; + flav.clear(); + return StatusCode::SUCCESS; +} + +StatusCode BTaggingTruthTaggingTool::setJets(TRFinfo &trfinf,std::vector<int>& flav, std::vector<Analysis::CalibrationDataVariables>* vars){ + if(flav.size()!=vars->size()){ + ATH_MSG_ERROR( "Vector of CalibrationDataVariables and flavour should have same size" ); + return StatusCode::FAILURE; + } + trfinf.jets.clear(); + for(unsigned int i =0; i<vars->size(); i++){ + jetVariable jetVar_appo; + jetVar_appo.flav=flav.at(i); + jetVar_appo.vars=vars->at(i); + trfinf.jets.push_back(jetVar_appo); + + } + trfinf.njets=trfinf.jets.size(); + return StatusCode::SUCCESS; +} + + + +bool BTaggingTruthTaggingTool::fillVariables( const xAOD::Jet& jet, CalibrationDataVariables& x){ + x.jetPt = jet.pt(); + x.jetEta = jet.eta(); + x.jetTagWeight = 0.; + x.jetAuthor = m_jetAuthor; + + const xAOD::BTagging* tagInfo = xAOD::BTaggingUtilities::getBTagging( jet ); + if (!tagInfo) return false; + + return tagInfo->MVx_discriminant(m_taggerName, x.jetTagWeight); + delete tagInfo; + +} + +bool BTaggingTruthTaggingTool::fillVariables( const double jetPt, const double jetEta, const double jetTagWeight, CalibrationDataVariables& x){ + x.jetPt = jetPt; + x.jetEta = jetEta; + x.jetTagWeight = jetTagWeight; + x.jetAuthor = m_jetAuthor; + return true; +} + +double BTaggingTruthTaggingTool::getPermutationRW(TRFinfo &trfinf,bool isIncl, unsigned int nbtag, int sys){ + double w = 1.; + if(nbtag < trfinf.njets && ((!isIncl && trfinf.permprob_ex.at(nbtag) == 0.) || (isIncl && trfinf.permprob_in.at(nbtag) == 0.)) ) { + ATH_MSG_ERROR("Permutations need to be chosen before computing reweighting"); + } + if(nbtag > trfinf.njets) return 1.; + if(isIncl) { + w = trfWeight(trfinf,trfinf.perm_in.at(nbtag)); + return w/trfinf.trfwsys_in[sys].at(nbtag)/trfinf.permprob_in.at(nbtag); + } + else { + w = trfWeight(trfinf,trfinf.perm_ex.at(nbtag)); + return w/trfinf.trfwsys_ex[sys].at(nbtag)/trfinf.permprob_ex.at(nbtag); + } +} + + + +StatusCode BTaggingTruthTaggingTool::GetTruthTagWeights(TRFinfo &trfinf, std::vector<double> &trf_weight_ex, std::vector<double> &trf_weight_in, int sys){ + + ANA_CHECK_SET_TYPE (StatusCode); + + if(sys==0) ANA_CHECK(getAllEffMC(trfinf)); + ANA_CHECK(check_syst_range(sys)); + if(trfinf.trfwsys_ex.size()==0) trfinf.trfwsys_ex.resize(m_eff_syst.size()); + if(trfinf.trfwsys_in.size()==0) trfinf.trfwsys_in.resize(m_eff_syst.size()); + + ANA_CHECK(getAllEffSF(trfinf,sys)); + ANA_CHECK(getTRFweight(trfinf,m_nbtag, true, sys)); + + if(sys==0){ // don't need permutation or tag bin reweighting + if(m_usePerm){ + // choice of the selected permutation + ANA_CHECK(chooseAllTagPermutation(trfinf,m_nbtag)); + } + if(m_useQuntile) { + // choice of the tagged bins + ANA_CHECK(chooseAllTagBins(trfinf)); + } + } + else { + if(m_usePerm) { + for(unsigned int ib = 0; ib < trfinf.trfwsys_ex[sys].size(); ib++) { + trfinf.trfwsys_ex[sys].at(ib) *= getPermutationRW(trfinf,false, ib, sys); + trfinf.trfwsys_in[sys].at(ib) *= getPermutationRW(trfinf,true, ib, sys); + if(m_useQuntile) { + trfinf.trfwsys_ex[sys].at(ib) *= getTagBinsRW(trfinf,false, ib); + trfinf.trfwsys_in[sys].at(ib) *= getTagBinsRW(trfinf,true, ib); + } + } + } + } + trf_weight_ex = trfinf.trfwsys_ex[sys]; + trf_weight_in = trfinf.trfwsys_in[sys]; + return StatusCode::SUCCESS; +} + + +StatusCode BTaggingTruthTaggingTool::CalculateResults(TRFinfo &trfinf,Analysis::TruthTagResults& results,int rand_seed){ + ANA_CHECK_SET_TYPE (StatusCode); + results.clear(); + + results.tagweight_bin_edges = m_binEdges; + + if(rand_seed!=-1){ + trfinf.rand.SetSeed(rand_seed); + } + + unsigned int n_systs = m_eff_syst.size(); + if(m_useSys){ + trfinf.trfwsys_ex.resize(m_eff_syst.size()); + trfinf.trfwsys_in.resize(m_eff_syst.size()); + } + else{ + n_systs = 1; //compute only the nominal + trfinf.trfwsys_ex.resize(1); + trfinf.trfwsys_in.resize(1); + } + std::vector<double> trf_weight_ex, trf_weight_in; + + for(unsigned int i =0; i< n_systs; i++){ + trf_weight_ex.clear(); + trf_weight_in.clear(); + + ANA_CHECK(GetTruthTagWeights(trfinf, trf_weight_ex, trf_weight_in, i)); + + } + + results.syst_names.clear(); + + for(unsigned int i=0; i<trfinf.trfwsys_ex.size(); i++){ + // for(unsigned int i=0; i<Nsysts; i++){ + + results.map_trf_weight_ex[m_sys_name.at(i)].resize(trfinf.trfwsys_ex.at(i).size()); + results.map_trf_weight_in[m_sys_name.at(i)].resize(trfinf.trfwsys_in.at(i).size()); + + //direct tagged SF + if(m_doDirectTag) + results.map_SF[m_sys_name.at(i)]=getEvtSF(trfinf,i); + + results.syst_names.push_back(m_sys_name.at(i)); + + for(unsigned int j=0; j< trfinf.trfwsys_ex.at(i).size(); j++){ + results.map_trf_weight_ex[m_sys_name.at(i)].at(j) = trfinf.trfwsys_ex.at(i).at(j); + results.map_trf_weight_in[m_sys_name.at(i)].at(j) = trfinf.trfwsys_in.at(i).at(j); + + } + } + + if(m_usePerm){ + ANA_CHECK(getTagPermutation(trfinf,results.trf_chosen_perm_ex,results.trf_chosen_perm_in)); + } + if(m_useQuntile){ + ANA_CHECK(getQuantiles(trfinf,results.trf_bin_ex, results.trf_bin_in)); + ANA_CHECK(generateRandomTaggerScores(results.trf_bin_ex, results.trf_bin_score_ex)); + ANA_CHECK(generateRandomTaggerScores(results.trf_bin_in, results.trf_bin_score_in)); + } + if(m_doDirectTag) + ANA_CHECK(getDirectTaggedJets(trfinf,results.is_tagged)); + + return StatusCode::SUCCESS; + +} + +StatusCode BTaggingTruthTaggingTool::CalculateResults(std::vector<double>& pt, std::vector<double>& eta, std::vector<int>& flav, std::vector<double>& tagw, Analysis::TruthTagResults& results,int rand_seed){ + + ANA_CHECK_SET_TYPE (StatusCode); + + TRFinfo trfinf; + + ANA_CHECK(setJets(trfinf,pt, eta, flav, tagw)); + + return CalculateResults(trfinf,results,rand_seed); +} + +StatusCode BTaggingTruthTaggingTool::CalculateResults(const xAOD::JetContainer& jets, Analysis::TruthTagResults& results,int rand_seed){ + + ANA_CHECK_SET_TYPE (StatusCode); + + TRFinfo trfinf; + + ANA_CHECK(setJets(trfinf,jets)); + + return CalculateResults(trfinf,results,rand_seed); +} + + +StatusCode BTaggingTruthTaggingTool::getAllEffMC(TRFinfo &trfinf){ + + float eff =1.; + float eff_all =1.; + trfinf.effMC.clear(); + if(m_useQuntile == true || m_continuous == true){ + for(auto op_appo: m_availableOP) + trfinf.effMC_allOP[op_appo].clear(); + } + for(size_t i=0; i < trfinf.jets.size(); i++){ + if(m_continuous){ + eff=1.; + // loop on OP + int OP_index = 0; + for(const auto & op_appo: m_availableOP){ + eff_all=1.; + //set a dumb value of the truth tag weight to get the different efficiency maps for each bin. to be improved.. + if(OP_index+1 < (int) m_availableOP.size()){ + trfinf.jets.at(i).vars.jetTagWeight = (m_binEdges.at(OP_index)+m_binEdges.at(OP_index+1))/2.; //to-do: make it fancy? random distribution inside the bin probably? + } + else{ + trfinf.jets.at(i).vars.jetTagWeight = (m_binEdges.at(OP_index)+1)/2.; //only for 60% WP + } + + CorrectionCode code = m_effTool->getMCEfficiency(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, eff_all) ; + + if(!(code==CorrectionCode::Ok || code==CorrectionCode::OutOfValidityRange)){ + ATH_MSG_ERROR("BTaggingEfficiencyTool::getMCEfficiency returned CorrectionCode::Error"); + return StatusCode::FAILURE; + } + trfinf.effMC_allOP[op_appo].push_back(eff_all); + OP_index++; + + } // end loop on OP + } //inside Continuous + else{ + eff=1.; + CorrectionCode code = m_effTool->getMCEfficiency(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, eff); + if(!(code==CorrectionCode::Ok || code==CorrectionCode::OutOfValidityRange)){ + ATH_MSG_ERROR("BTaggingEfficiencyTool::getMCEfficiency returned CorrectionCode::Error"); + return StatusCode::FAILURE;} + + trfinf.effMC.push_back(eff); + + if(m_useQuntile){ + // loop on OP + for(const auto & op_appo: m_availableOP){ + + if ( op_appo==m_OP) { + trfinf.effMC_allOP[op_appo].push_back(eff); + continue; + } + + eff_all=1.; + CorrectionCode code = m_effTool_allOP[op_appo]->getMCEfficiency(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, eff_all) ; + + if(!(code==CorrectionCode::Ok || code==CorrectionCode::OutOfValidityRange)){ + ATH_MSG_ERROR("BTaggingEfficiencyTool::getMCEfficiency returned CorrectionCode::Error"); + return StatusCode::FAILURE; + } + + trfinf.effMC_allOP[op_appo].push_back(eff_all); + } // end loop on OP + } // if useQuantile + } //!useContinuous + } // end loop on jets + return StatusCode::SUCCESS; +} + + +StatusCode BTaggingTruthTaggingTool::getAllEffSF(TRFinfo &trfinf,int sys){ + ANA_CHECK_SET_TYPE ( StatusCode ); + + trfinf.eff.clear(); + if(!m_continuous){ + trfinf.eff.resize(trfinf.effMC.size()); + if(m_useQuntile){ + for(const auto & op_appo: m_availableOP){ + trfinf.eff_allOP[op_appo].clear(); + trfinf.eff_allOP[op_appo].resize(trfinf.effMC.size()); + } + } + } + else{ + trfinf.eff.resize(trfinf.effMC_allOP[m_cutBenchmark].size()); + for(const auto & op_appo: m_availableOP){ + trfinf.eff_allOP[op_appo].clear(); + trfinf.eff_allOP[op_appo].resize(trfinf.effMC_allOP[op_appo].size()); + } + } + + if(m_ignoreSF && sys==0){ + if(m_continuous){ + for(int iop = (int) m_availableOP.size()-1; iop >= 0; iop--) { // loop on the tighter OPs + string op_appo = m_availableOP.at(iop); + if(!m_useQuntile && iop < (int) m_OperatingPoint_index) continue; + for(size_t ieff =0; ieff< trfinf.eff_allOP[op_appo].size(); ieff++){ //jets + trfinf.eff_allOP[op_appo].at(ieff)= 0; + for(unsigned int p = iop; p<m_availableOP.size(); p++){ //add all the eff above the WP + trfinf.eff_allOP[op_appo].at(ieff)+=trfinf.effMC_allOP[m_availableOP.at(p)].at(ieff); + } + if( op_appo == m_cutBenchmark) + trfinf.eff.at(ieff) = trfinf.eff_allOP[m_cutBenchmark].at(ieff); + } //jets + } //OP + } //continuous + else{ + for(size_t i =0; i< trfinf.effMC.size(); i++){ + trfinf.eff.at(i)=trfinf.effMC.at(i); + if(m_useQuntile){ + for(const auto & op_appo: m_availableOP){ + trfinf.eff_allOP[op_appo].at(i)=trfinf.effMC_allOP[op_appo].at(i); + } + } + } + } + return StatusCode::SUCCESS; + } + + if(m_ignoreSF && sys==0){ + ATH_MSG_ERROR("Tryig to access SF systematics but ignoring SF"); + return StatusCode::FAILURE; + } + + float SF =1.; + float SF_all =1.; + + if(sys!=0 && m_useSys){ + ATH_MSG_DEBUG("applying the syst: " <<m_sys_name[sys]); + ANA_CHECK_THROW( m_effTool->applySystematicVariation(m_eff_syst[sys]) ); + if(m_useQuntile && !m_continuous){ + for(const auto & op_appo: m_availableOP){ + if (op_appo==m_OP) continue; + ANA_CHECK( m_effTool_allOP[op_appo]->applySystematicVariation(m_eff_syst[sys]) ); + } + } + } + + if(m_continuous){ + for(int iop = (int) m_availableOP.size()-1; iop >= 0; iop--) { + std::string op_appo = m_availableOP.at(iop); + if(!m_useQuntile && iop < (int) m_OperatingPoint_index) continue; + for(size_t i=0; i<trfinf.jets.size(); i++){ + SF=1.; + //set a dumb value of the truth tag weight to get the different efficiency maps for each bin. to be improved.. + if(iop+1 < (int) m_availableOP.size()){ + trfinf.jets.at(i).vars.jetTagWeight = (m_binEdges.at(iop)+m_binEdges.at(iop+1))/2.; //to-do: make it fancy? random distribution for the tagger score + } + else{ + trfinf.jets.at(i).vars.jetTagWeight = (m_binEdges.at(iop)+1.)/2.; + } + + CorrectionCode code = m_effTool->getScaleFactor(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, SF) ; + if(!(code==CorrectionCode::Ok || code==CorrectionCode::OutOfValidityRange)){ + ATH_MSG_ERROR("BTaggingEfficiencyTool::getScaleFactor returned CorrectionCode::Error"); + return StatusCode::FAILURE; + } + + trfinf.eff_allOP[op_appo].at(i)=trfinf.effMC_allOP[op_appo].at(i)*SF; + + //now sum all the corrected MC Eff together + if(iop+1 < (int) m_availableOP.size()){ + trfinf.eff_allOP[op_appo].at(i)+=trfinf.eff_allOP[m_availableOP.at(iop+1)].at(i); //they are already corrected for SF + } + if( op_appo == m_cutBenchmark) + trfinf.eff.at(i) = trfinf.eff_allOP[m_cutBenchmark].at(i); + } //jets + } //OP + } //continuous + + else{ + for(unsigned int i=0; i<trfinf.jets.size(); i++){ + SF=1.; + CorrectionCode code = m_effTool->getScaleFactor(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, SF) ; + if(!(code==CorrectionCode::Ok || code==CorrectionCode::OutOfValidityRange)){ + ATH_MSG_ERROR("BTaggingEfficiencyTool::getScaleFactor returned CorrectionCode::Error"); + return StatusCode::FAILURE; + } + trfinf.eff.at(i) = trfinf.effMC.at(i)*SF; + if(m_useQuntile){ + // loop on OP + for(const auto & op_appo: m_availableOP){ + if (op_appo==m_OP) { + trfinf.eff_allOP[op_appo].at(i)=trfinf.effMC.at(i)*SF; + continue; + } + SF_all=1.; + CorrectionCode code = m_effTool_allOP[op_appo]->getScaleFactor(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, SF_all) ; + if(!(code==CorrectionCode::Ok || code==CorrectionCode::OutOfValidityRange)){ + ATH_MSG_ERROR("BTaggingEfficiencyTool::getScaleFactor returned CorrectionCode::Error"); + return StatusCode::FAILURE; + } + + trfinf.eff_allOP[op_appo].at(i) = trfinf.effMC_allOP[op_appo].at(i)*SF_all; + } // end loop on OP + } // if useQuantile + } //!Continuous + } //jets + + CP::SystematicSet defaultSet; + ANA_CHECK( m_effTool->applySystematicVariation(defaultSet) ); + if(m_useQuntile && !m_continuous){ + for(const auto & op_appo: m_availableOP){ + ANA_CHECK( m_effTool_allOP[op_appo]->applySystematicVariation(defaultSet) ); + } + } + + return StatusCode::SUCCESS; +} + +std::vector<std::vector<bool> > BTaggingTruthTaggingTool::generatePermutations(int njets, int tags, int start){ + std::vector<std::vector<bool> > perm; + std::vector<std::vector<bool> > temp_perm; + if(tags==0){ + std::vector<bool> tags(njets,false); + perm.push_back(tags); + } + else if(tags == njets) { + std::vector<bool> tags(njets,true); + perm.push_back(tags); + } + else { + for(int i=start; i<njets;i++){ + temp_perm = generatePermutations(njets,tags-1,i+1); + for(unsigned int j=0; j<temp_perm.size(); j++){ + temp_perm.at(j).at(i)=true; + perm.push_back(temp_perm.at(j)); + } + } + } + return perm; +} + + +double BTaggingTruthTaggingTool::trfWeight(TRFinfo &trfinf,const std::vector<bool> &tags){ + double weight = 1; + for (unsigned int j=0; j<tags.size();j++) { + double trf = 0.; + trf = trfinf.eff[j]; + if(trf>1.) { + ATH_MSG_WARNING("Truth Tagging weight > 1. --> setting it to 1. check maps!"); + trf = 1.; + } + if(tags.at(j)) weight *= trf; + else weight *= (1.-trf); + } // end loop over jets + return weight; +} + + +StatusCode BTaggingTruthTaggingTool::getTRFweight(TRFinfo &trfinf,unsigned int nbtag, bool isInclusive, int sys){ + + unsigned int njets = trfinf.njets; + // Consider permutations of njet jets with up to limit b-tags + unsigned int limit = (njets > 7) ? 8 : njets+1; + + // Permutations: njets, ntags, permutations + // From .h: std::map<int, std::vector<std::vector<std::vector<bool> > > > trfinf.perms; + + if (trfinf.perms.find(njets)==trfinf.perms.end()){ // if I don't have already saved the possible permutations for njet + trfinf.perms[njets] = std::vector<std::vector<std::vector<bool> > >(limit); + for(unsigned int i=0;i<limit;i++) + trfinf.perms[njets].at(i) = generatePermutations(njets,i); + } + + trfinf.permsWeight.clear(), trfinf.permsWeight.resize(limit); // trfinf.permsWeight.at(i).at(j): TRF weight of the j-th perm with i b-tags + trfinf.permsSumWeight.clear(), trfinf.permsSumWeight.resize(limit); // trfinf.permsSumWeight.at(i).at(j): partial sum of TRF weight of the permutations with i b-tags up to j (0,1,..,j-th) perm. Used in the choice of the selected permutation + + // compute TRF weight + unsigned int max = nbtag+1; // from 0 to nbtag b-tags --> nbtag+1 positions + trfinf.trfwsys_ex[sys].clear(), trfinf.trfwsys_in[sys].clear(); + trfinf.trfwsys_ex[sys].resize(max), trfinf.trfwsys_in[sys].resize(max); + + if(sys == 0) { // nominal case --> clear and resize elements of trfinf + trfinf.perm_ex.clear(), trfinf.perm_in.clear(); // vector<vector<bool>> --> for each number of tags the chosen permutation + trfinf.perm_ex.resize(max), trfinf.perm_in.resize(max); + trfinf.permprob_ex.clear(), trfinf.permprob_in.clear(); // probability of the perm in trfinf.perm_ex/in + trfinf.permprob_ex.resize(max), trfinf.permprob_in.resize(max); + } + if(isInclusive) { + for(unsigned int i=0; i<limit; i++) { // note: I consider maximum limit tags. It's an approximation + std::vector<double> weights; + double sum = 0., w = 0.; + trfinf.permsWeight.at(i).clear(); + trfinf.permsSumWeight.at(i).clear(); + trfinf.permsWeight.at(i).resize(trfinf.perms[njets].at(i).size()); + trfinf.permsSumWeight.at(i).resize(trfinf.perms[njets].at(i).size()); + + // loop on all the permutations with i tags + for(unsigned int p=0; p<trfinf.perms[njets].at(i).size(); p++) { + w = trfWeight(trfinf,trfinf.perms[njets].at(i).at(p)); + sum+=w; + //trfinf.permsWeight.at(i).push_back(w); //old way to do it without resizing, keep it for the moment + //trfinf.permsSumWeight.at(i).push_back(sum); + trfinf.permsWeight.at(i).at(p) = w; + trfinf.permsSumWeight.at(i).at(p) = sum; + + ATH_MSG_DEBUG("nbtag = " << i << " wei = " << w << " sum = " << sum); + } + if(i<limit && i<max) { + // note: I need to already have the exclusive weights filled to compite the inclusive + trfinf.trfwsys_ex[sys].at(i) = sum; // sum of TRF weights for all perm with i b-tags + if(i == 0) trfinf.trfwsys_in[sys].at(0) = 1.; + else trfinf.trfwsys_in[sys].at(i) = trfinf.trfwsys_in[sys].at(i-1) - trfinf.trfwsys_ex[sys].at(i-1); // P(>=4) = P(>=3) - P(==3) + ATH_MSG_DEBUG("i = " << i << " sum = " << sum << " TRF in " << trfinf.trfwsys_in[0].at(i) << " ex = " << trfinf.trfwsys_ex[0].at(i)); + } + } + ATH_MSG_DEBUG("before return, nbtag = " << nbtag << " size de trfinf.trfwsys_in[sys] = " << trfinf.trfwsys_in[sys].size()); + return StatusCode::SUCCESS; + } + else { // exclusive case, only one calculation needed + std::vector<double> weights; + double sum = 0., w = 0.; + size_t size = trfinf.perms[njets].at(nbtag).size(); + trfinf.permsWeight.at(nbtag).clear(); + trfinf.permsSumWeight.at(nbtag).clear(); + trfinf.permsWeight.at(nbtag).resize(size); + trfinf.permsSumWeight.at(nbtag).resize(size); + // loop on all the permutations with i tags + for(unsigned int p=0; p<trfinf.perms[njets].at(nbtag).size(); p++) { + + w = trfWeight(trfinf,trfinf.perms[njets].at(nbtag).at(p)); + sum+=w; + // trfinf.permsWeight.at(nbtag).push_back(w); //old way, before resizing: keep it for the moment + // trfinf.permsSumWeight.at(nbtag).push_back(sum); + trfinf.permsWeight.at(nbtag).at(p) = w; + trfinf.permsSumWeight.at(nbtag).at(p) = sum; + } + trfinf.trfwsys_ex[sys].at(nbtag) = sum; + return StatusCode::SUCCESS; + } + return StatusCode::SUCCESS; +} + + +StatusCode BTaggingTruthTaggingTool::getTagPermutation(TRFinfo &trfinf, std::vector<std::vector<bool> > &trf_chosen_perm_ex, std::vector<std::vector<bool> > &trf_chosen_perm_in){ + trf_chosen_perm_ex.resize(m_nbtag+1); + trf_chosen_perm_in.resize(m_nbtag+1); + trf_chosen_perm_ex = trfinf.perm_ex; + trf_chosen_perm_in = trfinf.perm_in; + std::string print_perm = "Permutation: "; + for(auto perm: trfinf.perm_ex){ + for(auto is: perm) { + if(is) print_perm+=std::to_string(1); + else print_perm+=std::to_string(0); + print_perm+=" "; + } + } + ATH_MSG_DEBUG(print_perm); + return StatusCode::SUCCESS; +} + +StatusCode BTaggingTruthTaggingTool::chooseAllTagPermutation(TRFinfo &trfinf,unsigned int nbtag){ + + ANA_CHECK_SET_TYPE (StatusCode); + + if(!m_usePerm){ + return StatusCode::FAILURE; + } + + unsigned int njets = trfinf.njets; + unsigned int limit = (njets > 7) ? 8 : njets+1; + unsigned int max = (njets < nbtag+1) ? limit : nbtag+1; + + trfinf.perm_ex.clear(), trfinf.perm_ex.resize(nbtag+1); + trfinf.perm_in.clear(), trfinf.perm_in.resize(nbtag+1); + + trfinf.permprob_ex.clear(), trfinf.permprob_ex.resize(nbtag+1); + trfinf.permprob_in.clear(), trfinf.permprob_in.resize(nbtag+1); + + for(unsigned int i=0; i<max; i++) { // need +1 as 0 is included + ANA_CHECK(chooseTagPermutation(trfinf,i,false)); + ANA_CHECK(chooseTagPermutation(trfinf,i,true)); + } + + return StatusCode::SUCCESS; +} + +StatusCode BTaggingTruthTaggingTool::chooseTagPermutation(TRFinfo &trfinf,unsigned int nbtag, bool isIncl){ + std::vector<double> incl; + std::vector<std::pair<unsigned int, unsigned int> > trackPerm; + double sum = 0; + if(isIncl) { + for(unsigned int itag=nbtag; itag < trfinf.permsWeight.size(); itag++) { + for(unsigned int ip = 0; ip < trfinf.permsWeight.at(itag).size(); ip++) { + sum += trfinf.permsWeight.at(itag).at(ip); + incl.push_back(sum); + trackPerm.push_back(std::make_pair(itag,ip)); + } + } + } + else { // in exclusive case + sum = trfinf.permsSumWeight.at(nbtag).back(); + incl = trfinf.permsSumWeight.at(nbtag); + for(unsigned int ip = 0; ip < trfinf.permsSumWeight.at(nbtag).size(); ip++) trackPerm.push_back(std::make_pair(nbtag,ip)); + } + double theX = trfinf.rand.Uniform(sum); + for(unsigned int ip=0; ip < incl.size(); ip++) { + ATH_MSG_DEBUG("incl.at(ip): " << incl.at(ip) << " theX: " << theX); + if(incl.at(ip) >= theX) { + if(isIncl) { + trfinf.perm_in.at(nbtag) = trfinf.perms[trfinf.njets].at(trackPerm.at(ip).first).at(trackPerm.at(ip).second); + trfinf.permprob_in.at(nbtag) = trfinf.permsWeight.at(trackPerm.at(ip).first).at(trackPerm.at(ip).second) / trfinf.trfwsys_in[0].at(nbtag); + } + else { + trfinf.perm_ex.at(nbtag) = trfinf.perms[trfinf.njets].at(trackPerm.at(ip).first).at(trackPerm.at(ip).second); + trfinf.permprob_ex.at(nbtag) = trfinf.permsWeight.at(trackPerm.at(ip).first).at(trackPerm.at(ip).second) / trfinf.trfwsys_ex[0].at(nbtag); + } + return StatusCode::SUCCESS; + } + } + return StatusCode::SUCCESS; +} + + + +///// tag bins ////////////////////// +// Cheatsheet: +// returns 5 if between 60% and 0% +// returns 4 if between 70% and 60% +// returns 3 if between 77% and 70% +// returns 2 if between 85% and 77% +// returns 1 if between 100% and 85% +// return -1 if not in b-tagging acceptance +////////////////////// + + +StatusCode BTaggingTruthTaggingTool::getQuantiles(TRFinfo &trfinf,std::vector<std::vector<int> > &trf_bin_ex, std::vector<std::vector<int> > &trf_bin_in){ + trf_bin_ex.resize(trfinf.tbins_ex.size()); + for(unsigned int i =0; i<trfinf.tbins_ex.size(); i++) + trf_bin_ex.at(i).resize(trfinf.tbins_ex.at(i).size()); + + trf_bin_in.resize(trfinf.tbins_in.size()); + for(unsigned int i =0; i<trfinf.tbins_in.size(); i++) + trf_bin_in.at(i).resize(trfinf.tbins_in.at(i).size()); + // increasing the value by 1 to match conventions in selectionTool + for(unsigned int i =0; i<trfinf.tbins_ex.size(); i++) + for(unsigned int j=0; j<trfinf.tbins_ex.at(i).size(); j++) + trf_bin_ex.at(i).at(j)=trfinf.tbins_ex.at(i).at(j) +1; + + for(unsigned int i =0; i<trfinf.tbins_in.size(); i++) + for(unsigned int j=0; j<trfinf.tbins_in.at(i).size(); j++) + trf_bin_in.at(i).at(j)=trfinf.tbins_in.at(i).at(j) +1; + + return StatusCode::SUCCESS; +} + +StatusCode BTaggingTruthTaggingTool::chooseAllTagBins(TRFinfo &trfinf){ + ANA_CHECK_SET_TYPE (StatusCode); + trfinf.tbins_ex.clear(); + trfinf.tbins_in.clear(); + trfinf.tbins_ex.resize( trfinf.trfwsys_ex[0].size()); + trfinf.tbins_in.resize( trfinf.trfwsys_in[0].size()); + + trfinf.binsprob_ex.clear(); + trfinf.binsprob_in.clear(); + trfinf.binsprob_ex.resize( trfinf.trfwsys_ex[0].size()); + trfinf.binsprob_in.resize( trfinf.trfwsys_in[0].size()); + + if(trfinf.perm_ex.size() != trfinf.perm_in.size()) ATH_MSG_WARNING("Different sizes in exclusive and inclusive permutation choices"); + + for(unsigned int nb=0; nb<trfinf.perm_ex.size(); nb++) { + ANA_CHECK(chooseTagBins_cum(trfinf,trfinf.perm_ex.at(nb), false, nb)); + ANA_CHECK(chooseTagBins_cum(trfinf,trfinf.perm_in.at(nb), true, nb)); + } + return StatusCode::SUCCESS; +} + + +// chiara: non posso uniformare il codice con getTagBinsConfProb?? +StatusCode BTaggingTruthTaggingTool::chooseTagBins_cum(TRFinfo &trfinf,std::vector<bool> &tagconf, bool isIncl, unsigned int nbtag){ + std::vector<int> btagops; + + std::vector<double> incl; + double prob = 1.; + + for(unsigned int j=0; j<tagconf.size(); j++) { + if(tagconf.at(j)) { // tagged jet + double sum=0.; + incl.clear(); + for(int iop = (int)trfinf.eff_allOP.size()-1; iop >= (int)m_OperatingPoint_index; iop--) { // loop on the tighter OPs + sum = trfinf.eff_allOP[m_availableOP.at(iop)][j]; + incl.push_back(sum); + } + double theX = trfinf.rand.Uniform(sum); + + for(unsigned int k=0; k<incl.size(); k++) { + double valm1 = 0.; + if(k!=0) valm1 = incl.at(k-1); + if(incl.at(k) >= theX) { + btagops.push_back(m_availableOP.size()-k); + prob *= (incl.at(k)-valm1) / sum; + break; + } + } + } + else { // untagged jet + double sum=0.; + incl.clear(); + incl.push_back(sum); // fill the "0_0" OP as no real value affected and start the loop at 1 + for(unsigned int iop=0; iop<=m_OperatingPoint_index; iop++) { // need to include the chosen tag cut to have the last MV1 bin of untagged jets filled, start at 0 with cumulative as iop = 0 = first OP + // sum = 1 - trf here + sum = 1 - trfinf.eff_allOP[m_availableOP.at(iop)][j]; + incl.push_back(sum); + } + + double theX = trfinf.rand.Uniform(sum); + for(unsigned int k=1; k<incl.size(); k++) { + if(incl.at(k) >= theX){ + btagops.push_back(k-1); + prob *= (incl.at(k) - incl.at(k-1)) / sum; + break; + } + } + } + } + if(btagops.size() != tagconf.size()) { + ATH_MSG_ERROR("You should not be here -> wrong size of tag bins vector"); + return StatusCode::FAILURE; + } + if(isIncl) { + trfinf.tbins_in.at(nbtag) = btagops; + trfinf.binsprob_in.at(nbtag) = prob; + ATH_MSG_DEBUG("incl, nbtag " << nbtag << " prob " << prob); + } + else { + trfinf.tbins_ex.at(nbtag) = btagops; + trfinf.binsprob_ex.at(nbtag) = prob; + ATH_MSG_DEBUG("excl, nbtag " << nbtag << " prob " << prob); + } + return StatusCode::SUCCESS; +} + + + +double BTaggingTruthTaggingTool::getTagBinsRW(TRFinfo &trfinf,bool isIncl, unsigned int nbtag){ + + if((!isIncl && trfinf.binsprob_ex.size() == 0) || (isIncl && trfinf.binsprob_in.size() == 0)) { + ATH_MSG_ERROR("Need to choose quantiles before computing the reweighting"); + exit(-1); + } + + double tbw = 0.; + double prob_sys=1.; + + if(isIncl) { + prob_sys=getTagBinsConfProb(trfinf,trfinf.tbins_in.at(nbtag)); + tbw = prob_sys/trfinf.binsprob_in.at(nbtag); + return tbw; + } + else { + prob_sys=getTagBinsConfProb(trfinf,trfinf.tbins_ex.at(nbtag)); + tbw = prob_sys/trfinf.binsprob_ex.at(nbtag); + return tbw; + } +} + + +double BTaggingTruthTaggingTool::getTagBinsConfProb(TRFinfo &trfinf,std::vector<int> &tagws){ + double prob = 1.; + for(unsigned int j=0; j<tagws.size(); j++) { + if((unsigned int)tagws.at(j) > m_OperatingPoint_index) { // tagged + double prevBinW = 0.; + int mOP = m_availableOP.size(); + if(tagws.at(j) != mOP) { // not the last tag-bin + prevBinW = trfinf.eff_allOP[m_availableOP.at(tagws.at(j))][j]; + } + // prob *= (eff*SF-exactly-that-bin)/(ef*SF-all-tagged-bins) + // (eff*SF-exactly-that-bin): eff(==60) = eff(70) - eff(60) --> eff(==5) = eff(4)-eff(5) + prob *= (trfinf.eff_allOP[m_availableOP.at(tagws.at(j)-1)][j] - prevBinW) / (trfinf.eff_allOP[m_availableOP.at(m_OperatingPoint_index)][j]); + ATH_MSG_DEBUG("prob " << prob); + } + else { // untagged + double prevBinW = 0.; + if(tagws.at(j) != 0) { + prevBinW = 1 - trfinf.eff_allOP[m_availableOP.at(tagws.at(j)-1)][j]; + } + prob *= ((1 - trfinf.eff_allOP[m_availableOP.at(tagws.at(j))][j]) - prevBinW) / (1 - trfinf.eff_allOP[m_availableOP.at(m_OperatingPoint_index)][j]); + ATH_MSG_DEBUG("prob " << prob); + } + } + return prob; +} + +StatusCode BTaggingTruthTaggingTool::getDirectTaggedJets(TRFinfo &trfinf,std::vector<bool> &is_tagged){ + + is_tagged.clear(); + std::vector<int> appo; + + for(const auto jet : trfinf.jets) { + ATH_MSG_DEBUG("pt " << jet.vars.jetPt << " eta " << jet.vars.jetEta << " wei " << jet.vars.jetTagWeight); + bool is_btagged = false; + if(!m_continuous) + is_btagged = static_cast<bool>(m_selTool->accept(jet.vars.jetPt, jet.vars.jetEta, jet.vars.jetTagWeight)); + else{ + int quantile = m_selTool->getQuantile(jet.vars.jetPt, jet.vars.jetEta, jet.vars.jetTagWeight); + is_btagged = quantile > (int) m_OperatingPoint_index ? true : false; + ATH_MSG_DEBUG("quantile " <<quantile <<" m_OperatingPoint_index " <<m_OperatingPoint_index <<" is_tagged? " <<is_btagged); + + } + + ATH_MSG_DEBUG("is tagged? " << is_btagged); + if(is_btagged) is_tagged.push_back(1); + else is_tagged.push_back(0); + } + + return StatusCode::SUCCESS; +} + + +double BTaggingTruthTaggingTool::getEvtSF(TRFinfo &trfinf,int sys){ + ANA_CHECK_SET_TYPE (StatusCode); + double SF = 1.; + std::vector<bool> is_tagged; + ANA_CHECK_THROW( getDirectTaggedJets(trfinf,is_tagged) ); + + if(sys!=0 && m_useSys) { + + ANA_CHECK_THROW( m_effTool->applySystematicVariation(m_eff_syst[sys]) ); + } + + for(unsigned int i =0; i< trfinf.jets.size(); i++) { + bool is_btagged = is_tagged.at(i); + float ineffSF =1; + float effSF=1; + + if(is_btagged){ // tagged --> look at sf + // CorrectionCode code = m_effTool->getScaleFactor(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, ineffSF); + // if(!(code==CorrectionCode::Ok || code==CorrectionCode::OutOfValidityRange)){ + // ATH_MSG_ERROR("BTaggingEfficiencyTool::getMCEfficiency returned CorrectionCode::Error"); + // return -1.0; + // } + ANA_CHECK_THROW(m_effTool->getScaleFactor(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, ineffSF)); + + SF*=ineffSF; + } + else{ // not tagged --> loop at ineff SF + // CorrectionCode code = m_effTool->getInefficiencyScaleFactor(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, effSF); + // if(!(code==CorrectionCode::Ok || code==CorrectionCode::OutOfValidityRange)){ + // ATH_MSG_ERROR("BTaggingEfficiencyTool::getMCEfficiency returned CorrectionCode::Error"); + // return -1.0; + // } + + ANA_CHECK_THROW(m_effTool->getInefficiencyScaleFactor(trfinf.jets.at(i).flav, trfinf.jets.at(i).vars, effSF)); + SF *= effSF; + } + } + + if(sys!=0 && m_useSys) { // reset syst to nominal + CP::SystematicSet defaultSet; + + ANA_CHECK_THROW( m_effTool->applySystematicVariation(defaultSet) ); + } + return SF; +} + + +StatusCode BTaggingTruthTaggingTool::check_syst_range(unsigned int sys){ + if(sys < m_eff_syst.size()) return StatusCode::SUCCESS; + ATH_MSG_ERROR(sys << " Out of range of available systematics"); + return StatusCode::FAILURE; +} + + + +BTaggingTruthTaggingTool::~BTaggingTruthTaggingTool(){ + + // delete trfinf.jets; + +} + + +int BTaggingTruthTaggingTool::jetFlavourLabel (const xAOD::Jet& jet){ + if (m_coneFlavourLabel) + return (m_oldConeFlavourLabel) ? ConeFinalPartonFlavourLabel(jet) : ExclusiveConeHadronFlavourLabel(jet); + else + return GAFinalHadronFlavourLabel(jet); +} + +int BTaggingTruthTaggingTool::GAFinalHadronFlavourLabel (const xAOD::Jet& jet) { + + const std::string labelB = "GhostBHadronsFinal"; + const std::string labelC = "GhostCHadronsFinal"; + const std::string labelTau = "GhostTausFinal"; + + std::vector<const IParticle*> ghostB; + if (jet.getAssociatedObjects<IParticle>(labelB, ghostB) && ghostB.size() > 0) return 5; + std::vector<const IParticle*> ghostC; + if (jet.getAssociatedObjects<IParticle>(labelC, ghostC) && ghostC.size() > 0) return 4; + std::vector<const IParticle*> ghostTau; + if (jet.getAssociatedObjects<IParticle>(labelTau, ghostTau) && ghostTau.size() > 0) return 15; + + + return 0; +} + +int BTaggingTruthTaggingTool::ConeFinalPartonFlavourLabel (const xAOD::Jet& jet){ + // default label means "invalid" + int label = -1; + // First try the new naming scheme + if (jet.getAttribute("ConeTruthLabelID",label)) return label; + // If that fails, revert to the old scheme. In this case, further testing is not very useful + jet.getAttribute("TruthLabelID", label); + return label; +} + +int BTaggingTruthTaggingTool::ExclusiveConeHadronFlavourLabel (const xAOD::Jet& jet){ + // default label means "invalid" + int label = -1; + // We don't check the return value, as we would not be able to handle it gracefully anyway + jet.getAttribute("HadronConeExclTruthLabelID",label); + return label; +} + +// local utility function: trim leading and trailing whitespace in the property strings +std::string trim(const std::string& str, + const std::string& whitespace = " \t") { + const auto strBegin = str.find_first_not_of(whitespace); + if (strBegin == std::string::npos) + return ""; // no content + + const auto strEnd = str.find_last_not_of(whitespace); + const auto strRange = strEnd - strBegin + 1; + + return str.substr(strBegin, strRange); +} + + +std::vector<std::string> BTaggingTruthTaggingTool::split(const std::string& str, char token) { + std::vector<std::string> result; + if (str.size() > 0) { + std::string::size_type end; + std::string tmp(str); + do { + end = tmp.find(token); + std::string entry = trim(tmp.substr(0,end)); + if (entry.size() > 0) result.push_back(entry); + if (end != std::string::npos) tmp = tmp.substr(end+1); + } while (end != std::string::npos); + } + return result; +} + +StatusCode BTaggingTruthTaggingTool::generateRandomTaggerScores(std::vector< std::vector<int> > &quantiles, std::vector< std::vector<double> > &scores){ + + //quantiles: + // returns 5 if between 60% and 0% + // returns 4 if between 70% and 60% + // returns 3 if between 77% and 70% + // returns 2 if between 85% and 77% + // returns 1 if between 100% and 85% + //m_binEdges + // 3 60% + // 2 70% + // 1 77% + // 0 85% + + scores.clear(); + + TRandom3 random; + + scores.resize(quantiles.size()); + for(unsigned int i=0; i <quantiles.size(); i++ ){ + + scores.at(i).resize(quantiles.at(i).size()); + + for(unsigned int j=0; j <quantiles.at(i).size(); j++ ){ + + int quantile = quantiles.at(i).at(j); + + if(quantile == 1){ + double lowTaggerScore = -1.0; + if(m_taggerName.find("MV2") != string::npos){ lowTaggerScore = -1.0; } + if(m_taggerName.find("DL1") != string::npos){ lowTaggerScore = -20.0;} + + scores.at(i).at(j) = lowTaggerScore + random.Uniform()*( m_binEdges.at(0)-lowTaggerScore ); + }else if(quantile == 5){ + double highTaggerScore = +1.0; + if(m_taggerName.find("MV2") != string::npos){ highTaggerScore = 1.0; } + if(m_taggerName.find("DL1") != string::npos){ highTaggerScore = 20.0; } + + scores.at(i).at(j) = m_binEdges.at(3) + random.Uniform()*( highTaggerScore-m_binEdges.at(3) ); + }else{ + scores.at(i).at(j) = m_binEdges.at(quantile-2) + random.Uniform()*( m_binEdges.at(quantile-1)-m_binEdges.at(quantile-2) ); + } + } + } + + return StatusCode::SUCCESS; + +} + diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/LinkDef.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/LinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..1ea08cfd6eb495650249d8a8cd0d40f6f3aef7b8 --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/Root/LinkDef.h @@ -0,0 +1,18 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "xAODBTaggingEfficiency/TruthTagResults.h" + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ nestedclass; + +#pragma link C++ namespace Analysis; +#pragma link C++ class Analysis::TruthTagResults; + +#endif diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/src/ToolTester.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/src/ToolTester.cxx index 6e8d1936c7b3e68fec72f160764e3b1b054e21b6..daf681e37eab416c54420d3a6efa5c116c61495f 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/src/ToolTester.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/src/ToolTester.cxx @@ -5,7 +5,7 @@ // $Id$ #include "xAODJet/JetContainer.h" -#include "CalibrationDataInterface/CalibrationDataInterfaceROOT.h" +//#include "CalibrationDataInterface/CalibrationDataInterfaceROOT.h" #include "ToolTester.h" diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/src/components/xAODBTaggingEfficiency_entries.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/src/components/xAODBTaggingEfficiency_entries.cxx index 9322d19701c8eeb07d14dd2ac852b86b336b034d..3cedaaa3fb4808ed17ba0c68430314cbf56b6a23 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/src/components/xAODBTaggingEfficiency_entries.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/src/components/xAODBTaggingEfficiency_entries.cxx @@ -1,11 +1,18 @@ + + #include "xAODBTaggingEfficiency/BTaggingEfficiencyTool.h" #include "xAODBTaggingEfficiency/BTaggingSelectionTool.h" +#include "xAODBTaggingEfficiency/BTaggingTruthTaggingTool.h" +#include "xAODBTaggingEfficiency/BTaggingEigenVectorRecompositionTool.h" + #include "../ToolTester.h" -// Should probably alter the namespace +// Should probably alter the namespace DECLARE_COMPONENT( BTaggingEfficiencyTool ) DECLARE_COMPONENT( BTaggingSelectionTool ) +DECLARE_COMPONENT( BTaggingTruthTaggingTool ) +DECLARE_COMPONENT( BTaggingEigenVectorRecompositionTool ) DECLARE_COMPONENT( BTagToolTester ) diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingEfficiencyToolTester.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingEfficiencyToolTester.cxx index 87106c843d505bb91c373f08d873c934462b6616..3aebe5cec7bde09e01bf4c156a542badd52fd4fb 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingEfficiencyToolTester.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingEfficiencyToolTester.cxx @@ -3,11 +3,12 @@ */ -#ifdef ROOTCORE +//#ifdef XAOD_STANDALONE # include "xAODRootAccess/TStore.h" -#endif // ROOTCORE +//#endif // XAOD_STANDALONE -#include "xAODBTaggingEfficiency/BTaggingEfficiencyTool.h" +#include <AsgTools/AnaToolHandle.h> +#include "FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h" #include <string> #include <iomanip> @@ -16,49 +17,50 @@ using CP::CorrectionCode; using CP::SystematicCode; int main() { - + bool retval = true; xAOD::TStore store; + - BTaggingEfficiencyTool * tool = new BTaggingEfficiencyTool("BTagTest"); - // tagger name as specified in the CDI file - StatusCode code = tool->setProperty("TaggerName", "MV2c10"); - if (code != StatusCode::SUCCESS) std::cout << "error setting BTaggingEfficiencyTool TaggerName property" << std::endl; - // operating point as specified in the CDI file - code = tool->setProperty("OperatingPoint", "FixedCutBEff_77"); - if (code != StatusCode::SUCCESS) std::cout << "error setting BTaggingEfficiencyTool OperatingPoint property" << std::endl; - // jet collection name as specified in the CDI file (for 2012, this contains also the JVF specification) - code = tool->setProperty("JetAuthor", "AntiKt4EMTopoJets"); - if (code != StatusCode::SUCCESS) std::cout << "error setting BTaggingEfficiencyTool JetAuthor property" << std::endl; - // name of the CDI file - code = tool->setProperty("ScaleFactorFileName", "13TeV/2016-20_7-13TeV-MC15-CDI-2017-04-24_v1.root"); - if (code != StatusCode::SUCCESS) std::cout << "error setting BTaggingEfficiencyTool ScaleFactorFileName property" << std::endl; - // calibration specification (there should always be a "default" available so this doesn't need to be set - // tool->setProperty("ScaleFactorBCalibration", "ttbar_PDF_7b_SF"); + std::string taggerName = "DL1"; + std::string workingPointName = "FixedCutBEff_70"; + + asg::AnaToolHandle<IBTaggingEfficiencyTool> tool("BTaggingEfficiencyTool/BTagEffTest"); + StatusCode code1 = tool.setProperty("ScaleFactorFileName","xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root" ); + StatusCode code2 = tool.setProperty("TaggerName", taggerName ); + StatusCode code3 = tool.setProperty("OperatingPoint", workingPointName); + StatusCode code4 = tool.setProperty("JetAuthor", "AntiKt4EMPFlowJets_BTagging201810" ); + + //provide a file which tells the tool which efficiency maps to use, and connects sample DSIDs to the right efficiency map. + //you can find a tool to automatically create this config file here: https://gitlab.cern.ch/mstamenk/automate-hadronisation-information + StatusCode code5 = tool.setProperty("EfficiencyConfig","/afs/cern.ch/work/j/jshlomi/public/example_eff_config.txt"); + // specify an aggressive ("Tight") or not-so-aggressive ("Medium") eigenvector suppression scheme - // (this needs information stored in the calibration objects which will not be available for older files) - // optionally, specify non-default and multiple efficiency objects - // tool->setProperty("EfficiencyBCalibrations", "410000;410004;410006;410021"); - // tool->setProperty("EfficiencyCCalibrations", "410000;410004;410006;410021"); - // tool->setProperty("EfficiencyTCalibrations", "410000;410004;410006;410021"); - // tool->setProperty("EfficiencyLightCalibrations", "410000;410004;410006;410021"); - // tool->setProperty("EigenvectorReductionB", "Medium"); - // tool->setProperty("EigenvectorReductionC", "Medium"); - // tool->setProperty("EigenvectorReductionLight", "Medium"); - // specify that the file is to be looked for in the PathResolver "development" area (don't use this for official productions) - // tool->setProperty("UseDevelopmentFile", true); - // specify the use of the cone-based labelling rather than the ghost association - code = tool->setProperty("ConeFlavourLabel", true); - if (code != StatusCode::SUCCESS) std::cout << "error setting BTaggingEfficiencyTool ConeFlavourLabel property" << std::endl; - // uncomment this to use the Run-1 style cone labelling (parton based, inclusive) instead of the Run-2 default (hadron based, exclusive) - // tool->setProperty("OldConeFlavourLabel", true); + // tool.setProperty("EigenvectorReductionB", "Medium"); + // tool.setProperty("EigenvectorReductionC", "Medium"); + // tool.setProperty("EigenvectorReductionLight", "Medium"); + // uncomment this if the "Envelope" systematics model is to be used instead of the eigenvector variations - // tool->setProperty("SystematicsStrategy", "Envelope"); - // A successful initialisation ought to be checked for - code = tool->initialize(); - if (code != StatusCode::SUCCESS) { - std::cout << "Initialization of tool " << tool->name() << " failed! Subsequent results may not make sense." << std::endl; + // code = tool.setProperty("SystematicsStrategy", "Envelope"); + + StatusCode code6 = tool.initialize(); + + if (code1 != StatusCode::SUCCESS || code2 != StatusCode::SUCCESS || code3 != StatusCode::SUCCESS || code4 != StatusCode::SUCCESS + || code5 != StatusCode::SUCCESS + || code6 != StatusCode::SUCCESS) { + std::cout << "Initialization of tool " << tool->name() << " failed! " << std::endl; + return -1; + } + else { + std::cout << "Initialization of tool " << tool->name() << " finished." << std::endl; } + + // select your efficiency map based on the DSID of your sample: + unsigned int sample_dsid = 410470; + + tool->setMapIndex(sample_dsid); + + std::cout << "-----------------------------------------------------" << std::endl; const std::map<CP::SystematicVariation, std::vector<std::string> > allowed_variations = tool->listSystematics(); std::cout << "Allowed systematics variations for tool " << tool->name() << ":" << std::endl; @@ -68,80 +70,35 @@ int main() { std::cout << std::endl; } std::cout << "-----------------------------------------------------" << std::endl; + - bool retval = true; std::cout << "Creating a jet" << std::endl; - xAOD::JetFourMom_t p4(25000.,0.7,0.3,1000.); + xAOD::JetFourMom_t p4(50000.,0.7,0.3,1000.); xAOD::Jet * jet = new xAOD::Jet(); jet->makePrivateStore(); std::cout << "Setting jet 4 momentum" << std::endl; jet->setJetP4(p4); std::cout << "Setting jet attribute" << std::endl; - // light quark. Note that here and in the following, we fill both the Run-1 and Run-2 style flavour label variables - jet->setAttribute("ConeTruthLabelID", 0); - jet->setAttribute("HadronConeExclTruthLabelID", 0); + // b jet (label==5) + jet->setAttribute("HadronConeExclTruthLabelID", 5); float sf=0; + float eff=0; CorrectionCode result; - std::cout << "\nTesting function calls without systematics..." << std::endl; - result = tool->getEfficiency(*jet,sf); - if( result!=CorrectionCode::Ok) { std::cout << "Light quark get efficiency failed"<<std::endl; retval=false;} + std::cout << "Testing function calls without systematics..." << std::endl; + result = tool->getEfficiency(*jet,eff); + if( result!=CorrectionCode::Ok) { std::cout << "b jet get efficiency failed"<<std::endl; retval=false;} else { - std::cout << "Light quark get efficiency succeeded: " << sf << std::endl; + std::cout << "b jet get efficiency succeeded: " << eff << std::endl; } result = tool->getScaleFactor(*jet,sf); - if( result!=CorrectionCode::Ok) { std::cout << "Light quark get scale factor failed"<<std::endl; retval=false;} + if( result!=CorrectionCode::Ok) { std::cout << "b jet get scale factor failed"<<std::endl; retval=false;} else { - std::cout << "Light quark get scale factor succeeded: " << sf << std::endl; + std::cout << "b jet get scale factor succeeded: " << sf << std::endl; } - jet->setAttribute("ConeTruthLabelID", 5); - jet->setAttribute("HadronConeExclTruthLabelID", 5); - sf=0; - result = tool->getEfficiency(*jet,sf); - if( result!=CorrectionCode::Ok) { std::cout << "Bottom quark get efficiency failed"<<std::endl; retval=false;} - else { - std::cout << "Bottom quark get efficiency succeeded: " << sf << std::endl; - } - result = tool->getScaleFactor(*jet,sf); - if( result!=CorrectionCode::Ok) { std::cout << "Bottom quark get scale factor failed"<<std::endl; retval=false;} - else { - std::cout << "Bottom quark get scale factor succeeded: " << sf << std::endl; - } - - jet->setAttribute("ConeTruthLabelID", 4); - jet->setAttribute("HadronConeExclTruthLabelID", 4); - sf=0; - result = tool->getEfficiency(*jet,sf); - if( result!=CorrectionCode::Ok) { std::cout << "Charm quark get efficiency failed"<<std::endl; retval=false;} - else { - std::cout << "Charm quark get efficiency succeeded: " << sf << std::endl; - } - result = tool->getScaleFactor(*jet,sf); - if( result!=CorrectionCode::Ok) { std::cout << "Charm quark get scale factor failed"<<std::endl; retval=false;} - else { - std::cout << "Charm quark get scale factor succeeded: " << sf << std::endl; - } - - jet->setAttribute("ConeTruthLabelID", 15); - jet->setAttribute("HadronConeExclTruthLabelID", 15); - sf=0; - result = tool->getEfficiency(*jet,sf); - if( result!=CorrectionCode::Ok) { std::cout << "Tau quark get efficiency failed"<<std::endl; retval=false;} - else { - std::cout << "Tau quark get efficiency succeeded: " << sf << std::endl; - } - result = tool->getScaleFactor(*jet,sf); - if( result!=CorrectionCode::Ok) { std::cout << "Tau quark get scale factor failed"<<std::endl; retval=false;} - else { - std::cout << "Tau quark get scale factor succeeded: " << sf << std::endl; - } - - // systematics interface - jet->setAttribute("ConeTruthLabelID", 5); - jet->setAttribute("HadronConeExclTruthLabelID", 5); - std::cout << "\nTesting application of systematics to b jets..." << std::endl; + std::cout << "Testing function calls with systematics..." << std::endl; CP::SystematicSet systs = tool->affectingSystematics(); for( CP::SystematicSet::const_iterator iter = systs.begin(); iter!=systs.end(); ++iter) { @@ -151,7 +108,7 @@ int main() { SystematicCode sresult = tool->applySystematicVariation(set); if( sresult !=SystematicCode::Ok) { std::cout << var.name() << " apply systematic variation FAILED " << std::endl; - } + } result = tool->getScaleFactor(*jet,sf); if( result!=CorrectionCode::Ok) { std::cout << var.name() << " getScaleFactor FAILED" << std::endl; @@ -165,68 +122,7 @@ int main() { if (dummyResult != SystematicCode::Ok) std::cout << "problem disabling systematics setting!" << std::endl; - // out-of-bounds tests: - // (1) b jet outside the calibration range (300 GeV, at present) but inside the extrapolation range - xAOD::JetFourMom_t p4Extrapolated(500000.,0.7,0.3,1000.); - xAOD::Jet* extrapolatedJet = new xAOD::Jet; - extrapolatedJet->makePrivateStore(); - std::cout << "\nSetting jet 4 momentum for b jet outside calibration but inside extrapolation range" << std::endl; - extrapolatedJet->setJetP4(p4Extrapolated); - extrapolatedJet->setAttribute("ConeTruthLabelID", 5); - extrapolatedJet->setAttribute("HadronConeExclTruthLabelID", 5); - result = tool->getScaleFactor(*extrapolatedJet,sf); - switch (result) { - case CorrectionCode::Error: - std::cout << "extrapolated b-jet get scale factor failed" << std::endl; break; - case CorrectionCode::OutOfValidityRange: - std::cout << "extrapolated b-jet get scale factor should not be flagged as out-of-validity!" << std::endl; break; - case CorrectionCode::Ok: - std::cout << "extrapolated b-jet get scale factor OK" << std::endl; break; - default: - break; - } - // (2) b jet outside the extrapolation range (3000 GeV, at present) - xAOD::JetFourMom_t p4Invalid(4000000.,0.7,0.3,1000.); - xAOD::Jet* invalidJet = new xAOD::Jet; - invalidJet->makePrivateStore(); - std::cout << "\nSetting jet 4 momentum for b jet outside extrapolation range" << std::endl; - invalidJet->setJetP4(p4Invalid); - invalidJet->setAttribute("ConeTruthLabelID", 5); - invalidJet->setAttribute("HadronConeExclTruthLabelID", 5); - result = tool->getScaleFactor(*invalidJet,sf); - if (result != CorrectionCode::OutOfValidityRange) { - std::cout << "invalid b-jet get scale factor should have been flagged as out-of-validity but is not!" << std::endl; - } else { - std::cout << "invalid b-jet get scale factor correctly flagged as out-of-validity" << std::endl; - } - // test tool copying - - // BTaggingEfficiencyTool* copiedTool = new BTaggingEfficiencyTool(*tool); - // std::cout << "-----------------------------------------------------" << std::endl; - // const std::map<CP::SystematicVariation, std::vector<std::string> > copied_variations = copiedTool->listSystematics(); - // std::cout << "Allowed systematics variations for tool " << copiedTool->name() << ":" << std::endl; - // for (auto var : copied_variations) { - // std::cout << std::setw(40) << std::left << var.first.name() << ":"; - // for (auto flv : var.second) std::cout << " " << flv; - // std::cout << std::endl; - // } - // std::cout << "-----------------------------------------------------" << std::endl; - // sf=0; - // result = copiedTool->getEfficiency(*jet,sf); - // if( result!=CorrectionCode::Ok) { std::cout << "Bottom quark get efficiency failed"<<std::endl; retval=false;} - // else { - // std::cout << "Bottom quark get efficiency succeeded: " << sf << std::endl; - // } - // result = copiedTool->getScaleFactor(*jet,sf); - // if( result!=CorrectionCode::Ok) { std::cout << "Bottom quark get scale factor failed"<<std::endl; retval=false;} - // else { - // std::cout << "Bottom quark get scale factor succeeded: " << sf << std::endl; - // } - - - // release our resources - delete tool; return retval; } diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingEigenVectorRecompositionToolTester.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingEigenVectorRecompositionToolTester.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5b7ef7f2ca946dfe18bb577ce13f97c451e9136e --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingEigenVectorRecompositionToolTester.cxx @@ -0,0 +1,108 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + + +#include <AsgTools/AnaToolHandle.h> +#include <AsgTools/ToolHandle.h> +#include "FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h" +#include "FTagAnalysisInterfaces/IBTaggingEigenVectorRecompositionTool.h" + + +int main() { + bool retval = true; + + std::string taggerName = "MV2c10"; + std::string workingPointName = "Continuous"; + + asg::AnaToolHandle<IBTaggingEfficiencyTool> btag_eff_tool("BTaggingEfficiencyTool/BTagEffTest"); + StatusCode code1 = btag_eff_tool.setProperty("ScaleFactorFileName","xAODBTaggingEfficiency/13TeV/2017-21-13TeV-MC16-CDI-2019-07-30_v1.root" ); + StatusCode code2 = btag_eff_tool.setProperty("TaggerName", taggerName ); + StatusCode code3 = btag_eff_tool.setProperty("OperatingPoint", workingPointName); + StatusCode code4 = btag_eff_tool.setProperty("JetAuthor", "AntiKt4EMTopoJets" ); + StatusCode code5 = btag_eff_tool.setProperty("MinPt", 20. ); + // Exclude certain original uncertainties from Eigenvector scheme so that + // it these uncertainties will be exclude from eigen vector recomposition. + // The original uncertainty names are separated by semicolon. + // Here exclude two uncertainties as an example. + // StatusCode code0 = btag_eff_tool.setProperty("ExcludeFromEigenVectorBTreatment","FT_EFF_PDF4LHC_np_19;JET_EffectiveNP_Mixed3"); + StatusCode code6 = btag_eff_tool.initialize(); + if (code1 != StatusCode::SUCCESS + || code2 != StatusCode::SUCCESS + || code3 != StatusCode::SUCCESS + || code4 != StatusCode::SUCCESS + || code5 != StatusCode::SUCCESS + || code6 != StatusCode::SUCCESS ){ + std::cout << "Initialization of tool " << btag_eff_tool->name() << " failed! " << std::endl; + return -1; + } + else { + std::cout << "Initialization of tool " << btag_eff_tool->name() << " finished." << std::endl; + } + + asg::AnaToolHandle<IBTaggingEigenVectorRecompositionTool> evr_tool("BTaggingEigenVectorRecompositionTool/BTagEVRTest"); + StatusCode code7 = evr_tool.setProperty("BTaggingEfficiencyTool", btag_eff_tool); + StatusCode code8 = evr_tool.initialize(); + if (code7 != StatusCode::SUCCESS + ||code8 != StatusCode::SUCCESS ) { + std::cout << "Initialization of tool" << evr_tool->name() << " failed!" << std::endl; + } else { + std::cout << "Initialization of tool " << evr_tool->name() << " finished." << std::endl; + } + + const std::string label = "B"; + const unsigned int evIdx = 0; + + /** + getCoefficientMap(label, EigenIdxList) + + input value: + 1. label: falvor label in std::string format, could be one of B, C, T, Light + 2. EigenIdxList is user defined vector containing all eigenvector index + that user interested in. + output: + Map of format map<string, map<string, float>> containing decomposition + coefficient of the list of eigenvectors defined by EigenIdxList. + */ + std::vector<unsigned int> eigenIdxList = {1,2,3,4,5}; + std::map<std::string, std::map<std::string, float>> coefficientMap = evr_tool->getCoefficientMap(label, eigenIdxList); + + /** + getCoefficients(label, evIdx) + + input value: + 1. label: falvor label in std::string format, could be one of B, C, T, Light + 2. evIdx: The index of eigenvector user interested in. + output value: + vector of coefficient values. The order is the same as output given by + getListOfOriginalNuisanceParameters() + */ + std::vector<float> coeffs = evr_tool->getCoefficients(label, evIdx); + + /** + getListOfOriginalNuisanceParameters(label) + + input value: + 1. label: falvor label in std::string format, could be one of B, C, T, Light + output value: + List of original nuisance parameter names. + */ + std::vector<std::string> orig_nps = evr_tool->getListOfOriginalNuisanceParameters(label); + + /** + getNumEigenVectors(label) + + input value: + 1. label: falvor label in std::string format, could be one of B, C, T, Light + return value: + number of eigen vectors used for chosen label. Return 0 if error occured. + */ + int nEigen = evr_tool->getNumEigenVectors("B"); + if (nEigen >= 0){ + std::cout<<"There are "<<nEigen + <<" eigen vectors for flavour B."<<std::endl; + } + + return retval; + +} diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingSelectionToolTester.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingSelectionToolTester.cxx index d4a739656cbfa36935f6bdc3e5d35682b268323e..4df275359d44231dd1689e25cab6f38cd97d988a 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingSelectionToolTester.cxx +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingSelectionToolTester.cxx @@ -2,80 +2,230 @@ Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration */ -#include "xAODBTaggingEfficiency/BTaggingSelectionTool.h" - +#ifdef XAOD_STANDALONE +#include "xAODRootAccess/TEvent.h" +#else +#include "POOLRootAccess/TEvent.h" +#endif +#include <AsgTools/AnaToolHandle.h> +#include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h" + +#include "PATInterfaces/CorrectionCode.h" #include "xAODJet/JetAuxContainer.h" #include "xAODJet/JetContainer.h" #include "xAODBTagging/BTaggingAuxContainer.h" +#include "xAODBTagging/BTagging.h" +#include "xAODBTagging/BTaggingUtilities.h" + -#include "AsgMessaging/MessageCheck.h" #include <string> #include <iomanip> +#include "TFile.h" + +using CP::CorrectionCode; int main() { - using namespace asg::msgUserCode; - ANA_CHECK_SET_TYPE (int); - BTaggingSelectionTool * tool = new BTaggingSelectionTool("BTagSelecTest"); - ANA_CHECK (tool->setProperty( "MaxEta", 2.5 )); - ANA_CHECK (tool->setProperty( "MinPt", 20000. )); - // ANA_CHECK (tool->setProperty( "FlvTagCutDefinitionsFileName","xAODBTaggingEfficiency/13TeV/2016-20_7-13TeV-MC15-CDI-May31_v1.root" )); - ANA_CHECK (tool->setProperty( "FlvTagCutDefinitionsFileName","xAODBTaggingEfficiency/share/AntiKt2TrackJets_20160615.root" )); - ANA_CHECK (tool->setProperty("TaggerName", "MV2c00_MV2c100" )); - ANA_CHECK (tool->setProperty("OperatingPoint", "2DFixedCutBEff_85" )); - ANA_CHECK (tool->setProperty("JetAuthor", "AntiKt2PV0TrackJets" )); + std::string taggerName = "DL1"; + std::string workingPointName = "HybBEff_77"; + + asg::AnaToolHandle<IBTaggingSelectionTool> tool("BTaggingSelectionTool/BTagSelecTest"); + StatusCode code1 = tool.setProperty( "FlvTagCutDefinitionsFileName","xAODBTaggingEfficiency/13TeV/2017-21-13TeV-MC16-CDI-2018-02-09_v1.root" ); + StatusCode code2 = tool.setProperty("TaggerName", taggerName ); + StatusCode code3 = tool.setProperty("OperatingPoint", workingPointName); + StatusCode code4 = tool.setProperty("JetAuthor", "AntiKt4EMTopoJets" ); // A successful initialisation ought to be checked for - StatusCode code = tool->initialize(); - if (code != StatusCode::SUCCESS) { - std::cout << "Initialization of tool " << tool->name() << " failed! Subsequent results may not make sense." << std::endl; + StatusCode code5 = tool.initialize(); + + if (code1 != StatusCode::SUCCESS || code2 != StatusCode::SUCCESS || code3 != StatusCode::SUCCESS || code4 != StatusCode::SUCCESS || code5 != StatusCode::SUCCESS) { + std::cout << "Initialization of tool " << tool->name() << " failed! " << std::endl; + return -1; } else { std::cout << "Initialization of tool " << tool->name() << " finished." << std::endl; } - bool retval = true; - std::cout << "\nTesting function calls for a large pT range..." << std::endl; - for (unsigned pt=15000; pt<1200000; pt+=100000){ - if (tool->accept(pt, 0.5, 0.5543, 0.)){ - std::cout << "Jet is tagged" << std::endl; - } else { - std::cout << "Jet is untagged" << std::endl; + //load some jets to show how to use the tool + + // xAOD::TEvent event; + #ifdef XAOD_STANDALONE + xAOD::TEvent event(xAOD::TEvent::kClassAccess); + #else + POOL::TEvent event(POOL::TEvent::kClassAccess); + #endif + + + TFile* m_file = TFile::Open("/afs/cern.ch/work/j/jshlomi/public/DAOD_FTAG2.root","read"); + + if(!event.readFrom(m_file).isSuccess()){ std::cout << "failed to load file" << std::endl; return -1; } + + event.getEntry(0); + + const xAOD::JetContainer* jets = 0; + + if (!event.retrieve( jets, "AntiKt4EMTopoJets" ).isSuccess() ){ std::cout << " error retrieving jets " << std::endl; return -1;} + + int jet_index = 0; + for (const xAOD::Jet* jet : *jets) { + + //getting a tagging decision, is the jet tagged or not + bool tagged = static_cast<bool>(tool->accept(*jet)); + + //you can get the tagger weight, + double tagweight; + if( tool->getTaggerWeight( *jet ,tagweight)!=CorrectionCode::Ok ){ std::cout << " error retrieving tagger weight " << std::endl; return -1; } + + std::cout << "jet " << jet_index << " " << taggerName << " " << workingPointName << " is tagged " << tagged << " tag weight " << tagweight << std::endl; + + + + + //if you have DL1 weights, you can get the tagger weight this way + const xAOD::BTagging *btag = xAOD::BTaggingUtilities::getBTagging( *jet ); + + double dl1_pb = btag->auxdata<double>("DL1_pb"); + double dl1_pc = btag->auxdata<double>("DL1_pc"); + double dl1_pu = btag->auxdata<double>("DL1_pu"); + + + if( tool->getTaggerWeight(dl1_pb,dl1_pc,dl1_pu, tagweight) !=CorrectionCode::Ok ){ std::cout << " error retrieving tagger weight " << std::endl; return -1; } + + std::cout << " tagweight " << tagweight << std::endl; + + double pT = jet->pt(); + double eta = jet->eta(); + + // you can see if the jet is tagged using its pt/eta and tagweight + + tagged = static_cast<bool>(tool->accept(pT,eta,tagweight)); + + //you can also extract the cut value (which may or may not depend on the jet pt) + + double cutval; + //provide the pt in MeV + if( tool->getCutValue( jet->pt() , cutval)!=CorrectionCode::Ok ){ std::cout << " error retrieving cut value " << std::endl; return -1; } + + std::cout << " tagged " << tagged << " cut value " << cutval << std::endl; + + jet_index++; + + } + + //Continuous working points + //************************* + //with a selection tool using the Continuous working point, + //you can get the jets tag weight bin (between the different fixedcutBEff working points, 60,70,77,85) + taggerName = "DL1"; + workingPointName = "Continuous"; + asg::AnaToolHandle<IBTaggingSelectionTool> tool_Continuous("BTaggingSelectionTool/BTagSelContinuousTest"); + code1 = tool_Continuous.setProperty( "FlvTagCutDefinitionsFileName","xAODBTaggingEfficiency/13TeV/2017-21-13TeV-MC16-CDI-2018-02-09_v1.root" ); + code2 = tool_Continuous.setProperty("TaggerName", taggerName ); + code3 = tool_Continuous.setProperty("OperatingPoint", workingPointName ); + code4 = tool_Continuous.setProperty("JetAuthor", "AntiKt4EMTopoJets" ); + code5 = tool_Continuous.initialize(); + + if (code1 != StatusCode::SUCCESS || code2 != StatusCode::SUCCESS || code3 != StatusCode::SUCCESS || code4 != StatusCode::SUCCESS || code5 != StatusCode::SUCCESS) { + std::cout << "Initialization of tool " << tool_Continuous->name() << " failed! " << std::endl; + return -1; + } + else { + std::cout << "Initialization of tool " << tool_Continuous->name() << " finished." << std::endl; + } + + jet_index = 0; + for (const xAOD::Jet* jet : *jets) { + + double tagweight; + if( tool->getTaggerWeight( *jet ,tagweight)!=CorrectionCode::Ok ){ + std::cout << " error retrieving tagger weight " << std::endl; return -1; } + int quantile = tool_Continuous->getQuantile(*jet); + + + std::cout << "jet " << jet_index << " " << taggerName << " " << workingPointName << " tag weight " << tagweight << " quantile " << quantile << std::endl; + + jet_index++; + } - // #### Trying to build a b-jet on the fly - // auto JetAuxContainer = new xAOD::JetAuxContainer(); - // auto JetContainer = new xAOD::JetContainer(); - // JetContainer->setStore(JetAuxContainer); - // auto tjet = new xAOD::Jet(); - // JetContainer->push_back(tjet); - - // std::cout << "jet container ready, now btagging ones" << std::endl; - - // auto BTaggingAuxContainer = new xAOD::BTaggingAuxContainer(); - // auto BTaggingContainer = new xAOD::BTaggingContainer(); - // BTaggingContainer->setStore(BTaggingAuxContainer); - // auto BTagging = new xAOD::BTagging(); - // BTaggingContainer->push_back(BTagging); - - // std::cout << "BTagging container ready, now the store" << std::endl; - // xAOD::TStore store; - // store.record(JetContainer, "JetTest"); - // store.record(JetAuxContainer, "JetTestAux."); - // store.record(BTaggingContainer, "BTagTest"); - // store.record(BTaggingAuxContainer, "BTagTestAux."); - // std::cout << "Store ready" << std::endl; - // std::cout << tjet << "\t\t" << BTaggingContainer << "\t\t" << BTagging << std::endl; - - // ElementLink< xAOD::BTaggingContainer> linkBTagger; - // linkBTagger.toContainedElement(*BTaggingContainer, BTagging); - // // tjet->setBTaggingLink(linkBTagger); - // // BTagging->setVariable("MV2c20", "discriminant", 0.20); - // ###### - - return retval; + + //Veto working points + //************************** + //by setting the OperatingPoint to a string with the format WP1_Veto_Tagger2_WP2 + //for example, FixedCutBEff_70_Veto_DL1_CTag_Loose + //the selection tool will require the jet to be + //tagged by the standard working point + //and to not be tagged by the secondary tagger and working point + + taggerName = "MV2c10"; + workingPointName = "FixedCutBEff_70_Veto_DL1_CTag_Loose"; + + asg::AnaToolHandle<IBTaggingSelectionTool> tool_veto("BTaggingSelectionTool/BTagSelecVetoTest"); + code1 = tool_veto.setProperty( "FlvTagCutDefinitionsFileName","xAODBTaggingEfficiency/13TeV/2017-21-13TeV-MC16-CDI-2018-02-09_v1.root" ); + code2 = tool_veto.setProperty("TaggerName", taggerName ); + code3 = tool_veto.setProperty("OperatingPoint", workingPointName ); + code4 = tool_veto.setProperty("JetAuthor", "AntiKt4EMTopoJets" ); + code5 = tool_veto.initialize(); + + if (code1 != StatusCode::SUCCESS || code2 != StatusCode::SUCCESS || code3 != StatusCode::SUCCESS || code4 != StatusCode::SUCCESS || code5 != StatusCode::SUCCESS) { + std::cout << "Initialization of tool " << tool_veto->name() << " failed! " << std::endl; + return -1; + } + else { + std::cout << "Initialization of tool " << tool_veto->name() << " finished." << std::endl; + } + + + jet_index = 0; + for (const xAOD::Jet* jet : *jets) { + + //getting a tagging decision, is the jet tagged or not + bool tagged = static_cast<bool>(tool_veto->accept(*jet)); + + + // if you are using a format without xAOD::Jets or where the jet does not have a properly filled b-tagging object, + // you need the two tagger weights, for the nominal tagger and the veto tagger. + + //you can get the tagger weight, + double tagweight_nominal; + double tagweight_veto_tagger; + + if( tool_veto->getTaggerWeight( *jet ,tagweight_nominal)!=CorrectionCode::Ok ){ std::cout << " error retrieving nominal tagger weight " << std::endl; return -1; } + //use a third argument set to true to getTaggerWeight for the veto tagger weight + if( tool_veto->getTaggerWeight( *jet ,tagweight_veto_tagger,true)!=CorrectionCode::Ok ){ std::cout << " error retrieving veto tagger weight " << std::endl; return -1; } + + + //if you have DL1 weights, you can get the tagger weight this way + const xAOD::BTagging *btag = xAOD::BTaggingUtilities::getBTagging( *jet ); + + double dl1_pb = btag->auxdata<double>("DL1_pb"); + double dl1_pc = btag->auxdata<double>("DL1_pc"); + double dl1_pu = btag->auxdata<double>("DL1_pu"); + + //the 5th argument tells it to retrive the veto tagger weight + if( tool_veto->getTaggerWeight(dl1_pb,dl1_pc,dl1_pu, tagweight_veto_tagger,true) !=CorrectionCode::Ok ){ std::cout << " error retrieving tagger weight " << std::endl; return -1; } + + + + double pT = jet->pt(); + double eta = jet->eta(); + + bool tagged_withtagweights = static_cast<bool>(tool_veto->accept(pT,eta,tagweight_nominal,tagweight_veto_tagger)); + + + std::cout << "jet " << jet_index << " " << taggerName << " " << workingPointName << " is tagged " << tagged << " tagged (with tagweights) "<< tagged_withtagweights << std::endl; + + jet_index++; + + } + + + + + + return 0; } diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingTruthTaggingTester.cxx b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingTruthTaggingTester.cxx new file mode 100644 index 0000000000000000000000000000000000000000..960db42f713b7deb485e8576330a3edbbd8ed5e9 --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/util/BTaggingTruthTaggingTester.cxx @@ -0,0 +1,99 @@ +#include "AsgTools/AsgTool.h" +#include "AsgMessaging/MessageCheck.h" +#include "AsgMessaging/MsgStream.h" +#include <AsgTools/AnaToolHandle.h> +#include "FTagAnalysisInterfaces/IBTaggingTruthTaggingTool.h" + + +#include <string> +#include <iomanip> +#include <vector> + +int main() { + + asg::AnaToolHandle<IBTaggingTruthTaggingTool> tool("BTaggingTruthTaggingTool/BtagTT_Tool"); + + + //choose working point and CDI file + StatusCode code = tool.setProperty("TaggerName", "MV2c10"); + StatusCode code2 = tool.setProperty("OperatingPoint", "FixedCutBEff_77"); + StatusCode code3 = tool.setProperty("JetAuthor", "AntiKt4EMTopoJets"); + StatusCode code4 = tool.setProperty("ScaleFactorFileName", "xAODBTaggingEfficiency/13TeV/2017-21-13TeV-MC16-CDI-2018-02-09_v1.root"); + + + //truth tagging settings + StatusCode code5 = tool.setProperty("IgnoreScaleFactors", false); //use the data/MC and MC/MC scale factors when computing event weights + StatusCode code6 = tool.setProperty("UseSystematics", true); // store event weights for all systematic variations in the results object + StatusCode code7 = tool.setProperty("MaxNtagged", 3); + StatusCode code8 = tool.setProperty("UsePermutations", true); + StatusCode code9 = tool.setProperty("UseQuantile", true); + + StatusCode code10 = tool.initialize(); + + if (code != StatusCode::SUCCESS || code2 != StatusCode::SUCCESS || code3 != StatusCode::SUCCESS || code4 != StatusCode::SUCCESS || code5 != StatusCode::SUCCESS || + code6 != StatusCode::SUCCESS || code7 != StatusCode::SUCCESS || code8 != StatusCode::SUCCESS || code9 != StatusCode::SUCCESS || code10 != StatusCode::SUCCESS ) { + std::cout << "Initialization of tool " << tool->name() << " failed! " << std::endl; + return -1; + } + else { + std::cout << "Initialization of tool " << tool->name() << " finished." << std::endl; + } + + //Set the jets to be used in the tool. + std::vector<double> pt = {44000., 66000., 77000.}; + std::vector<double> eta = {2.2, 1.6, 1.7}; + std::vector<int> flav = {0,4,5}; + std::vector<double> tagw = {0.3, 0.55, 0.99}; + + Analysis::TruthTagResults results; + + if(StatusCode::SUCCESS!=tool->CalculateResults( pt,eta,flav,tagw, results) ){ + std::cout << "failed to compute truth tagging results! " << std::endl; + return -1; + }; + + //direct tagged results: + std::cout << "Direct tagged results: "<< std::endl; + for(unsigned int i=0; i< results.is_tagged.size();i++) + { + std::cout << "jet "<< i << " is direct tagged: " << results.is_tagged.at(i) << std::endl; + } + //print the results for each of the systematic variations + + for(unsigned int systindex=0; systindex< results.syst_names.size(); systindex++){ + std::string syst_name = results.syst_names.at(systindex); + + std::cout << "direct tag Event SF ( "<< syst_name <<" ) = " <<results.getEvtDirectTagSF(syst_name) << std::endl; + + } + + + //truth tagging results: + for(int ntags=1; ntags<=3;ntags++){ + + std::cout << " for " << ntags << " tagged jets: " << std::endl; + std::cout << " --------------------------------- " << std::endl; + //print chosen premutation, tagweight bin assinment and event weight + + std::vector<bool> exclusive_permuation = results.getEventPermutation(ntags,true); + std::vector<int> exclusive_tagweightBin = results.getEventQuantiles(ntags,true); + + std::vector<bool> inclusive_permuation = results.getEventPermutation(ntags,false); + std::vector<int> inclusive_tagweightBin = results.getEventQuantiles(ntags,false); + + std::cout << " exclusive || inclusive" << std::endl; + std::cout << " tagged | bin || tagged | bin" << std::endl; + for(unsigned int i=0; i< exclusive_permuation.size();i++) + { + std::cout << "jet "<< i << " " << exclusive_permuation.at(i) << " " << exclusive_tagweightBin.at(i) + << " || " << inclusive_permuation.at(i) << " " << inclusive_tagweightBin.at(i) << std::endl; + } + + std::cout << " Nominal event weight exclusive: " << results.getEventWeight(ntags,true,"Nominal") << std::endl; + std::cout << " Nominal event weight inclusive: " << results.getEventWeight(ntags,false,"Nominal") << std::endl; + std::cout << " ---------------------------------\n\n " << std::endl; + + } + + return 0; +} diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingEfficiencyTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingEfficiencyTool.h index 0a1e9b595d4447bceef93e04fa6cf8cc53e33569..08daa349783d8147662c9a5ec6f56d722397582f 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingEfficiencyTool.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingEfficiencyTool.h @@ -1,7 +1,7 @@ // Dear emacs, this is -*- c++ -*- /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// @@ -196,6 +196,20 @@ class BTaggingEfficiencyTool: public asg::AsgTool, std::map<std::string, std::vector<std::string> > listScaleFactorSystematics(bool named = false) const; /// @} + /** + * Run EigenvectorRecomposition method and get the coefficient map. + * Calling EigenVectorRecomposition method in CDI and retrieve recomposition map. + * If success, coefficientMap would be filled and return ok. + * If failed, return error. + * label : flavour label + * coefficientMap: store returned coefficient map. This map could help expressing eigenvector NPs by linear + * combination of original uncertainty NPs in workspace level of physics analysis. The coefficient value + * is stored in the map in the format of: + * map<"Eigen_B_0", map<"[original uncertainty name]", [corresponding coefficient value]>> + */ + CP::CorrectionCode getEigenRecompositionCoefficientMap(const std::string &label, std::map<std::string, std::map<std::string, float>> & coefficientMap); + /// @} + private: struct SystInfo { @@ -344,7 +358,6 @@ private: /// actual information identifying efficiency calibration objects std::map<unsigned int, unsigned int> m_EffIndices; - //cache for efficiency map config file that maps from a sample DSID to the correct efficiency map std::map<unsigned int, unsigned int> m_DSID_to_MapIndex; /// @} diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingEigenVectorRecompositionTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingEigenVectorRecompositionTool.h new file mode 100644 index 0000000000000000000000000000000000000000..2e8b1f2084343ab4685e17ae4d54d65d8ae85fe5 --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingEigenVectorRecompositionTool.h @@ -0,0 +1,130 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// BTaggingEigenVectorRecomposition.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +/** +@class BTaggingEigenVectorRecompositionTool +Tool to help retrieving(from CDI) and providing coefficents values which +could be used for expressing eigen vector NPs by linear combination of +original uncertainty NPs in workspace level of the physics analysis. +Then eigenvector uncertainties are replaced by original uncertainties. +Replacement could help us correlate uncertainties between analyses +which are using different tagger algorighthms. +@author Y. Ke, Q. Buat +@contact yake@cern.ch, qbuat@cern.ch +**/ +#ifndef CPBTAGGINGEIGENVECTORRECOMPOSITIONTOOL_H +#define CPBTAGGINGEIGENVECTORRECOMPOSITIONTOOL_H + +#include "FTagAnalysisInterfaces/IBTaggingEigenVectorRecompositionTool.h" +#include "FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h" +#include "PATInterfaces/ISystematicsTool.h" +#include "PATInterfaces/SystematicCode.h" + +#include <string> +#include <vector> +#include <map> + +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" +#include "AsgTools/AnaToolHandle.h" + +class BTaggingEigenVectorRecompositionTool: public asg::AsgTool, + public virtual IBTaggingEigenVectorRecompositionTool +{ + /// Create a proper constructor for Athena + ASG_TOOL_CLASS2( BTaggingEigenVectorRecompositionTool, IBTaggingEigenVectorRecompositionTool, ISystematicsTool) + + public: + + + /// Create a constructor for standalone usage + BTaggingEigenVectorRecompositionTool( const std::string& name ); + + /// Create a constructor for standalone usage + virtual ~BTaggingEigenVectorRecompositionTool(); + + /** + * Return a vector which contains a list of original vector uncertainties names. + * vector list is for the chosen flavour label. The order of the names is the same + * as the coefficient values given by getCoefficients() + **/ + std::vector<std::string> getListOfOriginalNuisanceParameters(const std::string& label) const; + + /** + * Produce a coefficient map contains only eigenvectors that is showing in + * eigenIdxList and return it to user. If given empty evIdxList, the function + * returns a full map. Produced map is for the chosen flavour label. + **/ + std::map<std::string, std::map<std::string, float>> getCoefficientMap(const std::string & label, + const std::vector<unsigned int> eigenIdxList = + std::vector<unsigned int>()) const; + + /** + * Returns a vector contains the coefficients value of the chosen label + * and the chosen eigenvector. The order of the value is the same as + * the order of original uncertainty names given by + * getListOfOriginalNuisanceParameters() + **/ + std::vector<float> getCoefficients(const std::string & label, const unsigned int evIdx) const; + + // Return number of eigenvectors used for the chosen label. + int getNumEigenVectors(const std::string & label)const; + + /** + * Initialize BtaggingEfficiencyTool handle and retrieve coefficient map for + * all flavours. Also initialize vectors which contains all original sources + * uncertainties' names. One vector for each flavour. + **/ + StatusCode initialize(); + + // this returns a list of systematics supported by the btaggingEfficiency tool handle + CP::SystematicSet affectingSystematics() const; + + /** it indicates which systematic shifts are to be applied for all future calls + * no systematics for now, proxy for later + **/ + CP::SystematicCode applySystematicVariation( const CP::SystematicSet & systConfig); + + /** + * subset of systematics that are recommended by the + * btaggingEfficiency tool handle + **/ + CP::SystematicSet recommendedSystematics() const; + + /** + * returns true if the argument systematic is supported by the + * btaggingEfficiency tool handle + **/ + bool isAffectedBySystematic( const CP::SystematicVariation & systematic ) const; + + + private: + + // memeber variable maps which has format: + // map<"Eigen_[flavour]_[index]", map<"[original uncertainty name]", coefficent value> + // One map for each flavour. + std::map<std::string, std::map<std::string, float>> m_coefficientMapB; + std::map<std::string, std::map<std::string, float>> m_coefficientMapC; + std::map<std::string, std::map<std::string, float>> m_coefficientMapT; + std::map<std::string, std::map<std::string, float>> m_coefficientMapLight; + + // contains list of original uncertainty names. The aim for having this + // is to keep the order of uncertainty names. + // One list for each flavour. + std::vector<std::string> m_NPnameListB; + std::vector<std::string> m_NPnameListC; + std::vector<std::string> m_NPnameListT; + std::vector<std::string> m_NPnameListLight; + + // BtaggingEfficiencyTool handle. + ToolHandle<IBTaggingEfficiencyTool> m_btageffTool; + +}; + +#endif // CPBTAGGINGEIGENVECTORRECOMPOSITIONTOOL_H diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingSelectionTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingSelectionTool.h index 3f9fc8f3eb5cc163af40af8c51512e50da72b3a8..b57be79b68e07815770108486bc2002c45912af2 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingSelectionTool.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingSelectionTool.h @@ -1,8 +1,7 @@ - // Dear emacs, this is -*- c++ -*- /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ /////////////////////////////////////////////////////////////////// @@ -44,7 +43,7 @@ class BTaggingSelectionTool: public asg::AsgTool, /// Create a constructor for standalone usage BTaggingSelectionTool( const std::string& name ); StatusCode initialize() override; - + /// Get the decision using a generic IParticle pointer virtual asg::AcceptData accept( const xAOD::IParticle* p ) const override; virtual asg::AcceptData accept( const xAOD::Jet& jet ) const override; @@ -56,9 +55,9 @@ class BTaggingSelectionTool: public asg::AsgTool, /// Decide in which quantile of the MV2c20 weight distribution the jet belongs (continuous tagging) /// The return value represents the bin index of the quantile distribution - virtual int getQuantile( const xAOD::IParticle*) const override; - virtual int getQuantile( const xAOD::Jet&) const override; - virtual int getQuantile( double /* jet pt */, double /* jet eta */, double /* mv2c20 weight */) const override; + virtual int getQuantile( const xAOD::IParticle* ) const override; + virtual int getQuantile( const xAOD::Jet& ) const override; + virtual int getQuantile( double /* jet pt */, double /* jet eta */, double /* mv2c20 weight */ ) const override; virtual CP::CorrectionCode getCutValue(double /* jet pt */, double & cutval, bool useVetoWP = false) const override; virtual CP::CorrectionCode getTaggerWeight( const xAOD::Jet& jet, double & weight ,bool useVetoWP = false) const override; @@ -67,13 +66,13 @@ class BTaggingSelectionTool: public asg::AsgTool, const asg::AcceptInfo& getAcceptInfo( ) const override {return m_acceptinfo;} private: /// Helper function that decides whether a jet belongs to the correct jet selection for b-tagging - virtual bool checkRange( double /* jet pt */, double /* jet eta */, asg::AcceptData& ) const; + virtual bool checkRange( double /* jet pt */, double /* jet eta */ , asg::AcceptData& ) const; //fill the spline or vector that store the cut values for a particular working point void InitializeTaggerVariables(std::string taggerName,std::string OP, TSpline3 *spline, TVector *constcut, double &fraction); bool m_initialised; - bool m_ErrorOnTagWeightFailure; + bool m_ErrorOnTagWeightFailure; /// Object used to store the last decision asg::AcceptInfo m_acceptinfo; diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingTruthTaggingTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingTruthTaggingTool.h new file mode 100644 index 0000000000000000000000000000000000000000..0be22b4cb31a39bbd980d47ac0f7deff24a0009d --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/BTaggingTruthTaggingTool.h @@ -0,0 +1,266 @@ +// Dear emacs, this is -*- c++ -*- +/////////////////////////////////////////////////////////////////// +// BTaggingTruthTaggingTool.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +/** + @class BTaggingTruthTaggingTool + Tool to apply flavour-tagging requirements on jets + @author C. Rizzi, M. Ughetto + @contact chiara.rizzi@cern.ch, mughetto@cern.ch +**/ + +#ifndef CPBTAGGINGTRUTHTAGGINGTOOL_H +#define CPBTAGGINGTRUTHTAGGINGTOOL_H + +#include "FTagAnalysisInterfaces/IBTaggingTruthTaggingTool.h" +#include "xAODBTagging/BTagging.h" + +#include "AsgTools/AsgTool.h" +#include "AsgMessaging/MessageCheck.h" + +#include "TFile.h" +#include "TRandom3.h" +#include "TVector.h" +#include "TFile.h" +#include <string> +#include <vector> +#include <map> + +// include xAODBtaggingEfficiency classes +#include "FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h" +#include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h" +#include "xAODBTaggingEfficiency/BTaggingEfficiencyTool.h" +#include "AsgTools/AnaToolHandle.h" + +// calibration data variable +#include "CalibrationDataInterface/CalibrationDataVariables.h" +#include "xAODBTaggingEfficiency/TruthTagResults.h" + +// xAOD jet +#include "xAODJet/JetContainer.h" + +class BTaggingTruthTaggingTool: public asg::AsgTool, + public virtual IBTaggingTruthTaggingTool { + //typedef double (xAOD::BTagging::* tagWeight_member_t)() const; + + /// Create a proper constructor for Athena + ASG_TOOL_CLASS2( BTaggingTruthTaggingTool , IBTaggingTruthTaggingTool, ISystematicsTool ) + + private: + struct jetVariable{ + Analysis::CalibrationDataVariables vars; + int flav; + }; + + // all the results about a single event are stored in this object + struct TRFinfo { + + std::vector<jetVariable> jets; + unsigned int njets; + + TRandom3 rand; + + std::vector<std::vector<bool> > perm_ex; // for each tag mult, vector of bool: is the i-th jet tagged or not? + std::vector<std::vector<bool> > perm_in; + std::vector<std::vector<double> > trfwsys_ex; // map between syst and vecot with truth-tag weights (pos = # of b-tags) + std::vector<std::vector<double> > trfwsys_in; + std::vector<std::vector<int> > tbins_ex; //for each tag mult, vector of int: quantile of each jet + std::vector<std::vector<int> > tbins_in; + + std::vector<double> effMC; // map between syst and vector of eff*SF for each jet + std::vector<double> eff; // map between syst and vector of eff*SF for each jet + + std::map<std::string,std::vector<double>> eff_allOP; // same but map for each OP + std::map<std::string,std::vector<double>> effMC_allOP; // same but map for each OP + std::vector<double> permprob_ex; // probablity of chosen perm with nominal SF + std::vector<double> permprob_in; + std::vector<double> binsprob_ex; // probability of chosen quantile with nominal SF + std::vector<double> binsprob_in; + + std::map<int,std::vector<std::vector<std::vector<bool> > > > perms; + std::vector<std::vector<double> > permsWeight; + std::vector<std::vector<double> > permsSumWeight; + + }; + + public: + /// Create a constructor for standalone usage + BTaggingTruthTaggingTool( const std::string& name ); + + private: + StatusCode CalculateResults(TRFinfo &trfinf, Analysis::TruthTagResults& results,int rand_seed = -1); + + public: + StatusCode CalculateResults( std::vector<double>& pt, std::vector<double>& eta, std::vector<int>& flav, std::vector<double>& tagw, Analysis::TruthTagResults& results,int rand_seed = -1); + StatusCode CalculateResults( const xAOD::JetContainer& jets, Analysis::TruthTagResults& results,int rand_seed = -1); + StatusCode setEffMapIndex(const std::string& flavour, unsigned int index); + void setUseSystematics(bool useSystematics); + + virtual ~BTaggingTruthTaggingTool(); + + StatusCode initialize(); + + CP::SystematicSet affectingSystematics() const; + CP::SystematicCode applySystematicVariation( const CP::SystematicSet & systConfig); + CP::SystematicSet recommendedSystematics() const; + bool isAffectedBySystematic( const CP::SystematicVariation & systematic ) const; + + + private: + + // set the jets in the event (pass same jets that satisfy kinematic criteria for b-tagging in pT and eta) + StatusCode setJets(TRFinfo &trfinf,std::vector<double>& pt, std::vector<double>& eta, std::vector<int>& flav, std::vector<double>& tagw); + StatusCode setJets(TRFinfo &trfinf,const xAOD::JetContainer& jets); + StatusCode setJets(TRFinfo &trfinf,std::vector<int>& flav, std::vector<Analysis::CalibrationDataVariables>* vars); + + // get truth tagging weights + // for one single systematic (including "Nominal") + StatusCode GetTruthTagWeights(TRFinfo &trfinf, std::vector<double> &trf_weight_ex, std::vector<double> &trf_weight_in, int sys=0); + + // tag permutation: trf_chosen_perm_ex.at(ntag).at(i) tells if the i-th jet is tagged in a selection requiring == ntag tags + StatusCode getTagPermutation(TRFinfo &trfinf, std::vector<std::vector<bool> > &trf_chosen_perm_ex, std::vector<std::vector<bool> > &trf_chosen_perm_in); + + // chosen quantile: trf_bin_ex.at(ntag).at(i) tells the quantile in which the i-th jet falls in a selection requiring == ntag tags + // returns 5 if between 60% and 0% + // returns 4 if between 70% and 60% + // returns 3 if between 77% and 70% + // returns 2 if between 85% and 77% + // returns 1 if between 100% and 85% + // returns 0 if smaller than -1e4-> should never happen --> not currently implemented + // return -1 if bigger than 1e4 or not in b-tagging acceptance --> not currently implemented + StatusCode getQuantiles(TRFinfo &trfinf,std::vector<std::vector<int> > &trf_bin_ex, std::vector<std::vector<int> > &trf_bin_in); + + // functions to make comparison with direct-tagging easier + double getEvtSF(TRFinfo &trfinf,int syst=0); + StatusCode getDirectTaggedJets(TRFinfo &trfinf,std::vector<bool> &is_tagged); + + //These WP must be listed in ascending order of cut value, meaning 85 to 60 + std::vector<std::string> m_availableOP_fixCut= {"FixedCutBEff_85", "FixedCutBEff_77","FixedCutBEff_70","FixedCutBEff_60"}; + std::vector<std::string> m_availableOP_fixEff= {"FlatBEff_85", "FlatBEff_77", "FlatBEff_70", "FlatBEff_60"}; + std::vector<std::string> m_availableOP_HybEff= {"HybBEff_85", "HybBEff_77", "HybBEff_70", "HybBEff_60"}; + std::vector<std::string> m_availableOP; + + //this vector gets filled automatically when you initialize the tool, and given to the user. + std::vector<float> m_binEdges = {}; + TFile *m_inf; //file for reading the cut values from the CDI. + + bool m_initialised; + + StatusCode getTRFweight(TRFinfo &trfinf,unsigned int nbtag, bool isInclusive, int sys); + StatusCode getAllEffMC(TRFinfo &trfinf); + StatusCode getAllEffSF(TRFinfo &trfinf,int =0); + std::vector<CP::SystematicSet> m_eff_syst; + std::vector<std::string> m_sys_name; + + // flav labelling + int jetFlavourLabel (const xAOD::Jet& jet); + + int GAFinalHadronFlavourLabel(const xAOD::Jet& jet); + int ConeFinalPartonFlavourLabel (const xAOD::Jet& jet); + int ExclusiveConeHadronFlavourLabel (const xAOD::Jet& jet); + std::vector<std::string> split(const std::string& str, char token); + //*********************************// + // Prop. of BTaggingEfficiencyTool // + //*********************************// + + /// name of the data/MC efficiency scale factor calibration file (may be changed by the @c PathResolver) + std::string m_SFFile; + /// name of the optional MC efficiency file (may be changed by the @c PathResolver) + std::string m_EffFile; + /// name of the data/MC scale factor calibration for b jets + std::string m_SFBName; + /// name of the data/MC scale factor calibration for charm jets + std::string m_SFCName; + /// name of the data/MC scale factor calibration for tau jets + std::string m_SFTName; + /// name of the data/MC scale factor calibration for light-flavour jets + std::string m_SFLightName; + /// specification of the eigenvector reduction strategy for b jets (if eigenvectors are used) + std::string m_EVReductionB; + /// specification of the eigenvector reduction strategy for c jets (if eigenvectors are used) + std::string m_EVReductionC; + /// specification of the eigenvector reduction strategy for light-flavour jets (if eigenvectors are used) + std::string m_EVReductionLight; + /// semicolon-separated list of MC efficiency parametrisation names for b jets + std::string m_EffBName; + /// semicolon-separated list of MC efficiency parametrisation names for charm jets + std::string m_EffCName; + /// semicolon-separated list of MC efficiency parametrisation names for tau jets + std::string m_EffTName; + /// semicolon-separated list of MC efficiency parametrisation names for light-flavour jets + std::string m_EffLightName; + /// semicolon-separated list of uncertainties to be excluded from the eigenvector variation procedure + std::string m_excludeFromEV; + /// tagger name + std::string m_taggerName; + /// operating point + std::string m_OP; + /// operating point when running in Continuous + std::string m_cutBenchmark; + /// jet collection name + std::string m_jetAuthor; + /// systematics model to be used (current choices are "SFEigen" and "Envelope") + std::string m_systStrategy; + /// if true, attempt to retrieve the data/MC efficiency scale factor calibration files from the @PathResolver development area + bool m_useDevFile; + /// if true, use cone-based labelling (as opposed to ghost association) + bool m_coneFlavourLabel; + /// when using cone-based labelling (see above), if true, use the "traditional" (parton-based) labelling instead of the current default (hadron-based, exclusive) + bool m_oldConeFlavourLabel; + /// in case of continuous WP you can choose to ignore some of the eigenvectors + std::string m_excludeEV; + ///possibility to compute the direct tagging SFs map directly from the TruthTaggingTool + bool m_doDirectTag; + + //*********************************// + // Prop. of BTaggingSelectionTool // + //*********************************// + + double m_maxEta; + double m_minPt; + double m_maxRangePt; + // std::string m_CutFileName; + + // properties of truth tagging + bool m_doOnlyUpVariations; + bool m_ignoreSF; + bool m_usePerm; + bool m_useQuntile; + bool m_continuous; + bool m_useSys; + int m_nbtag; + + unsigned int m_OperatingPoint_index; + + std::map<std::string, asg::AnaToolHandle<IBTaggingEfficiencyTool> > m_effTool_allOP; + + + asg::AnaToolHandle<IBTaggingEfficiencyTool> m_effTool; + asg::AnaToolHandle<IBTaggingSelectionTool> m_selTool; //! + + StatusCode check_syst_range(unsigned int sys); + + std::vector<std::vector<bool> > generatePermutations(int njets, int tags, int start=0); + + double trfWeight(TRFinfo &trfinf,const std::vector<bool> &tags); + + StatusCode chooseAllTagPermutation(TRFinfo &trfinf,unsigned int nbtag); + StatusCode chooseTagPermutation(TRFinfo &trfinf,unsigned int nbtag, bool isIncl); + double getPermutationRW(TRFinfo &trfinf,bool isIncl,unsigned int nbtag, int sys); + + + StatusCode chooseAllTagBins(TRFinfo &trfinf); + StatusCode chooseTagBins_cum(TRFinfo &trfinf,std::vector<bool> &tagconf, bool isIncl, unsigned int nbtag); + StatusCode generateRandomTaggerScores(std::vector< std::vector<int> > &quantiles, std::vector< std::vector<double> > &scores); + double getTagBinsConfProb(TRFinfo &trfinf,std::vector<int> &tagws); + double getTagBinsRW(TRFinfo &trfinf,bool isIncl, unsigned int nbtag); + + + bool fillVariables(const xAOD::Jet& jet, Analysis::CalibrationDataVariables& x); + bool fillVariables(const double jetPt, const double jetEta, const double jetTagWeight, Analysis::CalibrationDataVariables& x); + + +}; + +#endif // CPBTAGGINGTRUTHTAGGINGTOOL_H + diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingEfficiencyTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingEfficiencyTool.h new file mode 100644 index 0000000000000000000000000000000000000000..bc478ba0f68d140238da3daecc19f838d8ec17c6 --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingEfficiencyTool.h @@ -0,0 +1,8 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ +#pragma message "The IBTaggingEfficiencyTool has moved to FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h . Please update your code." +#include <FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h> + diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingSelectionTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingSelectionTool.h new file mode 100644 index 0000000000000000000000000000000000000000..909e70a7ca0631bcc461360c81204087c107e6c3 --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingSelectionTool.h @@ -0,0 +1,8 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#pragma message "The IBTaggingSelectionTool has moved to FTagAnalysisInterfaces/IBTaggingSelectionTool.h . Please update your code." +#include <FTagAnalysisInterfaces/IBTaggingSelectionTool.h> diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingTruthTaggingTool.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingTruthTaggingTool.h new file mode 100644 index 0000000000000000000000000000000000000000..594b019d030c7f59b9299b6affedd032ed711b92 --- /dev/null +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/IBTaggingTruthTaggingTool.h @@ -0,0 +1,8 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#pragma message "The IBTaggingTruthTaggingTool has moved to FTagAnalysisInterfaces/IBTaggingTruthTaggingTool.h . Please update your code." +#include <FTagAnalysisInterfaces/IBTaggingTruthTaggingTool.h> diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/selection.xml b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/selection.xml index 071e1453f681170bfd4b8d5b17bdcf69c27ba87a..ed6cc9f04fbfc81a9e43c3d277878193d66df033 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/selection.xml +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/selection.xml @@ -2,4 +2,6 @@ <lcgdict> <class name="BTaggingEfficiencyTool" /> <class name="BTaggingSelectionTool" /> + <class name="BTaggingTruthTaggingTool" /> + <class name="BTaggingEigenVectorRecompositionTool" /> </lcgdict> diff --git a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/xAODBTaggingEfficiencyDict.h b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/xAODBTaggingEfficiencyDict.h index 3caca03f85580c68d5e8881336a357d1651492aa..18952ec7a5edffd4953a5b153726fddf15697bcc 100644 --- a/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/xAODBTaggingEfficiencyDict.h +++ b/PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency/xAODBTaggingEfficiency/xAODBTaggingEfficiencyDict.h @@ -13,5 +13,6 @@ #include "xAODBTaggingEfficiency/BTaggingEfficiencyTool.h" #include "xAODBTaggingEfficiency/BTaggingSelectionTool.h" - +#include "xAODBTaggingEfficiency/BTaggingTruthTaggingTool.h" +#include "xAODBTaggingEfficiency/BTaggingEigenVectorRecompositionTool.h" #endif // XAODBTAGGINGEFFICIENCY_XAODBTAGGINGEFFICIENCYDICT_H