File indexing completed on 2024-04-06 12:23:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <algorithm>
0016
0017 #include "FWCore/Utilities/interface/Exception.h"
0018
0019 #include "PhysicsTools/MVAComputer/interface/Variable.h"
0020 #include "PhysicsTools/MVAComputer/interface/VarProcessor.h"
0021 #include "PhysicsTools/MVAComputer/interface/Calibration.h"
0022
0023 using namespace PhysicsTools;
0024
0025 namespace {
0026
0027 class ProcForeach : public VarProcessor {
0028 public:
0029 typedef VarProcessor::Registry::Registry<ProcForeach, Calibration::ProcForeach> Registry;
0030
0031 ProcForeach(const char *name, const Calibration::ProcForeach *calib, const MVAComputer *computer);
0032 ~ProcForeach() override {}
0033
0034 void configure(ConfIterator iter, unsigned int n) override;
0035 ConfigCtx::Context *configureLoop(ConfigCtx::Context *ctx,
0036 ConfigCtx::iterator begin,
0037 ConfigCtx::iterator cur,
0038 ConfigCtx::iterator end) override;
0039
0040 void eval(ValueIterator iter, unsigned int n) const override;
0041 std::vector<double> deriv(ValueIterator iter, unsigned int n) const override;
0042 LoopStatus loop(double *output, int *conf, unsigned int nOutput, LoopCtx &ctx, unsigned int &nOffset) const override;
0043
0044 private:
0045 struct ConfContext : public VarProcessor::ConfigCtx::Context {
0046 ConfContext(unsigned int origin, unsigned int count) : origin(origin), count(count) {}
0047 ~ConfContext() override {}
0048
0049 unsigned int origin;
0050 unsigned int count;
0051 };
0052
0053 unsigned int count;
0054 };
0055
0056 ProcForeach::Registry registry("ProcForeach");
0057
0058 ProcForeach::ProcForeach(const char *name, const Calibration::ProcForeach *calib, const MVAComputer *computer)
0059 : VarProcessor(name, calib, computer), count(calib->nProcs) {}
0060
0061 void ProcForeach::configure(ConfIterator iter, unsigned int n) {
0062 iter << Variable::FLAG_NONE;
0063 while (iter)
0064 iter << iter++(Variable::FLAG_MULTIPLE);
0065 }
0066
0067 VarProcessor::ConfigCtx::Context *ProcForeach::configureLoop(ConfigCtx::Context *ctx_,
0068 ConfigCtx::iterator begin,
0069 ConfigCtx::iterator cur,
0070 ConfigCtx::iterator end) {
0071 ConfContext *ctx = dynamic_cast<ConfContext *>(ctx_);
0072 if (!ctx)
0073 return new ConfContext(cur - begin + 1, count);
0074
0075 for (ConfigCtx::iterator iter = cur; iter != end; iter++) {
0076 iter->mask = Variable::FLAG_ALL;
0077 iter->origin = ctx->origin;
0078 }
0079
0080 if (--ctx->count)
0081 return ctx;
0082 else
0083 return nullptr;
0084 }
0085
0086 void ProcForeach::eval(ValueIterator iter, unsigned int n) const {
0087 auto const offset = iter.loopCtx().offset();
0088 iter(offset);
0089
0090 auto &loopSize = iter.loopCtx().size();
0091 while (iter) {
0092 unsigned int size = iter.size();
0093 if (!loopSize)
0094 loopSize = size;
0095
0096 double value = iter[offset];
0097 iter(value);
0098 iter++;
0099 }
0100 }
0101
0102 std::vector<double> ProcForeach::deriv(ValueIterator iter, unsigned int n) const {
0103 auto const offset = iter.loopCtx().offset();
0104 std::vector<unsigned int> offsets;
0105 unsigned int in = 0, out = 0;
0106 while (iter) {
0107 offsets.push_back(in + offset);
0108 in += (iter++).size();
0109 out++;
0110 }
0111
0112 std::vector<double> result((out + 1) * in, 0.0);
0113 for (unsigned int i = 0; i < out; i++)
0114 result[(i + 1) * in + offsets[i]] = 1.0;
0115
0116 return result;
0117 }
0118
0119 VarProcessor::LoopStatus ProcForeach::loop(
0120 double *output, int *conf, unsigned int nOutput, LoopCtx &ctx, unsigned int &nOffset) const {
0121 auto &index = ctx.index();
0122 bool endIteration = false;
0123 if (index++ == count) {
0124 index = 0;
0125 endIteration = true;
0126 }
0127 auto &offset = ctx.offset();
0128 auto &size = ctx.size();
0129
0130 if (offset == 0 && !endIteration) {
0131 for (int cur = *conf + size; nOutput--; cur += size)
0132 *++conf = cur;
0133 }
0134
0135 if (endIteration) {
0136 if (++offset >= size) {
0137 return kStop;
0138 } else
0139 return kReset;
0140 } else if (offset > size) {
0141 return kSkip;
0142 } else {
0143 nOffset = offset;
0144 return kNext;
0145 }
0146 }
0147
0148 }