CMS 3D CMS Logo

LowPtGsfElectronIDProducer.cc
Go to the documentation of this file.
25 #include <string>
26 #include <vector>
27 
29 //
31 public:
33 
34  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
35 
37 
38 private:
39  double eval(const std::string& name,
41  double rho,
42  float unbiased,
43  float field_z,
44  const reco::Track* trk = nullptr) const;
45 
46  const bool useGsfToTrack_;
47  const bool usePAT_;
53  const std::vector<std::string> names_;
54  const bool passThrough_;
55  const double minPtThreshold_;
56  const double maxPtThreshold_;
57  std::vector<std::unique_ptr<const GBRForest> > models_;
58  const std::vector<double> thresholds_;
60 };
61 
63 //
65  : useGsfToTrack_(conf.getParameter<bool>("useGsfToTrack")),
66  usePAT_(conf.getParameter<bool>("usePAT")),
67  electrons_(),
68  patElectrons_(),
69  rho_(consumes<double>(conf.getParameter<edm::InputTag>("rho"))),
70  gsf2trk_(),
71  unbiased_(),
72  names_(conf.getParameter<std::vector<std::string> >("ModelNames")),
73  passThrough_(conf.getParameter<bool>("PassThrough")),
74  minPtThreshold_(conf.getParameter<double>("MinPtThreshold")),
75  maxPtThreshold_(conf.getParameter<double>("MaxPtThreshold")),
76  thresholds_(conf.getParameter<std::vector<double> >("ModelThresholds")),
77  version_(conf.getParameter<std::string>("Version")) {
78  if (useGsfToTrack_) {
79  gsf2trk_ = consumes<edm::Association<reco::TrackCollection> >(conf.getParameter<edm::InputTag>("gsfToTrack"));
80  }
81  if (usePAT_) {
82  patElectrons_ = consumes<pat::ElectronCollection>(conf.getParameter<edm::InputTag>("electrons"));
83  } else {
84  electrons_ = consumes<reco::GsfElectronCollection>(conf.getParameter<edm::InputTag>("electrons"));
85  unbiased_ = consumes<edm::ValueMap<float> >(conf.getParameter<edm::InputTag>("unbiased"));
86  }
87  for (auto& weights : conf.getParameter<std::vector<std::string> >("ModelWeights")) {
89  }
90  if (names_.size() != models_.size()) {
91  throw cms::Exception("Incorrect configuration")
92  << "'ModelNames' size (" << names_.size() << ") != 'ModelWeights' size (" << models_.size() << ").\n";
93  }
94  if (models_.size() != thresholds_.size()) {
95  throw cms::Exception("Incorrect configuration")
96  << "'ModelWeights' size (" << models_.size() << ") != 'ModelThresholds' size (" << thresholds_.size() << ").\n";
97  }
98  if (version_ != "V0" && version_ != "V1" && !version_.empty()) {
99  throw cms::Exception("Incorrect configuration") << "Unknown Version: " << version_ << "\n";
100  }
101  for (const auto& name : names_) {
102  produces<edm::ValueMap<float> >(name);
103  }
104 }
105 
107 //
109  // Get z-component of B field
111  setup.get<IdealMagneticFieldRecord>().get(field);
112  math::XYZVector zfield(field->inTesla(GlobalPoint(0, 0, 0)));
113 
114  // Pileup
116  event.getByToken(rho_, rho);
117  if (!rho.isValid()) {
118  std::ostringstream os;
119  os << "Problem accessing rho collection for low-pT electrons" << std::endl;
120  throw cms::Exception("InvalidHandle", os.str());
121  }
122 
123  // Retrieve GsfToTrack Association from Event
125  if (useGsfToTrack_) {
126  event.getByToken(gsf2trk_, gsf2trk);
127  }
128 
129  // Retrieve pat::Electrons or reco::GsfElectrons from Event
132  if (usePAT_) {
133  event.getByToken(patElectrons_, patElectrons);
134  } else {
135  event.getByToken(electrons_, electrons);
136  }
137 
138  // ElectronSeed unbiased BDT
140  if (!unbiased_.isUninitialized()) {
141  event.getByToken(unbiased_, unbiasedH);
142  }
143 
144  // Iterate through Electrons, evaluate BDT, and store result
145  std::vector<std::vector<float> > output;
146  unsigned int nElectrons = usePAT_ ? patElectrons->size() : electrons->size();
147  for (unsigned int iname = 0; iname < names_.size(); ++iname) {
148  output.emplace_back(nElectrons, -999.);
149  }
150 
151  if (usePAT_) {
152  for (unsigned int iele = 0; iele < nElectrons; iele++) {
153  edm::Ptr<pat::Electron> ele(patElectrons, iele);
154  if (!ele->isElectronIDAvailable("unbiased")) {
155  continue;
156  }
157 
158  // Extract Track
159  const reco::Track* trk = nullptr;
160  if (useGsfToTrack_) {
161  using PackedPtr = edm::Ptr<pat::PackedCandidate>;
162  const PackedPtr* ptr1 = ele->userData<PackedPtr>("ele2packed");
163  const PackedPtr* ptr2 = ele->userData<PackedPtr>("ele2lost");
164  auto hasBestTrack = [](const PackedPtr* ptr) {
165  return ptr != nullptr && ptr->isNonnull() && ptr->isAvailable() && ptr->get() != nullptr &&
166  ptr->get()->bestTrack() != nullptr;
167  };
168  if (hasBestTrack(ptr1)) {
169  trk = ptr1->get()->bestTrack();
170  } else if (hasBestTrack(ptr2)) {
171  trk = ptr2->get()->bestTrack();
172  }
173  } else {
174  reco::TrackRef ref = ele->closestCtfTrackRef();
175  if (ref.isNonnull() && ref.isAvailable()) {
176  trk = ref.get();
177  }
178  }
179 
180  for (unsigned int iname = 0; iname < names_.size(); ++iname) {
181  output[iname][iele] = eval(names_[iname], ele, *rho, ele->electronID("unbiased"), zfield.z(), trk);
182  }
183  }
184  } else {
185  for (unsigned int iele = 0; iele < nElectrons; iele++) {
186  edm::Ptr<reco::GsfElectron> ele(electrons, iele);
187  if (ele->core().isNull()) {
188  continue;
189  }
190  const auto& gsf = ele->core()->gsfTrack(); // reco::GsfTrackRef
191  if (gsf.isNull()) {
192  continue;
193  }
194 
195  // Extract Track
196  const reco::Track* trk = nullptr;
197  if (useGsfToTrack_) {
198  if (gsf.isAvailable()) {
199  auto const& ref = (*gsf2trk)[gsf];
200  if (ref.isNonnull() && ref.isAvailable()) {
201  trk = ref.get();
202  }
203  }
204  } else {
205  reco::TrackRef ref = ele->closestCtfTrackRef();
206  if (ref.isNonnull() && ref.isAvailable()) {
207  trk = ref.get();
208  }
209  }
210 
211  float unbiased = (*unbiasedH)[gsf];
212  for (unsigned int iname = 0; iname < names_.size(); ++iname) {
213  output[iname][iele] = eval(names_[iname], ele, *rho, unbiased, zfield.z(), trk);
214  }
215  }
216  }
217 
218  // Create and put ValueMap in Event
219  for (unsigned int iname = 0; iname < names_.size(); ++iname) {
220  auto ptr = std::make_unique<edm::ValueMap<float> >(edm::ValueMap<float>());
222  if (usePAT_) {
223  filler.insert(patElectrons, output[iname].begin(), output[iname].end());
224  } else {
225  filler.insert(electrons, output[iname].begin(), output[iname].end());
226  }
227  filler.fill();
228  event.put(std::move(ptr), names_[iname]);
229  }
230 }
231 
233 //
235  const edm::Ptr<reco::GsfElectron>& ele,
236  double rho,
237  float unbiased,
238  float field_z,
239  const reco::Track* trk) const {
240  auto iter = std::find(names_.begin(), names_.end(), name);
241  if (iter != names_.end()) {
242  int index = std::distance(names_.begin(), iter);
243  std::vector<float> inputs;
244  if (version_.empty()) { // Original XML model
246  features.set(*ele, rho);
247  inputs = features.get();
248  } else if (version_ == "V0") {
249  inputs = lowptgsfeleid::features_V0(*ele, rho, unbiased);
250  } else if (version_ == "V1") {
251  inputs = lowptgsfeleid::features_V1(*ele, rho, unbiased, field_z, trk);
252  }
253  return models_.at(index)->GetResponse(inputs.data());
254  } else {
255  throw cms::Exception("Unknown model name") << "'Name given: '" << name << "'. Check against configuration file.\n";
256  }
257  return 0.;
258 }
259 
261 //
264  desc.add<bool>("useGsfToTrack", false);
265  desc.add<bool>("usePAT", false);
266  desc.add<edm::InputTag>("electrons", edm::InputTag("lowPtGsfElectrons"));
267  desc.addOptional<edm::InputTag>("gsfToTrack", edm::InputTag("lowPtGsfToTrackLinks"));
268  desc.addOptional<edm::InputTag>("unbiased", edm::InputTag("lowPtGsfElectronSeedValueMaps:unbiased"));
269  desc.add<edm::InputTag>("rho", edm::InputTag("fixedGridRhoFastjetAllTmp"));
270  desc.add<std::vector<std::string> >("ModelNames", std::vector<std::string>());
271  desc.add<std::vector<std::string> >("ModelWeights", std::vector<std::string>());
272  desc.add<std::vector<double> >("ModelThresholds", std::vector<double>());
273  desc.add<bool>("PassThrough", false);
274  desc.add<double>("MinPtThreshold", 0.5);
275  desc.add<double>("MaxPtThreshold", 15.);
276  desc.add<std::string>("Version", "");
277  descriptions.add("defaultLowPtGsfElectronID", desc);
278 }
279 
281 //
bool isAvailable() const
Definition: Ref.h:575
T getParameter(std::string const &) const
bool isElectronIDAvailable(const std::string &name) const
Returns true if a specific ID is available in this pat::Electron.
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
virtual TrackRef closestCtfTrackRef() const
Definition: GsfElectron.h:205
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
static void fillDescriptions(edm::ConfigurationDescriptions &)
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:53
edm::EDGetTokenT< reco::GsfElectronCollection > electrons_
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:2
const std::vector< double > thresholds_
const std::vector< std::string > names_
std::vector< std::unique_ptr< const GBRForest > > models_
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
std::vector< float > features_V1(reco::GsfElectron const &ele, float rho, float unbiased, float field_z, const reco::Track *trk=0)
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
double eval(const std::string &name, const edm::Ptr< reco::GsfElectron > &, double rho, float unbiased, float field_z, const reco::Track *trk=0) const
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
LowPtGsfElectronIDProducer(const edm::ParameterSet &)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EDGetTokenT< pat::ElectronCollection > patElectrons_
float electronID(const std::string &name) const
Returns a specific electron ID associated to the pat::Electron given its name.
const T * userData(const std::string &key) const
Returns user-defined data. Returns NULL if the data is not present, or not of type T...
Definition: PATObject.h:280
#define end
Definition: vmac.h:39
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:243
std::vector< float > features_V0(reco::GsfElectron const &ele, float rho, float unbiased)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isNull() const
Checks for null.
Definition: Ref.h:248
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
const edm::EDGetTokenT< double > rho_
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
edm::EDGetTokenT< edm::ValueMap< float > > unbiased_
reco::TrackRef closestCtfTrackRef() const override
override the reco::GsfElectron::closestCtfTrackRef method, to access the internal storage of the trac...
void add(std::string const &label, ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< edm::Association< reco::TrackCollection > > gsf2trk_
virtual GsfElectronCoreRef core() const
Definition: GsfElectron.cc:8
#define begin
Definition: vmac.h:32
HLT enums.
T get() const
Definition: EventSetup.h:71
bool isUninitialized() const
Definition: EDGetToken.h:70
void set(const reco::GsfElectronRef &ele, double rho)
def move(src, dest)
Definition: eostools.py:511
std::unique_ptr< const GBRForest > createGBRForest(const std::string &weightsFile)
Definition: event.py:1