CMS 3D CMS Logo

VarProcessor.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: MVAComputer
4 // Class : VarProcessor
5 //
6 
7 // Implementation:
8 // Base class for variable processors. Basically only passes calls
9 // through to virtual methods in the actual implementation daughter class.
10 //
11 // Author: Christophe Saout
12 // Created: Sat Apr 24 15:18 CEST 2007
13 //
14 
15 #include <cassert>
16 
18 
22 
26 #include "PhysicsTools/MVAComputer/interface/ProcessRegistry.icc"
27 
28 // #define DEBUG_DERIV
29 
30 #ifdef DEBUG_DERIV
32 #endif
33 
35 EDM_REGISTER_PLUGINFACTORY(VPPluginFactory, "PhysicsToolsMVAComputer");
36 
37 namespace PhysicsTools {
38 
40  : computer(computer), inputVars(Calibration::convert(calib->inputVars)), nInputVars(inputVars.bits()) {}
41 
43  inputVars = BitSet(0);
44  nInputVars = 0;
45  }
46 
49  if (pos != inputVars.size())
50  return;
51 
53  configure(iter, nInputVars);
54 
55  VarProcessor *loop = config.loop ? config.loop : this;
56  ConfigCtx::Context *ctx = loop->configureLoop(config.ctx, config.begin(), config.begin() + pos, config.end());
57 
58  if (ctx != config.ctx) {
59  delete config.ctx;
60  config.ctx = ctx;
61  }
62 
63  if (config.loop && !ctx)
64  config.loop = nullptr;
65  else if (!config.loop && ctx)
66  config.loop = this;
67  }
68 
69  VarProcessor::ConfigCtx::ConfigCtx(const std::vector<Variable::Flags> &flags) : loop(nullptr), ctx(nullptr) {
70  for (std::vector<Variable::Flags>::const_iterator iter = flags.begin(); iter != flags.end(); ++iter)
71  configs.push_back(Config(*iter, 1));
72  }
73 
75  ConfigCtx::iterator begin,
77  ConfigCtx::iterator end) {
78  return nullptr;
79  }
80 
81  template <>
83  const char *name, const Calibration::VarProcessor *calib, const MVAComputer *parent) {
85  if (!result) {
86  // try to load the shared library and retry
87  try {
88  std::unique_ptr<PhysicsTools::VarProcessor::Dummy> tmp{
89  VPPluginFactory::get()->create(std::string("VarProcessor/") + name)};
91  } catch (const cms::Exception &e) {
92  // caller will have to deal with the null pointer
93  // in principle this will just give a slightly more
94  // descriptive error message (and will rethrow anyhow)
95 
96  edm::LogError("CannotBuildMVAProc")
97  << "Caught exception when building processor: " << name << " message: " << std::endl
98  << e.what() << std::endl;
99  throw e;
100  }
101  }
102  return result;
103  }
104 
106  int *conf,
107  double *output,
108  int *outConf,
109  int *loop,
110  LoopCtx &ctx,
111  unsigned int offset,
112  unsigned int in,
113  unsigned int out_,
114  std::vector<double> &deriv) const {
115  ValueIterator iter(inputVars.iter(), input, conf, output, outConf, loop, ctx, offset);
116 
117  eval(iter, nInputVars);
118 
119  std::vector<double> matrix = this->deriv(iter, nInputVars);
120 
121  unsigned int size = 0;
122  while (iter)
123  size += (iter++).size();
124  bool empty = matrix.empty();
125  assert(size != 0 || empty);
126  unsigned int out = empty ? 0 : (matrix.size() / size);
127 
128  if (matrix.size() != out * size || (out > 1 && (int)out != outConf[out_] - outConf[0]))
129  throw cms::Exception("VarProcessor")
130  << "Derivative matrix implausible size in " << typeid(*this).name() << "." << std::endl;
131 
132 #ifdef DEBUG_DERIV
133  if (!matrix.empty()) {
134  std::string demangledName;
135  edm::typeDemangle(typeid(*this).name(), demangledName);
136  std::cout << demangledName << std::endl;
137  for (unsigned int i = 0; i < out; i++) {
138  for (unsigned int j = 0; j < size; j++)
139  std::cout << matrix.at(i * size + j) << "\t";
140  std::cout << std::endl;
141  }
142  std::cout << "----------------" << std::endl;
143  }
144 
145  std::cout << "======= in = " << in << ", size = " << size << ", out = " << out << ", matrix = " << matrix.size()
146  << std::endl;
147 #endif
148 
149  unsigned int sz = (outConf[out_] - in) * in;
150  unsigned int oldSz = deriv.size();
151  if (oldSz < sz)
152  deriv.resize(sz);
153 
154  double *begin = &deriv.front() + (outConf[0] - in + offset) * in;
155  double *end = begin + out * in;
156  if (begin < &deriv.front() + oldSz)
157  std::fill(begin, end, 0.0);
158 
159  if (matrix.empty())
160  return;
161 
162  double *m0 = &matrix.front();
164  for (unsigned int i = 0; i < nInputVars; i++, ++cur) {
165 #ifdef DEBUG_DERIV
166  std::cout << " inputvar " << i << std::endl;
167 #endif
168  int *curConf = conf + cur();
169  unsigned int pos = *curConf;
170 #ifdef DEBUG_DERIV
171  std::cout << " -> cur = " << cur() << ", pos = " << pos << std::endl;
172 #endif
173  if (loop && curConf >= loop) {
174  pos += offset;
175  loop = nullptr;
176  }
177 
178  unsigned int n = loop ? (curConf[1] - curConf[0]) : 1;
179  for (unsigned int j = 0; j < n; m0++, j++, pos++) {
180 #ifdef DEBUG_DERIV
181  std::cout << " multip " << j << std::endl;
182 #endif
183  double *p = begin;
184  if (pos >= in) {
185 #ifdef DEBUG_DERIV
186  std::cout << " deriv " << (pos - in) << std::endl;
187 #endif
188  const double *q = &deriv.front() + (pos - in) * in;
189  for (const double *m = m0; p < end; m += size, q -= in)
190  for (unsigned int k = 0; k < in; k++)
191  *p++ += *m * *q++;
192  } else {
193 #ifdef DEBUG_DERIV
194  std::cout << " in " << pos << std::endl;
195 #endif
196  for (const double *m = m0; p < end; m += size, p += in)
197  p[pos] += *m;
198  }
199  }
200  }
201 
202 #ifdef DEBUG_DERIV
203  std::cout << "================" << std::endl;
204  for (const double *p = &deriv.front(); p != &deriv.front() + deriv.size();) {
205  for (unsigned int j = 0; j < in; j++)
206  std::cout << *p++ << "\t";
207  std::cout << std::endl;
208  }
209  std::cout << "================" << std::endl;
210 #endif
211  }
212 
213 } // namespace PhysicsTools
214 
215 // Force instantiation of its templated static methods.
218  PhysicsTools::MVAComputer const>::unregisterProcess(char const *);
222  registerProcess(char const *,
225  PhysicsTools::MVAComputer const> const *);
virtual ConfigCtx::Context * configureLoop(ConfigCtx::Context *ctx, ConfigCtx::iterator begin, ConfigCtx::iterator cur, ConfigCtx::iterator end)
virtual loop configure method
Definition: VarProcessor.cc:74
Iterator iter() const
create iterator over all set bits
Definition: BitSet.h:179
static Base_t * create(const char *name, const CalibBase_t *calib, Parent_t *parent)
create an instance of name, given a calibration calib and parent parent
void configure(ConfigCtx &config)
called from the discriminator computer to configure processor
Definition: VarProcessor.cc:47
Definition: config.py:1
Log< level::Error, false > LogError
assert(be >=bs)
ConfigCtx(const std::vector< Variable::Flags > &flags)
Definition: VarProcessor.cc:69
static std::string const input
Definition: EdmProvDump.cc:50
edmplugin::PluginFactory< PhysicsTools::VarProcessor::PluginFunctionPrototype > VPPluginFactory
Definition: VarProcessor.cc:34
Main interface class to the generic discriminator computer framework.
Definition: MVAComputer.h:39
Iterator to loop over the input/output variable configuration.
Definition: VarProcessor.h:149
BitSet inputVars
bit set to select the input variables to be passed to this processor
Definition: VarProcessor.h:337
A compact container for storing single bits.
Definition: BitSet.h:29
def convert(infile, ofile)
void deriv(double *input, int *conf, double *output, int *outConf, int *loop, LoopCtx &ctx, unsigned int offset, unsigned int in, unsigned int out, std::vector< double > &deriv) const
run the processor evaluation pass on this processor and compute derivatives
size_t size() const
returns the number of all bits in the container
Definition: BitSet.h:173
#define EDM_REGISTER_PLUGINFACTORY(_factory_, _category_)
Definition: PluginFactory.h:88
static Base_t * create(const char *name, const CalibBase_t *calib, Parent_t *parent=0)
std::string typeDemangle(char const *mangledName)
VarProcessor(const char *name, const Calibration::VarProcessor *calib, const MVAComputer *computer)
Definition: VarProcessor.cc:39
virtual LoopStatus loop(double *output, int *outConf, unsigned int nOutput, LoopCtx &ctx, unsigned int &nOffset) const
Definition: VarProcessor.h:134
void eval(double *input, int *conf, double *output, int *outConf, int *loop, LoopCtx &loopCtx, unsigned int offset) const
run the processor evaluation pass on this processor
Definition: VarProcessor.h:114
Definition: Config.py:1
dictionary config
Read in AllInOne config in JSON format.
Definition: DiMuonV_cfg.py:30
Hold context information for looping processors.
Definition: VarProcessor.h:95
Definition: output.py:1
#define get
Iterates over all set bits of a BitSet.
Definition: BitSet.h:77
Generic registry template for polymorphic processor implementations.
tmp
align.sh
Definition: createJobs.py:716
Common base class for variable processors.
Definition: VarProcessor.h:36