File indexing completed on 2024-04-06 12:23:37
0001 #ifndef PhysicsTools_MVAComputer_VarProcessor_h
0002 #define PhysicsTools_MVAComputer_VarProcessor_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <algorithm>
0015 #include <vector>
0016
0017 #include "PhysicsTools/MVAComputer/interface/ProcessRegistry.h"
0018 #include "PhysicsTools/MVAComputer/interface/CalibrationFwd.h"
0019 #include "PhysicsTools/MVAComputer/interface/Variable.h"
0020 #include "PhysicsTools/MVAComputer/interface/BitSet.h"
0021
0022 namespace PhysicsTools {
0023
0024
0025 class MVAComputer;
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 class VarProcessor : public ProcessRegistry<VarProcessor, Calibration::VarProcessor, const MVAComputer>::Factory {
0037 public:
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 struct Config {
0048 inline Config() : mask(Variable::FLAG_NONE), origin(0) {}
0049 inline Config(Variable::Flags mask, unsigned int origin) : mask(mask), origin(origin) {}
0050
0051 Variable::Flags mask;
0052 unsigned int origin;
0053 };
0054
0055 class ConfigCtx {
0056 public:
0057 typedef std::vector<Config> Config_t;
0058
0059 typedef Config_t::value_type value_type;
0060 typedef Config_t::size_type size_type;
0061 typedef Config_t::iterator iterator;
0062 typedef Config_t::const_iterator const_iterator;
0063
0064 struct Context {
0065 virtual ~Context() {}
0066 };
0067
0068 ConfigCtx(const std::vector<Variable::Flags> &flags);
0069 ~ConfigCtx() { delete ctx; }
0070
0071 inline size_type size() const { return configs.size(); }
0072 inline const_iterator begin() const { return configs.begin(); }
0073 inline iterator begin() { return configs.begin(); }
0074 inline const_iterator end() const { return configs.end(); }
0075 inline iterator end() { return configs.end(); }
0076 inline void push_back(const Config &config) { configs.push_back(config); }
0077 inline Config &operator[](size_type i) { return configs[i]; }
0078
0079 private:
0080 friend class VarProcessor;
0081
0082 Config_t configs;
0083 VarProcessor *loop;
0084 Context *ctx;
0085 };
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 class LoopCtx {
0096 public:
0097 LoopCtx() : index_(0), offset_(0), size_(0) {}
0098 inline unsigned int &index() { return index_; }
0099 inline unsigned int &offset() { return offset_; }
0100 inline unsigned int &size() { return size_; }
0101
0102 private:
0103 unsigned int index_;
0104 unsigned int offset_;
0105 unsigned int size_;
0106 };
0107
0108 virtual ~VarProcessor();
0109
0110
0111 void configure(ConfigCtx &config);
0112
0113
0114 inline void eval(
0115 double *input, int *conf, double *output, int *outConf, int *loop, LoopCtx &loopCtx, unsigned int offset) const {
0116 ValueIterator iter(inputVars.iter(), input, conf, output, outConf, loop, loopCtx, offset);
0117 eval(iter, nInputVars);
0118 }
0119
0120
0121 void deriv(double *input,
0122 int *conf,
0123 double *output,
0124 int *outConf,
0125 int *loop,
0126 LoopCtx &ctx,
0127 unsigned int offset,
0128 unsigned int in,
0129 unsigned int out,
0130 std::vector<double> &deriv) const;
0131
0132 enum LoopStatus { kStop, kNext, kReset, kSkip };
0133
0134 virtual LoopStatus loop(
0135 double *output, int *outConf, unsigned int nOutput, LoopCtx &ctx, unsigned int &nOffset) const {
0136 return kStop;
0137 }
0138
0139
0140 struct Dummy {};
0141 typedef Dummy *PluginFunctionPrototype();
0142
0143 protected:
0144
0145
0146
0147
0148
0149 struct ConfIterator {
0150 public:
0151
0152 ConfIterator &operator()(Variable::Flags mask) {
0153 config[cur()].mask = (Variable::Flags)(config[cur()].mask & mask);
0154 return *this;
0155 }
0156
0157
0158 ConfIterator &operator<<(Config config_) {
0159 config.push_back(config_);
0160 return *this;
0161 }
0162
0163
0164 ConfIterator &operator<<(Variable::Flags mask) { return *this << Config(mask, 0); }
0165
0166
0167 ConfIterator &operator<<(const ConfIterator &origin) {
0168 return *this << Config(config[origin.cur()].mask, origin.cur());
0169 }
0170
0171
0172 Variable::Flags operator*() const { return config[cur()].mask; }
0173
0174
0175 inline operator bool() const { return cur; }
0176
0177
0178 ConfIterator &operator++() {
0179 ++cur;
0180 return *this;
0181 }
0182
0183
0184 inline ConfIterator operator++(int dummy) {
0185 ConfIterator orig = *this;
0186 operator++();
0187 return orig;
0188 }
0189
0190 protected:
0191 friend class VarProcessor;
0192
0193 ConfIterator(BitSet::Iterator cur, ConfigCtx &config) : cur(cur), config(config) {}
0194
0195 private:
0196 BitSet::Iterator cur;
0197 ConfigCtx &config;
0198 };
0199
0200
0201
0202
0203
0204
0205 struct ValueIterator {
0206 public:
0207
0208 inline unsigned int size() const { return loop ? (conf[1] - conf[0]) : 1; }
0209
0210
0211 inline double *begin() const { return values; }
0212
0213
0214 inline double *end() const { return values + size(); }
0215
0216
0217 inline bool empty() const { return begin() == end(); }
0218
0219
0220 inline double operator*() { return *values; }
0221
0222
0223 inline double operator[](unsigned int idx) { return values[idx]; }
0224
0225
0226 inline ValueIterator &operator<<(double value) {
0227 *output++ = value;
0228 return *this;
0229 }
0230
0231
0232 inline void operator()() {
0233 int pos = output - start;
0234 if (*++outConf > pos)
0235 output = start + *outConf;
0236 else
0237 *outConf = pos;
0238 }
0239
0240
0241 inline void operator()(double value) {
0242 *this << value;
0243 (*this)();
0244 }
0245
0246
0247 inline operator bool() const { return cur; }
0248
0249 inline LoopCtx &loopCtx() { return ctx; }
0250
0251
0252 ValueIterator &operator++() {
0253 BitSet::size_t orig = cur();
0254 if (++cur) {
0255 unsigned int prev = *conf;
0256 conf += cur() - orig;
0257 values += *conf - prev;
0258 if (loop && conf >= loop) {
0259 values += offset;
0260 loop = nullptr;
0261 }
0262 }
0263 return *this;
0264 }
0265
0266
0267 inline ValueIterator operator++(int dummy) {
0268 ValueIterator orig = *this;
0269 operator++();
0270 return orig;
0271 }
0272
0273 protected:
0274 friend class VarProcessor;
0275
0276 ValueIterator(BitSet::Iterator cur,
0277 double *values,
0278 int *conf,
0279 double *output,
0280 int *outConf,
0281 int *loop,
0282 LoopCtx &ctx,
0283 unsigned int offset)
0284 : cur(cur),
0285 ctx(ctx),
0286 offset(offset),
0287 start(values + offset),
0288 values(values),
0289 conf(conf),
0290 loop(loop),
0291 output(output + offset),
0292 outConf(outConf) {
0293 this->conf += cur();
0294 this->values += *this->conf;
0295 if (loop && this->conf >= loop) {
0296 this->values += offset;
0297 this->loop = nullptr;
0298 }
0299 }
0300
0301 private:
0302 BitSet::Iterator cur;
0303 LoopCtx &ctx;
0304 const unsigned int offset;
0305 double *const start;
0306 double *values;
0307 const int *conf;
0308 const int *loop;
0309 double *output;
0310 int *outConf;
0311 };
0312
0313 typedef ProcessRegistry<VarProcessor, Calibration::VarProcessor, const MVAComputer> Registry;
0314
0315 VarProcessor(const char *name, const Calibration::VarProcessor *calib, const MVAComputer *computer);
0316
0317
0318 virtual void configure(ConfIterator iter, unsigned int n) = 0;
0319
0320
0321 virtual ConfigCtx::Context *configureLoop(ConfigCtx::Context *ctx,
0322 ConfigCtx::iterator begin,
0323 ConfigCtx::iterator cur,
0324 ConfigCtx::iterator end);
0325
0326
0327 virtual void eval(ValueIterator iter, unsigned int n) const = 0;
0328
0329
0330 virtual std::vector<double> deriv(ValueIterator iter, unsigned int n) const { return std::vector<double>(); }
0331
0332 protected:
0333 const MVAComputer *computer;
0334
0335 private:
0336
0337 BitSet inputVars;
0338 unsigned int nInputVars;
0339 };
0340
0341 template <>
0342 VarProcessor *ProcessRegistry<VarProcessor, Calibration::VarProcessor, const MVAComputer>::Factory::create(
0343 const char *, const Calibration::VarProcessor *, const MVAComputer *);
0344
0345 }
0346
0347 #endif