00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "FWCore/Utilities/interface/Exception.h"
00017
00018 #include "FWCore/PluginManager/interface/PluginManager.h"
00019 #include "FWCore/PluginManager/interface/PluginFactory.h"
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021
00022 #include "PhysicsTools/MVAComputer/interface/VarProcessor.h"
00023 #include "PhysicsTools/MVAComputer/interface/Calibration.h"
00024 #include "PhysicsTools/MVAComputer/interface/BitSet.h"
00025
00026
00027
00028 #ifdef DEBUG_DERIV
00029 # include <Reflex/Tools.h>
00030 #endif
00031
00032 EDM_REGISTER_PLUGINFACTORY(PhysicsTools::VarProcessor::PluginFactory,
00033 "PhysicsToolsMVAComputer");
00034
00035 namespace PhysicsTools {
00036
00037 VarProcessor::VarProcessor(const char *name,
00038 const Calibration::VarProcessor *calib,
00039 const MVAComputer *computer) :
00040 computer(computer),
00041 inputVars(Calibration::convert(calib->inputVars)),
00042 nInputVars(inputVars.bits())
00043 {
00044 }
00045
00046 VarProcessor::~VarProcessor()
00047 {
00048 inputVars = BitSet(0);
00049 nInputVars = 0;
00050 }
00051
00052 void VarProcessor::configure(ConfigCtx &config)
00053 {
00054 ConfigCtx::size_type pos = config.size();
00055 if (pos != inputVars.size())
00056 return;
00057
00058 ConfIterator iter(inputVars.iter(), config);
00059 configure(iter, nInputVars);
00060
00061 VarProcessor *loop = config.loop ? config.loop : this;
00062 ConfigCtx::Context *ctx =
00063 loop->configureLoop(config.ctx, config.begin(),
00064 config.begin() + pos, config.end());
00065
00066 if (ctx != config.ctx) {
00067 delete config.ctx;
00068 config.ctx = ctx;
00069 }
00070
00071 if (config.loop && !ctx)
00072 config.loop = 0;
00073 else if (!config.loop && ctx)
00074 config.loop = this;
00075 }
00076
00077 VarProcessor::ConfigCtx::ConfigCtx(std::vector<Variable::Flags> flags) :
00078 loop(0), ctx(0)
00079 {
00080 for(std::vector<Variable::Flags>::const_iterator iter = flags.begin();
00081 iter != flags.end(); ++iter)
00082 configs.push_back(Config(*iter, 1));
00083 }
00084
00085 VarProcessor::ConfigCtx::Context *
00086 VarProcessor::configureLoop(ConfigCtx::Context *ctx, ConfigCtx::iterator begin,
00087 ConfigCtx::iterator cur, ConfigCtx::iterator end)
00088 {
00089 return 0;
00090 }
00091
00092 template<>
00093 VarProcessor *ProcessRegistry<VarProcessor, Calibration::VarProcessor,
00094 const MVAComputer>::Factory::create(
00095 const char *name, const Calibration::VarProcessor *calib,
00096 const MVAComputer *parent)
00097 {
00098 VarProcessor *result = ProcessRegistry::create(name, calib, parent);
00099 if (!result) {
00100
00101 try {
00102 delete VarProcessor::PluginFactory::get()->create(
00103 std::string("VarProcessor/") + name);
00104 result = ProcessRegistry::create(name, calib, parent);
00105 } catch(const cms::Exception &e) {
00106
00107
00108
00109
00110 edm::LogError("CannotBuildMVAProc")
00111 << "Caught exception when building processor: "
00112 << name << " message: " << std::endl
00113 << e.what() << std::endl;
00114 throw e;
00115 }
00116 }
00117 return result;
00118 }
00119
00120 void VarProcessor::deriv(double *input, int *conf, double *output,
00121 int *outConf, int *loop, unsigned int offset,
00122 unsigned int in, unsigned int out_,
00123 std::vector<double> &deriv) const
00124 {
00125 ValueIterator iter(inputVars.iter(), input, conf,
00126 output, outConf, loop, offset);
00127
00128 eval(iter, nInputVars);
00129
00130 std::vector<double> matrix = this->deriv(iter, nInputVars);
00131
00132 unsigned int size = 0;
00133 while(iter)
00134 size += (iter++).size();
00135 unsigned int out = matrix.empty() ? 0 : (matrix.size() / size);
00136
00137 if (matrix.size() != out * size ||
00138 (out > 1 && (int)out != outConf[out_] - outConf[0]))
00139 throw cms::Exception("VarProcessor")
00140 << "Derivative matrix implausible size in "
00141 << typeid(*this).name() << "."
00142 << std::endl;
00143
00144 #ifdef DEBUG_DERIV
00145 if (!matrix.empty()) {
00146 std::cout << "---------------- "
00147 << ROOT::Reflex::Tools::Demangle(typeid(*this))
00148 << std::endl;
00149 for(unsigned int i = 0; i < out; i++) {
00150 for(unsigned int j = 0; j < size; j++)
00151 std::cout << matrix.at(i*size+j) << "\t";
00152 std::cout << std::endl;
00153 }
00154 std::cout << "----------------" << std::endl;
00155 }
00156
00157 std::cout << "======= in = " << in << ", size = " << size
00158 << ", out = " << out << ", matrix = " << matrix.size()
00159 << std::endl;
00160 #endif
00161
00162 unsigned int sz = (outConf[out_] - in) * in;
00163 unsigned int oldSz = deriv.size();
00164 if (oldSz < sz)
00165 deriv.resize(sz);
00166
00167 double *begin = &deriv.front() + (outConf[0] - in + offset) * in;
00168 double *end = begin + out * in;
00169 if (begin < &deriv.front() + oldSz)
00170 std::fill(begin, end, 0.0);
00171
00172 if (matrix.empty())
00173 return;
00174
00175 double *m0 = &matrix.front();
00176 BitSet::Iterator cur = inputVars.iter();
00177 for(unsigned int i = 0; i < nInputVars; i++, ++cur) {
00178 #ifdef DEBUG_DERIV
00179 std::cout << " inputvar " << i << std::endl;
00180 #endif
00181 int *curConf = conf + cur();
00182 unsigned int pos = *curConf;
00183 #ifdef DEBUG_DERIV
00184 std::cout << " -> cur = " << cur() << ", pos = "
00185 << pos << std::endl;
00186 #endif
00187 if (loop && curConf >= loop) {
00188 pos += offset;
00189 loop = 0;
00190 }
00191
00192 unsigned int n = loop ? (curConf[1] - curConf[0]) : 1;
00193 for(unsigned int j = 0; j < n; m0++, j++, pos++) {
00194 #ifdef DEBUG_DERIV
00195 std::cout << " multip " << j << std::endl;
00196 #endif
00197 double *p = begin;
00198 if (pos >= in) {
00199 #ifdef DEBUG_DERIV
00200 std::cout << " deriv " << (pos - in)
00201 << std::endl;
00202 #endif
00203 const double *q = &deriv.front() +
00204 (pos - in) * in;
00205 for(const double *m = m0; p < end;
00206 m += size, q -= in)
00207 for(unsigned int k = 0; k < in; k++)
00208 *p++ += *m * *q++;
00209 } else {
00210 #ifdef DEBUG_DERIV
00211 std::cout << " in " << pos << std::endl;
00212 #endif
00213 for(const double *m = m0; p < end;
00214 m += size, p += in)
00215 p[pos] += *m;
00216 }
00217 }
00218 }
00219
00220 #ifdef DEBUG_DERIV
00221 std::cout << "================" << std::endl;
00222 for(const double *p = &deriv.front();
00223 p != &deriv.front() + deriv.size();) {
00224 for(unsigned int j = 0; j < in; j++)
00225 std::cout << *p++ << "\t";
00226 std::cout << std::endl;
00227 }
00228 std::cout << "================" << std::endl;
00229 #endif
00230 }
00231
00232 }