File indexing completed on 2024-04-06 12:23:37
0001 #ifndef PhysicsTools_MVAComputer_MVAComputer_h
0002 #define PhysicsTools_MVAComputer_MVAComputer_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <iostream>
0015 #include <vector>
0016 #include <memory>
0017
0018 #include "PhysicsTools/MVAComputer/interface/CalibrationFwd.h"
0019 #include "PhysicsTools/MVAComputer/interface/VarProcessor.h"
0020 #include "PhysicsTools/MVAComputer/interface/Variable.h"
0021 #include "PhysicsTools/MVAComputer/interface/AtomicId.h"
0022
0023 namespace PhysicsTools {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 class MVAComputer {
0040 public:
0041
0042 MVAComputer(const Calibration::MVAComputer *calib);
0043
0044
0045 MVAComputer(Calibration::MVAComputer *calib, bool owned = false);
0046
0047 ~MVAComputer();
0048
0049
0050 template <typename Iterator_t>
0051 double eval(Iterator_t first, Iterator_t last) const;
0052
0053 template <typename Iterator_t>
0054 double deriv(Iterator_t first, Iterator_t last) const;
0055
0056
0057 template <typename Container_t>
0058 inline double eval(const Container_t &values) const {
0059 typedef typename Container_t::const_iterator Iterator_t;
0060 return this->template eval<Iterator_t>(values.begin(), values.end());
0061 }
0062
0063 template <typename Container_t>
0064 inline double deriv(Container_t &values) const {
0065 typedef typename Container_t::iterator Iterator_t;
0066 return this->template deriv<Iterator_t>(values.begin(), values.end());
0067 }
0068
0069
0070
0071
0072 static Calibration::MVAComputer *readCalibration(const char *filename);
0073
0074
0075 static Calibration::MVAComputer *readCalibration(std::istream &is);
0076
0077
0078 static void writeCalibration(const char *filename, const Calibration::MVAComputer *calib);
0079
0080
0081 static void writeCalibration(std::ostream &os, const Calibration::MVAComputer *calib);
0082
0083
0084 MVAComputer(const char *filename);
0085
0086
0087 MVAComputer(std::istream &is);
0088
0089
0090
0091
0092 struct InputVar {
0093
0094 Variable var;
0095
0096
0097 unsigned int index;
0098
0099
0100 unsigned int multiplicity;
0101
0102 bool operator<(AtomicId id) const { return var.getName() < id; }
0103
0104 bool operator<(const InputVar &other) const { return var.getName() < other.var.getName(); }
0105 };
0106
0107
0108
0109
0110 struct Processor {
0111 inline Processor(VarProcessor *processor, unsigned int nOutput) : processor(processor), nOutput(nOutput) {}
0112
0113 inline Processor(const Processor &orig) {
0114 processor = std::move(orig.processor);
0115 nOutput = orig.nOutput;
0116 }
0117
0118 inline Processor &operator=(const Processor &orig) {
0119 processor = std::move(orig.processor);
0120 nOutput = orig.nOutput;
0121 return *this;
0122 }
0123
0124
0125 mutable std::unique_ptr<VarProcessor> processor;
0126
0127
0128 unsigned int nOutput;
0129 };
0130
0131 struct EvalContext {
0132 EvalContext(double *values, int *conf, unsigned int n) : values_(values), conf_(conf), n_(n) {}
0133
0134 inline void eval(const VarProcessor *proc,
0135 int *outConf,
0136 double *output,
0137 int *loop,
0138 VarProcessor::LoopCtx &ctx,
0139 unsigned int offset,
0140 unsigned int out) const {
0141 proc->eval(values_, conf_, output, outConf, loop, ctx, offset);
0142 }
0143
0144 inline double output(unsigned int output) const { return values_[conf_[output]]; }
0145
0146 inline double *values() const { return values_; }
0147 inline int *conf() const { return conf_; }
0148 inline unsigned int n() const { return n_; }
0149
0150 double *values_;
0151 int *conf_;
0152 unsigned int n_;
0153 };
0154
0155 struct DerivContext {
0156 DerivContext() : n_(0) {}
0157
0158 void eval(const VarProcessor *proc,
0159 int *outConf,
0160 double *output,
0161 int *loop,
0162 VarProcessor::LoopCtx &ctx,
0163 unsigned int offset,
0164 unsigned int out) const;
0165
0166 double output(unsigned int output, std::vector<double> &derivs) const;
0167
0168 inline double *values() const { return &values_.front(); }
0169 inline int *conf() const { return &conf_.front(); }
0170 inline unsigned int n() const { return n_; }
0171
0172 mutable std::vector<double> values_;
0173 mutable std::vector<double> deriv_;
0174 mutable std::vector<int> conf_;
0175 unsigned int n_;
0176 };
0177
0178 private:
0179
0180 void setup(const Calibration::MVAComputer *calib);
0181
0182
0183 int getVariableId(AtomicId name) const;
0184
0185
0186 template <class T>
0187 void evalInternal(T &ctx) const;
0188
0189
0190 std::vector<InputVar> inputVariables;
0191
0192
0193 std::vector<Processor> varProcessors;
0194
0195
0196 unsigned int nVars;
0197
0198
0199 unsigned int output;
0200
0201
0202 std::unique_ptr<Calibration::MVAComputer> owned;
0203 };
0204
0205 }
0206
0207 #include "PhysicsTools/MVAComputer/interface/MVAComputer.icc"
0208
0209 #endif