CMS 3D CMS Logo

LowPtGsfElectronIDProducer.cc
Go to the documentation of this file.
24 #include <string>
25 #include <vector>
26 
28 //
30 public:
32 
33  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
34 
36 
37 private:
38  double eval(const GBRForest& model,
39  const reco::GsfElectron&,
40  double rho,
41  float unbiased,
42  float field_z,
43  const reco::Track* trk = nullptr) const;
44 
45  template <typename EL, typename FID, typename FTRK>
46  void doWork(double rho, float bz, EL const& electrons, FID&& idFunctor, FTRK&& trkFunctor, edm::Event&) const;
47  const bool useGsfToTrack_;
48  const bool usePAT_;
55 
56  const std::vector<std::string> names_;
57  std::vector<edm::EDPutTokenT<edm::ValueMap<float>>> putTokens_;
58  const bool passThrough_;
59  const double minPtThreshold_;
60  const double maxPtThreshold_;
61  std::vector<std::unique_ptr<const GBRForest>> models_;
62  const std::vector<double> thresholds_;
64  enum class Version { V0, V1 };
66 };
67 
69 //
71  : useGsfToTrack_(conf.getParameter<bool>("useGsfToTrack")),
72  usePAT_(conf.getParameter<bool>("usePAT")),
73  electrons_(),
74  patElectrons_(),
75  rho_(consumes<double>(conf.getParameter<edm::InputTag>("rho"))),
76  gsf2trk_(),
77  unbiased_(),
78  fieldToken_(esConsumes()),
79  names_(conf.getParameter<std::vector<std::string>>("ModelNames")),
80  passThrough_(conf.getParameter<bool>("PassThrough")),
81  minPtThreshold_(conf.getParameter<double>("MinPtThreshold")),
82  maxPtThreshold_(conf.getParameter<double>("MaxPtThreshold")),
83  thresholds_(conf.getParameter<std::vector<double>>("ModelThresholds")),
84  versionName_(conf.getParameter<std::string>("Version")) {
85  if (useGsfToTrack_) {
86  gsf2trk_ = consumes<edm::Association<reco::TrackCollection>>(conf.getParameter<edm::InputTag>("gsfToTrack"));
87  }
88  if (usePAT_) {
89  patElectrons_ = consumes<pat::ElectronCollection>(conf.getParameter<edm::InputTag>("electrons"));
90  } else {
91  electrons_ = consumes<reco::GsfElectronCollection>(conf.getParameter<edm::InputTag>("electrons"));
92  unbiased_ = consumes<edm::ValueMap<float>>(conf.getParameter<edm::InputTag>("unbiased"));
93  }
94  for (auto& weights : conf.getParameter<std::vector<std::string>>("ModelWeights")) {
96  }
97  if (names_.size() != models_.size()) {
98  throw cms::Exception("Incorrect configuration")
99  << "'ModelNames' size (" << names_.size() << ") != 'ModelWeights' size (" << models_.size() << ").\n";
100  }
101  if (models_.size() != thresholds_.size()) {
102  throw cms::Exception("Incorrect configuration")
103  << "'ModelWeights' size (" << models_.size() << ") != 'ModelThresholds' size (" << thresholds_.size() << ").\n";
104  }
105  if (versionName_ == "V0") {
107  } else if (versionName_ == "V1") {
109  } else {
110  throw cms::Exception("Incorrect configuration") << "Unknown Version: " << versionName_ << "\n";
111  }
112  putTokens_.reserve(names_.size());
113  for (const auto& name : names_) {
115  }
116 }
117 
119 //
121  // Get z-component of B field
122  math::XYZVector zfield(setup.getData(fieldToken_).inTesla(GlobalPoint(0, 0, 0)));
123 
124  // Pileup
125  edm::Handle<double> hRho;
126  event.getByToken(rho_, hRho);
127  if (!hRho.isValid()) {
128  std::ostringstream os;
129  os << "Problem accessing rho collection for low-pT electrons" << std::endl;
130  throw cms::Exception("InvalidHandle", os.str());
131  }
132 
133  // Retrieve GsfToTrack Association from Event
135  if (useGsfToTrack_) {
136  event.getByToken(gsf2trk_, gsf2trk);
137  }
138 
139  double rho = *hRho;
140  // Retrieve pat::Electrons or reco::GsfElectrons from Event
143  if (usePAT_) {
144  auto const& electrons = event.getHandle(patElectrons_);
145 
146  const std::string kUnbiased("unbiased");
147  doWork(
148  rho,
149  zfield.z(),
150  electrons,
151  [&](auto const& ele) {
152  if (!ele.isElectronIDAvailable(kUnbiased)) {
154  }
155  return ele.electronID(kUnbiased);
156  },
157  [&](auto const& ele) { // trkFunctor ...
158  if (useGsfToTrack_) {
159  using PackedPtr = edm::Ptr<pat::PackedCandidate>;
160  const PackedPtr* ptr1 = ele.template userData<PackedPtr>("ele2packed");
161  const PackedPtr* ptr2 = ele.template userData<PackedPtr>("ele2lost");
162  auto hasBestTrack = [](const PackedPtr* ptr) {
163  return ptr != nullptr && ptr->isNonnull() && ptr->isAvailable() && ptr->get() != nullptr &&
164  ptr->get()->bestTrack() != nullptr;
165  };
166  if (hasBestTrack(ptr1)) {
167  return ptr1->get()->bestTrack();
168  } else if (hasBestTrack(ptr2)) {
169  return ptr2->get()->bestTrack();
170  }
171  } else {
172  reco::TrackRef ref = ele.closestCtfTrackRef();
173  if (ref.isNonnull() && ref.isAvailable()) {
174  return ref.get();
175  }
176  }
177  return static_cast<const reco::Track*>(nullptr);
178  },
179  event);
180  } else {
181  auto const& electrons = event.getHandle(electrons_);
182  // ElectronSeed unbiased BDT
183  edm::ValueMap<float> const& unbiasedH = event.get(unbiased_);
184  doWork(
185  rho,
186  zfield.z(),
187  electrons,
188  [&](auto const& ele) {
189  if (ele.core().isNull()) {
191  }
192  const auto& gsf = ele.core()->gsfTrack(); // reco::GsfTrackRef
193  if (gsf.isNull()) {
195  }
196  return unbiasedH[gsf];
197  },
198  [&](auto const& ele) { // trkFunctor ...
199  if (useGsfToTrack_) {
200  const auto& gsf = ele.core()->gsfTrack();
201  if (gsf.isNonnull() && gsf.isAvailable()) {
202  auto const& ref = (*gsf2trk)[gsf];
203  if (ref.isNonnull() && ref.isAvailable()) {
204  return ref.get();
205  }
206  }
207  } else {
208  reco::TrackRef ref = ele.closestCtfTrackRef();
209  if (ref.isNonnull() && ref.isAvailable()) {
210  return ref.get();
211  }
212  }
213  return static_cast<const reco::Track*>(nullptr);
214  },
215  event);
216  }
217 }
218 
219 template <typename EL, typename FID, typename FTRK>
221  double rho, float bz, EL const& electrons, FID&& idFunctor, FTRK&& trkFunctor, edm::Event& event) const {
222  auto nElectrons = electrons->size();
223  std::vector<float> ids;
224  ids.reserve(nElectrons);
225  std::transform(electrons->begin(), electrons->end(), std::back_inserter(ids), idFunctor);
226  std::vector<const reco::Track*> trks;
227  trks.reserve(nElectrons);
228  std::transform(electrons->begin(), electrons->end(), std::back_inserter(trks), trkFunctor);
229 
230  std::vector<float> output(nElectrons); //resused for each model
231  for (unsigned int index = 0; index < names_.size(); ++index) {
232  // Iterate through Electrons, evaluate BDT, and store result
233  for (unsigned int iele = 0; iele < nElectrons; iele++) {
234  auto const& ele = (*electrons)[iele];
235  if (ids[iele] != std::numeric_limits<float>::max()) {
236  output[iele] = eval(*models_[index], ele, rho, ids[iele], bz, trks[iele]);
237  } else {
238  output[iele] = -999.;
239  }
240  }
241  edm::ValueMap<float> valueMap;
243  filler.insert(electrons, output.begin(), output.end());
244  filler.fill();
245  event.emplace(putTokens_[index], std::move(valueMap));
246  }
247 }
248 
250 //
252  const reco::GsfElectron& ele,
253  double rho,
254  float unbiased,
255  float field_z,
256  const reco::Track* trk) const {
257  std::vector<float> inputs;
258  if (version_ == Version::V0) {
260  } else if (version_ == Version::V1) {
261  inputs = lowptgsfeleid::features_V1(ele, rho, unbiased, field_z, trk);
262  }
263  return model.GetResponse(inputs.data());
264 }
265 
267 //
270  desc.add<bool>("useGsfToTrack", false);
271  desc.add<bool>("usePAT", false);
272  desc.add<edm::InputTag>("electrons", edm::InputTag("lowPtGsfElectrons"));
273  desc.addOptional<edm::InputTag>("gsfToTrack", edm::InputTag("lowPtGsfToTrackLinks"));
274  desc.addOptional<edm::InputTag>("unbiased", edm::InputTag("lowPtGsfElectronSeedValueMaps:unbiased"));
275  desc.add<edm::InputTag>("rho", edm::InputTag("fixedGridRhoFastjetAll"));
276  desc.add<std::vector<std::string>>("ModelNames", {""});
277  desc.add<std::vector<std::string>>(
278  "ModelWeights", {"RecoEgamma/ElectronIdentification/data/LowPtElectrons/LowPtElectrons_ID_2020Nov28.root"});
279  desc.add<std::vector<double>>("ModelThresholds", {-99.});
280  desc.add<bool>("PassThrough", false);
281  desc.add<double>("MinPtThreshold", 0.5);
282  desc.add<double>("MaxPtThreshold", 15.);
283  desc.add<std::string>("Version", "V1");
284  descriptions.add("defaultLowPtGsfElectronID", desc);
285 }
286 
288 //
double eval(const GBRForest &model, const reco::GsfElectron &, double rho, float unbiased, float field_z, const reco::Track *trk=nullptr) const
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
static void fillDescriptions(edm::ConfigurationDescriptions &)
const_reference_type get(ProductID id, size_t idx) const
Definition: ValueMap.h:138
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
edm::EDGetTokenT< reco::GsfElectronCollection > electrons_
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
const std::vector< double > thresholds_
const std::vector< std::string > names_
std::vector< std::unique_ptr< const GBRForest > > models_
LowPtGsfElectronIDProducer(const edm::ParameterSet &)
void doWork(double rho, float bz, EL const &electrons, FID &&idFunctor, FTRK &&trkFunctor, edm::Event &) const
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:146
bool isAvailable() const
Definition: Ref.h:541
edm::EDGetTokenT< pat::ElectronCollection > patElectrons_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::vector< float > features_V0(reco::GsfElectron const &ele, float rho, float unbiased)
std::vector< float > features_V1(reco::GsfElectron const &ele, float rho, float unbiased, float field_z, const reco::Track *trk=nullptr)
const edm::EDGetTokenT< double > rho_
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
edm::EDGetTokenT< edm::ValueMap< float > > unbiased_
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > fieldToken_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< edm::Association< reco::TrackCollection > > gsf2trk_
HLT enums.
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
Definition: output.py:1
std::vector< edm::EDPutTokenT< edm::ValueMap< float > > > putTokens_
def move(src, dest)
Definition: eostools.py:511
std::unique_ptr< const GBRForest > createGBRForest(const std::string &weightsFile)
Definition: event.py:1
unsigned transform(const HcalDetId &id, unsigned transformCode)