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 "FWCore/PluginManager/interface/PluginFactory.h"
00019
00020 #include "PhysicsTools/MVAComputer/interface/ProcessRegistry.h"
00021 #include "PhysicsTools/MVAComputer/interface/CalibrationFwd.h"
00022 #include "PhysicsTools/MVAComputer/interface/Variable.h"
00023 #include "PhysicsTools/MVAComputer/interface/BitSet.h"
00024
00025 namespace PhysicsTools {
00026
00027
00028 class MVAComputer;
00029
00039 class VarProcessor :
00040 public ProcessRegistry<VarProcessor,
00041 Calibration::VarProcessor,
00042 const MVAComputer>::Factory {
00043 public:
00053 struct Config {
00054 inline Config() : mask(Variable::FLAG_NONE), origin(0) {}
00055 inline Config(Variable::Flags mask, unsigned int origin) :
00056 mask(mask), origin(origin) {}
00057
00058 Variable::Flags mask;
00059 unsigned int origin;
00060 };
00061
00062 class ConfigCtx {
00063 public:
00064 typedef std::vector<Config> Config_t;
00065
00066 typedef Config_t::value_type value_type;
00067 typedef Config_t::size_type size_type;
00068 typedef Config_t::iterator iterator;
00069 typedef Config_t::const_iterator const_iterator;
00070
00071 struct Context { virtual ~Context() {} };
00072
00073 ConfigCtx(std::vector<Variable::Flags> flags);
00074 ~ConfigCtx() { delete ctx; }
00075
00076 inline size_type size() const { return configs.size(); }
00077 inline const_iterator begin() const { return configs.begin(); }
00078 inline iterator begin() { return configs.begin(); }
00079 inline const_iterator end() const { return configs.end(); }
00080 inline iterator end() { return configs.end(); }
00081 inline void push_back(const Config &config) { configs.push_back(config); }
00082 inline Config &operator [] (size_type i) { return configs[i]; }
00083
00084 private:
00085 friend class VarProcessor;
00086
00087 Config_t configs;
00088 VarProcessor *loop;
00089 Context *ctx;
00090 };
00091
00092 virtual ~VarProcessor();
00093
00095 void configure(ConfigCtx &config);
00096
00098 inline void
00099 eval(double *input, int *conf, double *output, int *outConf,
00100 int *loop, unsigned int offset) const
00101 {
00102 ValueIterator iter(inputVars.iter(), input, conf,
00103 output, outConf, loop, offset);
00104 eval(iter, nInputVars);
00105 }
00106
00108 void deriv(double *input, int *conf, double *output, int *outConf,
00109 int *loop, unsigned int offset, unsigned int in,
00110 unsigned int out, std::vector<double> &deriv) const;
00111
00112 enum LoopStatus { kStop, kNext, kReset, kSkip };
00113
00114 virtual LoopStatus loop(double *output, int *outConf,
00115 unsigned int nOutput,
00116 unsigned int &nOffset) const
00117 { return kStop; }
00118
00119 struct Dummy {};
00120 typedef edmplugin::PluginFactory<Dummy*()> PluginFactory;
00121
00122 protected:
00128 struct ConfIterator {
00129 public:
00131 ConfIterator &operator () (Variable::Flags mask)
00132 {
00133 config[cur()].mask =
00134 (Variable::Flags)(config[cur()].mask & mask);
00135 return *this;
00136 }
00137
00139 ConfIterator &operator << (Config config_)
00140 { config.push_back(config_); return *this; }
00141
00143 ConfIterator &operator << (Variable::Flags mask)
00144 { return *this << Config(mask, 0); }
00145
00147 ConfIterator &operator << (const ConfIterator &origin)
00148 { return *this << Config(config[origin.cur()].mask, origin.cur()); }
00149
00151 Variable::Flags operator * () const
00152 { return config[cur()].mask; }
00153
00155 inline operator bool() const { return cur; }
00156
00158 ConfIterator &operator ++ () { ++cur; return *this; }
00159
00161 inline ConfIterator operator ++ (int dummy)
00162 { ConfIterator orig = *this; operator ++ (); return orig; }
00163
00164 protected:
00165 friend class VarProcessor;
00166
00167 ConfIterator(BitSet::Iterator cur, ConfigCtx &config) :
00168 cur(cur), config(config) {}
00169
00170 private:
00171 BitSet::Iterator cur;
00172 ConfigCtx &config;
00173 };
00174
00180 struct ValueIterator {
00181 public:
00183 inline unsigned int size() const
00184 { return loop ? (conf[1] - conf[0]) : 1; }
00185
00187 inline double *begin() const { return values; }
00188
00190 inline double *end() const { return values + size(); }
00191
00193 inline bool empty() const { return begin() == end(); }
00194
00196 inline double operator * ()
00197 { return *values; }
00198
00200 inline double operator [] (unsigned int idx)
00201 { return values[idx]; }
00202
00204 inline ValueIterator &operator << (double value)
00205 { *output++ = value; return *this; }
00206
00208 inline void operator () ()
00209 {
00210 int pos = output - start;
00211 if (*++outConf > pos)
00212 output = start + *outConf;
00213 else
00214 *outConf = pos;
00215 }
00216
00218 inline void operator () (double value)
00219 { *this << value; (*this)(); }
00220
00222 inline operator bool() const { return cur; }
00223
00225 ValueIterator &operator ++ ()
00226 {
00227 BitSet::size_t orig = cur();
00228 if (++cur) {
00229 unsigned int prev = *conf;
00230 conf += cur() - orig;
00231 values += *conf - prev;
00232 if (loop && conf >= loop) {
00233 values += offset;
00234 loop = 0;
00235 }
00236 }
00237 return *this;
00238 }
00239
00241 inline ValueIterator operator ++ (int dummy)
00242 { ValueIterator orig = *this; operator ++ (); return orig; }
00243
00244 protected:
00245 friend class VarProcessor;
00246
00247 ValueIterator(BitSet::Iterator cur, double *values,
00248 int *conf, double *output, int *outConf,
00249 int *loop, unsigned int offset) :
00250 cur(cur), offset(offset), start(values + offset),
00251 values(values), conf(conf), loop(loop),
00252 output(output + offset), outConf(outConf)
00253 {
00254 this->conf += cur();
00255 this->values += *this->conf;
00256 if (loop && this->conf >= loop) {
00257 this->values += offset;
00258 this->loop = 0;
00259 }
00260 }
00261
00262 private:
00263 BitSet::Iterator cur;
00264 const unsigned int offset;
00265 double *const start;
00266 double *values;
00267 const int *conf;
00268 const int *loop;
00269 double *output;
00270 int *outConf;
00271 };
00272
00273 typedef ProcessRegistry<VarProcessor,
00274 Calibration::VarProcessor,
00275 const MVAComputer> Registry;
00276
00277 VarProcessor(const char *name, const Calibration::VarProcessor *calib,
00278 const MVAComputer *computer);
00279
00281 virtual void configure(ConfIterator iter, unsigned int n) = 0;
00282
00284 virtual ConfigCtx::Context *
00285 configureLoop(ConfigCtx::Context *ctx, ConfigCtx::iterator begin,
00286 ConfigCtx::iterator cur, ConfigCtx::iterator end);
00287
00289 virtual void eval(ValueIterator iter, unsigned int n) const = 0;
00290
00292 virtual std::vector<double> deriv(ValueIterator iter,
00293 unsigned int n) const
00294 { return std::vector<double>(); }
00295
00296 protected:
00297 const MVAComputer *computer;
00298
00299 private:
00301 BitSet inputVars;
00302 unsigned int nInputVars;
00303 };
00304
00305 template<>
00306 VarProcessor *ProcessRegistry<VarProcessor, Calibration::VarProcessor,
00307 const MVAComputer>::Factory::create(
00308 const char*, const Calibration::VarProcessor*, const MVAComputer*);
00309
00310 }
00311
00312 #define MVA_COMPUTER_DEFINE_PLUGIN(T) \
00313 DEFINE_EDM_PLUGIN(::PhysicsTools::VarProcessor::PluginFactory, \
00314 ::PhysicsTools::VarProcessor::Dummy, \
00315 "VarProcessor/" #T)
00316
00317 #endif // PhysicsTools_MVAComputer_VarProcessor_h