CMS 3D CMS Logo

PFCTRecHitProducer.cc
Go to the documentation of this file.
2 
3 #include <memory>
4 
6 
14 
18 
22 
30 
32 
35 
39 
40 using namespace std;
41 using namespace edm;
42 
44  thresh_Barrel_ = iConfig.getParameter<double>("thresh_Barrel");
45  thresh_Endcap_ = iConfig.getParameter<double>("thresh_Endcap");
46 
47  thresh_HF_ = iConfig.getParameter<double>("thresh_HF");
48  navigation_HF_ = iConfig.getParameter<bool>("navigation_HF");
49  weight_HFem_ = iConfig.getParameter<double>("weight_HFem");
50  weight_HFhad_ = iConfig.getParameter<double>("weight_HFhad");
51 
52  HCAL_Calib_ = iConfig.getParameter<bool>("HCAL_Calib");
53  HF_Calib_ = iConfig.getParameter<bool>("HF_Calib");
54  HCAL_Calib_29 = iConfig.getParameter<double>("HCAL_Calib_29");
55  HF_Calib_29 = iConfig.getParameter<double>("HF_Calib_29");
56 
57  shortFibre_Cut = iConfig.getParameter<double>("ShortFibre_Cut");
58  longFibre_Fraction = iConfig.getParameter<double>("LongFibre_Fraction");
59 
60  longFibre_Cut = iConfig.getParameter<double>("LongFibre_Cut");
61  shortFibre_Fraction = iConfig.getParameter<double>("ShortFibre_Fraction");
62 
63  applyLongShortDPG_ = iConfig.getParameter<bool>("ApplyLongShortDPG");
64 
65  longShortFibre_Cut = iConfig.getParameter<double>("LongShortFibre_Cut");
66  minShortTiming_Cut = iConfig.getParameter<double>("MinShortTiming_Cut");
67  maxShortTiming_Cut = iConfig.getParameter<double>("MaxShortTiming_Cut");
68  minLongTiming_Cut = iConfig.getParameter<double>("MinLongTiming_Cut");
69  maxLongTiming_Cut = iConfig.getParameter<double>("MaxLongTiming_Cut");
70 
71  applyTimeDPG_ = iConfig.getParameter<bool>("ApplyTimeDPG");
72  applyPulseDPG_ = iConfig.getParameter<bool>("ApplyPulseDPG");
73  HcalMaxAllowedHFLongShortSev_ = iConfig.getParameter<int>("HcalMaxAllowedHFLongShortSev");
74  HcalMaxAllowedHFDigiTimeSev_ = iConfig.getParameter<int>("HcalMaxAllowedHFDigiTimeSev");
75  HcalMaxAllowedHFInTimeWindowSev_ = iConfig.getParameter<int>("HcalMaxAllowedHFInTimeWindowSev");
76  HcalMaxAllowedChannelStatusSev_ = iConfig.getParameter<int>("HcalMaxAllowedChannelStatusSev");
77 
78  ECAL_Compensate_ = iConfig.getParameter<bool>("ECAL_Compensate");
79  ECAL_Threshold_ = iConfig.getParameter<double>("ECAL_Threshold");
80  ECAL_Compensation_ = iConfig.getParameter<double>("ECAL_Compensation");
81  ECAL_Dead_Code_ = iConfig.getParameter<unsigned int>("ECAL_Dead_Code");
82 
83  EM_Depth_ = iConfig.getParameter<double>("EM_Depth");
84  HAD_Depth_ = iConfig.getParameter<double>("HAD_Depth");
85 
86  //Get integer values of individual HCAL HF flags
87  hcalHFLongShortFlagValue_ = 1 << HcalCaloFlagLabels::HFLongShort;
88  hcalHFDigiTimeFlagValue_ = 1 << HcalCaloFlagLabels::HFDigiTime;
89  hcalHFInTimeWindowFlagValue_ = 1 << HcalCaloFlagLabels::HFInTimeWindow;
90 
91  hcalToken_ = consumes<HBHERecHitCollection>(iConfig.getParameter<InputTag>("hcalRecHitsHBHE"));
92  hfToken_ = consumes<HFRecHitCollection>(iConfig.getParameter<InputTag>("hcalRecHitsHF"));
93  towersToken_ = consumes<CaloTowerCollection>(iConfig.getParameter<InputTag>("caloTowers"));
94 
95  edm::ParameterSet navSet = iConfig.getParameter<edm::ParameterSet>("navigator");
96  navigator_ = PFRecHitNavigationFactory::get()->create(navSet.getParameter<std::string>("name"), navSet);
97 
98  //--ab
99  produces<reco::PFRecHitCollection>();
100  produces<reco::PFRecHitCollection>("Cleaned");
101  produces<reco::PFRecHitCollection>("HFHAD").setBranchAlias("HFHADRecHits");
102  produces<reco::PFRecHitCollection>("HFEM").setBranchAlias("HFEMRecHits");
103  //--ab
104 }
105 
107  navigator_->beginEvent(iSetup);
108 
109  edm::ESHandle<CaloGeometry> geoHandle;
110  iSetup.get<CaloGeometryRecord>().get(geoHandle);
111 
112  // get the hcalBarrel geometry
113  const CaloSubdetectorGeometry* hcalBarrelGeometry = geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalBarrel);
114 
115  // get the endcap geometry
116  const CaloSubdetectorGeometry* hcalEndcapGeometry = geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalEndcap);
117 
118  // Get Hcal Severity Level Computer, so that the severity of each rechit flag/status may be determined
119  edm::ESHandle<HcalSeverityLevelComputer> hcalSevLvlComputerHndl;
120  iSetup.get<HcalSeverityLevelComputerRcd>().get(hcalSevLvlComputerHndl);
121  const HcalSeverityLevelComputer* hcalSevLvlComputer = hcalSevLvlComputerHndl.product();
122 
123  // Get Hcal Topology
124  edm::ESHandle<HcalTopology> hcalTopology;
125  iSetup.get<HcalRecNumberingRecord>().get(hcalTopology);
126  theHcalTopology = hcalTopology.product();
127 
128  auto rechits = std::make_unique<std::vector<reco::PFRecHit>>();
129  auto rechitsCleaned = std::make_unique<std::vector<reco::PFRecHit>>();
130  auto HFHADRecHits = std::make_unique<std::vector<reco::PFRecHit>>();
131  auto HFEMRecHits = std::make_unique<std::vector<reco::PFRecHit>>();
132 
134  iEvent.getByToken(towersToken_, caloTowers);
136  iEvent.getByToken(hfToken_, hfHandle);
137 
139  iEvent.getByToken(hcalToken_, hbheHandle);
140  // create rechits
142 
143  for (auto const& ct : *caloTowers) {
144  // get the hadronic energy.
145 
146  // Mike: Just ask for the Hadronic part only now!
147  // Patrick : ARGH ! While this is ok for the HCAL, this is
148  // just wrong for the HF (in which em/had are artificially
149  // separated.
150  double energy = ct.hadEnergy();
151  //Auguste: Photons in HF have no hadEnergy in fastsim: -> all RecHit collections are empty with photons.
152  double energyEM = ct.emEnergy(); // For HF !
153  //so test the total energy to deal with the photons in HF:
154  if ((energy + energyEM) < 1e-9)
155  continue;
156 
157  //get the constituents of the tower
158  const std::vector<DetId>& hits = ct.constituents();
159  const std::vector<DetId>& allConstituents = theTowerConstituentsMap->constituentsOf(ct.id());
160  HcalDetId detid;
161  bool foundHCALConstituent = false;
162  //Loop on the calotower constituents and search for HCAL
163  double dead = 0.;
164  double alive = 0.;
165  for (auto hit : hits) {
166  if (hit.det() == DetId::Hcal) {
167  foundHCALConstituent = true;
168  detid = hit;
169  if (theHcalTopology->getMergePositionFlag() && detid.subdet() == HcalEndcap) {
170  detid = theHcalTopology->idFront(detid);
171  }
172  // An HCAL tower was found: Look for dead ECAL channels in the same CaloTower.
173  if (ECAL_Compensate_ && energy > ECAL_Threshold_) {
174  for (auto allConstituent : allConstituents) {
175  if (allConstituent.det() == DetId::Ecal) {
176  alive += 1.;
177  auto chIt = theEcalChStatus->find(allConstituent);
178  unsigned int dbStatus = chIt != theEcalChStatus->end() ? chIt->getStatusCode() : 0;
179  if (dbStatus > ECAL_Dead_Code_)
180  dead += 1.;
181  }
182  }
183  }
184  // Protection: tower 29 in HF is merged with tower 30.
185  // Just take the position of tower 30 in that case.
186  if (detid.subdet() == HcalForward && abs(detid.ieta()) == 29)
187  continue;
188  break;
189  }
190  }
191 
192  // In case of dead ECAL channel, rescale the HCAL energy...
193  double rescaleFactor = alive > 0. ? 1. + ECAL_Compensation_ * dead / alive : 1.;
194 
195  reco::PFRecHit* pfrh = nullptr;
196  reco::PFRecHit* pfrhCleaned = nullptr;
197  //---ab: need 2 rechits for the HF:
198  reco::PFRecHit* pfrhHFEM = nullptr;
199  reco::PFRecHit* pfrhHFHAD = nullptr;
200  reco::PFRecHit* pfrhHFEMCleaned = nullptr;
201  reco::PFRecHit* pfrhHFHADCleaned = nullptr;
202  reco::PFRecHit* pfrhHFEMCleaned29 = nullptr;
203  reco::PFRecHit* pfrhHFHADCleaned29 = nullptr;
204 
205  if (foundHCALConstituent) {
206  // std::cout << ", new Energy = " << energy << std::endl;
207  switch (detid.subdet()) {
208  case HcalBarrel: {
209  if (energy < thresh_Barrel_)
210  continue;
211  if (rescaleFactor > 1.) {
212  pfrhCleaned = createHcalRecHit(detid, energy, PFLayer::HCAL_BARREL1, hcalBarrelGeometry, ct.id());
213  pfrhCleaned->setTime(rescaleFactor);
214  energy *= rescaleFactor;
215  }
216  pfrh = createHcalRecHit(detid, energy, PFLayer::HCAL_BARREL1, hcalBarrelGeometry, ct.id());
217  pfrh->setTime(rescaleFactor);
218  } break;
219  case HcalEndcap: {
220  if (energy < thresh_Endcap_)
221  continue;
222  // Apply tower 29 calibration
223  if (HCAL_Calib_ && abs(detid.ieta()) == 29)
224  energy *= HCAL_Calib_29;
225  if (rescaleFactor > 1.) {
226  pfrhCleaned = createHcalRecHit(detid, energy, PFLayer::HCAL_ENDCAP, hcalEndcapGeometry, ct.id());
227  pfrhCleaned->setTime(rescaleFactor);
228  energy *= rescaleFactor;
229  }
230  pfrh = createHcalRecHit(detid, energy, PFLayer::HCAL_ENDCAP, hcalEndcapGeometry, ct.id());
231  pfrh->setTime(rescaleFactor);
232  } break;
233  case HcalOuter: {
234  } break;
235  case HcalForward: {
236  //---ab: 2 rechits for HF:
237  //double energyemHF = weight_HFem_*ct.emEnergy();
238  //double energyhadHF = weight_HFhad_*ct.hadEnergy();
239  double energyemHF = weight_HFem_ * energyEM;
240  double energyhadHF = weight_HFhad_ * energy;
241  // Some energy in the tower !
242  if ((energyemHF + energyhadHF) < thresh_HF_)
243  continue;
244 
245  // Some cleaning in the HF
246  double longFibre = energyemHF + energyhadHF / 2.;
247  double shortFibre = energyhadHF / 2.;
248  int ieta = detid.ieta();
249  int iphi = detid.iphi();
250  HcalDetId theLongDetId(HcalForward, ieta, iphi, 1);
251  HcalDetId theShortDetId(HcalForward, ieta, iphi, 2);
253  auto theLongHit = hfHandle->find(theLongDetId);
254  auto theShortHit = hfHandle->find(theShortDetId);
255  //
256  double theLongHitEnergy = 0.;
257  double theShortHitEnergy = 0.;
258  bool flagShortDPG = false;
259  bool flagLongDPG = false;
260  bool flagShortTimeDPG = false;
261  bool flagLongTimeDPG = false;
262  bool flagShortPulseDPG = false;
263  bool flagLongPulseDPG = false;
264  //
265  if (theLongHit != hfHandle->end()) {
266  int theLongFlag = theLongHit->flags();
267  theLongHitEnergy = theLongHit->energy();
268  flagLongDPG = applyLongShortDPG_ && (hcalSevLvlComputer->getSeverityLevel(
269  theLongDetId, theLongFlag & hcalHFLongShortFlagValue_, 0) >
270  HcalMaxAllowedHFLongShortSev_);
271  flagLongTimeDPG = applyTimeDPG_ && (hcalSevLvlComputer->getSeverityLevel(
272  theLongDetId, theLongFlag & hcalHFInTimeWindowFlagValue_, 0) >
273  HcalMaxAllowedHFInTimeWindowSev_);
274  flagLongPulseDPG = applyPulseDPG_ && (hcalSevLvlComputer->getSeverityLevel(
275  theLongDetId, theLongFlag & hcalHFDigiTimeFlagValue_, 0) >
276  HcalMaxAllowedHFDigiTimeSev_);
277 
278  //flagLongDPG = applyLongShortDPG_ && theLongHit->flagField(HcalCaloFlagLabels::HFLongShort)==1;
279  //flagLongTimeDPG = applyTimeDPG_ && theLongHit->flagField(HcalCaloFlagLabels::HFInTimeWindow)==1;
280  //flagLongPulseDPG = applyPulseDPG_ && theLongHit->flagField(HcalCaloFlagLabels::HFDigiTime)==1;
281  }
282  //
283  if (theShortHit != hfHandle->end()) {
284  int theShortFlag = theShortHit->flags();
285  theShortHitEnergy = theShortHit->energy();
286  flagShortDPG = applyLongShortDPG_ && (hcalSevLvlComputer->getSeverityLevel(
287  theShortDetId, theShortFlag & hcalHFLongShortFlagValue_, 0) >
288  HcalMaxAllowedHFLongShortSev_);
289  flagShortTimeDPG = applyTimeDPG_ && (hcalSevLvlComputer->getSeverityLevel(
290  theShortDetId, theShortFlag & hcalHFInTimeWindowFlagValue_, 0) >
291  HcalMaxAllowedHFInTimeWindowSev_);
292  flagShortPulseDPG = applyPulseDPG_ && (hcalSevLvlComputer->getSeverityLevel(
293  theShortDetId, theShortFlag & hcalHFDigiTimeFlagValue_, 0) >
294  HcalMaxAllowedHFDigiTimeSev_);
295  //flagShortDPG = applyLongShortDPG_ && theShortHit->flagField(HcalCaloFlagLabels::HFLongShort)==1;
296  //flagShortTimeDPG = applyTimeDPG_ && theShortHit->flagField(HcalCaloFlagLabels::HFInTimeWindow)==1;
297  //flagShortPulseDPG = applyPulseDPG_ && theShortHit->flagField(HcalCaloFlagLabels::HFDigiTime)==1;
298  }
299 
300  // Then check the timing in short and long fibres in all other towers.
301  if (theShortHitEnergy > longShortFibre_Cut &&
302  (theShortHit->time() < minShortTiming_Cut || theShortHit->time() > maxShortTiming_Cut ||
303  flagShortTimeDPG || flagShortPulseDPG)) {
304  // rescaleFactor = 0. ;
305  pfrhHFHADCleaned = createHcalRecHit(detid, theShortHitEnergy, PFLayer::HF_HAD, hcalEndcapGeometry, ct.id());
306  pfrhHFHADCleaned->setTime(theShortHit->time());
307  /*
308  std::cout << "ieta/iphi = " << ieta << " " << iphi
309  << ", Energy em/had/long/short = "
310  << energyemHF << " " << energyhadHF << " "
311  << theLongHitEnergy << " " << theShortHitEnergy << " "
312  << ". Time = " << theShortHit->time() << " "
313  << ". The short and long flags : "
314  << flagShortDPG << " " << flagLongDPG << " "
315  << flagShortTimeDPG << " " << flagLongTimeDPG << " "
316  << flagShortPulseDPG << " " << flagLongPulseDPG << " "
317  << ". Short fibres were cleaned." << std::endl;
318  */
319  shortFibre -= theShortHitEnergy;
320  theShortHitEnergy = 0.;
321  }
322 
323  if (theLongHitEnergy > longShortFibre_Cut &&
324  (theLongHit->time() < minLongTiming_Cut || theLongHit->time() > maxLongTiming_Cut || flagLongTimeDPG ||
325  flagLongPulseDPG)) {
326  //rescaleFactor = 0. ;
327  pfrhHFEMCleaned = createHcalRecHit(detid, theLongHitEnergy, PFLayer::HF_EM, hcalEndcapGeometry, ct.id());
328  pfrhHFEMCleaned->setTime(theLongHit->time());
329  /*
330  std::cout << "ieta/iphi = " << ieta << " " << iphi
331  << ", Energy em/had/long/short = "
332  << energyemHF << " " << energyhadHF << " "
333  << theLongHitEnergy << " " << theShortHitEnergy << " "
334  << ". Time = " << theLongHit->time() << " "
335  << ". The short and long flags : "
336  << flagShortDPG << " " << flagLongDPG << " "
337  << flagShortTimeDPG << " " << flagLongTimeDPG << " "
338  << flagShortPulseDPG << " " << flagLongPulseDPG << " "
339  << ". Long fibres were cleaned." << std::endl;
340  */
341  longFibre -= theLongHitEnergy;
342  theLongHitEnergy = 0.;
343  }
344 
345  // Some energy must be in the long fibres is there is some energy in the short fibres !
346  if (theShortHitEnergy > shortFibre_Cut &&
347  (theLongHitEnergy / theShortHitEnergy < longFibre_Fraction || flagShortDPG)) {
348  // Check if the long-fibre hit was not cleaned already (because hot)
349  // In this case don't apply the cleaning
350  const HcalChannelStatus* theStatus = theHcalChStatus->getValues(theLongDetId);
351  unsigned theStatusValue = theStatus->getValue();
352  int theSeverityLevel = hcalSevLvlComputer->getSeverityLevel(detid, 0, theStatusValue);
353  // The channel is killed
355  if (theSeverityLevel <= HcalMaxAllowedChannelStatusSev_) {
356  // rescaleFactor = 0. ;
357  pfrhHFHADCleaned =
358  createHcalRecHit(detid, theShortHitEnergy, PFLayer::HF_HAD, hcalEndcapGeometry, ct.id());
359  pfrhHFHADCleaned->setTime(theShortHit->time());
360  /*
361  std::cout << "ieta/iphi = " << ieta << " " << iphi
362  << ", Energy em/had/long/short = "
363  << energyemHF << " " << energyhadHF << " "
364  << theLongHitEnergy << " " << theShortHitEnergy << " "
365  << ". Time = " << theShortHit->time() << " "
366  << ". The status value is " << theStatusValue
367  << ". The short and long flags : "
368  << flagShortDPG << " " << flagLongDPG << " "
369  << flagShortTimeDPG << " " << flagLongTimeDPG << " "
370  << flagShortPulseDPG << " " << flagLongPulseDPG << " "
371  << ". Short fibres were cleaned." << std::endl;
372  */
373  shortFibre -= theShortHitEnergy;
374  theShortHitEnergy = 0.;
375  }
376  }
377 
378  if (theLongHitEnergy > longFibre_Cut &&
379  (theShortHitEnergy / theLongHitEnergy < shortFibre_Fraction || flagLongDPG)) {
380  // Check if the long-fibre hit was not cleaned already (because hot)
381  // In this case don't apply the cleaning
382  const HcalChannelStatus* theStatus = theHcalChStatus->getValues(theShortDetId);
383  unsigned theStatusValue = theStatus->getValue();
384 
385  int theSeverityLevel = hcalSevLvlComputer->getSeverityLevel(detid, 0, theStatusValue);
386  // The channel is killed
388  if (theSeverityLevel <= HcalMaxAllowedChannelStatusSev_) {
389  //rescaleFactor = 0. ;
390  pfrhHFEMCleaned = createHcalRecHit(detid, theLongHitEnergy, PFLayer::HF_EM, hcalEndcapGeometry, ct.id());
391  pfrhHFEMCleaned->setTime(theLongHit->time());
392  /*
393  std::cout << "ieta/iphi = " << ieta << " " << iphi
394  << ", Energy em/had/long/short = "
395  << energyemHF << " " << energyhadHF << " "
396  << theLongHitEnergy << " " << theShortHitEnergy << " "
397  << ". The status value is " << theStatusValue
398  << ". Time = " << theLongHit->time() << " "
399  << ". The short and long flags : "
400  << flagShortDPG << " " << flagLongDPG << " "
401  << flagShortTimeDPG << " " << flagLongTimeDPG << " "
402  << flagShortPulseDPG << " " << flagLongPulseDPG << " "
403  << ". Long fibres were cleaned." << std::endl;
404  */
405  longFibre -= theLongHitEnergy;
406  theLongHitEnergy = 0.;
407  }
408  }
409 
410  // Special treatment for tower 29
411  // A tower with energy only at ieta = +/- 29 is not physical -> Clean
412  if (abs(ieta) == 29) {
413  // rescaleFactor = 0. ;
414  // Clean long fibres
415  if (theLongHitEnergy > shortFibre_Cut / 2.) {
416  pfrhHFEMCleaned29 =
417  createHcalRecHit(detid, theLongHitEnergy, PFLayer::HF_EM, hcalEndcapGeometry, ct.id());
418  pfrhHFEMCleaned29->setTime(theLongHit->time());
419  /*
420  std::cout << "ieta/iphi = " << ieta << " " << iphi
421  << ", Energy em/had/long/short = "
422  << energyemHF << " " << energyhadHF << " "
423  << theLongHitEnergy << " " << theShortHitEnergy << " "
424  << ". Long fibres were cleaned." << std::endl;
425  */
426  longFibre -= theLongHitEnergy;
427  theLongHitEnergy = 0.;
428  }
429  // Clean short fibres
430  if (theShortHitEnergy > shortFibre_Cut / 2.) {
431  pfrhHFHADCleaned29 =
432  createHcalRecHit(detid, theShortHitEnergy, PFLayer::HF_HAD, hcalEndcapGeometry, ct.id());
433  pfrhHFHADCleaned29->setTime(theShortHit->time());
434  /*
435  std::cout << "ieta/iphi = " << ieta << " " << iphi
436  << ", Energy em/had/long/short = "
437  << energyemHF << " " << energyhadHF << " "
438  << theLongHitEnergy << " " << theShortHitEnergy << " "
439  << ". Short fibres were cleaned." << std::endl;
440  */
441  shortFibre -= theShortHitEnergy;
442  theShortHitEnergy = 0.;
443  }
444  }
445  // Check the timing of the long and short fibre rechits
446 
447  // First, check the timing of long and short fibre in eta = 29 if tower 30.
448  else if (abs(ieta) == 30) {
449  int ieta29 = ieta > 0 ? 29 : -29;
450  HcalDetId theLongDetId29(HcalForward, ieta29, iphi, 1);
451  HcalDetId theShortDetId29(HcalForward, ieta29, iphi, 2);
452  auto theLongHit29 = hfHandle->find(theLongDetId29);
453  auto theShortHit29 = hfHandle->find(theShortDetId29);
454  //
455  double theLongHitEnergy29 = 0.;
456  double theShortHitEnergy29 = 0.;
457  bool flagShortDPG29 = false;
458  bool flagLongDPG29 = false;
459  bool flagShortTimeDPG29 = false;
460  bool flagLongTimeDPG29 = false;
461  bool flagShortPulseDPG29 = false;
462  bool flagLongPulseDPG29 = false;
463  //
464  if (theLongHit29 != hfHandle->end()) {
465  int theLongFlag29 = theLongHit29->flags();
466  theLongHitEnergy29 = theLongHit29->energy();
467  flagLongDPG29 = applyLongShortDPG_ && (hcalSevLvlComputer->getSeverityLevel(
468  theLongDetId29, theLongFlag29 & hcalHFLongShortFlagValue_, 0) >
469  HcalMaxAllowedHFLongShortSev_);
470  flagLongTimeDPG29 =
471  applyTimeDPG_ && (hcalSevLvlComputer->getSeverityLevel(theLongDetId29,
472  theLongFlag29 & hcalHFInTimeWindowFlagValue_,
473  0) > HcalMaxAllowedHFInTimeWindowSev_);
474  flagLongPulseDPG29 = applyPulseDPG_ && (hcalSevLvlComputer->getSeverityLevel(
475  theLongDetId29, theLongFlag29 & hcalHFDigiTimeFlagValue_, 0) >
476  HcalMaxAllowedHFDigiTimeSev_);
477 
478  //flagLongDPG29 = applyLongShortDPG_ && theLongHit29->flagField(HcalCaloFlagLabels::HFLongShort)==1;
479  //flagLongTimeDPG29 = applyTimeDPG_ && theLongHit29->flagField(HcalCaloFlagLabels::HFInTimeWindow)==1;
480  //flagLongPulseDPG29 = applyPulseDPG_ && theLongHit29->flagField(HcalCaloFlagLabels::HFDigiTime)==1;
481  }
482  //
483  if (theShortHit29 != hfHandle->end()) {
484  int theShortFlag29 = theShortHit29->flags();
485  theShortHitEnergy29 = theShortHit29->energy();
486  flagShortDPG29 =
487  applyLongShortDPG_ &&
488  (hcalSevLvlComputer->getSeverityLevel(
489  theShortDetId29, theShortFlag29 & hcalHFLongShortFlagValue_, 0) > HcalMaxAllowedHFLongShortSev_);
490  flagShortTimeDPG29 =
491  applyTimeDPG_ && (hcalSevLvlComputer->getSeverityLevel(theShortDetId29,
492  theShortFlag29 & hcalHFInTimeWindowFlagValue_,
493  0) > HcalMaxAllowedHFInTimeWindowSev_);
494  flagLongPulseDPG29 =
495  applyPulseDPG_ &&
496  (hcalSevLvlComputer->getSeverityLevel(theShortDetId29, theShortFlag29 & hcalHFDigiTimeFlagValue_, 0) >
497  HcalMaxAllowedHFDigiTimeSev_);
498 
499  //flagShortDPG29 = applyLongShortDPG_ && theShortHit29->flagField(HcalCaloFlagLabels::HFLongShort)==1;
500  //flagShortTimeDPG29 = applyTimeDPG_ && theShortHit29->flagField(HcalCaloFlagLabels::HFInTimeWindow)==1;
501  //flagShortPulseDPG29 = applyPulseDPG_ && theShortHit29->flagField(HcalCaloFlagLabels::HFDigiTime)==1;
502  }
503 
504  if (theLongHitEnergy29 > longShortFibre_Cut &&
505  (theLongHit29->time() < minLongTiming_Cut || theLongHit29->time() > maxLongTiming_Cut ||
506  flagLongTimeDPG29 || flagLongPulseDPG29)) {
507  //rescaleFactor = 0. ;
508  pfrhHFEMCleaned29 =
509  createHcalRecHit(detid, theLongHitEnergy29, PFLayer::HF_EM, hcalEndcapGeometry, ct.id());
510  pfrhHFEMCleaned29->setTime(theLongHit29->time());
511  /*
512  std::cout << "ieta/iphi = " << ieta29 << " " << iphi
513  << ", Energy em/had/long/short = "
514  << energyemHF << " " << energyhadHF << " "
515  << theLongHitEnergy29 << " " << theShortHitEnergy29 << " "
516  << ". Time = " << theLongHit29->time() << " "
517  << ". The short and long flags : "
518  << flagShortDPG29 << " " << flagLongDPG29 << " "
519  << flagShortTimeDPG29 << " " << flagLongTimeDPG29 << " "
520  << flagShortPulseDPG29 << " " << flagLongPulseDPG29 << " "
521  << ". Long fibres were cleaned." << std::endl;
522  */
523  longFibre -= theLongHitEnergy29;
524  theLongHitEnergy29 = 0;
525  }
526 
527  if (theShortHitEnergy29 > longShortFibre_Cut &&
528  (theShortHit29->time() < minShortTiming_Cut || theShortHit29->time() > maxShortTiming_Cut ||
529  flagShortTimeDPG29 || flagShortPulseDPG29)) {
530  //rescaleFactor = 0. ;
531  pfrhHFHADCleaned29 =
532  createHcalRecHit(detid, theShortHitEnergy29, PFLayer::HF_HAD, hcalEndcapGeometry, ct.id());
533  pfrhHFHADCleaned29->setTime(theShortHit29->time());
534  /*
535  std::cout << "ieta/iphi = " << ieta29 << " " << iphi
536  << ", Energy em/had/long/short = "
537  << energyemHF << " " << energyhadHF << " "
538  << theLongHitEnergy29 << " " << theShortHitEnergy29 << " "
539  << ". Time = " << theShortHit29->time() << " "
540  << ". The short and long flags : "
541  << flagShortDPG29 << " " << flagLongDPG29 << " "
542  << flagShortTimeDPG29 << " " << flagLongTimeDPG29 << " "
543  << flagShortPulseDPG29 << " " << flagLongPulseDPG29 << " "
544  << ". Short fibres were cleaned." << std::endl;
545  */
546  shortFibre -= theShortHitEnergy29;
547  theShortHitEnergy29 = 0;
548  }
549 
550  // Some energy must be in the long fibres is there is some energy in the short fibres !
551  if (theShortHitEnergy29 > shortFibre_Cut &&
552  (theLongHitEnergy29 / theShortHitEnergy29 < 2. * longFibre_Fraction || flagShortDPG29)) {
553  // Check if the long-fibre hit was not cleaned already (because hot)
554  // In this case don't apply the cleaning
555  const HcalChannelStatus* theStatus = theHcalChStatus->getValues(theLongDetId29);
556  unsigned theStatusValue = theStatus->getValue();
557 
558  int theSeverityLevel = hcalSevLvlComputer->getSeverityLevel(detid, 0, theStatusValue);
559  // The channel is killed
561  if (theSeverityLevel <= HcalMaxAllowedChannelStatusSev_) {
562  //rescaleFactor = 0. ;
563  pfrhHFHADCleaned29 =
564  createHcalRecHit(detid, theShortHitEnergy29, PFLayer::HF_HAD, hcalEndcapGeometry, ct.id());
565  pfrhHFHADCleaned29->setTime(theShortHit29->time());
566  /*
567  std::cout << "ieta/iphi = " << ieta29 << " " << iphi
568  << ", Energy em/had/long/short = "
569  << energyemHF << " " << energyhadHF << " "
570  << theLongHitEnergy29 << " " << theShortHitEnergy29 << " "
571  << ". Time = " << theShortHit29->time() << " "
572  << ". The status value is " << theStatusValue
573  << ". The short and long flags : "
574  << flagShortDPG29 << " " << flagLongDPG29 << " "
575  << flagShortTimeDPG29 << " " << flagLongTimeDPG29 << " "
576  << flagShortPulseDPG29 << " " << flagLongPulseDPG29 << " "
577  << ". Short fibres were cleaned." << std::endl;
578  */
579  shortFibre -= theShortHitEnergy29;
580  theShortHitEnergy29 = 0.;
581  }
582  }
583 
584  // Some energy must be in the short fibres is there is some energy in the long fibres !
585  if (theLongHitEnergy29 > longFibre_Cut &&
586  (theShortHitEnergy29 / theLongHitEnergy29 < shortFibre_Fraction || flagLongDPG29)) {
587  // Check if the long-fibre hit was not cleaned already (because hot)
588  // In this case don't apply the cleaning
589  const HcalChannelStatus* theStatus = theHcalChStatus->getValues(theShortDetId29);
590  unsigned theStatusValue = theStatus->getValue();
591  int theSeverityLevel = hcalSevLvlComputer->getSeverityLevel(detid, 0, theStatusValue);
592  // The channel is killed
594  if (theSeverityLevel <= HcalMaxAllowedChannelStatusSev_) {
595  //rescaleFactor = 0. ;
596  pfrhHFEMCleaned29 =
597  createHcalRecHit(detid, theLongHitEnergy29, PFLayer::HF_EM, hcalEndcapGeometry, ct.id());
598  pfrhHFEMCleaned29->setTime(theLongHit29->time());
599  /*
600  std::cout << "ieta/iphi = " << ieta29 << " " << iphi
601  << ", Energy em/had/long/short = "
602  << energyemHF << " " << energyhadHF << " "
603  << theLongHitEnergy29 << " " << theShortHitEnergy29 << " "
604  << ". The status value is " << theStatusValue
605  << ". Time = " << theLongHit29->time() << " "
606  << ". The short and long flags : "
607  << flagShortDPG29 << " " << flagLongDPG29 << " "
608  << flagShortTimeDPG29 << " " << flagLongTimeDPG29 << " "
609  << flagShortPulseDPG29 << " " << flagLongPulseDPG29 << " "
610  << ". Long fibres were cleaned." << std::endl;
611  */
612  longFibre -= theLongHitEnergy29;
613  theLongHitEnergy29 = 0.;
614  }
615  }
616 
617  // Check that the energy in tower 29 is smaller than in tower 30
618  // First in long fibres
619  if (theLongHitEnergy29 > std::max(theLongHitEnergy, shortFibre_Cut / 2)) {
620  pfrhHFEMCleaned29 =
621  createHcalRecHit(detid, theLongHitEnergy29, PFLayer::HF_EM, hcalEndcapGeometry, ct.id());
622  pfrhHFEMCleaned29->setTime(theLongHit29->time());
623  /*
624  std::cout << "ieta/iphi = " << ieta29 << " " << iphi
625  << ", Energy L29/S29/L30/S30 = "
626  << theLongHitEnergy29 << " " << theShortHitEnergy29 << " "
627  << theLongHitEnergy << " " << theShortHitEnergy << " "
628  << ". Long fibres were cleaned." << std::endl;
629  */
630  longFibre -= theLongHitEnergy29;
631  theLongHitEnergy29 = 0.;
632  }
633  // Second in short fibres
634  if (theShortHitEnergy29 > std::max(theShortHitEnergy, shortFibre_Cut / 2.)) {
635  pfrhHFHADCleaned29 =
636  createHcalRecHit(detid, theShortHitEnergy29, PFLayer::HF_HAD, hcalEndcapGeometry, ct.id());
637  pfrhHFHADCleaned29->setTime(theShortHit29->time());
638  /*
639  std::cout << "ieta/iphi = " << ieta << " " << iphi
640  << ", Energy L29/S29/L30/S30 = "
641  << theLongHitEnergy29 << " " << theShortHitEnergy29 << " "
642  << theLongHitEnergy << " " << theShortHitEnergy << " "
643  << ". Short fibres were cleaned." << std::endl;
644  */
645  shortFibre -= theShortHitEnergy29;
646  theShortHitEnergy29 = 0.;
647  }
648  }
649 
650  // Determine EM and HAD after cleaning of short and long fibres
651  energyhadHF = 2. * shortFibre;
652  energyemHF = longFibre - shortFibre;
653 
654  // The EM energy might be negative, as it amounts to Long - Short
655  // In that case, put the EM "energy" in the HAD energy
656  // Just to avoid systematic positive bias due to "Short" high fluctuations
657  if (energyemHF < thresh_HF_) {
658  energyhadHF += energyemHF;
659  energyemHF = 0.;
660  }
661 
662  // Apply HCAL calibration factors flor towers close to 29, if requested
663  if (HF_Calib_ && abs(detid.ieta()) <= 32) {
664  energyhadHF *= HF_Calib_29;
665  energyemHF *= HF_Calib_29;
666  }
667 
668  // Create an EM and a HAD rechit if above threshold.
669  if (energyemHF > thresh_HF_ || energyhadHF > thresh_HF_) {
670  pfrhHFEM = createHcalRecHit(detid, energyemHF, PFLayer::HF_EM, hcalEndcapGeometry, ct.id());
671  pfrhHFHAD = createHcalRecHit(detid, energyhadHF, PFLayer::HF_HAD, hcalEndcapGeometry, ct.id());
672  }
673 
674  } break;
675  default:
676  LogError("PFCTRecHitProducerHCAL") << "CaloTower constituent: unknown layer : " << detid.subdet() << endl;
677  }
678 
679  if (pfrh) {
680  rechits->push_back(*pfrh);
681  delete pfrh;
682  }
683  if (pfrhCleaned) {
684  rechitsCleaned->push_back(*pfrhCleaned);
685  delete pfrhCleaned;
686  }
687  if (pfrhHFEM) {
688  HFEMRecHits->push_back(*pfrhHFEM);
689  delete pfrhHFEM;
690  }
691  if (pfrhHFHAD) {
692  HFHADRecHits->push_back(*pfrhHFHAD);
693  delete pfrhHFHAD;
694  }
695  if (pfrhHFEMCleaned) {
696  rechitsCleaned->push_back(*pfrhHFEMCleaned);
697  delete pfrhHFEMCleaned;
698  }
699  if (pfrhHFHADCleaned) {
700  rechitsCleaned->push_back(*pfrhHFHADCleaned);
701  delete pfrhHFHADCleaned;
702  }
703  if (pfrhHFEMCleaned29) {
704  rechitsCleaned->push_back(*pfrhHFEMCleaned29);
705  delete pfrhHFEMCleaned29;
706  }
707  if (pfrhHFHADCleaned29) {
708  rechitsCleaned->push_back(*pfrhHFHADCleaned29);
709  delete pfrhHFHADCleaned29;
710  }
711  }
712  }
713 
714  //ok now do navigation
715  //create a refprod here
716 
718 
719  for (unsigned int i = 0; i < rechits->size(); ++i) {
720  navigator_->associateNeighbours(rechits->at(i), rechits, refProd);
721  }
722 
723  if (navigation_HF_) {
725 
726  for (unsigned int i = 0; i < HFEMRecHits->size(); ++i) {
727  navigator_->associateNeighbours(HFEMRecHits->at(i), HFEMRecHits, refProdEM);
728  }
729 
731 
732  for (unsigned int i = 0; i < HFHADRecHits->size(); ++i) {
733  navigator_->associateNeighbours(HFHADRecHits->at(i), HFHADRecHits, refProdHAD);
734  }
735  }
736 
737  iEvent.put(std::move(rechits), "");
738  iEvent.put(std::move(rechitsCleaned), "Cleaned");
739  iEvent.put(std::move(HFEMRecHits), "HFEM");
740  iEvent.put(std::move(HFHADRecHits), "HFHAD");
741 }
742 
744 
745 // ------------ method called once each job just before starting event loop ------------
747  // Get cleaned channels in the HCAL and HF
748  // HCAL channel status map ****************************************
750  es.get<HcalChannelQualityRcd>().get("withTopo", hcalChStatus);
751  theHcalChStatus = hcalChStatus.product();
752 
753  // Retrieve the good/bad ECAL channels from the DB
755  es.get<EcalChannelStatusRcd>().get(ecalChStatus);
756  theEcalChStatus = ecalChStatus.product();
757 
759  es.get<CaloGeometryRecord>().get(cttopo);
760  theTowerConstituentsMap = cttopo.product();
761 }
762 
764  double energy,
765  PFLayer::Layer layer,
767  const CaloTowerDetId& newDetId) {
768  std::shared_ptr<const CaloCellGeometry> thisCell = geom->getGeometry(detid);
769  if (!thisCell) {
770  edm::LogError("PFRecHitProducerHCAL")
771  << "warning detid " << detid.rawId() << " not found in layer " << layer << endl;
772  return nullptr;
773  }
774 
775  switch (layer) {
776  case PFLayer::HF_EM:
777  case PFLayer::HF_HAD: {
778  auto zp = dynamic_cast<IdealZPrism const*>(thisCell.get());
779  assert(zp);
780  thisCell = zp->forPF();
781  } break;
782  default:
783  break;
784  }
785 
786  auto rh = new reco::PFRecHit(thisCell, newDetId.rawId(), layer, energy);
787 
788  return rh;
789 }
T getParameter(std::string const &) const
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:34
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
void beginLuminosityBlock(const edm::LuminosityBlock &lumi, const edm::EventSetup &es) override
HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:138
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
PFCTRecHitProducer(const edm::ParameterSet &)
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
std::vector< CaloTower >::const_iterator const_iterator
~PFCTRecHitProducer() override
std::vector< PFRecHit > PFRecHitCollection
collection of PFRecHit objects
Definition: PFRecHitFwd.h:9
reco::PFRecHit * createHcalRecHit(const DetId &detid, double energy, PFLayer::Layer layer, const CaloSubdetectorGeometry *geom, const CaloTowerDetId &newDetId)
int iEvent
Definition: GenABIO.cc:224
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
int ieta() const
get the cell ieta
Definition: HcalDetId.h:155
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void setTime(double time)
Definition: PFRecHit.h:69
RefProd< PROD > getRefBeforePut()
Definition: Event.h:156
const_iterator end() const
Layer
layer definition
Definition: PFLayer.h:29
int iphi() const
get the cell iphi
Definition: HcalDetId.h:157
Definition: DetId.h:17
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
int getSeverityLevel(const DetId &myid, const uint32_t &myflag, const uint32_t &mystatus) const
iterator find(key_type k)
HLT enums.
T get() const
Definition: EventSetup.h:73
uint32_t getValue() const
T const * product() const
Definition: ESHandle.h:86
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
def move(src, dest)
Definition: eostools.py:511