CMS 3D CMS Logo

MVAValueMapProducer.h
Go to the documentation of this file.
1 #ifndef __RecoEgamma_EgammaTools_MVAValueMapProducer_H__
2 #define __RecoEgamma_EgammaTools_MVAValueMapProducer_H__
3 
21 
22 #include <atomic>
23 #include <cmath>
24 #include <memory>
25 #include <string>
26 #include <vector>
27 
28 template <class ParticleType>
30 public:
32 
33  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
34 
35 private:
36  static auto getMVAEstimators(const edm::VParameterSet& vConfig) {
37  std::vector<std::unique_ptr<AnyMVAEstimatorRun2Base>> mvaEstimators;
38 
39  // Loop over the list of MVA configurations passed here from python and
40  // construct all requested MVA estimators.
41  for (auto& imva : vConfig) {
42  // The factory below constructs the MVA of the appropriate type based
43  // on the "mvaName" which is the name of the derived MVA class (plugin)
44  if (!imva.empty()) {
45  mvaEstimators.emplace_back(
46  AnyMVAEstimatorRun2Factory::get()->create(imva.getParameter<std::string>("mvaName"), imva));
47 
48  } else
49  throw cms::Exception(" MVA configuration not found: ")
50  << " failed to find proper configuration for one of the MVAs in the main python script " << std::endl;
51  }
52 
53  return mvaEstimators;
54  }
55 
56  static std::vector<std::string> getValueMapNames(const edm::VParameterSet& vConfig, std::string&& suffix) {
57  std::vector<std::string> names;
58  for (auto& imva : vConfig) {
59  names.push_back(imva.getParameter<std::string>("mvaName") + imva.getParameter<std::string>("mvaTag") + suffix);
60  }
61 
62  return names;
63  }
64 
65  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
66 
69 
70  // MVA estimators
71  const std::vector<std::unique_ptr<AnyMVAEstimatorRun2Base>> mvaEstimators_;
72 
73  // Value map names
74  const std::vector<std::string> mvaValueMapNames_;
75  const std::vector<std::string> mvaRawValueMapNames_;
76  const std::vector<std::string> mvaCategoriesMapNames_;
77 
78  // To get the auxiliary MVA variables
80 
81  CMS_THREAD_SAFE mutable std::atomic<bool> validated_ = false;
82 };
83 
84 namespace {
85 
86  template <typename ValueType, class HandleType>
87  void writeValueMap(edm::Event& iEvent,
89  const std::vector<ValueType>& values,
90  const std::string& label) {
91  auto valMap = std::make_unique<edm::ValueMap<ValueType>>();
92  typename edm::ValueMap<ValueType>::Filler filler(*valMap);
93  filler.insert(handle, values.begin(), values.end());
94  filler.fill();
95  iEvent.put(std::move(valMap), label);
96  }
97 
98  template <class ParticleType>
99  auto getKeysForValueMapsToken(edm::InputTag const& keysForValueMapsTag, edm::ConsumesCollector&& cc) {
100  const bool tagGiven = !keysForValueMapsTag.label().empty();
101  return tagGiven ? cc.consumes<edm::View<ParticleType>>(keysForValueMapsTag)
103  }
104 
105 } // namespace
106 
107 template <class ParticleType>
109  : srcToken_(consumes<edm::View<ParticleType>>(iConfig.getParameter<edm::InputTag>("src"))),
110  keysForValueMapsToken_(getKeysForValueMapsToken<ParticleType>(
111  iConfig.getParameter<edm::InputTag>("keysForValueMaps"), consumesCollector())),
112  mvaEstimators_(getMVAEstimators(iConfig.getParameterSetVector("mvaConfigurations"))),
113  mvaValueMapNames_(getValueMapNames(iConfig.getParameterSetVector("mvaConfigurations"), "Values")),
114  mvaRawValueMapNames_(getValueMapNames(iConfig.getParameterSetVector("mvaConfigurations"), "RawValues")),
115  mvaCategoriesMapNames_(getValueMapNames(iConfig.getParameterSetVector("mvaConfigurations"), "Categories")),
116  variableHelper_(consumesCollector()) {
117  for (auto const& name : mvaValueMapNames_)
118  produces<edm::ValueMap<float>>(name);
119  for (auto const& name : mvaRawValueMapNames_)
120  produces<edm::ValueMap<float>>(name);
121  for (auto const& name : mvaCategoriesMapNames_)
122  produces<edm::ValueMap<int>>(name);
123 }
124 
125 template <class ParticleType>
128  const edm::EventSetup& iSetup) const {
129  std::vector<float> auxVariables = variableHelper_.getAuxVariables(iEvent);
130 
131  auto srcHandle = iEvent.getHandle(srcToken_);
132  auto keysForValueMapsHandle =
133  keysForValueMapsToken_.isUninitialized() ? srcHandle : iEvent.getHandle(keysForValueMapsToken_);
134 
135  // check if nothing is wrong with the data format of the candidates
136  if (!validated_ && !srcHandle->empty()) {
137  egammaTools::validateEgammaCandidate((*srcHandle)[0]);
138  validated_ = true;
139  }
140 
141  // Loop over MVA estimators
142  for (unsigned iEstimator = 0; iEstimator < mvaEstimators_.size(); iEstimator++) {
143  std::vector<float> mvaValues;
144  std::vector<float> mvaRawValues;
145  std::vector<int> mvaCategories;
146 
147  // Loop over particles
148  for (auto const& cand : *srcHandle) {
149  int cat = -1; // Passed by reference to the mvaValue function to store the category
150  const float response = mvaEstimators_[iEstimator]->mvaValue(&cand, auxVariables, cat);
151  mvaRawValues.push_back(response); // The MVA score
152  mvaValues.push_back(2.0 / (1.0 + exp(-2.0 * response)) - 1); // MVA output between -1 and 1
153  mvaCategories.push_back(cat);
154  } // end loop over particles
155 
156  writeValueMap(iEvent, keysForValueMapsHandle, mvaValues, mvaValueMapNames_[iEstimator]);
157  writeValueMap(iEvent, keysForValueMapsHandle, mvaRawValues, mvaRawValueMapNames_[iEstimator]);
158  writeValueMap(iEvent, keysForValueMapsHandle, mvaCategories, mvaCategoriesMapNames_[iEstimator]);
159 
160  } // end loop over estimators
161 }
162 
163 template <class ParticleType>
166  desc.add<edm::InputTag>("src", {});
167  desc.add<edm::InputTag>("keysForValueMaps", {});
168  {
169  //The following says we do not know what parameters are allowed so do no validation
170  // Please change this to state exactly what you do use, even if it is no parameters
172  mvaConfigurations.setUnknown();
173  desc.addVPSet("mvaConfigurations", mvaConfigurations);
174  }
175  descriptions.addDefault(desc);
176 }
177 
178 #endif
const edm::EDGetTokenT< edm::View< ParticleType > > keysForValueMapsToken_
const std::vector< std::string > mvaRawValueMapNames_
def create(alignables, pedeDump, additionalData, outputFile, config)
std::vector< ParameterSet > VParameterSet
Definition: ParameterSet.h:35
void validateEgammaCandidate(Candidate const &candidate)
const MVAVariableHelper variableHelper_
std::string const & label() const
Definition: InputTag.h:36
const std::vector< std::unique_ptr< AnyMVAEstimatorRun2Base > > mvaEstimators_
const std::string names[nVars_]
char const * label
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
int iEvent
Definition: GenABIO.cc:224
def cat(path)
Definition: eostools.py:401
void addDefault(ParameterSetDescription const &psetDescription)
const std::vector< std::string > mvaCategoriesMapNames_
const std::vector< std::string > mvaValueMapNames_
static std::vector< std::string > getValueMapNames(const edm::VParameterSet &vConfig, std::string &&suffix)
#define CMS_THREAD_SAFE
std::atomic< bool > validated_
MVAValueMapProducer(const edm::ParameterSet &)
const edm::EDGetTokenT< edm::View< ParticleType > > srcToken_
HLT enums.
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
#define get
def move(src, dest)
Definition: eostools.py:511
static auto getMVAEstimators(const edm::VParameterSet &vConfig)
ParticleType
Definition of particle types.
Definition: ParticleCode.h:17