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  EcalPFClusterIsoMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("EcalPFClusterIsoMap"))),
60  EleGsfTrackIsoMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("EleGsfTrackIsoMap"))),
61  HcalPFClusterIsoMap_(consumes<RecoEcalCandMap>(iConfig.getParameter<edm::InputTag>("HcalPFClusterIsoMap"))),
62  egammaPtCut(iConfig.getParameter<double>("egammaPtCut")),
63  egammaEtaCut(iConfig.getParameter<double>("egammaEtaCut")),
64  egammaHoverECut(iConfig.getParameter<double>("egammaHoverECut")),
65  egammaSigmaIEtaIEtaCut(iConfig.getParameter<std::vector<double>>("egammaSigmaIEtaIEtaCut")),
66  absEtaBinUpperEdges(iConfig.getParameter<std::vector<double>>("absEtaBinUpperEdges")),
67  mantissaPrecision(iConfig.getParameter<int>("mantissaPrecision")),
68  saveRecHitTiming(iConfig.getParameter<bool>("saveRecHitTiming")),
69  rechitMatrixSize(iConfig.getParameter<int>("rechitMatrixSize")), //(2n+1)^2
70  rechitZeroSuppression(iConfig.getParameter<bool>("rechitZeroSuppression")),
71  ecalRechitEB_(consumes<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>("ecalRechitEB"))),
72  ecalRechitEE_(consumes<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>("ecalRechitEE"))) {
73  // cross-check for compatibility in input vectors
74  if (absEtaBinUpperEdges.size() != egammaSigmaIEtaIEtaCut.size()) {
75  throw cms::Exception("IncompatibleVects")
76  << "size of \"absEtaBinUpperEdges\" (" << absEtaBinUpperEdges.size() << ") and \"egammaSigmaIEtaIEtaCut\" ("
77  << egammaSigmaIEtaIEtaCut.size() << ") differ";
78  }
79 
80  for (auto aIt = 1u; aIt < absEtaBinUpperEdges.size(); ++aIt) {
81  if (absEtaBinUpperEdges[aIt - 1] < 0 || absEtaBinUpperEdges[aIt] < 0) {
82  throw cms::Exception("IncorrectValue") << "absEtaBinUpperEdges entries should be greater than or equal to zero.";
83  }
84  if (absEtaBinUpperEdges[aIt - 1] >= absEtaBinUpperEdges[aIt]) {
85  throw cms::Exception("ImproperBinning") << "absEtaBinUpperEdges entries should be in increasing order.";
86  }
87  }
88 
89  if (not absEtaBinUpperEdges.empty() and absEtaBinUpperEdges[absEtaBinUpperEdges.size() - 1] < egammaEtaCut) {
90  throw cms::Exception("IncorrectValue")
91  << "Last entry in \"absEtaBinUpperEdges\" (" << absEtaBinUpperEdges[absEtaBinUpperEdges.size() - 1]
92  << ") should have a value larger than \"egammaEtaCut\" (" << egammaEtaCut << ").";
93  }
94 
95  //register products
96  produces<Run3ScoutingElectronCollection>();
97  produces<Run3ScoutingPhotonCollection>();
99 }
100 
102 
103 // ------------ method called to produce the data ------------
105  using namespace edm;
106 
107  auto outElectrons = std::make_unique<Run3ScoutingElectronCollection>();
108  auto outPhotons = std::make_unique<Run3ScoutingPhotonCollection>();
109 
110  // Get RecoEcalCandidate
111  Handle<reco::RecoEcalCandidateCollection> EgammaCandidateCollection;
112  if (!iEvent.getByToken(EgammaCandidateCollection_, EgammaCandidateCollection)) {
113  iEvent.put(std::move(outElectrons));
114  iEvent.put(std::move(outPhotons));
115  return;
116  }
117 
118  // Get GsfTrack
119  Handle<reco::GsfTrackCollection> EgammaGsfTrackCollection;
120  if (!iEvent.getByToken(EgammaGsfTrackCollection_, EgammaGsfTrackCollection)) {
121  iEvent.put(std::move(outElectrons));
122  iEvent.put(std::move(outPhotons));
123  return;
124  }
125 
126  // Get SigmaIEtaIEtaMap
128  if (!iEvent.getByToken(SigmaIEtaIEtaMap_, SigmaIEtaIEtaMap)) {
129  iEvent.put(std::move(outElectrons));
130  iEvent.put(std::move(outPhotons));
131  return;
132  }
133 
134  // Get R9Map
136  if (!iEvent.getByToken(R9Map_, R9Map)) {
137  iEvent.put(std::move(outElectrons));
138  iEvent.put(std::move(outPhotons));
139  return;
140  }
141 
142  // Get HoverEMap
144  if (!iEvent.getByToken(HoverEMap_, HoverEMap)) {
145  iEvent.put(std::move(outElectrons));
146  iEvent.put(std::move(outPhotons));
147  return;
148  }
149 
150  // Get DetaMap
152  if (!iEvent.getByToken(DetaMap_, DetaMap)) {
153  iEvent.put(std::move(outElectrons));
154  iEvent.put(std::move(outPhotons));
155  return;
156  }
157 
158  // Get DphiMap
160  if (!iEvent.getByToken(DphiMap_, DphiMap)) {
161  iEvent.put(std::move(outElectrons));
162  iEvent.put(std::move(outPhotons));
163  return;
164  }
165 
166  // Get MissingHitsMap
168  if (!iEvent.getByToken(MissingHitsMap_, MissingHitsMap)) {
169  iEvent.put(std::move(outElectrons));
170  iEvent.put(std::move(outPhotons));
171  return;
172  }
173 
174  // Get 1/E - 1/p Map
176  if (!iEvent.getByToken(OneOEMinusOneOPMap_, OneOEMinusOneOPMap)) {
177  iEvent.put(std::move(outElectrons));
178  iEvent.put(std::move(outPhotons));
179  return;
180  }
181 
182  // Get EcalPFClusterIsoMap
184  if (!iEvent.getByToken(EcalPFClusterIsoMap_, EcalPFClusterIsoMap)) {
185  iEvent.put(std::move(outElectrons));
186  iEvent.put(std::move(outPhotons));
187  return;
188  }
189 
190  // Get EleGsfTrackIsoMap
192  if (!iEvent.getByToken(EleGsfTrackIsoMap_, EleGsfTrackIsoMap)) {
193  iEvent.put(std::move(outElectrons));
194  iEvent.put(std::move(outPhotons));
195  return;
196  }
197 
198  // Get HcalPFClusterIsoMap
200  if (!iEvent.getByToken(HcalPFClusterIsoMap_, HcalPFClusterIsoMap)) {
201  iEvent.put(std::move(outElectrons));
202  iEvent.put(std::move(outPhotons));
203  return;
204  }
205 
208  iEvent.getByToken(ecalRechitEB_, rechitsEB);
209  iEvent.getByToken(ecalRechitEE_, rechitsEE);
210 
211  const CaloTopology* topology = &setup.getData(topologyToken_);
212 
213  // Produce electrons and photons
214  int index = 0;
215  for (auto& candidate : *EgammaCandidateCollection) {
216  reco::RecoEcalCandidateRef candidateRef = getRef(EgammaCandidateCollection, index);
217  ++index;
218  if (candidateRef.isNull() && !candidateRef.isAvailable())
219  continue;
220 
221  if (candidate.pt() < egammaPtCut)
222  continue;
223  if (fabs(candidate.eta()) > egammaEtaCut)
224  continue;
225 
226  reco::SuperClusterRef scRef = candidate.superCluster();
227  if (scRef.isNull() && !scRef.isAvailable())
228  continue;
229 
230  reco::CaloClusterPtr SCseed = candidate.superCluster()->seed();
231  const EcalRecHitCollection* rechits = (std::abs(scRef->eta()) < 1.479) ? rechitsEB.product() : rechitsEE.product();
232  Cluster2ndMoments moments = EcalClusterTools::cluster2ndMoments(*SCseed, *rechits);
233  float sMin = moments.sMin;
234  float sMaj = moments.sMaj;
235 
236  uint32_t seedId = (*SCseed).seed();
237 
238  std::vector<DetId> mDetIds = EcalClusterTools::matrixDetId((topology), (*SCseed).seed(), rechitMatrixSize);
239 
240  int detSize = mDetIds.size();
241  std::vector<uint32_t> mDetIdIds;
242  std::vector<float> mEnergies;
243  std::vector<float> mTimes;
244  mDetIdIds.reserve(detSize);
245  mEnergies.reserve(detSize);
246  mTimes.reserve(detSize);
247 
248  for (int i = 0; i < detSize; i++) {
249  auto const recHit_en = recHitE(mDetIds[i], *rechits);
250  if (not rechitZeroSuppression or recHit_en > 0) {
251  mDetIdIds.push_back(mDetIds[i]);
253  if (saveRecHitTiming) {
254  mTimes.push_back(
256  }
257  }
258  }
259 
260  auto const HoE = candidate.superCluster()->energy() != 0.
261  ? ((*HoverEMap)[candidateRef] / candidate.superCluster()->energy())
262  : 999.;
263  if (HoE > egammaHoverECut)
264  continue;
265 
266  if (not absEtaBinUpperEdges.empty()) {
267  auto const sinin = candidate.superCluster()->energy() != 0. ? (*SigmaIEtaIEtaMap)[candidateRef] : 999.;
268  auto etaBinIdx = std::distance(
269  absEtaBinUpperEdges.begin(),
270  std::lower_bound(absEtaBinUpperEdges.begin(), absEtaBinUpperEdges.end(), std::abs(candidate.eta())));
271 
272  if (sinin > egammaSigmaIEtaIEtaCut[etaBinIdx])
273  continue;
274  }
275 
276  unsigned int const maxTrkSize = EgammaGsfTrackCollection->size();
277  std::vector<float> trkd0;
278  std::vector<float> trkdz;
279  std::vector<float> trkpt;
280  std::vector<float> trketa;
281  std::vector<float> trkphi;
282  std::vector<float> trkpMode;
283  std::vector<float> trketaMode;
284  std::vector<float> trkphiMode;
285  std::vector<float> trkqoverpModeError;
286  std::vector<float> trkchi2overndf;
287  std::vector<int> trkcharge;
288  trkd0.reserve(maxTrkSize);
289  trkdz.reserve(maxTrkSize);
290  trkpt.reserve(maxTrkSize);
291  trketa.reserve(maxTrkSize);
292  trkphi.reserve(maxTrkSize);
293  trkpMode.reserve(maxTrkSize);
294  trketaMode.reserve(maxTrkSize);
295  trkphiMode.reserve(maxTrkSize);
296  trkqoverpModeError.reserve(maxTrkSize);
297  trkchi2overndf.reserve(maxTrkSize);
298  trkcharge.reserve(maxTrkSize);
299 
300  for (auto& track : *EgammaGsfTrackCollection) {
301  RefToBase<TrajectorySeed> seed = track.extra()->seedRef();
303  RefToBase<reco::CaloCluster> caloCluster = elseed->caloCluster();
304  reco::SuperClusterRef scRefFromTrk = caloCluster.castTo<reco::SuperClusterRef>();
305  if (scRefFromTrk == scRef) {
306  trkd0.push_back(track.d0());
307  trkdz.push_back(track.dz());
308  trkpt.push_back(track.pt());
309  trketa.push_back(track.eta());
310  trkphi.push_back(track.phi());
311  trkpMode.push_back(track.pMode());
312  trketaMode.push_back(track.etaMode());
313  trkphiMode.push_back(track.phiMode());
314  trkqoverpModeError.push_back(track.qoverpModeError());
315  auto const trackndof = track.ndof();
316  trkchi2overndf.push_back(((trackndof == 0) ? -1 : (track.chi2() / trackndof)));
317  trkcharge.push_back(track.charge());
318  }
319  }
320  if (trkcharge.empty()) { // No associated track. Candidate is a scouting photon
321  outPhotons->emplace_back(candidate.pt(),
322  candidate.eta(),
323  candidate.phi(),
324  candidate.mass(),
325  scRef->rawEnergy(),
326  scRef->preshowerEnergy(),
327  scRef->correctedEnergyUncertainty(),
328  (*SigmaIEtaIEtaMap)[candidateRef],
329  HoE,
330  (*EcalPFClusterIsoMap)[candidateRef],
331  (*HcalPFClusterIsoMap)[candidateRef],
332  0.,
333  (*R9Map)[candidateRef],
334  sMin,
335  sMaj,
336  seedId,
337  scRef->clustersSize(),
338  scRef->size(),
339  mEnergies,
340  mDetIdIds,
341  mTimes,
342  rechitZeroSuppression); //read for(ieta){for(iphi){}}
343  } else { // Candidate is a scouting electron
344  outElectrons->emplace_back(candidate.pt(),
345  candidate.eta(),
346  candidate.phi(),
347  candidate.mass(),
348  scRef->rawEnergy(),
349  scRef->preshowerEnergy(),
350  scRef->correctedEnergyUncertainty(),
351  trkd0,
352  trkdz,
353  trkpt,
354  trketa,
355  trkphi,
356  trkpMode,
357  trketaMode,
358  trkphiMode,
359  trkqoverpModeError,
360  trkchi2overndf,
361  (*DetaMap)[candidateRef],
362  (*DphiMap)[candidateRef],
363  (*SigmaIEtaIEtaMap)[candidateRef],
364  HoE,
365  (*OneOEMinusOneOPMap)[candidateRef],
366  (*MissingHitsMap)[candidateRef],
367  trkcharge,
368  0.0 /* waiting implementation of the track fbrem producer*/,
369  (*EcalPFClusterIsoMap)[candidateRef],
370  (*HcalPFClusterIsoMap)[candidateRef],
371  (*EleGsfTrackIsoMap)[candidateRef],
372  (*R9Map)[candidateRef],
373  sMin,
374  sMaj,
375  seedId,
376  scRef->clustersSize(),
377  scRef->size(),
378  mEnergies,
379  mDetIdIds,
380  mTimes,
381  rechitZeroSuppression); //read for(ieta){for(iphi){}}
382  }
383  }
384 
385  // Put output
386  iEvent.put(std::move(outElectrons));
387  iEvent.put(std::move(outPhotons));
388 }
389 
390 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
393  desc.add<edm::InputTag>("EgammaCandidates", edm::InputTag("hltEgammaCandidates"));
394  desc.add<edm::InputTag>("EgammaGsfTracks", edm::InputTag("hltEgammaGsfTracks"));
395  desc.add<edm::InputTag>("SigmaIEtaIEtaMap", edm::InputTag("hltEgammaClusterShape:sigmaIEtaIEta5x5"));
396  desc.add<edm::InputTag>("r9Map", edm::InputTag("hltEgammaR9ID:r95x5"));
397  desc.add<edm::InputTag>("HoverEMap", edm::InputTag("hltEgammaHoverE"));
398  desc.add<edm::InputTag>("DetaMap", edm::InputTag("hltEgammaGsfTrackVars:DetaSeed"));
399  desc.add<edm::InputTag>("DphiMap", edm::InputTag("hltEgammaGsfTrackVars:Dphi"));
400  desc.add<edm::InputTag>("MissingHitsMap", edm::InputTag("hltEgammaGsfTrackVars:MissingHits"));
401  desc.add<edm::InputTag>("OneOEMinusOneOPMap", edm::InputTag("hltEgammaGsfTrackVars:OneOESuperMinusOneOP"));
402  desc.add<edm::InputTag>("EcalPFClusterIsoMap", edm::InputTag("hltEgammaEcalPFClusterIso"));
403  desc.add<edm::InputTag>("EleGsfTrackIsoMap", edm::InputTag("hltEgammaEleGsfTrackIso"));
404  desc.add<edm::InputTag>("HcalPFClusterIsoMap", edm::InputTag("hltEgammaHcalPFClusterIso"));
405  desc.add<double>("egammaPtCut", 4.0);
406  desc.add<double>("egammaEtaCut", 2.5);
407  desc.add<double>("egammaHoverECut", 1.0);
408  desc.add<std::vector<double>>("egammaSigmaIEtaIEtaCut", {99999.0, 99999.0});
409  desc.add<std::vector<double>>("absEtaBinUpperEdges", {1.479, 5.0});
410  desc.add<bool>("saveRecHitTiming", false);
411  desc.add<int>("mantissaPrecision", 10)->setComment("default float16, change to 23 for float32");
412  desc.add<int>("rechitMatrixSize", 10);
413  desc.add<bool>("rechitZeroSuppression", true);
414  desc.add<edm::InputTag>("ecalRechitEB", edm::InputTag("hltEcalRecHit:EcalRecHitsEB"));
415  desc.add<edm::InputTag>("ecalRechitEE", edm::InputTag("hltEcalRecHit:EcalRecHitsEE"));
416  descriptions.add("hltScoutingEgammaProducer", desc);
417 }
418 
419 // 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 > 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 &)