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