CMS 3D CMS Logo

HLTCaloObjInRegionsProducer.cc
Go to the documentation of this file.
1 #include <memory>
2 
13 
23 
28 
32 
35 
36 /**************************************************************
37 / purpose: enable filtering of calo objects in eta/phi or deltaR
38 / regions around generic objects
39 /
40 / operation : accepts all objects with
41 / (dEta <dEtaMax && dPhi < dPhiMax) || dR < dRMax
42 / so the OR of a rectangular region and cone region
43 ****************************************************************/
44 
45 //this is a struct which contains all the eta/phi regions
46 //from which to filter the calo objs
47 class EtaPhiRegion {
48 private:
49  float centreEta_;
50  float centrePhi_;
51  float maxDeltaR2_;
52  float maxDEta_;
53  float maxDPhi_;
54 
55 public:
56  EtaPhiRegion(float iEta, float iPhi, float iDR, float iDEta, float iDPhi)
57  : centreEta_(iEta), centrePhi_(iPhi), maxDeltaR2_(iDR * iDR), maxDEta_(iDEta), maxDPhi_(iDPhi) {}
59  bool operator()(float eta, float phi) const {
62  }
63 };
64 
66 public:
68  virtual ~EtaPhiRegionDataBase() = default;
69  virtual void getEtaPhiRegions(const edm::Event&, std::vector<EtaPhiRegion>&) const = 0;
70 };
71 
72 //this class stores the tokens to access the objects around which we wish to filter
73 //it makes a vector of EtaPhiRegions which are then used to filter the CaloObjs
74 template <typename T1>
76 private:
77  float minEt_;
78  float maxEt_;
79  float maxDeltaR_;
80  float maxDEta_;
81  float maxDPhi_;
83 
84 public:
86  : minEt_(para.getParameter<double>("minEt")),
87  maxEt_(para.getParameter<double>("maxEt")),
88  maxDeltaR_(para.getParameter<double>("maxDeltaR")),
89  maxDEta_(para.getParameter<double>("maxDEta")),
90  maxDPhi_(para.getParameter<double>("maxDPhi")),
91  token_(consumesColl.consumes<T1>(para.getParameter<edm::InputTag>("inputColl"))) {}
92 
93  void getEtaPhiRegions(const edm::Event&, std::vector<EtaPhiRegion>&) const override;
94 };
95 
96 template <typename CaloObjType, typename CaloObjCollType = edm::SortedCollection<CaloObjType>>
98 public:
101 
102  void produce(edm::Event&, const edm::EventSetup&) override;
103  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
104 
105 private:
107  const edm::ParameterSet&,
108  edm::ConsumesCollector&&); //calling function owns this
109  static std::unique_ptr<CaloObjCollType> makeFilteredColl(const edm::Handle<CaloObjCollType>& inputColl,
110  CaloGeometry const& caloGeomHandle,
111  const std::vector<EtaPhiRegion>& regions);
112  static bool validIDForGeom(const DetId& id);
113  std::vector<std::string> outputProductNames_;
114  std::vector<edm::InputTag> inputCollTags_;
115  std::vector<edm::EDGetTokenT<CaloObjCollType>> inputTokens_;
116  std::vector<std::unique_ptr<EtaPhiRegionDataBase>> etaPhiRegionData_;
118 };
119 
120 template <typename CaloObjType, typename CaloObjCollType>
122  : caloGeometryToken_{esConsumes()} {
123  const std::vector<edm::ParameterSet> etaPhiRegions =
124  para.getParameter<std::vector<edm::ParameterSet>>("etaPhiRegions");
125  for (auto& pset : etaPhiRegions) {
126  const std::string type = pset.getParameter<std::string>("type");
127  etaPhiRegionData_.emplace_back(createEtaPhiRegionData(
128  type,
129  pset,
130  consumesCollector())); //meh I was going to use a factory but it was going to be overly complex for my needs
131  }
132 
133  outputProductNames_ = para.getParameter<std::vector<std::string>>("outputProductNames");
134  inputCollTags_ = para.getParameter<std::vector<edm::InputTag>>("inputCollTags");
135  if (outputProductNames_.size() != inputCollTags_.size()) {
136  throw cms::Exception("InvalidConfiguration")
137  << " error outputProductNames and inputCollTags must be the same size, they are " << outputProductNames_.size()
138  << " vs " << inputCollTags_.size();
139  }
140  for (unsigned int collNr = 0; collNr < inputCollTags_.size(); collNr++) {
141  inputTokens_.push_back(consumes<CaloObjCollType>(inputCollTags_[collNr]));
142  produces<CaloObjCollType>(outputProductNames_[collNr]);
143  }
144 }
145 
146 template <typename CaloObjType, typename CaloObjCollType>
148  edm::ConfigurationDescriptions& descriptions) {
150  std::vector<std::string> outputProductNames;
151  outputProductNames.push_back("EcalRegionalRecHitsEB");
152  desc.add<std::vector<std::string>>("outputProductNames", outputProductNames);
153  std::vector<edm::InputTag> inputColls;
154  inputColls.push_back(edm::InputTag("hltHcalDigis"));
155  desc.add<std::vector<edm::InputTag>>("inputCollTags", inputColls);
156  std::vector<edm::ParameterSet> etaPhiRegions;
157 
158  edm::ParameterSet ecalCandPSet;
159  ecalCandPSet.addParameter<std::string>("type", "RecoEcalCandidate");
160  ecalCandPSet.addParameter<double>("minEt", -1);
161  ecalCandPSet.addParameter<double>("maxEt", -1);
162  ecalCandPSet.addParameter<double>("maxDeltaR", 0.5);
163  ecalCandPSet.addParameter<double>("maxDEta", 0.);
164  ecalCandPSet.addParameter<double>("maxDPhi", 0.);
165  ecalCandPSet.addParameter<edm::InputTag>("inputColl", edm::InputTag("hltEgammaCandidates"));
166  etaPhiRegions.push_back(ecalCandPSet);
167 
168  edm::ParameterSetDescription etaPhiRegionDesc;
169  etaPhiRegionDesc.add<std::string>("type");
170  etaPhiRegionDesc.add<double>("minEt");
171  etaPhiRegionDesc.add<double>("maxEt");
172  etaPhiRegionDesc.add<double>("maxDeltaR");
173  etaPhiRegionDesc.add<double>("maxDEta");
174  etaPhiRegionDesc.add<double>("maxDPhi");
175  etaPhiRegionDesc.add<edm::InputTag>("inputColl");
176  desc.addVPSet("etaPhiRegions", etaPhiRegionDesc, etaPhiRegions);
177 
179 }
180 
181 template <typename CaloObjType, typename CaloObjCollType>
183  const edm::EventSetup& setup) {
184  // get the collection geometry:
185  auto const& caloGeom = setup.getData(caloGeometryToken_);
186 
187  std::vector<EtaPhiRegion> regions;
188  std::for_each(etaPhiRegionData_.begin(),
189  etaPhiRegionData_.end(),
190  [&event, &regions](const std::unique_ptr<EtaPhiRegionDataBase>& input) {
191  input->getEtaPhiRegions(event, regions);
192  });
193 
194  for (size_t inputCollNr = 0; inputCollNr < inputTokens_.size(); inputCollNr++) {
196  event.getByToken(inputTokens_[inputCollNr], inputColl);
197 
198  if (!(inputColl.isValid())) {
199  edm::LogError("ProductNotFound") << "could not get a handle on the " << typeid(CaloObjCollType).name()
200  << " named " << inputCollTags_[inputCollNr].encode() << std::endl;
201  continue;
202  }
203  auto outputColl = makeFilteredColl(inputColl, caloGeom, regions);
204  event.put(std::move(outputColl), outputProductNames_[inputCollNr]);
205  }
206 }
207 
208 template <typename CaloObjType, typename CaloObjCollType>
211  CaloGeometry const& caloGeomHandle,
212  const std::vector<EtaPhiRegion>& regions) {
213  auto outputColl = std::make_unique<CaloObjCollType>();
214  if (!inputColl->empty()) {
215  const CaloSubdetectorGeometry* subDetGeom = caloGeomHandle.getSubdetectorGeometry(inputColl->begin()->id());
216  if (!regions.empty()) {
217  for (auto const& obj : *inputColl) {
218  auto objGeom = subDetGeom->getGeometry(obj.id());
219  if (objGeom == nullptr) {
220  //wondering what to do here
221  //something is very very wrong
222  //given HLT should never crash or throw, decided to log an error
223  //update: so turns out HCAL can pass through calibration channels in QIE11 so for that module, its an expected behaviour
224  //so we check if the ID is valid
225  if (validIDForGeom(obj.id())) {
226  edm::LogError("HLTCaloObjInRegionsProducer")
227  << "for an object of type " << typeid(CaloObjType).name() << " the geometry returned null for id "
228  << DetId(obj.id()).rawId() << " with initial ID " << DetId(inputColl->begin()->id()).rawId()
229  << " in HLTCaloObjsInRegion, this shouldnt be possible and something has gone wrong, auto accepting "
230  "hit";
231  }
232  outputColl->push_back(obj);
233  continue;
234  }
235  float eta = objGeom->getPosition().eta();
236  float phi = objGeom->getPosition().phi();
237 
238  for (const auto& region : regions) {
239  if (region(eta, phi)) {
240  outputColl->push_back(obj);
241  break;
242  }
243  }
244  }
245  } //end check of empty regions
246  } //end check of empty rec-hits
247  return outputColl;
248 }
249 
250 //tells us if an ID should have a valid geometry
251 //it assumes that all IDs do except those specifically mentioned
252 //HCAL for example have laser calibs in the digi collection so
253 //so we have to ensure that HCAL is HB,HE or HO
254 template <typename CaloObjType, typename CaloObjCollType>
256  if (id.det() == DetId::Hcal) {
257  if (id.subdetId() == HcalSubdetector::HcalEmpty || id.subdetId() == HcalSubdetector::HcalOther) {
258  return false;
259  }
260  }
261  return true;
262 }
263 
264 template <typename CaloObjType, typename CaloObjCollType>
266  const std::string& type, const edm::ParameterSet& para, edm::ConsumesCollector&& consumesColl) {
267  if (type == "L1P2GTCandidate") {
268  return new EtaPhiRegionData<l1t::P2GTCandidateCollection>(para, consumesColl);
269  } else if (type == "L1EGamma") {
270  return new EtaPhiRegionData<l1t::EGammaBxCollection>(para, consumesColl);
271  } else if (type == "L1Jet") {
272  return new EtaPhiRegionData<l1t::JetBxCollection>(para, consumesColl);
273  } else if (type == "L1Muon") {
274  return new EtaPhiRegionData<l1t::MuonBxCollection>(para, consumesColl);
275  } else if (type == "L1Tau") {
276  return new EtaPhiRegionData<l1t::TauBxCollection>(para, consumesColl);
277  } else if (type == "RecoEcalCandidate") {
278  return new EtaPhiRegionData<reco::RecoEcalCandidateCollection>(para, consumesColl);
279  } else if (type == "RecoChargedCandidate") {
280  return new EtaPhiRegionData<reco::RecoChargedCandidateCollection>(para, consumesColl);
281  } else if (type == "Electron") {
282  return new EtaPhiRegionData<reco::Electron>(para, consumesColl);
283  } else {
284  //this is a major issue and could lead to rather subtle efficiency losses, so if its incorrectly configured, we're aborting the job!
285  throw cms::Exception("InvalidConfig")
286  << " type " << type
287  << " is not recognised, this means the rec-hit you think you are keeping may not be and you should fix this "
288  "error as it can lead to hard to find efficiency loses"
289  << std::endl;
290  }
291 }
292 
293 template <typename CandCollType>
295  std::vector<EtaPhiRegion>& regions) const {
297  event.getByToken(token_, cands);
298 
299  for (auto const& cand : *cands) {
300  if (cand.et() >= minEt_ && (maxEt_ < 0 || cand.et() < maxEt_)) {
301  regions.push_back(EtaPhiRegion(cand.eta(), cand.phi(), maxDeltaR_, maxDEta_, maxDPhi_));
302  }
303  }
304 }
305 
307 
311 
316 
320 
328 
329 //these two classes are intended to ultimately replace the EcalRecHit and EcalUncalibratedRecHit
330 //instances of HLTRecHitInAllL1RegionsProducer, particulary as we're free of legacy / stage-1 L1 now
337 
338 // HGCAL Digis
342 
343 // HGCAL RecHits
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
std::vector< edm::EDGetTokenT< CaloObjCollType > > inputTokens_
std::vector< edm::InputTag > inputCollTags_
void getEtaPhiRegions(const edm::Event &, std::vector< EtaPhiRegion > &) const override
EtaPhiRegionDataBase * createEtaPhiRegionData(const std::string &, const edm::ParameterSet &, edm::ConsumesCollector &&)
constexpr SubDetector subDetGeom[21]
const edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeometryToken_
std::string defaultModuleLabel()
static bool validIDForGeom(const DetId &id)
Log< level::Error, false > LogError
virtual ~EtaPhiRegionDataBase()=default
bool operator()(float eta, float phi) const
static std::string const input
Definition: EdmProvDump.cc:50
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< std::string > outputProductNames_
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:136
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
EtaPhiRegionData(const edm::ParameterSet &para, edm::ConsumesCollector &consumesColl)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual void getEtaPhiRegions(const edm::Event &, std::vector< EtaPhiRegion > &) const =0
ParameterDescriptionBase * add(U const &iLabel, T const &value)
HLTCaloObjInRegionsProducer(const edm::ParameterSet &ps)
Definition: DetId.h:17
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
edm::EDGetTokenT< T1 > token_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
HLT enums.
static std::unique_ptr< CaloObjCollType > makeFilteredColl(const edm::Handle< CaloObjCollType > &inputColl, CaloGeometry const &caloGeomHandle, const std::vector< EtaPhiRegion > &regions)
EtaPhiRegion(float iEta, float iPhi, float iDR, float iDEta, float iDPhi)
std::vector< std::unique_ptr< EtaPhiRegionDataBase > > etaPhiRegionData_
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:34
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1
void produce(edm::Event &, const edm::EventSetup &) override