CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/PhysicsTools/MVAComputer/interface/VarProcessor.h

Go to the documentation of this file.
00001 #ifndef PhysicsTools_MVAComputer_VarProcessor_h
00002 #define PhysicsTools_MVAComputer_VarProcessor_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     MVAComputer
00006 // Class  :     VarProcessor
00007 //
00008 
00009 //
00010 // Author:      Christophe Saout <christophe.saout@cern.ch>
00011 // Created:     Sat Apr 24 15:18 CEST 2007
00012 // $Id: VarProcessor.h,v 1.9 2009/06/03 09:50:14 saout Exp $
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 // forward declaration
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 } // namespace PhysicsTools
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