CMS 3D CMS Logo

HLTScoutingEgammaProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: HLTrigger/Egamma
4 // Class: HLTScoutingEgammaProducer
5 //
11 //
12 // Original Author: David G. Sheffield (Rutgers)
13 // Created: Mon, 20 Jul 2015
14 //
15 //
16 
18 
19 #include <cstdint>
20 
21 // function to find rechhit associated to detid and return energy
22 float recHitE(const DetId id, const EcalRecHitCollection& recHits) {
23  if (id == DetId(0)) {
24  return 0;
25  } else {
27  if (it != recHits.end())
28  return (*it).energy();
29  }
30  return 0;
31 }
32 
33 float recHitT(const DetId id, const EcalRecHitCollection& recHits) {
34  if (id == DetId(0)) {
35  return 0;
36  } else {
38  if (it != recHits.end())
39  return (*it).time();
40  }
41  return 0;
42 }
43 
44 //
45 // constructors and destructor
46 //
48  : EgammaCandidateCollection_(
49  consumes<reco::RecoEcalCandidateCollection>(iConfig.getParameter<edm::InputTag>("EgammaCandidates"))),
50  EgammaGsfTrackCollection_(
51  consumes<reco::GsfTrackCollection>(iConfig.getParameter<edm::InputTag>("EgammaGsfTracks"))),
52  SigmaIEtaIEtaMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("SigmaIEtaIEtaMap"))),
53  R9Map_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("r9Map"))),
54  HoverEMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("HoverEMap"))),
55  DetaMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("DetaMap"))),
56  DphiMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("DphiMap"))),
57  MissingHitsMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("MissingHitsMap"))),
58  OneOEMinusOneOPMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("OneOEMinusOneOPMap"))),
59  fBremMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("fBremMap"))),
60  EcalPFClusterIsoMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("EcalPFClusterIsoMap"))),
61  EleGsfTrackIsoMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("EleGsfTrackIsoMap"))),
62  HcalPFClusterIsoMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("HcalPFClusterIsoMap"))),
63  egammaPtCut(iConfig.getParameter<double>("egammaPtCut")),
64  egammaEtaCut(iConfig.getParameter<double>("egammaEtaCut")),
65  egammaHoverECut(iConfig.getParameter<double>("egammaHoverECut")),
66  egammaSigmaIEtaIEtaCut(iConfig.getParameter<std::vector<double>>("egammaSigmaIEtaIEtaCut")),
67  absEtaBinUpperEdges(iConfig.getParameter<std::vector<double>>("absEtaBinUpperEdges")),
68  mantissaPrecision(iConfig.getParameter<int>("mantissaPrecision")),
69  saveRecHitTiming(iConfig.getParameter<bool>("saveRecHitTiming")),
70  rechitMatrixSize(iConfig.getParameter<int>("rechitMatrixSize")), //(2n+1)^2
71  rechitZeroSuppression(iConfig.getParameter<bool>("rechitZeroSuppression")),
72  ecalRechitEB_(consumes<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>("ecalRechitEB"))),
73  ecalRechitEE_(consumes<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>("ecalRechitEE"))) {
74  // cross-check for compatibility in input vectors
75  if (absEtaBinUpperEdges.size() != egammaSigmaIEtaIEtaCut.size()) {
76  throw cms::Exception("IncompatibleVects")
77  << "size of \"absEtaBinUpperEdges\" (" << absEtaBinUpperEdges.size() << ") and \"egammaSigmaIEtaIEtaCut\" ("
78  << egammaSigmaIEtaIEtaCut.size() << ") differ";
79  }
80 
81  for (auto aIt = 1u; aIt < absEtaBinUpperEdges.size(); ++aIt) {
82  if (absEtaBinUpperEdges[aIt - 1] < 0 || absEtaBinUpperEdges[aIt] < 0) {
83  throw cms::Exception("IncorrectValue") << "absEtaBinUpperEdges entries should be greater than or equal to zero.";
84  }
85  if (absEtaBinUpperEdges[aIt - 1] >= absEtaBinUpperEdges[aIt]) {
86  throw cms::Exception("ImproperBinning") << "absEtaBinUpperEdges entries should be in increasing order.";
87  }
88  }
89 
90  if (not absEtaBinUpperEdges.empty() and absEtaBinUpperEdges[absEtaBinUpperEdges.size() - 1] < egammaEtaCut) {
91  throw cms::Exception("IncorrectValue")
92  << "Last entry in \"absEtaBinUpperEdges\" (" << absEtaBinUpperEdges[absEtaBinUpperEdges.size() - 1]
93  << ") should have a value larger than \"egammaEtaCut\" (" << egammaEtaCut << ").";
94  }
95 
96  //register products
97  produces<Run3ScoutingElectronCollection>();
98  produces<Run3ScoutingPhotonCollection>();
100 }
101 
103 
104 // ------------ method called to produce the data ------------
106  using namespace edm;
107 
108  auto outElectrons = std::make_unique<Run3ScoutingElectronCollection>();
109  auto outPhotons = std::make_unique<Run3ScoutingPhotonCollection>();
110 
111  // Get RecoEcalCandidate
112  Handle<reco::RecoEcalCandidateCollection> EgammaCandidateCollection;
113  if (!iEvent.getByToken(EgammaCandidateCollection_, EgammaCandidateCollection)) {
114  iEvent.put(std::move(outElectrons));
115  iEvent.put(std::move(outPhotons));
116  return;
117  }
118 
119  // Get GsfTrack
120  Handle<reco::GsfTrackCollection> EgammaGsfTrackCollection;
121  if (!iEvent.getByToken(EgammaGsfTrackCollection_, EgammaGsfTrackCollection)) {
122  iEvent.put(std::move(outElectrons));
123  iEvent.put(std::move(outPhotons));
124  return;
125  }
126 
127  // Get SigmaIEtaIEtaMap
129  if (!iEvent.getByToken(SigmaIEtaIEtaMap_, SigmaIEtaIEtaMap)) {
130  iEvent.put(std::move(outElectrons));
131  iEvent.put(std::move(outPhotons));
132  return;
133  }
134 
135  // Get R9Map
137  if (!iEvent.getByToken(R9Map_, R9Map)) {
138  iEvent.put(std::move(outElectrons));
139  iEvent.put(std::move(outPhotons));
140  return;
141  }
142 
143  // Get HoverEMap
145  if (!iEvent.getByToken(HoverEMap_, HoverEMap)) {
146  iEvent.put(std::move(outElectrons));
147  iEvent.put(std::move(outPhotons));
148  return;
149  }
150 
151  // Get DetaMap
153  if (!iEvent.getByToken(DetaMap_, DetaMap)) {
154  iEvent.put(std::move(outElectrons));
155  iEvent.put(std::move(outPhotons));
156  return;
157  }
158 
159  // Get DphiMap
161  if (!iEvent.getByToken(DphiMap_, DphiMap)) {
162  iEvent.put(std::move(outElectrons));
163  iEvent.put(std::move(outPhotons));
164  return;
165  }
166 
167  // Get MissingHitsMap
169  if (!iEvent.getByToken(MissingHitsMap_, MissingHitsMap)) {
170  iEvent.put(std::move(outElectrons));
171  iEvent.put(std::move(outPhotons));
172  return;
173  }
174 
175  // Get 1/E - 1/p Map
177  if (!iEvent.getByToken(OneOEMinusOneOPMap_, OneOEMinusOneOPMap)) {
178  iEvent.put(std::move(outElectrons));
179  iEvent.put(std::move(outPhotons));
180  return;
181  }
182 
183  // Get fBrem Map
185  if (!iEvent.getByToken(fBremMap_, fBremMap)) {
186  iEvent.put(std::move(outElectrons));
187  iEvent.put(std::move(outPhotons));
188  return;
189  }
190 
191  // Get EcalPFClusterIsoMap
193  if (!iEvent.getByToken(EcalPFClusterIsoMap_, EcalPFClusterIsoMap)) {
194  iEvent.put(std::move(outElectrons));
195  iEvent.put(std::move(outPhotons));
196  return;
197  }
198 
199  // Get EleGsfTrackIsoMap
201  if (!iEvent.getByToken(EleGsfTrackIsoMap_, EleGsfTrackIsoMap)) {
202  iEvent.put(std::move(outElectrons));
203  iEvent.put(std::move(outPhotons));
204  return;
205  }
206 
207  // Get HcalPFClusterIsoMap
209  if (!iEvent.getByToken(HcalPFClusterIsoMap_, HcalPFClusterIsoMap)) {
210  iEvent.put(std::move(outElectrons));
211  iEvent.put(std::move(outPhotons));
212  return;
213  }
214 
217  iEvent.getByToken(ecalRechitEB_, rechitsEB);
218  iEvent.getByToken(ecalRechitEE_, rechitsEE);
219 
220  const CaloTopology* topology = &setup.getData(topologyToken_);
221 
222  // Produce electrons and photons
223  int index = 0;
224  for (auto& candidate : *EgammaCandidateCollection) {
225  reco::RecoEcalCandidateRef candidateRef = getRef(EgammaCandidateCollection, index);
226  ++index;
227  if (candidateRef.isNull() && !candidateRef.isAvailable())
228  continue;
229 
230  if (candidate.pt() < egammaPtCut)
231  continue;
232  if (fabs(candidate.eta()) > egammaEtaCut)
233  continue;
234 
235  reco::SuperClusterRef scRef = candidate.superCluster();
236  if (scRef.isNull() && !scRef.isAvailable())
237  continue;
238 
239  reco::CaloClusterPtr SCseed = candidate.superCluster()->seed();
240  const EcalRecHitCollection* rechits = (std::abs(scRef->eta()) < 1.479) ? rechitsEB.product() : rechitsEE.product();
241  Cluster2ndMoments moments = EcalClusterTools::cluster2ndMoments(*SCseed, *rechits);
242  float sMin = moments.sMin;
243  float sMaj = moments.sMaj;
244 
245  uint32_t seedId = (*SCseed).seed();
246 
247  std::vector<DetId> mDetIds = EcalClusterTools::matrixDetId((topology), (*SCseed).seed(), rechitMatrixSize);
248 
249  int detSize = mDetIds.size();
250  std::vector<uint32_t> mDetIdIds;
251  std::vector<float> mEnergies;
252  std::vector<float> mTimes;
253  mDetIdIds.reserve(detSize);
254  mEnergies.reserve(detSize);
255  mTimes.reserve(detSize);
256 
257  for (int i = 0; i < detSize; i++) {
258  auto const recHit_en = recHitE(mDetIds[i], *rechits);
259  if (not rechitZeroSuppression or recHit_en > 0) {
260  mDetIdIds.push_back(mDetIds[i]);
262  if (saveRecHitTiming) {
263  mTimes.push_back(
265  }
266  }
267  }
268 
269  auto const HoE = candidate.superCluster()->energy() != 0.
270  ? ((*HoverEMap)[candidateRef] / candidate.superCluster()->energy())
271  : 999.;
272  if (HoE > egammaHoverECut)
273  continue;
274 
275  if (not absEtaBinUpperEdges.empty()) {
276  auto const sinin = candidate.superCluster()->energy() != 0. ? (*SigmaIEtaIEtaMap)[candidateRef] : 999.;
277  auto etaBinIdx = std::distance(
278  absEtaBinUpperEdges.begin(),
279  std::lower_bound(absEtaBinUpperEdges.begin(), absEtaBinUpperEdges.end(), std::abs(candidate.eta())));
280 
281  if (sinin > egammaSigmaIEtaIEtaCut[etaBinIdx])
282  continue;
283  }
284 
285  unsigned int const maxTrkSize = EgammaGsfTrackCollection->size();
286  std::vector<float> trkd0;
287  std::vector<float> trkdz;
288  std::vector<float> trkpt;
289  std::vector<float> trketa;
290  std::vector<float> trkphi;
291  std::vector<float> trkpMode;
292  std::vector<float> trketaMode;
293  std::vector<float> trkphiMode;
294  std::vector<float> trkqoverpModeError;
295  std::vector<float> trkchi2overndf;
296  std::vector<int> trkcharge;
297  trkd0.reserve(maxTrkSize);
298  trkdz.reserve(maxTrkSize);
299  trkpt.reserve(maxTrkSize);
300  trketa.reserve(maxTrkSize);
301  trkphi.reserve(maxTrkSize);
302  trkpMode.reserve(maxTrkSize);
303  trketaMode.reserve(maxTrkSize);
304  trkphiMode.reserve(maxTrkSize);
305  trkqoverpModeError.reserve(maxTrkSize);
306  trkchi2overndf.reserve(maxTrkSize);
307  trkcharge.reserve(maxTrkSize);
308 
309  for (auto& track : *EgammaGsfTrackCollection) {
310  RefToBase<TrajectorySeed> seed = track.extra()->seedRef();
312  RefToBase<reco::CaloCluster> caloCluster = elseed->caloCluster();
313  reco::SuperClusterRef scRefFromTrk = caloCluster.castTo<reco::SuperClusterRef>();
314  if (scRefFromTrk == scRef) {
315  trkd0.push_back(track.d0());
316  trkdz.push_back(track.dz());
317  trkpt.push_back(track.pt());
318  trketa.push_back(track.eta());
319  trkphi.push_back(track.phi());
320  trkpMode.push_back(track.pMode());
321  trketaMode.push_back(track.etaMode());
322  trkphiMode.push_back(track.phiMode());
323  trkqoverpModeError.push_back(track.qoverpModeError());
324  auto const trackndof = track.ndof();
325  trkchi2overndf.push_back(((trackndof == 0) ? -1 : (track.chi2() / trackndof)));
326  trkcharge.push_back(track.charge());
327  }
328  }
329  if (trkcharge.empty()) { // No associated track. Candidate is a scouting photon
330  outPhotons->emplace_back(candidate.pt(),
331  candidate.eta(),
332  candidate.phi(),
333  candidate.mass(),
334  scRef->rawEnergy(),
335  scRef->preshowerEnergy(),
336  scRef->correctedEnergyUncertainty(),
337  (*SigmaIEtaIEtaMap)[candidateRef],
338  HoE,
339  (*EcalPFClusterIsoMap)[candidateRef],
340  (*HcalPFClusterIsoMap)[candidateRef],
341  0.,
342  (*R9Map)[candidateRef],
343  sMin,
344  sMaj,
345  seedId,
346  scRef->clustersSize(),
347  scRef->size(),
348  mEnergies,
349  mDetIdIds,
350  mTimes,
351  rechitZeroSuppression); //read for(ieta){for(iphi){}}
352  } else { // Candidate is a scouting electron
353  outElectrons->emplace_back(candidate.pt(),
354  candidate.eta(),
355  candidate.phi(),
356  candidate.mass(),
357  scRef->rawEnergy(),
358  scRef->preshowerEnergy(),
359  scRef->correctedEnergyUncertainty(),
360  trkd0,
361  trkdz,
362  trkpt,
363  trketa,
364  trkphi,
365  trkpMode,
366  trketaMode,
367  trkphiMode,
368  trkqoverpModeError,
369  trkchi2overndf,
370  (*DetaMap)[candidateRef],
371  (*DphiMap)[candidateRef],
372  (*SigmaIEtaIEtaMap)[candidateRef],
373  HoE,
374  (*OneOEMinusOneOPMap)[candidateRef],
375  (*MissingHitsMap)[candidateRef],
376  trkcharge,
377  (*fBremMap)[candidateRef],
378  (*EcalPFClusterIsoMap)[candidateRef],
379  (*HcalPFClusterIsoMap)[candidateRef],
380  (*EleGsfTrackIsoMap)[candidateRef],
381  (*R9Map)[candidateRef],
382  sMin,
383  sMaj,
384  seedId,
385  scRef->clustersSize(),
386  scRef->size(),
387  mEnergies,
388  mDetIdIds,
389  mTimes,
390  rechitZeroSuppression); //read for(ieta){for(iphi){}}
391  }
392  }
393 
394  // Put output
395  iEvent.put(std::move(outElectrons));
396  iEvent.put(std::move(outPhotons));
397 }
398 
399 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
402  desc.add<edm::InputTag>("EgammaCandidates", edm::InputTag("hltEgammaCandidates"));
403  desc.add<edm::InputTag>("EgammaGsfTracks", edm::InputTag("hltEgammaGsfTracks"));
404  desc.add<edm::InputTag>("SigmaIEtaIEtaMap", edm::InputTag("hltEgammaClusterShape:sigmaIEtaIEta5x5"));
405  desc.add<edm::InputTag>("r9Map", edm::InputTag("hltEgammaR9ID:r95x5"));
406  desc.add<edm::InputTag>("HoverEMap", edm::InputTag("hltEgammaHoverE"));
407  desc.add<edm::InputTag>("DetaMap", edm::InputTag("hltEgammaGsfTrackVarsUnseeded:DetaSeed"));
408  desc.add<edm::InputTag>("DphiMap", edm::InputTag("hltEgammaGsfTrackVarsUnseeded:Dphi"));
409  desc.add<edm::InputTag>("MissingHitsMap", edm::InputTag("hltEgammaGsfTrackVarsUnseeded:MissingHits"));
410  desc.add<edm::InputTag>("OneOEMinusOneOPMap", edm::InputTag("hltEgammaGsfTrackVarsUnseeded:OneOESuperMinusOneOP"));
411  desc.add<edm::InputTag>("fBremMap", edm::InputTag("hltEgammaGsfTrackVarsUnseeded:fbrem"));
412  desc.add<edm::InputTag>("EcalPFClusterIsoMap", edm::InputTag("hltEgammaEcalPFClusterIso"));
413  desc.add<edm::InputTag>("EleGsfTrackIsoMap", edm::InputTag("hltEgammaEleGsfTrackIso"));
414  desc.add<edm::InputTag>("HcalPFClusterIsoMap", edm::InputTag("hltEgammaHcalPFClusterIso"));
415  desc.add<double>("egammaPtCut", 4.0);
416  desc.add<double>("egammaEtaCut", 2.5);
417  desc.add<double>("egammaHoverECut", 1.0);
418  desc.add<std::vector<double>>("egammaSigmaIEtaIEtaCut", {99999.0, 99999.0});
419  desc.add<std::vector<double>>("absEtaBinUpperEdges", {1.479, 5.0});
420  desc.add<bool>("saveRecHitTiming", false);
421  desc.add<int>("mantissaPrecision", 10)->setComment("default float16, change to 23 for float32");
422  desc.add<int>("rechitMatrixSize", 10);
423  desc.add<bool>("rechitZeroSuppression", true);
424  desc.add<edm::InputTag>("ecalRechitEB", edm::InputTag("hltEcalRecHit:EcalRecHitsEB"));
425  desc.add<edm::InputTag>("ecalRechitEE", edm::InputTag("hltEcalRecHit:EcalRecHitsEE"));
426  descriptions.add("hltScoutingEgammaProducer", desc);
427 }
428 
429 // declare this class as a framework plugin
helper::MatcherGetRef< C >::ref_type getRef(const Handle< C > &c, size_t k)
Definition: getRef.h:28
const edm::EDGetTokenT< RecoEcalCandMap > SigmaIEtaIEtaMap_
const edm::EDGetTokenT< EcalRecHitCollection > ecalRechitEE_
edm::ESGetToken< CaloTopology, CaloTopologyRecord > topologyToken_
const edm::EDGetTokenT< RecoEcalCandMap > R9Map_
const std::vector< double > egammaSigmaIEtaIEtaCut
T const * product() const
Definition: Handle.h:70
std::vector< EcalRecHit >::const_iterator const_iterator
const edm::EDGetTokenT< reco::GsfTrackCollection > EgammaGsfTrackCollection_
const edm::EDGetTokenT< RecoEcalCandMap > EleGsfTrackIsoMap_
const edm::EDGetTokenT< RecoEcalCandMap > fBremMap_
const edm::EDGetTokenT< RecoEcalCandMap > HoverEMap_
const edm::EDGetTokenT< reco::RecoEcalCandidateCollection > EgammaCandidateCollection_
const std::vector< double > absEtaBinUpperEdges
int iEvent
Definition: GenABIO.cc:224
const edm::EDGetTokenT< RecoEcalCandMap > DetaMap_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
bool isAvailable() const
Definition: Ref.h:541
std::vector< GsfTrack > GsfTrackCollection
collection of GsfTracks
Definition: GsfTrackFwd.h:9
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
bool isNull() const
Checks for null.
Definition: Ref.h:235
float recHitT(const DetId id, const EcalRecHitCollection &recHits)
const edm::EDGetTokenT< RecoEcalCandMap > OneOEMinusOneOPMap_
const edm::EDGetTokenT< RecoEcalCandMap > MissingHitsMap_
const edm::EDGetTokenT< RecoEcalCandMap > DphiMap_
Definition: DetId.h:17
void add(std::string const &label, ParameterSetDescription const &psetDescription)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< RecoEcalCandidate > RecoEcalCandidateCollection
collectin of RecoEcalCandidate objects
void produce(edm::StreamID sid, edm::Event &iEvent, edm::EventSetup const &setup) const final
static float reduceMantissaToNbitsRounding(const float &f)
Definition: libminifloat.h:79
fixed size matrix
HLT enums.
const edm::EDGetTokenT< EcalRecHitCollection > ecalRechitEB_
float recHitE(const DetId id, const EcalRecHitCollection &recHits)
~HLTScoutingEgammaProducer() override
const edm::EDGetTokenT< RecoEcalCandMap > HcalPFClusterIsoMap_
def move(src, dest)
Definition: eostools.py:511
const edm::EDGetTokenT< RecoEcalCandMap > EcalPFClusterIsoMap_
HLTScoutingEgammaProducer(const edm::ParameterSet &)