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