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 
33 EDM_REGISTER_PLUGINFACTORY(VPPluginFactory, "PhysicsToolsMVAComputer");
34 
35 namespace PhysicsTools {
36 
38  : computer(computer), inputVars(Calibration::convert(calib->inputVars)), nInputVars(inputVars.bits()) {}
39 
41  inputVars = BitSet(0);
42  nInputVars = 0;
43  }
44 
46  ConfigCtx::size_type pos = config.size();
47  if (pos != inputVars.size())
48  return;
49 
51  configure(iter, nInputVars);
52 
53  VarProcessor *loop = config.loop ? config.loop : this;
54  ConfigCtx::Context *ctx = loop->configureLoop(config.ctx, config.begin(), config.begin() + pos, config.end());
55 
56  if (ctx != config.ctx) {
57  delete config.ctx;
58  config.ctx = ctx;
59  }
60 
61  if (config.loop && !ctx)
62  config.loop = nullptr;
63  else if (!config.loop && ctx)
64  config.loop = this;
65  }
66 
67  VarProcessor::ConfigCtx::ConfigCtx(const std::vector<Variable::Flags> &flags) : loop(nullptr), ctx(nullptr) {
68  for (std::vector<Variable::Flags>::const_iterator iter = flags.begin(); iter != flags.end(); ++iter)
69  configs.push_back(Config(*iter, 1));
70  }
71 
76  return nullptr;
77  }
78 
79  template <>
81  const char *name, const Calibration::VarProcessor *calib, const MVAComputer *parent) {
82  VarProcessor *result = ProcessRegistry::create(name, calib, parent);
83  if (!result) {
84  // try to load the shared library and retry
85  try {
86  std::unique_ptr<PhysicsTools::VarProcessor::Dummy> tmp{
87  VPPluginFactory::get()->create(std::string("VarProcessor/") + name)};
88  result = ProcessRegistry::create(name, calib, parent);
89  } catch (const cms::Exception &e) {
90  // caller will have to deal with the null pointer
91  // in principle this will just give a slightly more
92  // descriptive error message (and will rethrow anyhow)
93 
94  edm::LogError("CannotBuildMVAProc")
95  << "Caught exception when building processor: " << name << " message: " << std::endl
96  << e.what() << std::endl;
97  throw e;
98  }
99  }
100  return result;
101  }
102 
104  int *conf,
105  double *output,
106  int *outConf,
107  int *loop,
108  LoopCtx &ctx,
109  unsigned int offset,
110  unsigned int in,
111  unsigned int out_,
112  std::vector<double> &deriv) const {
113  ValueIterator iter(inputVars.iter(), input, conf, output, outConf, loop, ctx, offset);
114 
115  eval(iter, nInputVars);
116 
117  std::vector<double> matrix = this->deriv(iter, nInputVars);
118 
119  unsigned int size = 0;
120  while (iter)
121  size += (iter++).size();
122  bool empty = matrix.empty();
123  assert(size != 0 || empty);
124  unsigned int out = empty ? 0 : (matrix.size() / size);
125 
126  if (matrix.size() != out * size || (out > 1 && (int)out != outConf[out_] - outConf[0]))
127  throw cms::Exception("VarProcessor")
128  << "Derivative matrix implausible size in " << typeid(*this).name() << "." << std::endl;
129 
130 #ifdef DEBUG_DERIV
131  if (!matrix.empty()) {
132  std::string demangledName;
133  edm::typeDemangle(typeid(*this).name(), demangledName);
134  std::cout << demangledName << std::endl;
135  for (unsigned int i = 0; i < out; i++) {
136  for (unsigned int j = 0; j < size; j++)
137  std::cout << matrix.at(i * size + j) << "\t";
138  std::cout << std::endl;
139  }
140  std::cout << "----------------" << std::endl;
141  }
142 
143  std::cout << "======= in = " << in << ", size = " << size << ", out = " << out << ", matrix = " << matrix.size()
144  << std::endl;
145 #endif
146 
147  unsigned int sz = (outConf[out_] - in) * in;
148  unsigned int oldSz = deriv.size();
149  if (oldSz < sz)
150  deriv.resize(sz);
151 
152  double *begin = &deriv.front() + (outConf[0] - in + offset) * in;
153  double *end = begin + out * in;
154  if (begin < &deriv.front() + oldSz)
155  std::fill(begin, end, 0.0);
156 
157  if (matrix.empty())
158  return;
159 
160  double *m0 = &matrix.front();
162  for (unsigned int i = 0; i < nInputVars; i++, ++cur) {
163 #ifdef DEBUG_DERIV
164  std::cout << " inputvar " << i << std::endl;
165 #endif
166  int *curConf = conf + cur();
167  unsigned int pos = *curConf;
168 #ifdef DEBUG_DERIV
169  std::cout << " -> cur = " << cur() << ", pos = " << pos << std::endl;
170 #endif
171  if (loop && curConf >= loop) {
172  pos += offset;
173  loop = nullptr;
174  }
175 
176  unsigned int n = loop ? (curConf[1] - curConf[0]) : 1;
177  for (unsigned int j = 0; j < n; m0++, j++, pos++) {
178 #ifdef DEBUG_DERIV
179  std::cout << " multip " << j << std::endl;
180 #endif
181  double *p = begin;
182  if (pos >= in) {
183 #ifdef DEBUG_DERIV
184  std::cout << " deriv " << (pos - in) << std::endl;
185 #endif
186  const double *q = &deriv.front() + (pos - in) * in;
187  for (const double *m = m0; p < end; m += size, q -= in)
188  for (unsigned int k = 0; k < in; k++)
189  *p++ += *m * *q++;
190  } else {
191 #ifdef DEBUG_DERIV
192  std::cout << " in " << pos << std::endl;
193 #endif
194  for (const double *m = m0; p < end; m += size, p += in)
195  p[pos] += *m;
196  }
197  }
198  }
199 
200 #ifdef DEBUG_DERIV
201  std::cout << "================" << std::endl;
202  for (const double *p = &deriv.front(); p != &deriv.front() + deriv.size();) {
203  for (unsigned int j = 0; j < in; j++)
204  std::cout << *p++ << "\t";
205  std::cout << std::endl;
206  }
207  std::cout << "================" << std::endl;
208 #endif
209  }
210 
211 } // namespace PhysicsTools
212 
213 // Force instantiation of its templated static methods.
216  PhysicsTools::MVAComputer const>::unregisterProcess(char const *);
220  registerProcess(char const *,
223  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:72
#define EDM_REGISTER_PLUGINFACTORY(_factory_, _category_)
Definition: PluginFactory.h:89
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
#define nullptr
void configure(ConfigCtx &config)
called from the discriminator computer to configure processor
Definition: VarProcessor.cc:45
char const * what() const override
Definition: Exception.cc:103
Definition: config.py:1
ConfigCtx(const std::vector< Variable::Flags > &flags)
Definition: VarProcessor.cc:67
static std::string const input
Definition: EdmProvDump.cc:48
config
Definition: looper.py:291
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: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
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:37
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:95
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
virtual LoopStatus loop(double *output, int *outConf, unsigned int nOutput, LoopCtx &ctx, unsigned int &nOffset) const
Definition: VarProcessor.h:134
Common base class for variable processors.
Definition: VarProcessor.h:36
const_iterator begin() const
Definition: VarProcessor.h:72
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