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 
16 
20 
24 #include "PhysicsTools/MVAComputer/interface/ProcessRegistry.icc"
25 
26 // #define DEBUG_DERIV
27 
28 #ifdef DEBUG_DERIV
30 #endif
31 
34  "PhysicsToolsMVAComputer");
35 
36 namespace PhysicsTools {
37 
40  const MVAComputer *computer) :
41  computer(computer),
42  inputVars(Calibration::convert(calib->inputVars)),
43  nInputVars(inputVars.bits())
44 {
45 }
46 
48 {
49  inputVars = BitSet(0);
50  nInputVars = 0;
51 }
52 
54 {
55  ConfigCtx::size_type pos = config.size();
56  if (pos != inputVars.size())
57  return;
58 
60  configure(iter, nInputVars);
61 
62  VarProcessor *loop = config.loop ? config.loop : this;
63  ConfigCtx::Context *ctx =
64  loop->configureLoop(config.ctx, config.begin(),
65  config.begin() + pos, config.end());
66 
67  if (ctx != config.ctx) {
68  delete config.ctx;
69  config.ctx = ctx;
70  }
71 
72  if (config.loop && !ctx)
73  config.loop = nullptr;
74  else if (!config.loop && ctx)
75  config.loop = this;
76 }
77 
78 VarProcessor::ConfigCtx::ConfigCtx(const std::vector<Variable::Flags>& flags) :
79  loop(nullptr), ctx(nullptr)
80 {
81  for(std::vector<Variable::Flags>::const_iterator iter = flags.begin();
82  iter != flags.end(); ++iter)
83  configs.push_back(Config(*iter, 1));
84 }
85 
89 {
90  return nullptr;
91 }
92 
93 template<>
96  const char *name, const Calibration::VarProcessor *calib,
97  const MVAComputer *parent)
98 {
99  VarProcessor *result = ProcessRegistry::create(name, calib, parent);
100  if (!result) {
101  // try to load the shared library and retry
102  try {
103  delete VPPluginFactory::get()->create(
104  std::string("VarProcessor/") + name);
105  result = ProcessRegistry::create(name, calib, parent);
106  } catch(const cms::Exception &e) {
107  // caller will have to deal with the null pointer
108  // in principle this will just give a slightly more
109  // descriptive error message (and will rethrow anyhow)
110 
111  edm::LogError("CannotBuildMVAProc")
112  << "Caught exception when building processor: "
113  << name << " message: " << std::endl
114  << e.what() << std::endl;
115  throw e;
116  }
117  }
118  return result;
119 }
120 
121 void VarProcessor::deriv(double *input, int *conf, double *output,
122  int *outConf, int *loop, LoopCtx& ctx,
123  unsigned int offset,
124  unsigned int in, unsigned int out_,
125  std::vector<double> &deriv) const
126 {
127  ValueIterator iter(inputVars.iter(), input, conf,
128  output, outConf, loop, ctx, offset);
129 
130  eval(iter, nInputVars);
131 
132  std::vector<double> matrix = this->deriv(iter, nInputVars);
133 
134  unsigned int size = 0;
135  while(iter)
136  size += (iter++).size();
137  bool empty = matrix.empty();
138  assert(size != 0 || empty);
139  unsigned int out = empty ? 0 : (matrix.size() / size);
140 
141  if (matrix.size() != out * size ||
142  (out > 1 && (int)out != outConf[out_] - outConf[0]))
143  throw cms::Exception("VarProcessor")
144  << "Derivative matrix implausible size in "
145  << typeid(*this).name() << "."
146  << std::endl;
147 
148 #ifdef DEBUG_DERIV
149  if (!matrix.empty()) {
150  std::string demangledName;
151  edm::typeDemangle(typeid(*this).name(), demangledName);
152  std::cout << demangledName << std::endl;
153  for(unsigned int i = 0; i < out; i++) {
154  for(unsigned int j = 0; j < size; j++)
155  std::cout << matrix.at(i*size+j) << "\t";
156  std::cout << std::endl;
157  }
158  std::cout << "----------------" << std::endl;
159  }
160 
161  std::cout << "======= in = " << in << ", size = " << size
162  << ", out = " << out << ", matrix = " << matrix.size()
163  << std::endl;
164 #endif
165 
166  unsigned int sz = (outConf[out_] - in) * in;
167  unsigned int oldSz = deriv.size();
168  if (oldSz < sz)
169  deriv.resize(sz);
170 
171  double *begin = &deriv.front() + (outConf[0] - in + offset) * in;
172  double *end = begin + out * in;
173  if (begin < &deriv.front() + oldSz)
174  std::fill(begin, end, 0.0);
175 
176  if (matrix.empty())
177  return;
178 
179  double *m0 = &matrix.front();
181  for(unsigned int i = 0; i < nInputVars; i++, ++cur) {
182 #ifdef DEBUG_DERIV
183  std::cout << " inputvar " << i << std::endl;
184 #endif
185  int *curConf = conf + cur();
186  unsigned int pos = *curConf;
187 #ifdef DEBUG_DERIV
188  std::cout << " -> cur = " << cur() << ", pos = "
189  << pos << std::endl;
190 #endif
191  if (loop && curConf >= loop) {
192  pos += offset;
193  loop = nullptr;
194  }
195 
196  unsigned int n = loop ? (curConf[1] - curConf[0]) : 1;
197  for(unsigned int j = 0; j < n; m0++, j++, pos++) {
198 #ifdef DEBUG_DERIV
199  std::cout << " multip " << j << std::endl;
200 #endif
201  double *p = begin;
202  if (pos >= in) {
203 #ifdef DEBUG_DERIV
204  std::cout << " deriv " << (pos - in)
205  << std::endl;
206 #endif
207  const double *q = &deriv.front() +
208  (pos - in) * in;
209  for(const double *m = m0; p < end;
210  m += size, q -= in)
211  for(unsigned int k = 0; k < in; k++)
212  *p++ += *m * *q++;
213  } else {
214 #ifdef DEBUG_DERIV
215  std::cout << " in " << pos << std::endl;
216 #endif
217  for(const double *m = m0; p < end;
218  m += size, p += in)
219  p[pos] += *m;
220  }
221  }
222  }
223 
224 #ifdef DEBUG_DERIV
225  std::cout << "================" << std::endl;
226  for(const double *p = &deriv.front();
227  p != &deriv.front() + deriv.size();) {
228  for(unsigned int j = 0; j < in; j++)
229  std::cout << *p++ << "\t";
230  std::cout << std::endl;
231  }
232  std::cout << "================" << std::endl;
233 #endif
234 }
235 
236 } // namespace PhysicsTools
237 
238 // Force instantiation of its templated static methods.
virtual ConfigCtx::Context * configureLoop(ConfigCtx::Context *ctx, ConfigCtx::iterator begin, ConfigCtx::iterator cur, ConfigCtx::iterator end)
virtual loop configure method
Definition: VarProcessor.cc:87
def create(alignables, pedeDump, additionalData, outputFile, config)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision bits
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
static void unregisterProcess(const char *name)
void configure(ConfigCtx &config)
called from the discriminator computer to configure processor
Definition: VarProcessor.cc:53
static void registerProcess(const char *name, const ProcessRegistry *process)
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
char const * what() const override
Definition: Exception.cc:141
Definition: config.py:1
#define nullptr
ConfigCtx(const std::vector< Variable::Flags > &flags)
Definition: VarProcessor.cc:78
static std::string const input
Definition: EdmProvDump.cc:44
config
Definition: looper.py:288
edmplugin::PluginFactory< PhysicsTools::VarProcessor::PluginFunctionPrototype > VPPluginFactory
Definition: VarProcessor.cc:32
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:148
BitSet inputVars
bit set to select the input variables to be passed to this processor
Definition: VarProcessor.h:324
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
int k[5][pyjets_maxn]
#define EDM_REGISTER_PLUGINFACTORY(_factory_, _category_)
Definition: PluginFactory.h:91
size_t size() const
returns the number of all bits in the container
Definition: BitSet.h:173
std::string typeDemangle(char const *mangledName)
VarProcessor(const char *name, const Calibration::VarProcessor *calib, const MVAComputer *computer)
Definition: VarProcessor.cc:38
Iterator iter() const
create iterator over all set bits
Definition: BitSet.h:179
Definition: Config.py:1
Hold context information for looping processors.
Definition: VarProcessor.h:98
Iterates over all set bits of a BitSet.
Definition: BitSet.h:77
Generic registry template for polymorphic processor implementations.
virtual LoopStatus loop(double *output, int *outConf, unsigned int nOutput, LoopCtx &ctx, unsigned int &nOffset) const
Definition: VarProcessor.h:132
T get(const Candidate &c)
Definition: component.h:55
Common base class for variable processors.
Definition: VarProcessor.h:36
const_iterator begin() const
Definition: VarProcessor.h:74
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:117