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  float d0 = 0.0;
277  float dz = 0.0;
278  int charge = -999;
279  for (auto& track : *EgammaGsfTrackCollection) {
280  RefToBase<TrajectorySeed> seed = track.extra()->seedRef();
282  RefToBase<reco::CaloCluster> caloCluster = elseed->caloCluster();
283  reco::SuperClusterRef scRefFromTrk = caloCluster.castTo<reco::SuperClusterRef>();
284  if (scRefFromTrk == scRef) {
285  d0 = track.d0();
286  dz = track.dz();
287  charge = track.charge();
288  }
289  }
290  if (charge == -999) { // No associated track. Candidate is a scouting photon
291  outPhotons->emplace_back(candidate.pt(),
292  candidate.eta(),
293  candidate.phi(),
294  candidate.mass(),
295  (*SigmaIEtaIEtaMap)[candidateRef],
296  HoE,
297  (*EcalPFClusterIsoMap)[candidateRef],
298  (*HcalPFClusterIsoMap)[candidateRef],
299  0.,
300  (*R9Map)[candidateRef],
301  sMin,
302  sMaj,
303  seedId,
304  mEnergies,
305  mDetIdIds,
306  mTimes,
307  rechitZeroSuppression); //read for(ieta){for(iphi){}}
308  } else { // Candidate is a scouting electron
309  outElectrons->emplace_back(candidate.pt(),
310  candidate.eta(),
311  candidate.phi(),
312  candidate.mass(),
313  d0,
314  dz,
315  (*DetaMap)[candidateRef],
316  (*DphiMap)[candidateRef],
317  (*SigmaIEtaIEtaMap)[candidateRef],
318  HoE,
319  (*OneOEMinusOneOPMap)[candidateRef],
320  (*MissingHitsMap)[candidateRef],
321  charge,
322  (*EcalPFClusterIsoMap)[candidateRef],
323  (*HcalPFClusterIsoMap)[candidateRef],
324  (*EleGsfTrackIsoMap)[candidateRef],
325  (*R9Map)[candidateRef],
326  sMin,
327  sMaj,
328  seedId,
329  mEnergies,
330  mDetIdIds,
331  mTimes,
332  rechitZeroSuppression); //read for(ieta){for(iphi){}}
333  }
334  }
335 
336  // Put output
337  iEvent.put(std::move(outElectrons));
338  iEvent.put(std::move(outPhotons));
339 }
340 
341 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
344  desc.add<edm::InputTag>("EgammaCandidates", edm::InputTag("hltEgammaCandidates"));
345  desc.add<edm::InputTag>("EgammaGsfTracks", edm::InputTag("hltEgammaGsfTracks"));
346  desc.add<edm::InputTag>("SigmaIEtaIEtaMap", edm::InputTag("hltEgammaClusterShape:sigmaIEtaIEta5x5"));
347  desc.add<edm::InputTag>("r9Map", edm::InputTag("hltEgammaR9ID:r95x5"));
348  desc.add<edm::InputTag>("HoverEMap", edm::InputTag("hltEgammaHoverE"));
349  desc.add<edm::InputTag>("DetaMap", edm::InputTag("hltEgammaGsfTrackVars:DetaSeed"));
350  desc.add<edm::InputTag>("DphiMap", edm::InputTag("hltEgammaGsfTrackVars:Dphi"));
351  desc.add<edm::InputTag>("MissingHitsMap", edm::InputTag("hltEgammaGsfTrackVars:MissingHits"));
352  desc.add<edm::InputTag>("OneOEMinusOneOPMap", edm::InputTag("hltEgammaGsfTrackVars:OneOESuperMinusOneOP"));
353  desc.add<edm::InputTag>("EcalPFClusterIsoMap", edm::InputTag("hltEgammaEcalPFClusterIso"));
354  desc.add<edm::InputTag>("EleGsfTrackIsoMap", edm::InputTag("hltEgammaEleGsfTrackIso"));
355  desc.add<edm::InputTag>("HcalPFClusterIsoMap", edm::InputTag("hltEgammaHcalPFClusterIso"));
356  desc.add<double>("egammaPtCut", 4.0);
357  desc.add<double>("egammaEtaCut", 2.5);
358  desc.add<double>("egammaHoverECut", 1.0);
359  desc.add<std::vector<double>>("egammaSigmaIEtaIEtaCut", {99999.0, 99999.0});
360  desc.add<std::vector<double>>("absEtaBinUpperEdges", {1.479, 5.0});
361  desc.add<bool>("saveRecHitTiming", false);
362  desc.add<int>("mantissaPrecision", 10)->setComment("default float16, change to 23 for float32");
363  desc.add<int>("rechitMatrixSize", 10);
364  desc.add<bool>("rechitZeroSuppression", true);
365  desc.add<edm::InputTag>("ecalRechitEB", edm::InputTag("hltEcalRecHit:EcalRecHitsEB"));
366  desc.add<edm::InputTag>("ecalRechitEE", edm::InputTag("hltEcalRecHit:EcalRecHitsEE"));
367  descriptions.add("hltScoutingEgammaProducer", desc);
368 }
369 
370 // 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
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
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:537
std::vector< GsfTrack > GsfTrackCollection
collection of GsfTracks
Definition: GsfTrackFwd.h:9
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
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
static constexpr float d0
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 &)