00001
00002
00003 #ifndef EGAMMA_CALIB_TOOL_H_
00004 #define EGAMMA_CALIB_TOOL_H_
00005
00006 #include <functional>
00007 #include <string>
00008 #include <array>
00009 #include <memory>
00010
00011 #include "AsgTools/AsgTool.h"
00012 #include "AsgTools/AsgMetadataTool.h"
00013 #include "AsgTools/AsgMessaging.h"
00014 #include "ElectronPhotonFourMomentumCorrection/IEgammaCalibrationAndSmearingTool.h"
00015 #include "PATInterfaces/ISystematicsTool.h"
00016 #include "PATInterfaces/SystematicSet.h"
00017 #include "xAODEgamma/Electron.h"
00018 #include "xAODEgamma/Photon.h"
00019 #include "xAODEgamma/Egamma.h"
00020 #include "xAODCaloEvent/CaloCluster.h"
00021 #include "xAODEventInfo/EventInfo.h"
00022 #include "AsgTools/AnaToolHandle.h"
00023
00024 #include "ElectronPhotonFourMomentumCorrection/egammaEnergyCorrectionTool.h"
00025
00026
00027 class egammaMVATool;
00028 class egammaLayerRecalibTool;
00029 namespace egGain { class GainTool; }
00030
00031 namespace xAOD {
00032 inline float get_phi_calo(const xAOD::CaloCluster& cluster, bool do_throw=false)
00033 {
00034 double phi_calo;
00035 if (cluster.retrieveMoment(xAOD::CaloCluster::PHICALOFRAME, phi_calo)) { }
00036 else if (cluster.isAvailable<float>("phiCalo")) {
00037 phi_calo = cluster.auxdata<float>("phiCalo");
00038 }
00039 else {
00040 asg::AsgMessaging msg("get_phi_calo");
00041 msg.msg(MSG::ERROR) << "phiCalo not available as auxilliary variable" << endmsg;
00042 if (do_throw) { throw std::runtime_error("phiCalo not available as auxilliary variable"); }
00043 msg.msg(MSG::WARNING) << "using phi as phiCalo" << endmsg;
00044 phi_calo = cluster.phi();
00045 }
00046 return phi_calo;
00047 }
00048
00049 inline float get_eta_calo(const xAOD::CaloCluster& cluster, bool do_throw=false)
00050 {
00051 double eta_calo;
00052 if (cluster.retrieveMoment(xAOD::CaloCluster::ETACALOFRAME,
00053 eta_calo)) { }
00054 else if (cluster.isAvailable<float>("etaCalo")) {
00055 eta_calo = cluster.auxdata<float>("etaCalo");
00056 }
00057 else {
00058 asg::AsgMessaging msg("get_eta_calo");
00059 msg.msg(MSG::ERROR) << "etaCalo not available as auxilliary variable" << endmsg;
00060 if (do_throw) { throw std::runtime_error("etaCalo not available as auxilliary variable"); }
00061 msg.msg(MSG::WARNING) << "using eta as etaCalo" << endmsg;
00062 }
00063 return eta_calo;
00064 }
00065 }
00066
00067 namespace CP {
00068
00069 class EgammaCalibrationAndSmearingTool : virtual public IEgammaCalibrationAndSmearingTool, public asg::AsgMetadataTool {
00070
00071 ASG_TOOL_CLASS2( EgammaCalibrationAndSmearingTool, IEgammaCalibrationAndSmearingTool, CP::ISystematicsTool)
00072
00073 public:
00074
00075 enum class ScaleDecorrelation {FULL, ONENP, FULL_ETA_CORRELATED, ONENP_PLUS_UNCONR};
00076 enum class ResolutionDecorrelation {FULL, ONENP};
00077 static const int AUTO = 2;
00078 typedef unsigned int RandomNumber;
00079 typedef std::function<int(const EgammaCalibrationAndSmearingTool&, const xAOD::Egamma&, const xAOD::EventInfo&)> IdFunction;
00080 typedef std::function<bool(const xAOD::Egamma&)> EgammaPredicate;
00081
00082 EgammaCalibrationAndSmearingTool(const std::string& name);
00083 ~EgammaCalibrationAndSmearingTool();
00084
00085 StatusCode initialize() override;
00086
00087 virtual StatusCode beginInputFile() override;
00088 virtual StatusCode beginEvent() override;
00089 virtual StatusCode endInputFile() override;
00090
00091
00092 virtual CP::CorrectionCode applyCorrection(xAOD::Egamma&) override;
00093 virtual CP::CorrectionCode applyCorrection(xAOD::Egamma & input, const xAOD::EventInfo& event_info);
00094
00095
00096
00097 virtual CP::CorrectionCode correctedCopy(const xAOD::Electron&, xAOD::Electron*&) override;
00098 virtual CP::CorrectionCode correctedCopy(const xAOD::Photon&, xAOD::Photon*&) override;
00099 double getEnergy(const xAOD::Photon&);
00100 double getEnergy(const xAOD::Electron&);
00101
00102
00103
00104 virtual CP::SystematicSet affectingSystematics() const override;
00105
00106 virtual bool isAffectedBySystematic( const CP::SystematicVariation& systematic ) const override;
00107
00108 virtual CP::SystematicSet recommendedSystematics() const override;
00109
00110 virtual CP::SystematicCode applySystematicVariation(const CP::SystematicSet& systConfig) override;
00111 virtual void setRandomSeed(unsigned seed=0) override;
00112 virtual void setRandomSeedFunction(const IdFunction&& function) { m_set_seed_function = function; }
00113 const IdFunction getRandomSeedFuction() const { return m_set_seed_function; }
00114
00115 virtual double resolution( double energy, double cl_eta, double cl_etaCalo,
00116 PATCore::ParticleType::Type ptype = PATCore::ParticleType::Electron, bool withCT=false) const override;
00117
00118 private:
00119
00120 bool m_metadata_retrieved = false;
00121 std::string m_ESModel;
00122 std::string m_decorrelation_model_name;
00123 std::string m_decorrelation_model_scale_name;
00124 std::string m_decorrelation_model_resolution_name;
00125 ScaleDecorrelation m_decorrelation_model_scale = ScaleDecorrelation::FULL;
00126 ResolutionDecorrelation m_decorrelation_model_resolution = ResolutionDecorrelation::FULL;
00127 egEnergyCorr::ESModel m_TESModel;
00128 int m_doScaleCorrection;
00129 int m_doSmearing;
00130 bool m_auto_reseed;
00131 double m_varSF;
00132 std::string m_ResolutionType;
00133 egEnergyCorr::Resolution::resolutionType m_TResolutionType;
00134 int m_use_AFII;
00135 PATCore::ParticleDataType::DataType m_simulation = PATCore::ParticleDataType::Full;
00136 int m_RandomRunNumber;
00137
00138 int m_useLayerCorrection;
00139 int m_usePSCorrection;
00140 int m_useS12Correction;
00141 int m_useLayer2Recalibration;
00142 int m_useIntermoduleCorrection;
00143 int m_usePhiUniformCorrection;
00144 int m_useGainCorrection;
00145 bool m_use_ep_combination;
00146 int m_use_mva_calibration;
00147 bool m_use_full_statistical_error;
00148 int m_use_temp_correction201215;
00149 int m_use_uA2MeV_2015_first2weeks_correction;
00150 bool m_use_mapping_correction;
00151 int m_user_random_run_number;
00152
00153 void setupSystematics();
00154
00155 StatusCode get_simflavour_from_metadata(PATCore::ParticleDataType::DataType& result) const;
00156
00157
00158 struct AbsEtaCaloPredicate
00159 {
00160 AbsEtaCaloPredicate(double eta_min, double eta_max) : m_eta_min(eta_min), m_eta_max(eta_max) {}
00161 bool operator()(const xAOD::Egamma& p) {
00162 const double aeta = std::abs(xAOD::get_eta_calo(*p.caloCluster()));
00163 return (aeta >= m_eta_min and aeta < m_eta_max);
00164 }
00165 private:
00166 float m_eta_min, m_eta_max;
00167 };
00168
00169 const EgammaPredicate AbsEtaCaloPredicateFactory(double eta_min, double eta_max) const
00170 {
00171
00172
00173
00174 return AbsEtaCaloPredicate(eta_min, eta_max);
00175 }
00176
00177 const EgammaPredicate AbsEtaCaloPredicateFactory(std::pair<double, double> edges) const
00178 {
00179 return AbsEtaCaloPredicateFactory(edges.first, edges.second);
00180 }
00181
00182 const std::vector<EgammaPredicate> AbsEtaCaloPredicatesFactory(const std::vector<std::pair<double, double>> edges) const
00183 {
00184 std::vector<EgammaPredicate> result;
00185 result.reserve(edges.size());
00186 for (const auto& it : edges) {
00187 result.push_back(AbsEtaCaloPredicateFactory(it.first, it.second));
00188 }
00189 return result;
00190 }
00191
00192 const std::vector<EgammaPredicate> AbsEtaCaloPredicatesFactory(const std::vector<double> edges) const
00193 {
00194 std::vector<EgammaPredicate> result;
00195 result.reserve(edges.size() - 1);
00196 auto it2 = edges.begin();
00197 auto it = it2++;
00198 for(; it2 != edges.end(); ++it, ++it2)
00199 {
00200 result.push_back(AbsEtaCaloPredicateFactory(*it, *it2));
00201 }
00202 return result;
00203 }
00204
00205 PATCore::ParticleType::Type xAOD2ptype(const xAOD::Egamma& particle) const;
00206 public:
00207 virtual double getEnergy(xAOD::Egamma*, const xAOD::EventInfo*);
00208 virtual double getElectronMomentum(const xAOD::Electron*, const xAOD::EventInfo*);
00209 double getResolution(const xAOD::Egamma& particle, bool withCT=true) const override;
00210 double intermodule_correction(double Ecl, double phi, double eta) const;
00211 double correction_phi_unif(double eta, double phi) const;
00212
00213
00214 private:
00215
00216 mutable egammaMVATool* m_mva_tool = nullptr;
00217 egGain::GainTool* m_gain_tool = nullptr;
00218 egammaLayerRecalibTool* m_layer_recalibration_tool = nullptr;
00219 std::string m_layer_recalibration_tune;
00220
00221
00222 std::unique_ptr<AtlasRoot::egammaEnergyCorrectionTool> m_rootTool;
00223 std::string m_MVAfolder;
00224
00225 struct SysInfo {
00226 EgammaPredicate predicate;
00227 egEnergyCorr::Scale::Variation effect;
00228 };
00229
00230 std::map<CP::SystematicVariation, SysInfo> m_syst_description;
00231 std::map<CP::SystematicVariation, egEnergyCorr::Resolution::Variation> m_syst_description_resolution;
00232
00233
00234
00235 egEnergyCorr::Scale::Variation m_currentScaleVariation_MC;
00236 egEnergyCorr::Scale::Variation m_currentScaleVariation_data;
00237 egEnergyCorr::Resolution::Variation m_currentResolutionVariation_MC;
00238 egEnergyCorr::Resolution::Variation m_currentResolutionVariation_data;
00239
00240 EgammaPredicate m_currentScalePredicate;
00241
00242 IdFunction m_set_seed_function;
00243
00244 inline egEnergyCorr::Scale::Variation oldtool_scale_flag_this_event(const xAOD::Egamma& p, const xAOD::EventInfo& event_info) const;
00245 inline egEnergyCorr::Resolution::Variation oldtool_resolution_flag_this_event(const xAOD::Egamma& p, const xAOD::EventInfo& event_info) const;
00246
00247 };
00248
00249 }
00250 #endif