CMS 3D CMS Logo

EgammaHLTPixelMatchParamObjects.h
Go to the documentation of this file.
1 //These objects allow an arbitary parameristisation to be used
2 //design:
3 // the function and parameterisation can be changing without having to change the interface
4 // or breaking backwards compatibiltiy with existing configs.
5 // This is vital for the HLT and the main driving force behind the design which otherwise
6 // could have been a lot simplier
7 //
8 //usage:
9 // The variables used are defined by an intermediate object which defines the
10 // variables x,y, and z. 1D objects only need to define x, 2D objects x,y, etc.
11 // Example is "AbsEtaNrClus" which defines x as |supercluster eta| and y as #subclusters of the supercluster.
12 // The object also defines a pass function where it determines if x (and y,z) is
13 // within the specificed xmin and xmax range. This is mainly done as individual
14 // objects can decide whether this means min<=x<max or min<=x<=max
15 //
16 // These objects are used by the binning objects. The bins can currently be 1D, 2D,
17 // or 3D based on the intermediate object. Each bin has a function with it.
18 // The function takes a ParmaType as an argument and returns a float.
19 // The function is defined by a string of format FUNCID:=ExtraConfigInfo
20 // FUNCID = function type which allows different functions to be selected
21 // while ExtraConfigInfo is any extra information needed to configure that func
22 // currently implimented types are TF1, TF2, TF3
23 // so to get a TF1 which is a pol3 just do TF1:=pol3
24 //
25 //future plans:
26 // Seperate out intermediate wrapper objects such as AbsEtaNrClus
27 // and put them in their own file. However some mechanism is needed to register them
28 // so for now this isnt done. Note we might move to the standard CMSSW of dealing
29 // with this
30 
35 
36 #include "TF1.h"
37 #include "TF2.h"
38 #include "TF3.h"
39 
40 namespace egPM {
41 
42  struct AbsEtaNrClus {
43  float x;
44  size_t y;
45 
47  reco::SuperClusterRef scRef = seed.caloCluster().castTo<reco::SuperClusterRef>();
48  x = std::abs(scRef->eta());
49  y = scRef->clustersSize();
50  }
51  bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax) const {
52  return x >= absEtaMin && x < absEtaMax && y >= nrClusMin && y <= nrClusMax;
53  }
54  };
55  struct AbsEtaNrClusPhi {
56  float x;
57  size_t y;
58  float z;
59 
61  reco::SuperClusterRef scRef = seed.caloCluster().castTo<reco::SuperClusterRef>();
62  x = std::abs(scRef->eta());
63  y = scRef->clustersSize();
64  z = scRef->phi();
65  }
66  bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax, float phiMin, float phiMax) const {
67  return x >= absEtaMin && x < absEtaMax && y >= nrClusMin && y <= nrClusMax && z >= phiMin && z < phiMax;
68  }
69  };
70 
71  struct AbsEtaNrClusEt {
72  float x;
73  size_t y;
74  float z;
75 
77  reco::SuperClusterRef scRef = seed.caloCluster().castTo<reco::SuperClusterRef>();
78  x = std::abs(scRef->eta());
79  y = scRef->clustersSize();
80  z = scRef->energy() * sin(scRef->position().Theta());
81  }
82  bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax, float etMin, float etMax) const {
83  return x >= absEtaMin && x < absEtaMax && y >= nrClusMin && y <= nrClusMax && z >= etMin && z < etMax;
84  }
85  };
86 
87  //these structs wrap the TF1 object
88  //also if the ParamType doesnt have a high enough dimension
89  //(ie using only one with x,y for a TF3), then the second
90  //template parameter disables the function
91  template <typename ParamType, bool = true>
92  struct TF1Wrap {
93  private:
94  TF1 func_;
95 
96  public:
97  TF1Wrap(const std::string& funcExpr, const std::vector<double>& params) : func_("func", funcExpr.c_str()) {
98  for (size_t paraNr = 0; paraNr < params.size(); paraNr++) {
99  func_.SetParameter(paraNr, params[paraNr]);
100  }
101  }
102  float operator()(const ParamType& obj) { return func_.Eval(obj.x); };
103  };
104  template <typename ParamType>
105  class TF1Wrap<ParamType, false> {
106  public:
107  TF1Wrap(const std::string& funcExpr, const std::vector<double>& params) {}
108  float operator()(const ParamType& obj) { return 1.; };
109  };
110 
111  template <typename ParamType, bool = true>
112  struct TF2Wrap {
113  private:
114  TF2 func_;
115 
116  public:
117  TF2Wrap(const std::string& funcExpr, const std::vector<double>& params) : func_("func", funcExpr.c_str()) {
118  for (size_t paraNr = 0; paraNr < params.size(); paraNr++) {
119  func_.SetParameter(paraNr, params[paraNr]);
120  }
121  }
122  float operator()(const ParamType& obj) { return func_.Eval(obj.x, obj.y); };
123  };
124  template <typename ParamType>
125  class TF2Wrap<ParamType, false> {
126  public:
127  TF2Wrap(const std::string& funcExpr, const std::vector<double>& params) {}
128  float operator()(const ParamType& obj) { return 1.; };
129  };
130 
131  template <typename ParamType, bool = true>
132  struct TF3Wrap {
133  private:
134  TF3 func_;
135 
136  public:
137  TF3Wrap(const std::string& funcExpr, const std::vector<double>& params) : func_("func", funcExpr.c_str()) {
138  for (size_t paraNr = 0; paraNr < params.size(); paraNr++) {
139  func_.SetParameter(paraNr, params[paraNr]);
140  }
141  }
142  float operator()(const ParamType& obj) { return func_.Eval(obj.x, obj.y, obj.z); };
143  };
144  template <typename ParamType>
145  class TF3Wrap<ParamType, false> {
146  public:
147  TF3Wrap(const std::string& funcExpr, const std::vector<double>& params) {}
148  float operator()(const ParamType& obj) { return 1.; };
149  };
150 
151  //the following functions allow for the fact that the type in the CMSSW PSet does not
152  //have floats do when it sees a float parameter, it retrieves a double
153  template <typename T>
154  struct ConfigType {
155  typedef T type;
156  };
157  template <>
158  struct ConfigType<float> {
159  typedef double type;
160  };
161  template <>
162  struct ConfigType<size_t> {
163  typedef int type;
164  };
165 
166  //helper functions to figure out what dimension the ParamType is
167  //and not generate functions which require a higher dimension
168  template <typename T>
169  constexpr auto has1D(int) -> decltype(T::x, bool()) {
170  return true;
171  }
172  template <typename T>
173  constexpr bool has1D(...) {
174  return false;
175  }
176  template <typename T>
177  constexpr auto has2D(int) -> decltype(T::y, bool()) {
178  return true;
179  }
180  template <typename T>
181  constexpr bool has2D(...) {
182  return false;
183  }
184  template <typename T>
185  constexpr auto has3D(int) -> decltype(T::z, bool()) {
186  return true;
187  }
188  template <typename T>
189  constexpr bool has3D(...) {
190  return false;
191  }
192 
193  template <typename InputType>
194  class ParamBin {
195  public:
196  ParamBin() {}
197  virtual ~ParamBin() {}
198  virtual bool pass(const InputType&) const = 0;
199  virtual float operator()(const InputType&) const = 0;
200 
201  protected:
202  //the FUNCTYPE:=funcExpr is designed for future extensions
203  static std::pair<std::string, std::string> readFuncStr(const std::string& inStr) {
204  size_t pos = inStr.find(":=");
205  if (pos != std::string::npos)
206  return std::make_pair(inStr.substr(0, pos), inStr.substr(pos + 2));
207  else
208  return std::make_pair(inStr, std::string(""));
209  }
210  template <typename ParamType>
211  static std::function<float(const ParamType&)> makeFunc(const edm::ParameterSet& config) {
212  auto funcType = readFuncStr(config.getParameter<std::string>("funcType"));
213  auto funcParams = config.getParameter<std::vector<double>>("funcParams");
214  if (funcType.first == "TF1" && has1D<ParamType>(0))
215  return TF1Wrap<ParamType, has1D<ParamType>(0)>(funcType.second, funcParams);
216  else if (funcType.first == "TF2" && has2D<ParamType>(0))
217  return TF2Wrap<ParamType, has2D<ParamType>(0)>(funcType.second, funcParams);
218  else if (funcType.first == "TF3" && has3D<ParamType>(0))
219  return TF3Wrap<ParamType, has3D<ParamType>(0)>(funcType.second, funcParams);
220  else
221  throw cms::Exception("InvalidConfig") << " type " << funcType.first
222  << " is not recognised or is imcompatable with the ParamType, "
223  "configuration is invalid and needs to be fixed"
224  << std::endl;
225  }
226  };
227 
228  template <typename InputType, typename ParamType>
229  class ParamBin1D : public ParamBin<InputType> {
230  private:
231  using XType = decltype(ParamType::x);
233  std::function<float(const ParamType&)> func_;
234 
235  public:
237  : xMin_(config.getParameter<typename ConfigType<XType>::type>("xMin")),
238  xMax_(config.getParameter<typename ConfigType<XType>::type>("xMax")),
239  func_(ParamBin<InputType>::template makeFunc<ParamType>(config)) {}
240  bool pass(const InputType& input) const override { return ParamType(input).pass(xMin_, xMax_); }
241  float operator()(const InputType& input) const override {
242  if (!pass(input))
243  return 0;
244  else
245  return func_(ParamType(input));
246  }
247  };
248 
249  template <typename InputType, typename ParamType>
250  class ParamBin2D : public ParamBin<InputType> {
251  private:
252  using XType = decltype(ParamType::x);
253  using YType = decltype(ParamType::y);
256  std::function<float(const ParamType&)> func_;
257 
258  public:
260  : xMin_(config.getParameter<typename ConfigType<XType>::type>("xMin")),
261  xMax_(config.getParameter<typename ConfigType<XType>::type>("xMax")),
262  yMin_(config.getParameter<typename ConfigType<YType>::type>("yMin")),
263  yMax_(config.getParameter<typename ConfigType<YType>::type>("yMax")),
264  func_(ParamBin<InputType>::template makeFunc<ParamType>(config)) {}
265 
266  bool pass(const InputType& input) const override { return ParamType(input).pass(xMin_, xMax_, yMin_, yMax_); }
267  float operator()(const InputType& input) const override {
268  if (!pass(input))
269  return 0;
270  else
271  return func_(ParamType(input));
272  }
273  };
274 
275  template <typename InputType, typename ParamType>
276  class ParamBin3D : public ParamBin<InputType> {
277  using XType = decltype(ParamType::x);
278  using YType = decltype(ParamType::y);
279  using ZType = decltype(ParamType::z);
280 
284  std::function<float(const ParamType&)> func_;
285 
286  public:
288  : xMin_(config.getParameter<typename ConfigType<XType>::type>("xMin")),
289  xMax_(config.getParameter<typename ConfigType<XType>::type>("xMax")),
290  yMin_(config.getParameter<typename ConfigType<YType>::type>("yMin")),
291  yMax_(config.getParameter<typename ConfigType<YType>::type>("yMax")),
292  zMin_(config.getParameter<typename ConfigType<ZType>::type>("zMin")),
293  zMax_(config.getParameter<typename ConfigType<ZType>::type>("zMax")),
294  func_(ParamBin<InputType>::template makeFunc<ParamType>(config)) {}
295 
296  bool pass(const InputType& input) const override {
297  return ParamType(input).pass(xMin_, xMax_, yMin_, yMax_, zMin_, zMax_);
298  }
299  float operator()(const InputType& input) const override {
300  if (!pass(input))
301  return 0;
302  else
303  return func_(ParamType(input));
304  }
305  };
306 
307  template <typename InputType>
308  class Param {
309  std::vector<std::unique_ptr<ParamBin<InputType>>> bins_;
310 
311  public:
313  std::vector<edm::ParameterSet> binConfigs = config.getParameter<std::vector<edm::ParameterSet>>("bins");
314  for (auto& binConfig : binConfigs)
315  bins_.emplace_back(createParamBin_(binConfig));
316  }
317  float operator()(const InputType& input) const {
318  for (auto& bin : bins_) {
319  if (bin->pass(input))
320  return (*bin)(input);
321  }
322  return -1; //didnt find a suitable bin, just return -1 for now
323  }
324 
325  private:
326  std::unique_ptr<ParamBin<InputType>> createParamBin_(const edm::ParameterSet& config) {
327  std::string type = config.getParameter<std::string>("binType");
328  if (type == "AbsEtaClus")
329  return std::make_unique<ParamBin2D<InputType, AbsEtaNrClus>>(config);
330  else if (type == "AbsEtaClusPhi")
331  return std::make_unique<ParamBin3D<InputType, AbsEtaNrClusPhi>>(config);
332  else if (type == "AbsEtaClusEt")
333  return std::make_unique<ParamBin3D<InputType, AbsEtaNrClusEt>>(config);
334  else
335  throw cms::Exception("InvalidConfig")
336  << " type " << type << " is not recognised, configuration is invalid and needs to be fixed" << std::endl;
337  }
338  };
339 } // namespace egPM
float operator()(const InputType &input) const override
decltype(ParamType::x) XType
constexpr auto has2D(int) -> decltype(T::y, bool())
bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax) const
InputType
Definition: InputType.h:5
bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax, float phiMin, float phiMax) const
constexpr auto has1D(int) -> decltype(T::x, bool())
decltype(ParamType::x) XType
std::function< float(const ParamType &)> func_
ParamBin2D(const edm::ParameterSet &config)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
float operator()(const InputType &input) const
AbsEtaNrClusPhi(const reco::ElectronSeed &seed)
TF2Wrap(const std::string &funcExpr, const std::vector< double > &params)
float operator()(const ParamType &obj)
virtual bool pass(const InputType &) const =0
Definition: config.py:1
float operator()(const InputType &input) const override
float float float z
static std::string const input
Definition: EdmProvDump.cc:50
constexpr auto has3D(int) -> decltype(T::z, bool())
Param(const edm::ParameterSet &config)
AbsEtaNrClus(const reco::ElectronSeed &seed)
ParamBin1D(const edm::ParameterSet &config)
std::function< float(const ParamType &)> func_
static std::function< float(const ParamType &)> makeFunc(const edm::ParameterSet &config)
TF1Wrap(const std::string &funcExpr, const std::vector< double > &params)
bool pass(const InputType &input) const override
float operator()(const ParamType &obj)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float operator()(const InputType &input) const override
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:521
std::unique_ptr< ParamBin< InputType > > createParamBin_(const edm::ParameterSet &config)
bool pass(const InputType &input) const override
TF1Wrap(const std::string &funcExpr, const std::vector< double > &params)
bool pass(float absEtaMin, float absEtaMax, size_t nrClusMin, size_t nrClusMax, float etMin, float etMax) const
AbsEtaNrClusEt(const reco::ElectronSeed &seed)
decltype(ParamType::y) YType
TF3Wrap(const std::string &funcExpr, const std::vector< double > &params)
bool pass(const InputType &input) const override
decltype(ParamType::z) ZType
std::function< float(const ParamType &)> func_
TF3Wrap(const std::string &funcExpr, const std::vector< double > &params)
static std::pair< std::string, std::string > readFuncStr(const std::string &inStr)
dictionary config
Read in AllInOne config in JSON format.
Definition: DiMuonV_cfg.py:29
float x
std::vector< std::unique_ptr< ParamBin< InputType > > > bins_
decltype(ParamType::y) YType
long double T
decltype(ParamType::x) XType
ParamBin3D(const edm::ParameterSet &config)
virtual float operator()(const InputType &) const =0
float operator()(const ParamType &obj)
TF2Wrap(const std::string &funcExpr, const std::vector< double > &params)