Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:32:42

0001 // -*- C++ -*-
0002 //
0003 // Package:     MVAComputer
0004 // Class  :     ProcForeach
0005 //
0006 
0007 // Implementation:
0008 //     Loops over a specified amount of VarProcessors and passes each
0009 //     instance of a set of variables individually per iteration.
0010 //
0011 // Author:      Christophe Saout
0012 // Created:     Sat Apr 24 15:18 CEST 2007
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 {  // anonymous
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 }  // anonymous namespace