CMS 3D CMS Logo

EgammaHLTPhase2ExtraProducer.cc
Go to the documentation of this file.
8 
21 
26 
30 
31 #include <vector>
32 #include <unordered_map>
33 
34 //class complements EgammaHLTExtraProducer and adds all the phase-II specific E/g HLT debug information to the event
35 //this allows phase-II to be factorised from the standard class rather than having to extend EgammaHLTExtraProducer to deal with it
36 //although to be fair, given all the phase-II code is now in the release, the need for this factorisation is not as great
37 //and ultimately it could be merged into EgammaHLTExtraProducer
38 
39 namespace {
40  //changes double to string for product name
41  //ie "." is replaced with "p" and for -ve vals, string is M instead so -28 is M28
42  //has a fixed precision of precision although it removes trailing zeros and the .
43  std::string convertToProdNameStr(double val, int precision = 3) {
44  std::ostringstream valOStr;
45  valOStr << std::fixed << std::setprecision(precision) << val;
46  std::string valStr = valOStr.str();
47  while (valStr.size() > 1 && valStr.back() == '0') {
48  valStr.pop_back();
49  }
50  if (valStr.size() > 1 && valStr.back() == '.') {
51  valStr.pop_back();
52  }
53  auto decPoint = valStr.find('.');
54  if (decPoint != std::string::npos) {
55  valStr.replace(decPoint, 1, "p");
56  }
57  if (val < 0)
58  valStr.replace(0, 1, "M");
59  return valStr;
60  }
61 
62  template <typename T>
63  std::vector<std::unique_ptr<int>> countRecHits(const T& recHitHandle, const std::vector<double>& thresholds) {
64  std::vector<std::unique_ptr<int>> counts(thresholds.size());
65  for (auto& count : counts)
66  count = std::make_unique<int>(0);
67  if (recHitHandle.isValid()) {
68  for (const auto& recHit : *recHitHandle) {
69  for (size_t thresNr = 0; thresNr < thresholds.size(); thresNr++) {
70  if (recHit.energy() >= thresholds[thresNr]) {
71  (*counts[thresNr])++;
72  }
73  }
74  }
75  }
76  return counts;
77  }
78 } // namespace
79 
81 public:
83 
84  void produce(edm::StreamID streamID, edm::Event& event, const edm::EventSetup& eventSetup) const override;
85  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
86 
87 private:
88  template <typename CollType, typename RefType>
89  std::unique_ptr<CollType> filterObjs(const trigger::EgammaObjectCollection& egTrigObjs,
91  std::vector<RefType>& orgRefs,
92  float maxDR2 = 0.4 * 0.4) const;
93 
94  //these three filter functions are overly similar but with annoying differences
95  //eg rechits needs to access geometry, trk dr is also w.r.t the track eta/phi
96  //still could collapse into a single function
97  template <typename RecHitCollection>
98  std::unique_ptr<RecHitCollection> filterRecHits(const trigger::EgammaObjectCollection& egTrigObjs,
100  const CaloGeometry& geom,
101  float maxDR2 = 0.4 * 0.4) const;
102 
103  struct Tokens {
110  std::vector<std::pair<edm::EDGetTokenT<HGCRecHitCollection>, std::string>> hgcal;
111 
112  template <typename T>
115  const edm::ParameterSet& pset,
116  const std::string& tagname) {
117  token = cc.consumes<T>(pset.getParameter<edm::InputTag>(tagname));
118  }
119  template <typename T>
122  const edm::ParameterSet& pset,
123  const std::string& tagname) {
124  auto inputTags = pset.getParameter<std::vector<edm::InputTag>>(tagname);
125  tokens.resize(inputTags.size());
126  for (size_t tagNr = 0; tagNr < inputTags.size(); tagNr++) {
127  tokens[tagNr] = cc.consumes<T>(inputTags[tagNr]);
128  }
129  }
130  template <typename T>
131  static void setToken(std::vector<std::pair<edm::EDGetTokenT<T>, std::string>>& tokens,
133  const edm::ParameterSet& pset,
134  const std::string& tagname) {
135  const auto& collectionPSets = pset.getParameter<std::vector<edm::ParameterSet>>(tagname);
136  for (const auto& collPSet : collectionPSets) {
137  edm::EDGetTokenT<T> token = cc.consumes<T>(collPSet.getParameter<edm::InputTag>("src"));
138  std::string label = collPSet.getParameter<std::string>("label");
139  tokens.emplace_back(std::make_pair(token, label));
140  }
141  }
143  };
144  template <typename T, typename H>
145  static std::unique_ptr<edm::ValueMap<T>> makeValueMap(const H& handle, const std::vector<T>& values) {
146  auto valueMap = std::make_unique<edm::ValueMap<T>>();
147  typename edm::ValueMap<T>::Filler filler(*valueMap);
148  filler.insert(handle, values.begin(), values.end());
149  filler.fill();
150  return valueMap;
151  }
152 
154 
156 
160  std::vector<double> recHitCountThresholds_;
161 };
162 
164  setToken(egTrigObjs, cc, pset, "egTrigObjs");
165  setToken(l1Trks, cc, pset, "l1Trks");
166  setToken(trkParts, cc, pset, "trkParts");
167  setToken(l1TrkToTrkPartMap, cc, pset, "l1TrkToTrkPartMap");
168  setToken(hgcalLayerClusters, cc, pset, "hgcalLayerClusters");
169  setToken(hgcalLayerClustersTime, cc, pset, "hgcalLayerClustersTime");
170  setToken(hgcal, cc, pset, "hgcal");
171 }
172 
176  minPtToSaveHits_(pset.getParameter<double>("minPtToSaveHits")),
177  saveHitsPlusPi_(pset.getParameter<bool>("saveHitsPlusPi")),
178  saveHitsPlusHalfPi_(pset.getParameter<bool>("saveHitsPlusHalfPi")),
179  recHitCountThresholds_(pset.getParameter<std::vector<double>>("recHitCountThresholds")) {
180  produces<L1TrackCollection>();
181  produces<L1TrackTruthPairCollection>();
182  produces<TrackingParticleCollection>();
183  produces<reco::CaloClusterCollection>("hgcalLayerClusters");
184  produces<edm::ValueMap<std::pair<float, float>>>("hgcalLayerClustersTime");
185  for (auto& tokenLabel : tokens_.hgcal) {
186  produces<HGCRecHitCollection>(tokenLabel.second);
187  for (const auto& thres : recHitCountThresholds_) {
188  produces<int>("countHgcalRecHits" + tokenLabel.second + "Thres" + convertToProdNameStr(thres) + "GeV");
189  }
190  }
191 }
192 
195  desc.add<edm::InputTag>("egTrigObjs", edm::InputTag("hltEgammaHLTExtra"));
196  desc.add<edm::InputTag>("l1Trks", edm::InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks"));
197  desc.add<edm::InputTag>("trkParts", edm::InputTag("mix", "MergedTrackTruth"));
198  desc.add<edm::InputTag>("l1TrkToTrkPartMap", edm::InputTag("TTTrackAssociatorFromPixelDigis", "Level1TTTracks"));
199  desc.add<edm::InputTag>("hgcalLayerClusters", edm::InputTag("hgcalLayerClusters"));
200  desc.add<edm::InputTag>("hgcalLayerClustersTime", edm::InputTag("hgcalLayerClusters", "timeLayerCluster"));
201  desc.add<double>("minPtToSaveHits", 0.);
202  desc.add<bool>("saveHitsPlusPi", true);
203  desc.add<bool>("saveHitsPlusHalfPi", true);
204  desc.add<std::vector<double>>("recHitCountThresholds", std::vector{0., 0.5, 1.0, 1.5, 2.0});
205  std::vector<edm::ParameterSet> ecalDefaults(2);
206  edm::ParameterSetDescription tokenLabelDesc;
207  tokenLabelDesc.add<edm::InputTag>("src", edm::InputTag(""));
208  tokenLabelDesc.add<std::string>("label", "");
209  std::vector<edm::ParameterSet> hgcalDefaults(3);
210  hgcalDefaults[0].addParameter("src", edm::InputTag("HGCalRecHit", "HGCEERecHits"));
211  hgcalDefaults[0].addParameter("label", std::string("HGCEERecHits"));
212  hgcalDefaults[1].addParameter("src", edm::InputTag("HGCalRecHit", "HGCHEFRecHits"));
213  hgcalDefaults[1].addParameter("label", std::string("HGCHEFRecHits"));
214  hgcalDefaults[2].addParameter("src", edm::InputTag("HGCalRecHit", "HGCHEBRecHits"));
215  hgcalDefaults[2].addParameter("label", std::string("HGCHEBRecHits"));
216  desc.addVPSet("hgcal", tokenLabelDesc, hgcalDefaults);
217  descriptions.add(("hltEgammaHLTPhase2ExtraProducer"), desc);
218 }
219 
221  edm::Event& event,
222  const edm::EventSetup& eventSetup) const {
223  auto egTrigObjs = event.getHandle(tokens_.egTrigObjs);
224 
225  auto trkParts = event.getHandle(tokens_.trkParts);
226  auto l1trks = event.getHandle(tokens_.l1Trks);
227  auto l1TrkToTrkPartMap = event.getHandle(tokens_.l1TrkToTrkPartMap);
228 
229  auto const caloGeomHandle = eventSetup.getHandle(caloGeomToken_);
230 
231  for (const auto& tokenLabel : tokens_.hgcal) {
232  auto handle = event.getHandle(tokenLabel.first);
233  auto recHits = filterRecHits(*egTrigObjs, handle, *caloGeomHandle);
234  event.put(std::move(recHits), tokenLabel.second);
235  }
236 
237  auto storeCountRecHits = [&event](const auto& tokenLabels, const auto& thresholds, const std::string& prefixLabel) {
238  for (const auto& tokenLabel : tokenLabels) {
239  auto handle = event.getHandle(tokenLabel.first);
240  auto count = countRecHits(handle, thresholds);
241  for (size_t thresNr = 0; thresNr < thresholds.size(); thresNr++) {
242  const auto& thres = thresholds[thresNr];
243  event.put(std::move(count[thresNr]),
244  prefixLabel + tokenLabel.second + "Thres" + convertToProdNameStr(thres) + "GeV");
245  }
246  }
247  };
248  storeCountRecHits(tokens_.hgcal, recHitCountThresholds_, "countHgcalRecHits");
249 
250  auto hgcalLayerClusters = event.getHandle(tokens_.hgcalLayerClusters);
251  auto hgcalLayerClustersTime = event.getHandle(tokens_.hgcalLayerClustersTime);
252  std::vector<edm::Ref<reco::CaloClusterCollection>> orgHGCalLayerClusterRefs;
253  auto hgcalLayerClustersFiltered = filterObjs(*egTrigObjs, hgcalLayerClusters, orgHGCalLayerClusterRefs);
254  std::vector<std::pair<float, float>> timesFiltered;
255  timesFiltered.reserve(orgHGCalLayerClusterRefs.size());
256  for (auto& clusRef : orgHGCalLayerClusterRefs) {
257  timesFiltered.push_back((*hgcalLayerClustersTime)[clusRef]);
258  }
259  auto hgcalLayerClustersFilteredHandle = event.put(std::move(hgcalLayerClustersFiltered), "hgcalLayerClusters");
260  event.put(makeValueMap(hgcalLayerClustersFilteredHandle, timesFiltered), "hgcalLayerClustersTime");
261 
262  std::vector<edm::Ref<L1TrackCollection>> orgL1TrkRefs;
263  auto l1TrksFiltered = filterObjs(*egTrigObjs, l1trks, orgL1TrkRefs);
264  std::vector<edm::Ref<TrackingParticleCollection>> orgTPRefs;
265  auto trkPartsFiltered = filterObjs(*egTrigObjs, trkParts, orgTPRefs);
266 
267  //meh should make this edm::Ref<T>::key_type
268  std::unordered_map<size_t, size_t> orgTPIndxToNewIndx;
269  for (size_t refNr = 0; refNr < orgTPRefs.size(); refNr++) {
270  orgTPIndxToNewIndx.insert(std::make_pair(orgTPRefs[refNr].key(), refNr));
271  }
272 
273  edm::OrphanHandle<L1TrackCollection> l1TrksFiltHandle = event.put(std::move(l1TrksFiltered));
274  edm::OrphanHandle<TrackingParticleCollection> trkPartsFiltHandle = event.put(std::move(trkPartsFiltered));
275 
276  auto l1TrkExtraColl = std::make_unique<L1TrackTruthPairCollection>();
277 
278  for (size_t l1TrkNr = 0; l1TrkNr < orgL1TrkRefs.size(); l1TrkNr++) {
279  auto orgTrkRef = orgL1TrkRefs[l1TrkNr];
280  auto orgTrkPtr = edm::refToPtr(orgTrkRef);
281  int flags = 0;
282  if (l1TrkToTrkPartMap->isGenuine(orgTrkPtr))
284  if (l1TrkToTrkPartMap->isLooselyGenuine(orgTrkPtr))
286  if (l1TrkToTrkPartMap->isCombinatoric(orgTrkPtr))
288  if (l1TrkToTrkPartMap->isUnknown(orgTrkPtr))
290 
291  auto orgTPRef = l1TrkToTrkPartMap->findTrackingParticlePtr(orgTrkPtr);
292  auto getNewTPRef = [&orgTPIndxToNewIndx, &orgTPRef, &trkPartsFiltHandle]() {
293  auto newIndexPair = orgTPIndxToNewIndx.find(orgTPRef.key());
294  if (newIndexPair != orgTPIndxToNewIndx.end()) {
295  return edm::Ref<TrackingParticleCollection>(trkPartsFiltHandle, newIndexPair->second);
296  } else
297  return edm::Ref<TrackingParticleCollection>(trkPartsFiltHandle.id());
298  };
299  auto newTPRef = getNewTPRef();
300  edm::Ref<L1TrackCollection> newL1TrkRef(l1TrksFiltHandle, l1TrkNr);
301 
302  L1TrackTruthPair l1TrkExtra(newL1TrkRef, newTPRef, flags);
303  l1TrkExtraColl->push_back(l1TrkExtra);
304  }
305  event.put(std::move(l1TrkExtraColl));
306 }
307 
308 template <typename CollType, typename RefType>
311  std::vector<RefType>& orgRefs,
312  float maxDR2) const {
313  auto filteredObjs = std::make_unique<CollType>();
314  orgRefs.clear();
315  if (!objs.isValid())
316  return filteredObjs;
317 
318  //so because each egamma object can have multiple eta/phi pairs
319  //easier to just make a temp vector and then copy that in with the +pi and +pi/2
320  std::vector<std::pair<float, float>> etaPhisTmp;
321  for (const auto& egTrigObj : egTrigObjs) {
322  if (egTrigObj.pt() >= minPtToSaveHits_) {
323  etaPhisTmp.push_back({egTrigObj.eta(), egTrigObj.phi()});
324  //also save the eta /phi of all gsf tracks with the object
325  for (const auto& gsfTrk : egTrigObj.gsfTracks()) {
326  etaPhisTmp.push_back({gsfTrk->eta(), gsfTrk->phi()});
327  }
328  }
329  }
330  std::vector<std::pair<float, float>> etaPhis;
331  for (const auto& etaPhi : etaPhisTmp) {
332  etaPhis.push_back(etaPhi);
333  if (saveHitsPlusPi_)
334  etaPhis.push_back({etaPhi.first, etaPhi.second + 3.14159});
336  etaPhis.push_back({etaPhi.first, etaPhi.second + 3.14159 / 2.});
337  }
338 
339  auto deltaR2Match = [&etaPhis, &maxDR2](float eta, float phi) {
340  for (auto& etaPhi : etaPhis) {
341  if (reco::deltaR2(eta, phi, etaPhi.first, etaPhi.second) < maxDR2)
342  return true;
343  }
344  return false;
345  };
346 
347  for (size_t objNr = 0; objNr < objs->size(); objNr++) {
348  RefType ref(objs, objNr);
349  if (deltaR2Match(ref->eta(), ref->phi())) {
350  filteredObjs->push_back(*ref);
351  orgRefs.push_back(ref);
352  }
353  }
354  return filteredObjs;
355 }
356 
357 template <typename RecHitCollection>
358 std::unique_ptr<RecHitCollection> EgammaHLTPhase2ExtraProducer::filterRecHits(
359  const trigger::EgammaObjectCollection& egTrigObjs,
361  const CaloGeometry& geom,
362  float maxDR2) const {
363  auto filteredHits = std::make_unique<RecHitCollection>();
364  if (!recHits.isValid())
365  return filteredHits;
366 
367  std::vector<std::pair<float, float>> etaPhis;
368  for (const auto& egTrigObj : egTrigObjs) {
369  if (egTrigObj.pt() >= minPtToSaveHits_) {
370  etaPhis.push_back({egTrigObj.eta(), egTrigObj.phi()});
371  if (saveHitsPlusPi_)
372  etaPhis.push_back({egTrigObj.eta(), egTrigObj.phi() + 3.14159});
374  etaPhis.push_back({egTrigObj.eta(), egTrigObj.phi() + 3.14159 / 2.});
375  }
376  }
377  auto deltaR2Match = [&etaPhis, &maxDR2](const GlobalPoint& pos) {
378  float eta = pos.eta();
379  float phi = pos.phi();
380  for (auto& etaPhi : etaPhis) {
381  if (reco::deltaR2(eta, phi, etaPhi.first, etaPhi.second) < maxDR2)
382  return true;
383  }
384  return false;
385  };
386 
387  for (auto& hit : *recHits) {
388  const CaloSubdetectorGeometry* subDetGeom = geom.getSubdetectorGeometry(hit.id());
389  if (subDetGeom) {
390  auto cellGeom = subDetGeom->getGeometry(hit.id());
391  if (deltaR2Match(cellGeom->getPosition()))
392  filteredHits->push_back(hit);
393  } else {
394  throw cms::Exception("GeomError") << "could not get geometry for det id " << hit.id().rawId();
395  }
396  }
397  return filteredHits;
398 }
399 
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
std::vector< EgammaObject > EgammaObjectCollection
Ptr< typename C::value_type > refToPtr(Ref< C, typename C::value_type, refhelper::FindUsingAdvance< C, typename C::value_type > > const &ref)
Definition: RefToPtr.h:18
constexpr SubDetector subDetGeom[21]
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
edm::EDGetTokenT< edm::ValueMap< std::pair< float, float > > > hgcalLayerClustersTime
std::unique_ptr< RecHitCollection > filterRecHits(const trigger::EgammaObjectCollection &egTrigObjs, const edm::Handle< RecHitCollection > &recHits, const CaloGeometry &geom, float maxDR2=0.4 *0.4) const
Tokens(const edm::ParameterSet &pset, edm::ConsumesCollector &&cc)
char const * label
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
edm::EDGetTokenT< L1TrackCollection > l1Trks
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static std::unique_ptr< edm::ValueMap< T > > makeValueMap(const H &handle, const std::vector< T > &values)
ProductID id() const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::EDGetTokenT< reco::CaloClusterCollection > hgcalLayerClusters
unsigned int id
std::vector< edm::EDGetTokenT< int > > tokens_
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
std::unique_ptr< CollType > filterObjs(const trigger::EgammaObjectCollection &egTrigObjs, const edm::Handle< CollType > &objs, std::vector< RefType > &orgRefs, float maxDR2=0.4 *0.4) const
inputTags
All input tags are specified in this pset for convenience.
void add(std::string const &label, ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< trigger::EgammaObjectCollection > egTrigObjs
static void setToken(std::vector< edm::EDGetTokenT< T >> &tokens, edm::ConsumesCollector &cc, const edm::ParameterSet &pset, const std::string &tagname)
edm::EDGetTokenT< TTTrackAssociationMap< Ref_Phase2TrackerDigi_ > > l1TrkToTrkPartMap
static void setToken(edm::EDGetTokenT< T > &token, edm::ConsumesCollector &cc, const edm::ParameterSet &pset, const std::string &tagname)
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > const caloGeomToken_
edm::EDGetTokenT< TrackingParticleCollection > trkParts
std::vector< std::pair< edm::EDGetTokenT< HGCRecHitCollection >, std::string > > hgcal
long double T
void produce(edm::StreamID streamID, edm::Event &event, const edm::EventSetup &eventSetup) const override
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1
EgammaHLTPhase2ExtraProducer(const edm::ParameterSet &pset)
static void setToken(std::vector< std::pair< edm::EDGetTokenT< T >, std::string >> &tokens, edm::ConsumesCollector &cc, const edm::ParameterSet &pset, const std::string &tagname)