File indexing completed on 2024-04-06 12:25:02
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;
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
0093
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