CMS 3D CMS Logo

BTagProbabilityToDiscriminator.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: RecoBTag/SecondaryVertex
4 // Class: BTagProbabilityToDiscriminator
5 //
17 //
18 // Original Author: Mauro Verzetti (CERN)
19 //
20 //
21 
22 // system include files
23 #include <memory>
24 
25 // user include files
28 
31 
34 
38 
39 // from lwtnn
40 #include <fstream>
41 #include <iostream>
42 #include <map>
43 #include <set>
44 #include <string>
45 #include <vector>
46 
47 #include <boost/algorithm/string.hpp>
48 #include <unordered_map>
49 using namespace std;
50 using namespace reco;
51 //
52 // class declaration
53 //
54 
56 public:
59 
60  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
61 
62 private:
63  typedef std::vector<edm::InputTag> vInputTag;
64  typedef std::vector<std::string> vstring;
65  typedef std::vector<edm::ParameterSet> vPSet;
66  struct Discriminator {
67  std::string name; // needed?
68  vstring numerator;
69  vstring denominator;
70  };
71 
72  void beginStream(edm::StreamID) override {}
73  void produce(edm::Event &, const edm::EventSetup &) override;
74  void endStream() override {}
75 
76  // ----------member data ---------------------------
77  std::vector<Discriminator> discrims_;
78  std::unordered_map<std::string, edm::EDGetTokenT<JetTagCollection>>
79  jet_tags_; // caches jet tags to avoid repetitions
80 };
81 
83  const edm::ParameterSet &iConfig) {
84  for (auto discriminator : iConfig.getParameter<vPSet>("discriminators")) {
85  Discriminator current;
86  current.name = discriminator.getParameter<std::string>("name");
87  produces<JetTagCollection>(current.name);
88 
89  for (auto intag : discriminator.getParameter<vInputTag>("numerator")) {
90  if (jet_tags_.find(intag.encode()) == jet_tags_.end()) { // new
91  // probability
92  jet_tags_[intag.encode()] = consumes<JetTagCollection>(intag);
93  }
94  current.numerator.push_back(intag.encode());
95  }
96 
97  for (auto intag : discriminator.getParameter<vInputTag>("denominator")) {
98  if (jet_tags_.find(intag.encode()) == jet_tags_.end()) { // new
99  // probability
100  jet_tags_[intag.encode()] = consumes<JetTagCollection>(intag);
101  }
102  current.denominator.push_back(intag.encode());
103  }
104  discrims_.push_back(current);
105  }
106 
107  if (jet_tags_.empty()) {
108  throw cms::Exception("RuntimeError")
109  << "The module BTagProbabilityToDiscriminator is run without any input "
110  "probability to work on!"
111  << std::endl;
112  }
113 }
114 
116  const edm::EventSetup &iSetup) {
117  std::unordered_map<std::string, edm::Handle<JetTagCollection>>
118  tags; // caches jet tags to avoid repetitions
119  size_t size = 0;
120  bool first = true;
121  for (const auto& entry : jet_tags_) {
123  iEvent.getByToken(entry.second, tmp);
124  tags[entry.first] = tmp;
125  if (first)
126  size = tmp->size();
127  else {
128  if (tmp->size() != size) {
129  throw cms::Exception("RuntimeError")
130  << "The length of one of the input jet tag collections does not "
131  "match "
132  << "with the others, this is probably due to the probabilities "
133  "belonging to different jet collections, which is forbidden!"
134  << std::endl;
135  }
136  }
137  first = false;
138  }
139 
140  // create the output collection
141  // which is a "map" RefToBase<Jet> --> float
142  vector<std::unique_ptr<JetTagCollection>> output_tags;
143  output_tags.reserve(discrims_.size());
144  for (size_t i = 0; i < discrims_.size(); ++i) {
145  output_tags.push_back(std::make_unique<JetTagCollection>(
146  *(tags.begin()->second)) // clone from the first element, will change
147  // the content later on
148  );
149  }
150 
151  // loop over jets
152  for (size_t idx = 0; idx < output_tags[0]->size(); idx++) {
153  auto key = output_tags[0]->key(idx); // use key only for writing
154  // loop over new discriminators to produce
155  for (size_t disc_idx = 0; disc_idx < output_tags.size(); disc_idx++) {
156  float numerator = 0;
157  for (auto &num : discrims_[disc_idx].numerator)
158  numerator += (*tags[num])[idx].second;
159  float denominator = !discrims_[disc_idx].denominator.empty() ? 0 : 1;
160  for (auto &den : discrims_[disc_idx].denominator)
161  denominator += (*tags[den])[idx].second;
162  //protect against 0 denominator and undefined jet values (numerator probability < 0)
163  float new_value = (denominator != 0 && numerator >= 0) ? numerator / denominator : -10.;
164  (*output_tags[disc_idx])[key] = new_value;
165  }
166  }
167 
168  // put the output in the event
169  for (size_t i = 0; i < output_tags.size(); ++i) {
170  iEvent.put(std::move(output_tags[i]), discrims_[i].name);
171  }
172 }
173 
174 // ------------ method fills 'descriptions' with the allowed parameters for the
175 // module ------------
177  edm::ConfigurationDescriptions &descriptions) {
179  {
181  vpsd1.add<std::vector<edm::InputTag>>("denominator", {});
182  vpsd1.add<std::vector<edm::InputTag>>(
183  "numerator",
184  {
185  edm::InputTag("pfDeepCSVJetTags", "probb"),
186  edm::InputTag("pfDeepCSVJetTags", "probbb"),
187  });
188  vpsd1.add<std::string>("name", "BvsAll");
189  std::vector<edm::ParameterSet> temp1;
190  temp1.reserve(3);
191  {
192  edm::ParameterSet temp2;
193  temp2.addParameter<std::vector<edm::InputTag>>("denominator", {});
194  temp2.addParameter<std::vector<edm::InputTag>>(
195  "numerator",
196  {
197  edm::InputTag("pfDeepCSVJetTags", "probb"),
198  edm::InputTag("pfDeepCSVJetTags", "probbb"),
199  });
200  temp2.addParameter<std::string>("name", "BvsAll");
201  temp1.push_back(temp2);
202  }
203  {
204  edm::ParameterSet temp2;
205  temp2.addParameter<std::vector<edm::InputTag>>(
206  "denominator",
207  {
208  edm::InputTag("pfDeepCSVJetTags", "probc"),
209  edm::InputTag("pfDeepCSVJetTags", "probb"),
210  edm::InputTag("pfDeepCSVJetTags", "probbb"),
211  });
212  temp2.addParameter<std::vector<edm::InputTag>>(
213  "numerator",
214  {
215  edm::InputTag("pfDeepCSVJetTags", "probc"),
216  });
217  temp2.addParameter<std::string>("name", "CvsB");
218  temp1.push_back(temp2);
219  }
220  {
221  edm::ParameterSet temp2;
222  temp2.addParameter<std::vector<edm::InputTag>>(
223  "denominator",
224  {
225  edm::InputTag("pfDeepCSVJetTags", "probudsg"),
226  edm::InputTag("pfDeepCSVJetTags", "probc"),
227  });
228  temp2.addParameter<std::vector<edm::InputTag>>(
229  "numerator",
230  {
231  edm::InputTag("pfDeepCSVJetTags", "probc"),
232  });
233  temp2.addParameter<std::string>("name", "CvsL");
234  temp1.push_back(temp2);
235  }
236  desc.addVPSet("discriminators", vpsd1, temp1);
237  }
238  descriptions.addDefault(desc);
239 }
240 
241 // define this as a plug-in
size
Write out results.
T getParameter(std::string const &) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
void produce(edm::Event &, const edm::EventSetup &) override
ParameterDescriptionBase * addVPSet(U const &iLabel, ParameterSetDescription const &validator, std::vector< ParameterSet > const &defaults)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
std::unordered_map< std::string, edm::EDGetTokenT< JetTagCollection > > jet_tags_
U second(std::pair< T, U > const &p)
BTagProbabilityToDiscriminator(const edm::ParameterSet &)
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void addDefault(ParameterSetDescription const &psetDescription)
std::vector< edm::ParameterSet > vPSet
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:125
ParameterDescriptionBase * add(U const &iLabel, T const &value)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
fixed size matrix
def move(src, dest)
Definition: eostools.py:511
size_type size() const