00001 #ifndef PhysicsTools_MVAComputer_VarProcessor_h
00002 #define PhysicsTools_MVAComputer_VarProcessor_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <algorithm>
00016 #include <vector>
00017
00018 #include "PhysicsTools/MVAComputer/interface/ProcessRegistry.h"
00019 #include "PhysicsTools/MVAComputer/interface/CalibrationFwd.h"
00020 #include "PhysicsTools/MVAComputer/interface/Variable.h"
00021 #include "PhysicsTools/MVAComputer/interface/BitSet.h"
00022
00023 namespace PhysicsTools {
00024
00025
00026 class MVAComputer;
00027
00037 class VarProcessor :
00038 public ProcessRegistry<VarProcessor,
00039 Calibration::VarProcessor,
00040 const MVAComputer>::Factory {
00041 public:
00051 struct Config {
00052 inline Config() : mask(Variable::FLAG_NONE), origin(0) {}
00053 inline Config(Variable::Flags mask, unsigned int origin) :
00054 mask(mask), origin(origin) {}
00055
00056 Variable::Flags mask;
00057 unsigned int origin;
00058 };
00059
00060 class ConfigCtx {
00061 public:
00062 typedef std::vector<Config> Config_t;
00063
00064 typedef Config_t::value_type value_type;
00065 typedef Config_t::size_type size_type;
00066 typedef Config_t::iterator iterator;
00067 typedef Config_t::const_iterator const_iterator;
00068
00069 struct Context { virtual ~Context() {} };
00070
00071 ConfigCtx(std::vector<Variable::Flags> flags);
00072 ~ConfigCtx() { delete ctx; }
00073
00074 inline size_type size() const { return configs.size(); }
00075 inline const_iterator begin() const { return configs.begin(); }
00076 inline iterator begin() { return configs.begin(); }
00077 inline const_iterator end() const { return configs.end(); }
00078 inline iterator end() { return configs.end(); }
00079 inline void push_back(const Config &config) { configs.push_back(config); }
00080 inline Config &operator [] (size_type i) { return configs[i]; }
00081
00082 private:
00083 friend class VarProcessor;
00084
00085 Config_t configs;
00086 VarProcessor *loop;
00087 Context *ctx;
00088 };
00089
00090 virtual ~VarProcessor();
00091
00093 void configure(ConfigCtx &config);
00094
00096 inline void
00097 eval(double *input, int *conf, double *output, int *outConf,
00098 int *loop, unsigned int offset) const
00099 {
00100 ValueIterator iter(inputVars.iter(), input, conf,
00101 output, outConf, loop, offset);
00102 eval(iter, nInputVars);
00103 }
00104
00105 enum LoopStatus { kStop, kNext, kReset, kSkip };
00106
00107 virtual LoopStatus loop(double *output, int *outConf,
00108 unsigned int nOutput,
00109 unsigned int &nOffset) const
00110 { return kStop; }
00111
00112 protected:
00118 struct ConfIterator {
00119 public:
00121 ConfIterator &operator () (Variable::Flags mask)
00122 {
00123 config[cur()].mask =
00124 (Variable::Flags)(config[cur()].mask & mask);
00125 return *this;
00126 }
00127
00129 ConfIterator &operator << (Config config_)
00130 { config.push_back(config_); return *this; }
00131
00133 ConfIterator &operator << (Variable::Flags mask)
00134 { return *this << Config(mask, 0); }
00135
00137 ConfIterator &operator << (const ConfIterator &origin)
00138 { return *this << Config(config[origin.cur()].mask, origin.cur()); }
00139
00141 Variable::Flags operator * () const
00142 { return config[cur()].mask; }
00143
00145 inline operator bool() const { return cur; }
00146
00148 ConfIterator &operator ++ () { ++cur; return *this; }
00149
00151 inline ConfIterator operator ++ (int dummy)
00152 { ConfIterator orig = *this; operator ++ (); return orig; }
00153
00154 protected:
00155 friend class VarProcessor;
00156
00157 ConfIterator(BitSet::Iterator cur, ConfigCtx &config) :
00158 cur(cur), config(config) {}
00159
00160 private:
00161 BitSet::Iterator cur;
00162 ConfigCtx &config;
00163 };
00164
00170 struct ValueIterator {
00171 public:
00173 inline unsigned int size() const
00174 { return loop ? (conf[1] - conf[0]) : 1; }
00175
00177 inline double *begin() const { return values; }
00178
00180 inline double *end() const { return values + size(); }
00181
00183 inline bool empty() const { return begin() == end(); }
00184
00186 inline double operator * ()
00187 { return *values; }
00188
00190 inline double operator [] (unsigned int idx)
00191 { return values[idx]; }
00192
00194 inline ValueIterator &operator << (double value)
00195 { *output++ = value; return *this; }
00196
00198 inline void operator () ()
00199 {
00200 int pos = output - start;
00201 if (*++outConf > pos)
00202 output = start + *outConf;
00203 else
00204 *outConf = pos;
00205 }
00206
00208 inline void operator () (double value)
00209 { *this << value; (*this)(); }
00210
00212 inline operator bool() const { return cur; }
00213
00215 ValueIterator &operator ++ ()
00216 {
00217 BitSet::size_t orig = cur();
00218 if (++cur) {
00219 unsigned int prev = *conf;
00220 conf += cur() - orig;
00221 values += *conf - prev;
00222 if (loop && conf >= loop) {
00223 values += offset;
00224 loop = 0;
00225 }
00226 }
00227 return *this;
00228 }
00229
00231 inline ValueIterator operator ++ (int dummy)
00232 { ValueIterator orig = *this; operator ++ (); return orig; }
00233
00234 protected:
00235 friend class VarProcessor;
00236
00237 ValueIterator(BitSet::Iterator cur, double *values,
00238 int *conf, double *output, int *outConf,
00239 int *loop, unsigned int offset) :
00240 cur(cur), offset(offset), start(values + offset),
00241 values(values), conf(conf), loop(loop),
00242 output(output + offset), outConf(outConf)
00243 {
00244 this->conf += cur();
00245 this->values += *this->conf;
00246 if (loop && this->conf >= loop) {
00247 this->values += offset;
00248 this->loop = 0;
00249 }
00250 }
00251
00252 private:
00253 BitSet::Iterator cur;
00254 const unsigned int offset;
00255 double *const start;
00256 double *values;
00257 const int *conf;
00258 const int *loop;
00259 double *output;
00260 int *outConf;
00261 };
00262
00263 typedef ProcessRegistry<VarProcessor,
00264 Calibration::VarProcessor,
00265 const MVAComputer> Registry;
00266
00267 VarProcessor(const char *name, const Calibration::VarProcessor *calib,
00268 const MVAComputer *computer);
00269
00271 virtual void configure(ConfIterator iter, unsigned int n) = 0;
00272
00274 virtual ConfigCtx::Context *
00275 configureLoop(ConfigCtx::Context *ctx, ConfigCtx::iterator begin,
00276 ConfigCtx::iterator cur, ConfigCtx::iterator end);
00277
00279 virtual void eval(ValueIterator iter, unsigned int n) const = 0;
00280
00281 protected:
00282 const MVAComputer *computer;
00283
00284 private:
00286 BitSet inputVars;
00287 unsigned int nInputVars;
00288 };
00289
00290 }
00291
00292 #endif // PhysicsTools_MVAComputer_VarProcessor_h