Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-06-12 03:09:35

0001 #ifndef RecoEgamma_EgammaTools_MVAVariableManager_H
0002 #define RecoEgamma_EgammaTools_MVAVariableManager_H
0003 
0004 #include "FWCore/ParameterSet/interface/FileInPath.h"
0005 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0006 #include "CommonTools/Utils/interface/StringObjectFunction.h"
0007 #include "CommonTools/Utils/interface/ThreadSafeFunctor.h"
0008 
0009 #include <fstream>
0010 
0011 template <class ParticleType>
0012 class MVAVariableManager {
0013 public:
0014   template <class IndexMap>
0015   MVAVariableManager(const std::string &variableDefinitionFileName, IndexMap const &indexMap) : nVars_(0) {
0016     edm::FileInPath variableDefinitionFileEdm(variableDefinitionFileName);
0017     std::ifstream file(variableDefinitionFileEdm.fullPath());
0018 
0019     std::string name, formula, upper, lower;
0020     while (true) {
0021       file >> name;
0022       if (file.eof()) {
0023         break;
0024       }
0025       if (name.find('#') != std::string::npos) {
0026         file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
0027         continue;
0028       }
0029       file >> formula >> lower >> upper;
0030       if (file.eof()) {
0031         break;
0032       }
0033       addVariable(name, formula, lower, upper, indexMap);
0034     }
0035   }
0036 
0037   int getVarIndex(const std::string &name) {
0038     std::map<std::string, int>::iterator it = indexMap_.find(name);
0039     if (it == indexMap_.end()) {
0040       return -1;
0041     } else {
0042       return it->second;
0043     }
0044   }
0045 
0046   const std::string &getName(int index) const { return names_[index]; }
0047 
0048   int getNVars() const { return nVars_; }
0049 
0050   float getValue(int index, const ParticleType &particle, const std::vector<float> &auxVariables) const {
0051     float value;
0052 
0053     MVAVariableInfo varInfo = variableInfos_[index];
0054 
0055     if (varInfo.auxIndex >= 0)
0056       value = auxVariables[varInfo.auxIndex];
0057     else
0058       value = functions_[index](particle);
0059 
0060     if (varInfo.hasLowerClip && value < varInfo.lowerClipValue) {
0061       value = varInfo.lowerClipValue;
0062     }
0063     if (varInfo.hasUpperClip && value > varInfo.upperClipValue) {
0064       value = varInfo.upperClipValue;
0065     }
0066     return value;
0067   }
0068 
0069 private:
0070   struct MVAVariableInfo {
0071     bool hasLowerClip;
0072     bool hasUpperClip;
0073     float lowerClipValue;
0074     float upperClipValue;
0075     int auxIndex;
0076   };
0077 
0078   template <class IndexMap>
0079   void addVariable(const std::string &name,
0080                    const std::string &formula,
0081                    const std::string &lowerClip,
0082                    const std::string &upperClip,
0083                    IndexMap const &indexMap) {
0084     bool hasLowerClip = lowerClip.find("None") == std::string::npos;
0085     bool hasUpperClip = upperClip.find("None") == std::string::npos;
0086     bool isAuxiliary = formula.find("Rho") != std::string::npos;  // *Rho* is still hardcoded...
0087     float lowerClipValue = hasLowerClip ? (float)::atof(lowerClip.c_str()) : 0.;
0088     float upperClipValue = hasUpperClip ? (float)::atof(upperClip.c_str()) : 0.;
0089 
0090     if (!isAuxiliary)
0091       functions_.emplace_back(formula);
0092     // Else push back a dummy function since we won't use the
0093     // StringObjectFunction to evaluate an auxiliary variable
0094     else
0095       functions_.emplace_back("pt");
0096 
0097     formulas_.push_back(formula);
0098 
0099     int auxIndex = isAuxiliary ? indexMap.at(formula) : -1;
0100 
0101     MVAVariableInfo varInfo{
0102         .hasLowerClip = hasLowerClip,
0103         .hasUpperClip = hasUpperClip,
0104         .lowerClipValue = lowerClipValue,
0105         .upperClipValue = upperClipValue,
0106         .auxIndex = auxIndex,
0107     };
0108 
0109     variableInfos_.push_back(varInfo);
0110     names_.push_back(name);
0111     indexMap_[name] = nVars_;
0112     nVars_++;
0113   };
0114 
0115   int nVars_;
0116 
0117   std::vector<MVAVariableInfo> variableInfos_;
0118   std::vector<ThreadSafeFunctor<StringObjectFunction<ParticleType>>> functions_;
0119   std::vector<std::string> formulas_;
0120   std::vector<std::string> names_;
0121   std::map<std::string, int> indexMap_;
0122 };
0123 
0124 #endif