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> trkchi2overndf;
283  std::vector<int> trkcharge;
284  trkd0.reserve(maxTrkSize);
285  trkdz.reserve(maxTrkSize);
286  trkpt.reserve(maxTrkSize);
287  trketa.reserve(maxTrkSize);
288  trkphi.reserve(maxTrkSize);
289  trkchi2overndf.reserve(maxTrkSize);
290  trkcharge.reserve(maxTrkSize);
291 
292  for (auto& track : *EgammaGsfTrackCollection) {
293  RefToBase<TrajectorySeed> seed = track.extra()->seedRef();
295  RefToBase<reco::CaloCluster> caloCluster = elseed->caloCluster();
296  reco::SuperClusterRef scRefFromTrk = caloCluster.castTo<reco::SuperClusterRef>();
297  if (scRefFromTrk == scRef) {
298  trkd0.push_back(track.d0());
299  trkdz.push_back(track.dz());
300  trkpt.push_back(track.pt());
301  trketa.push_back(track.eta());
302  trkphi.push_back(track.phi());
303  auto const trackndof = track.ndof();
304  trkchi2overndf.push_back(((trackndof == 0) ? -1 : (track.chi2() / trackndof)));
305  trkcharge.push_back(track.charge());
306  }
307  }
308  if (trkcharge.empty()) { // No associated track. Candidate is a scouting photon
309  outPhotons->emplace_back(candidate.pt(),
310  candidate.eta(),
311  candidate.phi(),
312  candidate.mass(),
313  (*SigmaIEtaIEtaMap)[candidateRef],
314  HoE,
315  (*EcalPFClusterIsoMap)[candidateRef],
316  (*HcalPFClusterIsoMap)[candidateRef],
317  0.,
318  (*R9Map)[candidateRef],
319  sMin,
320  sMaj,
321  seedId,
322  mEnergies,
323  mDetIdIds,
324  mTimes,
325  rechitZeroSuppression); //read for(ieta){for(iphi){}}
326  } else { // Candidate is a scouting electron
327  outElectrons->emplace_back(candidate.pt(),
328  candidate.eta(),
329  candidate.phi(),
330  candidate.mass(),
331  trkd0,
332  trkdz,
333  trkpt,
334  trketa,
335  trkphi,
336  trkchi2overndf,
337  (*DetaMap)[candidateRef],
338  (*DphiMap)[candidateRef],
339  (*SigmaIEtaIEtaMap)[candidateRef],
340  HoE,
341  (*OneOEMinusOneOPMap)[candidateRef],
342  (*MissingHitsMap)[candidateRef],
343  trkcharge,
344  (*EcalPFClusterIsoMap)[candidateRef],
345  (*HcalPFClusterIsoMap)[candidateRef],
346  (*EleGsfTrackIsoMap)[candidateRef],
347  (*R9Map)[candidateRef],
348  sMin,
349  sMaj,
350  seedId,
351  mEnergies,
352  mDetIdIds,
353  mTimes,
354  rechitZeroSuppression); //read for(ieta){for(iphi){}}
355  }
356  }
357 
358  // Put output
359  iEvent.put(std::move(outElectrons));
360  iEvent.put(std::move(outPhotons));
361 }
362 
363 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
366  desc.add<edm::InputTag>("EgammaCandidates", edm::InputTag("hltEgammaCandidates"));
367  desc.add<edm::InputTag>("EgammaGsfTracks", edm::InputTag("hltEgammaGsfTracks"));
368  desc.add<edm::InputTag>("SigmaIEtaIEtaMap", edm::InputTag("hltEgammaClusterShape:sigmaIEtaIEta5x5"));
369  desc.add<edm::InputTag>("r9Map", edm::InputTag("hltEgammaR9ID:r95x5"));
370  desc.add<edm::InputTag>("HoverEMap", edm::InputTag("hltEgammaHoverE"));
371  desc.add<edm::InputTag>("DetaMap", edm::InputTag("hltEgammaGsfTrackVars:DetaSeed"));
372  desc.add<edm::InputTag>("DphiMap", edm::InputTag("hltEgammaGsfTrackVars:Dphi"));
373  desc.add<edm::InputTag>("MissingHitsMap", edm::InputTag("hltEgammaGsfTrackVars:MissingHits"));
374  desc.add<edm::InputTag>("OneOEMinusOneOPMap", edm::InputTag("hltEgammaGsfTrackVars:OneOESuperMinusOneOP"));
375  desc.add<edm::InputTag>("EcalPFClusterIsoMap", edm::InputTag("hltEgammaEcalPFClusterIso"));
376  desc.add<edm::InputTag>("EleGsfTrackIsoMap", edm::InputTag("hltEgammaEleGsfTrackIso"));
377  desc.add<edm::InputTag>("HcalPFClusterIsoMap", edm::InputTag("hltEgammaHcalPFClusterIso"));
378  desc.add<double>("egammaPtCut", 4.0);
379  desc.add<double>("egammaEtaCut", 2.5);
380  desc.add<double>("egammaHoverECut", 1.0);
381  desc.add<std::vector<double>>("egammaSigmaIEtaIEtaCut", {99999.0, 99999.0});
382  desc.add<std::vector<double>>("absEtaBinUpperEdges", {1.479, 5.0});
383  desc.add<bool>("saveRecHitTiming", false);
384  desc.add<int>("mantissaPrecision", 10)->setComment("default float16, change to 23 for float32");
385  desc.add<int>("rechitMatrixSize", 10);
386  desc.add<bool>("rechitZeroSuppression", true);
387  desc.add<edm::InputTag>("ecalRechitEB", edm::InputTag("hltEcalRecHit:EcalRecHitsEB"));
388  desc.add<edm::InputTag>("ecalRechitEE", edm::InputTag("hltEcalRecHit:EcalRecHitsEE"));
389  descriptions.add("hltScoutingEgammaProducer", desc);
390 }
391 
392 // 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 &)