File indexing completed on 2024-04-06 12:24:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
0032 #include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
0033 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0034 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0035
0036 #include "TF1.h"
0037 #include "TF2.h"
0038 #include "TF3.h"
0039
0040 namespace egPM {
0041
0042 struct AbsEtaNrClus {
0043 float x;
0044 size_t y;
0045
0046 AbsEtaNrClus(const reco::ElectronSeed& seed) {
0047 reco::SuperClusterRef scRef = seed.caloCluster().castTo<reco::SuperClusterRef>();
0048 x = std::abs(scRef->eta());
0049 y = scRef->clustersSize();
0050 }
0051 bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax) const {
0052 return x >= absEtaMin && x < absEtaMax && y >= nrClusMin && y <= nrClusMax;
0053 }
0054 };
0055 struct AbsEtaNrClusPhi {
0056 float x;
0057 size_t y;
0058 float z;
0059
0060 AbsEtaNrClusPhi(const reco::ElectronSeed& seed) {
0061 reco::SuperClusterRef scRef = seed.caloCluster().castTo<reco::SuperClusterRef>();
0062 x = std::abs(scRef->eta());
0063 y = scRef->clustersSize();
0064 z = scRef->phi();
0065 }
0066 bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax, float phiMin, float phiMax) const {
0067 return x >= absEtaMin && x < absEtaMax && y >= nrClusMin && y <= nrClusMax && z >= phiMin && z < phiMax;
0068 }
0069 };
0070
0071 struct AbsEtaNrClusEt {
0072 float x;
0073 size_t y;
0074 float z;
0075
0076 AbsEtaNrClusEt(const reco::ElectronSeed& seed) {
0077 reco::SuperClusterRef scRef = seed.caloCluster().castTo<reco::SuperClusterRef>();
0078 x = std::abs(scRef->eta());
0079 y = scRef->clustersSize();
0080 z = scRef->energy() * sin(scRef->position().Theta());
0081 }
0082 bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax, float etMin, float etMax) const {
0083 return x >= absEtaMin && x < absEtaMax && y >= nrClusMin && y <= nrClusMax && z >= etMin && z < etMax;
0084 }
0085 };
0086
0087
0088
0089
0090
0091 template <typename ParamType, bool = true>
0092 struct TF1Wrap {
0093 private:
0094 TF1 func_;
0095
0096 public:
0097 TF1Wrap(const std::string& funcExpr, const std::vector<double>& params) : func_("func", funcExpr.c_str()) {
0098 for (size_t paraNr = 0; paraNr < params.size(); paraNr++) {
0099 func_.SetParameter(paraNr, params[paraNr]);
0100 }
0101 }
0102 float operator()(const ParamType& obj) { return func_.Eval(obj.x); };
0103 };
0104 template <typename ParamType>
0105 class TF1Wrap<ParamType, false> {
0106 public:
0107 TF1Wrap(const std::string& funcExpr, const std::vector<double>& params) {}
0108 float operator()(const ParamType& obj) { return 1.; };
0109 };
0110
0111 template <typename ParamType, bool = true>
0112 struct TF2Wrap {
0113 private:
0114 TF2 func_;
0115
0116 public:
0117 TF2Wrap(const std::string& funcExpr, const std::vector<double>& params) : func_("func", funcExpr.c_str()) {
0118 for (size_t paraNr = 0; paraNr < params.size(); paraNr++) {
0119 func_.SetParameter(paraNr, params[paraNr]);
0120 }
0121 }
0122 float operator()(const ParamType& obj) { return func_.Eval(obj.x, obj.y); };
0123 };
0124 template <typename ParamType>
0125 class TF2Wrap<ParamType, false> {
0126 public:
0127 TF2Wrap(const std::string& funcExpr, const std::vector<double>& params) {}
0128 float operator()(const ParamType& obj) { return 1.; };
0129 };
0130
0131 template <typename ParamType, bool = true>
0132 struct TF3Wrap {
0133 private:
0134 TF3 func_;
0135
0136 public:
0137 TF3Wrap(const std::string& funcExpr, const std::vector<double>& params) : func_("func", funcExpr.c_str()) {
0138 for (size_t paraNr = 0; paraNr < params.size(); paraNr++) {
0139 func_.SetParameter(paraNr, params[paraNr]);
0140 }
0141 }
0142 float operator()(const ParamType& obj) { return func_.Eval(obj.x, obj.y, obj.z); };
0143 };
0144 template <typename ParamType>
0145 class TF3Wrap<ParamType, false> {
0146 public:
0147 TF3Wrap(const std::string& funcExpr, const std::vector<double>& params) {}
0148 float operator()(const ParamType& obj) { return 1.; };
0149 };
0150
0151
0152
0153 template <typename T>
0154 struct ConfigType {
0155 typedef T type;
0156 };
0157 template <>
0158 struct ConfigType<float> {
0159 typedef double type;
0160 };
0161 template <>
0162 struct ConfigType<size_t> {
0163 typedef int type;
0164 };
0165
0166
0167
0168 template <typename T>
0169 constexpr auto has1D(int) -> decltype(T::x, bool()) {
0170 return true;
0171 }
0172 template <typename T>
0173 constexpr bool has1D(...) {
0174 return false;
0175 }
0176 template <typename T>
0177 constexpr auto has2D(int) -> decltype(T::y, bool()) {
0178 return true;
0179 }
0180 template <typename T>
0181 constexpr bool has2D(...) {
0182 return false;
0183 }
0184 template <typename T>
0185 constexpr auto has3D(int) -> decltype(T::z, bool()) {
0186 return true;
0187 }
0188 template <typename T>
0189 constexpr bool has3D(...) {
0190 return false;
0191 }
0192
0193 template <typename InputType>
0194 class ParamBin {
0195 public:
0196 ParamBin() {}
0197 virtual ~ParamBin() {}
0198 virtual bool pass(const InputType&) const = 0;
0199 virtual float operator()(const InputType&) const = 0;
0200
0201 protected:
0202
0203 static std::pair<std::string, std::string> readFuncStr(const std::string& inStr) {
0204 size_t pos = inStr.find(":=");
0205 if (pos != std::string::npos)
0206 return std::make_pair(inStr.substr(0, pos), inStr.substr(pos + 2));
0207 else
0208 return std::make_pair(inStr, std::string(""));
0209 }
0210 template <typename ParamType>
0211 static std::function<float(const ParamType&)> makeFunc(const edm::ParameterSet& config) {
0212 auto funcType = readFuncStr(config.getParameter<std::string>("funcType"));
0213 auto funcParams = config.getParameter<std::vector<double>>("funcParams");
0214 if (funcType.first == "TF1" && has1D<ParamType>(0))
0215 return TF1Wrap<ParamType, has1D<ParamType>(0)>(funcType.second, funcParams);
0216 else if (funcType.first == "TF2" && has2D<ParamType>(0))
0217 return TF2Wrap<ParamType, has2D<ParamType>(0)>(funcType.second, funcParams);
0218 else if (funcType.first == "TF3" && has3D<ParamType>(0))
0219 return TF3Wrap<ParamType, has3D<ParamType>(0)>(funcType.second, funcParams);
0220 else
0221 throw cms::Exception("InvalidConfig") << " type " << funcType.first
0222 << " is not recognised or is imcompatable with the ParamType, "
0223 "configuration is invalid and needs to be fixed"
0224 << std::endl;
0225 }
0226 };
0227
0228 template <typename InputType, typename ParamType>
0229 class ParamBin1D : public ParamBin<InputType> {
0230 private:
0231 using XType = decltype(ParamType::x);
0232 XType xMin_, xMax_;
0233 std::function<float(const ParamType&)> func_;
0234
0235 public:
0236 ParamBin1D(const edm::ParameterSet& config)
0237 : xMin_(config.getParameter<typename ConfigType<XType>::type>("xMin")),
0238 xMax_(config.getParameter<typename ConfigType<XType>::type>("xMax")),
0239 func_(ParamBin<InputType>::template makeFunc<ParamType>(config)) {}
0240 bool pass(const InputType& input) const override { return ParamType(input).pass(xMin_, xMax_); }
0241 float operator()(const InputType& input) const override {
0242 if (!pass(input))
0243 return 0;
0244 else
0245 return func_(ParamType(input));
0246 }
0247 };
0248
0249 template <typename InputType, typename ParamType>
0250 class ParamBin2D : public ParamBin<InputType> {
0251 private:
0252 using XType = decltype(ParamType::x);
0253 using YType = decltype(ParamType::y);
0254 XType xMin_, xMax_;
0255 YType yMin_, yMax_;
0256 std::function<float(const ParamType&)> func_;
0257
0258 public:
0259 ParamBin2D(const edm::ParameterSet& config)
0260 : xMin_(config.getParameter<typename ConfigType<XType>::type>("xMin")),
0261 xMax_(config.getParameter<typename ConfigType<XType>::type>("xMax")),
0262 yMin_(config.getParameter<typename ConfigType<YType>::type>("yMin")),
0263 yMax_(config.getParameter<typename ConfigType<YType>::type>("yMax")),
0264 func_(ParamBin<InputType>::template makeFunc<ParamType>(config)) {}
0265
0266 bool pass(const InputType& input) const override { return ParamType(input).pass(xMin_, xMax_, yMin_, yMax_); }
0267 float operator()(const InputType& input) const override {
0268 if (!pass(input))
0269 return 0;
0270 else
0271 return func_(ParamType(input));
0272 }
0273 };
0274
0275 template <typename InputType, typename ParamType>
0276 class ParamBin3D : public ParamBin<InputType> {
0277 using XType = decltype(ParamType::x);
0278 using YType = decltype(ParamType::y);
0279 using ZType = decltype(ParamType::z);
0280
0281 XType xMin_, xMax_;
0282 YType yMin_, yMax_;
0283 ZType zMin_, zMax_;
0284 std::function<float(const ParamType&)> func_;
0285
0286 public:
0287 ParamBin3D(const edm::ParameterSet& config)
0288 : xMin_(config.getParameter<typename ConfigType<XType>::type>("xMin")),
0289 xMax_(config.getParameter<typename ConfigType<XType>::type>("xMax")),
0290 yMin_(config.getParameter<typename ConfigType<YType>::type>("yMin")),
0291 yMax_(config.getParameter<typename ConfigType<YType>::type>("yMax")),
0292 zMin_(config.getParameter<typename ConfigType<ZType>::type>("zMin")),
0293 zMax_(config.getParameter<typename ConfigType<ZType>::type>("zMax")),
0294 func_(ParamBin<InputType>::template makeFunc<ParamType>(config)) {}
0295
0296 bool pass(const InputType& input) const override {
0297 return ParamType(input).pass(xMin_, xMax_, yMin_, yMax_, zMin_, zMax_);
0298 }
0299 float operator()(const InputType& input) const override {
0300 if (!pass(input))
0301 return 0;
0302 else
0303 return func_(ParamType(input));
0304 }
0305 };
0306
0307 template <typename InputType>
0308 class Param {
0309 std::vector<std::unique_ptr<ParamBin<InputType>>> bins_;
0310
0311 public:
0312 Param(const edm::ParameterSet& config) {
0313 std::vector<edm::ParameterSet> binConfigs = config.getParameter<std::vector<edm::ParameterSet>>("bins");
0314 for (auto& binConfig : binConfigs)
0315 bins_.emplace_back(createParamBin_(binConfig));
0316 }
0317 float operator()(const InputType& input) const {
0318 for (auto& bin : bins_) {
0319 if (bin->pass(input))
0320 return (*bin)(input);
0321 }
0322 return -1;
0323 }
0324
0325 private:
0326 std::unique_ptr<ParamBin<InputType>> createParamBin_(const edm::ParameterSet& config) {
0327 std::string type = config.getParameter<std::string>("binType");
0328 if (type == "AbsEtaClus")
0329 return std::make_unique<ParamBin2D<InputType, AbsEtaNrClus>>(config);
0330 else if (type == "AbsEtaClusPhi")
0331 return std::make_unique<ParamBin3D<InputType, AbsEtaNrClusPhi>>(config);
0332 else if (type == "AbsEtaClusEt")
0333 return std::make_unique<ParamBin3D<InputType, AbsEtaNrClusEt>>(config);
0334 else
0335 throw cms::Exception("InvalidConfig")
0336 << " type " << type << " is not recognised, configuration is invalid and needs to be fixed" << std::endl;
0337 }
0338 };
0339 }