CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CaloTowersCreationAlgo.cc
Go to the documentation of this file.
2 
10 #include "Math/Interpolator.h"
11 
12 #include <cmath>
13 
14 //#define EDM_ML_DEBUG
15 
17  : theEBthreshold(-1000.),
18  theEEthreshold(-1000.),
19 
20  theUseEtEBTresholdFlag(false),
21  theUseEtEETresholdFlag(false),
22  theUseSymEBTresholdFlag(false),
23  theUseSymEETresholdFlag(false),
24 
25  theHcalThreshold(-1000.),
26  theHBthreshold(-1000.),
27  theHBthreshold1(-1000.),
28  theHBthreshold2(-1000.),
29  theHESthreshold(-1000.),
30  theHESthreshold1(-1000.),
31  theHEDthreshold(-1000.),
32  theHEDthreshold1(-1000.),
33  theHOthreshold0(-1000.),
34  theHOthresholdPlus1(-1000.),
35  theHOthresholdMinus1(-1000.),
36  theHOthresholdPlus2(-1000.),
37  theHOthresholdMinus2(-1000.),
38  theHF1threshold(-1000.),
39  theHF2threshold(-1000.),
40  theEBGrid(std::vector<double>(5, 10.)),
41  theEBWeights(std::vector<double>(5, 1.)),
42  theEEGrid(std::vector<double>(5, 10.)),
43  theEEWeights(std::vector<double>(5, 1.)),
44  theHBGrid(std::vector<double>(5, 10.)),
45  theHBWeights(std::vector<double>(5, 1.)),
46  theHESGrid(std::vector<double>(5, 10.)),
47  theHESWeights(std::vector<double>(5, 1.)),
48  theHEDGrid(std::vector<double>(5, 10.)),
49  theHEDWeights(std::vector<double>(5, 1.)),
50  theHOGrid(std::vector<double>(5, 10.)),
51  theHOWeights(std::vector<double>(5, 1.)),
52  theHF1Grid(std::vector<double>(5, 10.)),
53  theHF1Weights(std::vector<double>(5, 1.)),
54  theHF2Grid(std::vector<double>(5, 10.)),
55  theHF2Weights(std::vector<double>(5, 1.)),
56  theEBweight(1.),
57  theEEweight(1.),
58  theHBweight(1.),
59  theHESweight(1.),
60  theHEDweight(1.),
61  theHOweight(1.),
62  theHF1weight(1.),
63  theHF2weight(1.),
64  theEcutTower(-1000.),
65  theEBSumThreshold(-1000.),
66  theEESumThreshold(-1000.),
67  theEBEScale(50.),
68  theEEEScale(50.),
69  theHBEScale(50.),
70  theHESEScale(50.),
71  theHEDEScale(50.),
72  theHOEScale(50.),
73  theHF1EScale(50.),
74  theHF2EScale(50.),
75  theHcalTopology(nullptr),
76  theGeometry(nullptr),
77  theTowerConstituentsMap(nullptr),
78  theHcalAcceptSeverityLevel(0),
79  theRecoveredHcalHitsAreUsed(false),
80  theRecoveredEcalHitsAreUsed(false),
81  useRejectedHitsOnly(false),
82  theHcalAcceptSeverityLevelForRejectedHit(0),
83  useRejectedRecoveredHcalHits(0),
84  useRejectedRecoveredEcalHits(0),
86  theHOIsUsed(true),
87  // (for momentum reconstruction algorithm)
88  theMomConstrMethod(0),
89  theMomHBDepth(0.),
90  theMomHEDepth(0.),
91  theMomEBDepth(0.),
92  theMomEEDepth(0.),
93  theHcalPhase(0) {}
94 
96  double EEthreshold,
97 
98  bool useEtEBTreshold,
99  bool useEtEETreshold,
100  bool useSymEBTreshold,
101  bool useSymEETreshold,
102 
103  double HcalThreshold,
104  double HBthreshold,
105  double HBthreshold1,
106  double HBthreshold2,
107  double HESthreshold,
108  double HESthreshold1,
109  double HEDthreshold,
110  double HEDthreshold1,
111  double HOthreshold0,
112  double HOthresholdPlus1,
113  double HOthresholdMinus1,
114  double HOthresholdPlus2,
115  double HOthresholdMinus2,
116  double HF1threshold,
117  double HF2threshold,
118  double EBweight,
119  double EEweight,
120  double HBweight,
121  double HESweight,
122  double HEDweight,
123  double HOweight,
124  double HF1weight,
125  double HF2weight,
126  double EcutTower,
127  double EBSumThreshold,
128  double EESumThreshold,
129  bool useHO,
130  // (momentum reconstruction algorithm)
131  int momConstrMethod,
132  double momHBDepth,
133  double momHEDepth,
134  double momEBDepth,
135  double momEEDepth,
136  int hcalPhase)
137 
138  : theEBthreshold(EBthreshold),
139  theEEthreshold(EEthreshold),
140 
141  theUseEtEBTresholdFlag(useEtEBTreshold),
142  theUseEtEETresholdFlag(useEtEETreshold),
143  theUseSymEBTresholdFlag(useSymEBTreshold),
144  theUseSymEETresholdFlag(useSymEETreshold),
145 
146  theHcalThreshold(HcalThreshold),
147  theHBthreshold(HBthreshold),
148  theHBthreshold1(HBthreshold1),
149  theHBthreshold2(HBthreshold2),
150  theHESthreshold(HESthreshold),
151  theHESthreshold1(HESthreshold1),
152  theHEDthreshold(HEDthreshold),
153  theHEDthreshold1(HEDthreshold1),
154  theHOthreshold0(HOthreshold0),
155  theHOthresholdPlus1(HOthresholdPlus1),
156  theHOthresholdMinus1(HOthresholdMinus1),
157  theHOthresholdPlus2(HOthresholdPlus2),
158  theHOthresholdMinus2(HOthresholdMinus2),
159  theHF1threshold(HF1threshold),
160  theHF2threshold(HF2threshold),
161  theEBGrid(std::vector<double>(5, 10.)),
162  theEBWeights(std::vector<double>(5, 1.)),
163  theEEGrid(std::vector<double>(5, 10.)),
164  theEEWeights(std::vector<double>(5, 1.)),
165  theHBGrid(std::vector<double>(5, 10.)),
166  theHBWeights(std::vector<double>(5, 1.)),
167  theHESGrid(std::vector<double>(5, 10.)),
168  theHESWeights(std::vector<double>(5, 1.)),
169  theHEDGrid(std::vector<double>(5, 10.)),
170  theHEDWeights(std::vector<double>(5, 1.)),
171  theHOGrid(std::vector<double>(5, 10.)),
172  theHOWeights(std::vector<double>(5, 1.)),
173  theHF1Grid(std::vector<double>(5, 10.)),
174  theHF1Weights(std::vector<double>(5, 1.)),
175  theHF2Grid(std::vector<double>(5, 10.)),
176  theHF2Weights(std::vector<double>(5, 1.)),
177  theEBweight(EBweight),
178  theEEweight(EEweight),
179  theHBweight(HBweight),
180  theHESweight(HESweight),
181  theHEDweight(HEDweight),
182  theHOweight(HOweight),
183  theHF1weight(HF1weight),
184  theHF2weight(HF2weight),
185  theEcutTower(EcutTower),
186  theEBSumThreshold(EBSumThreshold),
187  theEESumThreshold(EESumThreshold),
188  theEBEScale(50.),
189  theEEEScale(50.),
190  theHBEScale(50.),
191  theHESEScale(50.),
192  theHEDEScale(50.),
193  theHOEScale(50.),
194  theHF1EScale(50.),
195  theHF2EScale(50.),
196  theHcalTopology(nullptr),
197  theGeometry(nullptr),
198  theTowerConstituentsMap(nullptr),
199  theHcalAcceptSeverityLevel(0),
200  theRecoveredHcalHitsAreUsed(false),
201  theRecoveredEcalHitsAreUsed(false),
202  useRejectedHitsOnly(false),
203  theHcalAcceptSeverityLevelForRejectedHit(0),
204  useRejectedRecoveredHcalHits(0),
205  useRejectedRecoveredEcalHits(0),
207  theHOIsUsed(useHO),
208  // (momentum reconstruction algorithm)
209  theMomConstrMethod(momConstrMethod),
210  theMomHBDepth(momHBDepth),
211  theMomHEDepth(momHEDepth),
212  theMomEBDepth(momEBDepth),
213  theMomEEDepth(momEEDepth),
214  theHcalPhase(hcalPhase) {}
215 
217  double EEthreshold,
218  bool useEtEBTreshold,
219  bool useEtEETreshold,
220  bool useSymEBTreshold,
221  bool useSymEETreshold,
222 
223  double HcalThreshold,
224  double HBthreshold,
225  double HBthreshold1,
226  double HBthreshold2,
227  double HESthreshold,
228  double HESthreshold1,
229  double HEDthreshold,
230  double HEDthreshold1,
231  double HOthreshold0,
232  double HOthresholdPlus1,
233  double HOthresholdMinus1,
234  double HOthresholdPlus2,
235  double HOthresholdMinus2,
236  double HF1threshold,
237  double HF2threshold,
238  const std::vector<double>& EBGrid,
239  const std::vector<double>& EBWeights,
240  const std::vector<double>& EEGrid,
241  const std::vector<double>& EEWeights,
242  const std::vector<double>& HBGrid,
243  const std::vector<double>& HBWeights,
244  const std::vector<double>& HESGrid,
245  const std::vector<double>& HESWeights,
246  const std::vector<double>& HEDGrid,
247  const std::vector<double>& HEDWeights,
248  const std::vector<double>& HOGrid,
249  const std::vector<double>& HOWeights,
250  const std::vector<double>& HF1Grid,
251  const std::vector<double>& HF1Weights,
252  const std::vector<double>& HF2Grid,
253  const std::vector<double>& HF2Weights,
254  double EBweight,
255  double EEweight,
256  double HBweight,
257  double HESweight,
258  double HEDweight,
259  double HOweight,
260  double HF1weight,
261  double HF2weight,
262  double EcutTower,
263  double EBSumThreshold,
264  double EESumThreshold,
265  bool useHO,
266  // (for the momentum construction algorithm)
267  int momConstrMethod,
268  double momHBDepth,
269  double momHEDepth,
270  double momEBDepth,
271  double momEEDepth,
272  int hcalPhase)
273 
274  : theEBthreshold(EBthreshold),
275  theEEthreshold(EEthreshold),
276 
277  theUseEtEBTresholdFlag(useEtEBTreshold),
278  theUseEtEETresholdFlag(useEtEETreshold),
279  theUseSymEBTresholdFlag(useSymEBTreshold),
280  theUseSymEETresholdFlag(useSymEETreshold),
281 
282  theHcalThreshold(HcalThreshold),
283  theHBthreshold(HBthreshold),
284  theHBthreshold1(HBthreshold1),
285  theHBthreshold2(HBthreshold2),
286  theHESthreshold(HESthreshold),
287  theHESthreshold1(HESthreshold1),
288  theHEDthreshold(HEDthreshold),
289  theHEDthreshold1(HEDthreshold1),
290  theHOthreshold0(HOthreshold0),
291  theHOthresholdPlus1(HOthresholdPlus1),
292  theHOthresholdMinus1(HOthresholdMinus1),
293  theHOthresholdPlus2(HOthresholdPlus2),
294  theHOthresholdMinus2(HOthresholdMinus2),
295  theHF1threshold(HF1threshold),
296  theHF2threshold(HF2threshold),
297  theEBGrid(EBGrid),
298  theEBWeights(EBWeights),
299  theEEGrid(EEGrid),
300  theEEWeights(EEWeights),
301  theHBGrid(HBGrid),
302  theHBWeights(HBWeights),
303  theHESGrid(HESGrid),
304  theHESWeights(HESWeights),
305  theHEDGrid(HEDGrid),
306  theHEDWeights(HEDWeights),
307  theHOGrid(HOGrid),
308  theHOWeights(HOWeights),
309  theHF1Grid(HF1Grid),
310  theHF1Weights(HF1Weights),
311  theHF2Grid(HF2Grid),
312  theHF2Weights(HF2Weights),
313  theEBweight(EBweight),
314  theEEweight(EEweight),
315  theHBweight(HBweight),
316  theHESweight(HESweight),
317  theHEDweight(HEDweight),
318  theHOweight(HOweight),
319  theHF1weight(HF1weight),
320  theHF2weight(HF2weight),
321  theEcutTower(EcutTower),
322  theEBSumThreshold(EBSumThreshold),
323  theEESumThreshold(EESumThreshold),
324  theEBEScale(50.),
325  theEEEScale(50.),
326  theHBEScale(50.),
327  theHESEScale(50.),
328  theHEDEScale(50.),
329  theHOEScale(50.),
330  theHF1EScale(50.),
331  theHF2EScale(50.),
332  theHcalTopology(nullptr),
333  theGeometry(nullptr),
334  theTowerConstituentsMap(nullptr),
335  theHcalAcceptSeverityLevel(0),
336  theRecoveredHcalHitsAreUsed(false),
337  theRecoveredEcalHitsAreUsed(false),
338  useRejectedHitsOnly(false),
339  theHcalAcceptSeverityLevelForRejectedHit(0),
340  useRejectedRecoveredHcalHits(0),
341  useRejectedRecoveredEcalHits(0),
343  theHOIsUsed(useHO),
344  // (momentum reconstruction algorithm)
345  theMomConstrMethod(momConstrMethod),
346  theMomHBDepth(momHBDepth),
347  theMomHEDepth(momHEDepth),
348  theMomEBDepth(momEBDepth),
349  theMomEEDepth(momEEDepth),
350  theHcalPhase(hcalPhase) {
351  // static int N = 0;
352  // std::cout << "VI Algo " << ++N << std::endl;
353  // nalgo=N;
354 }
355 
357  const CaloTowerConstituentsMap* ctmap,
358  const HcalTopology* htopo,
359  const CaloGeometry* geo) {
360  theTowerTopology = cttopo;
361  theTowerConstituentsMap = ctmap;
362  theHcalTopology = htopo;
363  theGeometry = geo;
365 
366  //initialize ecal bad channel map
368 }
369 
371  theTowerMap.clear();
372  theTowerMapSize = 0;
373  //hcalDropChMap.clear();
374 }
375 
377  for (HBHERecHitCollection::const_iterator hbheItr = hbhe.begin(); hbheItr != hbhe.end(); ++hbheItr)
378  assignHitHcal(&(*hbheItr));
379 }
380 
382  for (HORecHitCollection::const_iterator hoItr = ho.begin(); hoItr != ho.end(); ++hoItr)
383  assignHitHcal(&(*hoItr));
384 }
385 
387  for (HFRecHitCollection::const_iterator hfItr = hf.begin(); hfItr != hf.end(); ++hfItr)
388  assignHitHcal(&(*hfItr));
389 }
390 
392  for (EcalRecHitCollection::const_iterator ecItr = ec.begin(); ecItr != ec.end(); ++ecItr)
393  assignHitEcal(&(*ecItr));
394 }
395 
396 // this method should not be used any more as the towers in the changed format
397 // can not be properly rescaled with the "rescale" method.
398 // "rescale was replaced by "rescaleTowers"
399 //
401  for (CaloTowerCollection::const_iterator ctcItr = ctc.begin(); ctcItr != ctc.end(); ++ctcItr) {
402  rescale(&(*ctcItr));
403  }
404 }
405 
407  // now copy this map into the final collection
408  result.reserve(theTowerMapSize);
409  // auto k=0U;
410  // if (!theEbHandle.isValid()) std::cout << "VI ebHandle not valid" << std::endl;
411  // if (!theEeHandle.isValid()) std::cout << "VI eeHandle not valid" << std::endl;
412 
413  for (auto const& mt : theTowerMap) {
414  // Convert only if there is at least one constituent in the metatower.
415  // The check of constituents size in the coverted tower is still needed!
416  if (!mt.empty()) {
417  convert(mt.id, mt, result);
418  } // ++k;}
419  }
420 
421  // assert(k==theTowerMapSize);
422  // std::cout << "VI TowerMap " << theTowerMapSize << " " << k << std::endl;
423 
424  theTowerMap.clear(); // save the memory
425  theTowerMapSize = 0;
426 }
427 
429  for (CaloTowerCollection::const_iterator ctcItr = ctc.begin(); ctcItr != ctc.end(); ++ctcItr) {
430  CaloTowerDetId twrId = ctcItr->id();
431  double newE_em = ctcItr->emEnergy();
432  double newE_had = ctcItr->hadEnergy();
433  double newE_outer = ctcItr->outerEnergy();
434 
435  double threshold = 0.0; // not used: we do not change thresholds
436  double weight = 1.0;
437 
438  // HF
439  if (ctcItr->ietaAbs() >= theTowerTopology->firstHFRing()) {
440  double E_short = 0.5 * newE_had; // from the definitions for HF
441  double E_long = newE_em + 0.5 * newE_had; //
442  // scale
443  E_long *= theHF1weight;
444  E_short *= theHF2weight;
445  // convert
446  newE_em = E_long - E_short;
447  newE_had = 2.0 * E_short;
448  }
449 
450  else { // barrel/endcap
451 
452  // find if its in EB, or EE; determine from first ecal constituent found
453  for (unsigned int iConst = 0; iConst < ctcItr->constituentsSize(); ++iConst) {
454  DetId constId = ctcItr->constituent(iConst);
455  if (constId.det() != DetId::Ecal)
456  continue;
457  getThresholdAndWeight(constId, threshold, weight);
458  newE_em *= weight;
459  break;
460  }
461  // HO
462  for (unsigned int iConst = 0; iConst < ctcItr->constituentsSize(); ++iConst) {
463  DetId constId = ctcItr->constituent(iConst);
464  if (constId.det() != DetId::Hcal)
465  continue;
466  if (HcalDetId(constId).subdet() != HcalOuter)
467  continue;
468  getThresholdAndWeight(constId, threshold, weight);
469  newE_outer *= weight;
470  break;
471  }
472  // HB/HE
473  for (unsigned int iConst = 0; iConst < ctcItr->constituentsSize(); ++iConst) {
474  DetId constId = ctcItr->constituent(iConst);
475  if (constId.det() != DetId::Hcal)
476  continue;
477  if (HcalDetId(constId).subdet() == HcalOuter)
478  continue;
479  getThresholdAndWeight(constId, threshold, weight);
480  newE_had *= weight;
481  if (ctcItr->ietaAbs() > theTowerTopology->firstHERing())
482  newE_outer *= weight;
483  break;
484  }
485 
486  } // barrel/endcap region
487 
488  // now make the new tower
489 
490  double newE_hadTot =
491  (theHOIsUsed && twrId.ietaAbs() <= theTowerTopology->lastHORing()) ? newE_had + newE_outer : newE_had;
492 
493  GlobalPoint emPoint = ctcItr->emPosition();
494  GlobalPoint hadPoint = ctcItr->emPosition();
495 
496  double f_em = 1.0 / cosh(emPoint.eta());
497  double f_had = 1.0 / cosh(hadPoint.eta());
498 
500 
501  if (ctcItr->ietaAbs() < theTowerTopology->firstHFRing()) {
502  if (newE_em > 0)
503  towerP4 += CaloTower::PolarLorentzVector(newE_em * f_em, emPoint.eta(), emPoint.phi(), 0);
504  if (newE_hadTot > 0)
505  towerP4 += CaloTower::PolarLorentzVector(newE_hadTot * f_had, hadPoint.eta(), hadPoint.phi(), 0);
506  } else {
507  double newE_tot = newE_em + newE_had;
508  // for HF we use common point for ecal, hcal shower positions regardless of the method
509  if (newE_tot > 0)
510  towerP4 += CaloTower::PolarLorentzVector(newE_tot * f_had, hadPoint.eta(), hadPoint.phi(), 0);
511  }
512 
513  CaloTower rescaledTower(twrId, newE_em, newE_had, newE_outer, -1, -1, towerP4, emPoint, hadPoint);
514  // copy the timings, have to convert back to int, 1 unit = 0.01 ns
515  rescaledTower.setEcalTime(int(ctcItr->ecalTime() * 100.0 + 0.5));
516  rescaledTower.setHcalTime(int(ctcItr->hcalTime() * 100.0 + 0.5));
517  //add topology info
518  rescaledTower.setHcalSubdet(theTowerTopology->lastHBRing(),
522 
523  std::vector<DetId> contains;
524  for (unsigned int iConst = 0; iConst < ctcItr->constituentsSize(); ++iConst) {
525  contains.push_back(ctcItr->constituent(iConst));
526  }
527  rescaledTower.addConstituents(contains);
528 
529  rescaledTower.setCaloTowerStatus(ctcItr->towerStatusWord());
530 
531  ctcResult.push_back(rescaledTower);
532 
533  } // end of loop over towers
534 }
535 
537  DetId detId = recHit->detid();
538  DetId detIdF(detId);
539  if (detId.det() == DetId::Hcal && theHcalTopology->getMergePositionFlag()) {
540  detIdF = theHcalTopology->idFront(HcalDetId(detId));
541 #ifdef EDM_ML_DEBUG
542  std::cout << "AssignHitHcal DetId " << HcalDetId(detId) << " Front " << HcalDetId(detIdF) << std::endl;
543 #endif
544  }
545 
546  unsigned int chStatusForCT = hcalChanStatusForCaloTower(recHit);
547 
548  // this is for skipping channls: mostly needed for the creation of
549  // bad towers from hits i the bad channel collections.
550  if (chStatusForCT == CaloTowersCreationAlgo::IgnoredChan)
551  return;
552 
553  double threshold, weight;
554  getThresholdAndWeight(detId, threshold, weight);
555 
556  double energy = recHit->energy(); // original RecHit energy is used to apply thresholds
557  double e = energy * weight; // energies scaled by user weight: used in energy assignments
558 
559  // SPECIAL handling of tower 28 merged depths --> half into tower 28 and half into tower 29
560  bool merge(false);
561  if (detIdF.det() == DetId::Hcal && HcalDetId(detIdF).subdet() == HcalEndcap &&
562  (theHcalPhase == 0 || theHcalPhase == 1) &&
563  //HcalDetId(detId).depth()==3 &&
564  HcalDetId(detIdF).ietaAbs() == theHcalTopology->lastHERing() - 1) {
565  merge = theHcalTopology->mergedDepth29(HcalDetId(detIdF));
566 #ifdef EDM_ML_DEBUG
567  std::cout << "Merge " << HcalDetId(detIdF) << ":" << merge << std::endl;
568 #endif
569  }
570  if (merge) {
572 
573  // bad channels are counted regardless of energy threshold
574 
575  if (chStatusForCT == CaloTowersCreationAlgo::BadChan) {
576  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
577  if (towerDetId.null())
578  return;
579  MetaTower& tower28 = find(towerDetId);
580  CaloTowerDetId towerDetId29(towerDetId.ieta() + towerDetId.zside(), towerDetId.iphi());
581  MetaTower& tower29 = find(towerDetId29);
582  tower28.numBadHcalCells += 1;
583  tower29.numBadHcalCells += 1;
584  }
585 
586  else if (0.5 * energy >= threshold) { // not bad channel: use energy if above threshold
587 
588  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
589  if (towerDetId.null())
590  return;
591  MetaTower& tower28 = find(towerDetId);
592  CaloTowerDetId towerDetId29(towerDetId.ieta() + towerDetId.zside(), towerDetId.iphi());
593  MetaTower& tower29 = find(towerDetId29);
594 
595  if (chStatusForCT == CaloTowersCreationAlgo::RecoveredChan) {
596  tower28.numRecHcalCells += 1;
597  tower29.numRecHcalCells += 1;
598  } else if (chStatusForCT == CaloTowersCreationAlgo::ProblematicChan) {
599  tower28.numProbHcalCells += 1;
600  tower29.numProbHcalCells += 1;
601  }
602 
603  // NOTE DIVIDE BY 2!!!
604  double e28 = 0.5 * e;
605  double e29 = 0.5 * e;
606 
607  tower28.E_had += e28;
608  tower28.E += e28;
609  std::pair<DetId, float> mc(detId, e28);
610  tower28.metaConstituents.push_back(mc);
611 
612  tower29.E_had += e29;
613  tower29.E += e29;
614  tower29.metaConstituents.push_back(mc);
615 
616  // time info: do not use in averaging if timing error is found: need
617  // full set of status info to implement: use only "good" channels for now
618 
619  if (chStatusForCT == CaloTowersCreationAlgo::GoodChan) {
620  tower28.hadSumTimeTimesE += (e28 * recHit->time());
621  tower28.hadSumEForTime += e28;
622  tower29.hadSumTimeTimesE += (e29 * recHit->time());
623  tower29.hadSumEForTime += e29;
624  }
625 
626  // store the energy in layer 3 also in E_outer
627  tower28.E_outer += e28;
628  tower29.E_outer += e29;
629  } // not a "bad" hit
630  } // end of special case
631 
632  else {
633  HcalDetId hcalDetId(detId);
634 
636 
637  if (hcalDetId.subdet() == HcalOuter) {
638  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
639  if (towerDetId.null())
640  return;
641  MetaTower& tower = find(towerDetId);
642 
643  if (chStatusForCT == CaloTowersCreationAlgo::BadChan) {
644  if (theHOIsUsed)
645  tower.numBadHcalCells += 1;
646  }
647 
648  else if (energy >= threshold) {
649  tower.E_outer += e; // store HO energy even if HO is not used
650  // add energy of the tower and/or flag if theHOIsUsed
651  if (theHOIsUsed) {
652  tower.E += e;
653 
654  if (chStatusForCT == CaloTowersCreationAlgo::RecoveredChan) {
655  tower.numRecHcalCells += 1;
656  } else if (chStatusForCT == CaloTowersCreationAlgo::ProblematicChan) {
657  tower.numProbHcalCells += 1;
658  }
659  } // HO is used
660 
661  // add HO to constituents even if it is not used: JetMET wants to keep these towers
662  std::pair<DetId, float> mc(detId, e);
663  tower.metaConstituents.push_back(mc);
664 
665  } // not a bad channel, energy above threshold
666 
667  } // HO hit
668 
669  // HF calculates EM fraction differently
670  else if (hcalDetId.subdet() == HcalForward) {
671  if (chStatusForCT == CaloTowersCreationAlgo::BadChan) {
672  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
673  if (towerDetId.null())
674  return;
675  MetaTower& tower = find(towerDetId);
676  tower.numBadHcalCells += 1;
677  }
678 
679  else if (energy >= threshold) {
680  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
681  if (towerDetId.null())
682  return;
683  MetaTower& tower = find(towerDetId);
684 
685  if (hcalDetId.depth() == 1) {
686  // long fiber, so E_EM = E(Long) - E(Short)
687  tower.E_em += e;
688  } else {
689  // short fiber, EHAD = 2 * E(Short)
690  tower.E_em -= e;
691  tower.E_had += 2. * e;
692  }
693  tower.E += e;
694  if (chStatusForCT == CaloTowersCreationAlgo::RecoveredChan) {
695  tower.numRecHcalCells += 1;
696  } else if (chStatusForCT == CaloTowersCreationAlgo::ProblematicChan) {
697  tower.numProbHcalCells += 1;
698  }
699 
700  // put the timing in HCAL -> have to check timing errors when available
701  // for now use only good channels
702  if (chStatusForCT == CaloTowersCreationAlgo::GoodChan) {
703  tower.hadSumTimeTimesE += (e * recHit->time());
704  tower.hadSumEForTime += e;
705  }
706 
707  std::pair<DetId, float> mc(detId, e);
708  tower.metaConstituents.push_back(mc);
709 
710  } // not a bad HF channel, energy above threshold
711 
712  } // HF hit
713 
714  else {
715  // HCAL situation normal in HB/HE
716  if (chStatusForCT == CaloTowersCreationAlgo::BadChan) {
717  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
718  if (towerDetId.null())
719  return;
720  MetaTower& tower = find(towerDetId);
721  tower.numBadHcalCells += 1;
722  } else if (energy >= threshold) {
723  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
724  if (towerDetId.null())
725  return;
726  MetaTower& tower = find(towerDetId);
727  tower.E_had += e;
728  tower.E += e;
729  if (chStatusForCT == CaloTowersCreationAlgo::RecoveredChan) {
730  tower.numRecHcalCells += 1;
731  } else if (chStatusForCT == CaloTowersCreationAlgo::ProblematicChan) {
732  tower.numProbHcalCells += 1;
733  }
734 
735  // Timing information: need specific accessors
736  // for now use only good channels
737  if (chStatusForCT == CaloTowersCreationAlgo::GoodChan) {
738  tower.hadSumTimeTimesE += (e * recHit->time());
739  tower.hadSumEForTime += e;
740  }
741  // store energy in highest depth for towers 18-27 (for electron,photon ID in endcap)
742  // also, store energy in HE part of tower 16 (for JetMET cleanup)
743  HcalDetId hcalDetId(detId);
744  if (hcalDetId.subdet() == HcalEndcap) {
745  if (theHcalPhase == 0) {
746  if ((hcalDetId.depth() == 2 && hcalDetId.ietaAbs() >= 18 && hcalDetId.ietaAbs() < 27) ||
747  (hcalDetId.depth() == 3 && hcalDetId.ietaAbs() == 27) ||
748  (hcalDetId.depth() == 3 && hcalDetId.ietaAbs() == 16)) {
749  tower.E_outer += e;
750  }
751  }
752  //combine depths in phase0-like way
753  else if (theHcalPhase == 1) {
754  if ((hcalDetId.depth() >= 3 && hcalDetId.ietaAbs() >= 18 && hcalDetId.ietaAbs() < 26) ||
755  (hcalDetId.depth() >= 4 && (hcalDetId.ietaAbs() == 26 || hcalDetId.ietaAbs() == 27)) ||
756  (hcalDetId.depth() == 3 && hcalDetId.ietaAbs() == 17) ||
757  (hcalDetId.depth() == 4 && hcalDetId.ietaAbs() == 16)) {
758  tower.E_outer += e;
759  }
760  }
761  }
762 
763  std::pair<DetId, float> mc(detId, e);
764  tower.metaConstituents.push_back(mc);
765 
766  } // not a "bad" channel, energy above threshold
767 
768  } // channel in HBHE (excluding twrs 28,29)
769 
770  } // recHit normal case (not in HE towers 28,29)
771 
772 } // end of assignHitHcal method
773 
775  DetId detId = recHit->detid();
776 
777  unsigned int chStatusForCT;
778  bool ecalIsBad = false;
779  std::tie(chStatusForCT, ecalIsBad) = ecalChanStatusForCaloTower(recHit);
780 
781  // this is for skipping channls: mostly needed for the creation of
782  // bad towers from hits i the bad channel collections.
783  if (chStatusForCT == CaloTowersCreationAlgo::IgnoredChan)
784  return;
785 
786  double threshold, weight;
787  getThresholdAndWeight(detId, threshold, weight);
788 
789  double energy = recHit->energy(); // original RecHit energy is used to apply thresholds
790  double e = energy * weight; // energies scaled by user weight: used in energy assignments
791 
793 
794  // For ECAL we count all bad channels after the metatower is complete
795 
796  // Include options for symmetric thresholds and cut on Et
797  // for ECAL RecHits
798 
799  bool passEmThreshold = false;
800 
801  if (detId.subdetId() == EcalBarrel) {
803  energy /= cosh((theGeometry->getGeometry(detId)->getPosition()).eta());
805  passEmThreshold = (fabs(energy) >= threshold);
806  else
807  passEmThreshold = (energy >= threshold);
808 
809  } else if (detId.subdetId() == EcalEndcap) {
811  energy /= cosh((theGeometry->getGeometry(detId)->getPosition()).eta());
813  passEmThreshold = (fabs(energy) >= threshold);
814  else
815  passEmThreshold = (energy >= threshold);
816  }
817 
818  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
819  if (towerDetId.null())
820  return;
821  MetaTower& tower = find(towerDetId);
822 
823  // count bad cells and avoid double counting with those from DB (Recovered are counted bad)
824 
825  // somehow misses some
826  // if ( (chStatusForCT == CaloTowersCreationAlgo::BadChan) & (!ecalIsBad) ) ++tower.numBadEcalCells;
827 
828  // a bit slower...
829  if (chStatusForCT == CaloTowersCreationAlgo::BadChan) {
830  auto thisEcalSevLvl = theEcalSevLvlAlgo->severityLevel(detId);
831  // check if the Ecal severity is ok to keep
832  auto sevit = std::find(theEcalSeveritiesToBeExcluded.begin(), theEcalSeveritiesToBeExcluded.end(), thisEcalSevLvl);
833  if (sevit == theEcalSeveritiesToBeExcluded.end())
834  ++tower.numBadEcalCells; // notinDB
835  }
836 
837  // if (chStatusForCT != CaloTowersCreationAlgo::BadChan && energy >= threshold) {
838  if (chStatusForCT != CaloTowersCreationAlgo::BadChan && passEmThreshold) {
839  tower.E_em += e;
840  tower.E += e;
841 
842  if (chStatusForCT == CaloTowersCreationAlgo::RecoveredChan) {
843  tower.numRecEcalCells += 1;
844  } else if (chStatusForCT == CaloTowersCreationAlgo::ProblematicChan) {
845  tower.numProbEcalCells += 1;
846  }
847 
848  // change when full status info is available
849  // for now use only good channels
850 
851  // add e>0 check (new options allow e<0)
852  if (chStatusForCT == CaloTowersCreationAlgo::GoodChan && e > 0) {
853  tower.emSumTimeTimesE += (e * recHit->time());
854  tower.emSumEForTime += e; // see above
855  }
856 
857  std::pair<DetId, float> mc(detId, e);
858  tower.metaConstituents.push_back(mc);
859  }
860 } // end of assignHitEcal method
861 
862 // This method is not flexible enough for the new CaloTower format.
863 // For now make a quick compatibility "fix" : WILL NOT WORK CORRECTLY with anything
864 // except the default simple p4 assignment!!!
865 // Must be rewritten for full functionality.
867  double threshold, weight;
868  CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(ct->id());
869  if (towerDetId.null())
870  return;
871  MetaTower& tower = find(towerDetId);
872 
873  tower.E_em = 0.;
874  tower.E_had = 0.;
875  tower.E_outer = 0.;
876  for (unsigned int i = 0; i < ct->constituentsSize(); i++) {
877  DetId detId = ct->constituent(i);
878  getThresholdAndWeight(detId, threshold, weight);
879  DetId::Detector det = detId.det();
880  if (det == DetId::Ecal) {
881  tower.E_em = ct->emEnergy() * weight;
882  } else {
883  HcalDetId hcalDetId(detId);
884  if (hcalDetId.subdet() == HcalForward) {
885  if (hcalDetId.depth() == 1)
886  tower.E_em = ct->emEnergy() * weight;
887  if (hcalDetId.depth() == 2)
888  tower.E_had = ct->hadEnergy() * weight;
889  } else if (hcalDetId.subdet() == HcalOuter) {
890  tower.E_outer = ct->outerEnergy() * weight;
891  } else {
892  tower.E_had = ct->hadEnergy() * weight;
893  }
894  }
895  tower.E = tower.E_had + tower.E_em + tower.E_outer;
896 
897  // this is to be compliant with the new MetaTower setup
898  // used only for the default simple vector assignment
899  std::pair<DetId, float> mc(detId, 0);
900  tower.metaConstituents.push_back(mc);
901  }
902 
903  // preserve time inforamtion
904  tower.emSumTimeTimesE = ct->ecalTime();
905  tower.hadSumTimeTimesE = ct->hcalTime();
906  tower.emSumEForTime = 1.0;
907  tower.hadSumEForTime = 1.0;
908 }
909 
911  if (theTowerMap.empty()) {
913  }
914 
915  auto& mt = theTowerMap[theTowerTopology->denseIndex(detId)];
916 
917  if (mt.empty()) {
918  mt.id = detId;
919  mt.metaConstituents.reserve(detId.ietaAbs() < theTowerTopology->firstHFRing() ? 12 : 2);
920  ++theTowerMapSize;
921  }
922 
923  return mt;
924 }
925 
927  assert(id.rawId() != 0);
928 
929  double ecalThres = (id.ietaAbs() <= 17) ? (theEBSumThreshold) : (theEESumThreshold);
930  double E = mt.E;
931  double E_em = mt.E_em;
932  double E_had = mt.E_had;
933  double E_outer = mt.E_outer;
934 
935  // Note: E_outer is used to save HO energy OR energy in the outermost depths in endcap region
936  // In the methods with separate treatment of EM and HAD components:
937  // - HO is not used to determine direction, however HO energy is added to get "total had energy"
938  // => Check if the tower is within HO coverage before adding E_outer to the "total had" energy
939  // else the energy will be double counted
940  // When summing up the energy of the tower these checks are performed in the loops over RecHits
941 
942  std::vector<std::pair<DetId, float> > metaContains = mt.metaConstituents;
943  if (id.ietaAbs() < theTowerTopology->firstHFRing() && E_em < ecalThres) { // ignore EM threshold in HF
944  E -= E_em;
945  E_em = 0;
946  std::vector<std::pair<DetId, float> > metaContains_noecal;
947 
948  for (std::vector<std::pair<DetId, float> >::iterator i = metaContains.begin(); i != metaContains.end(); ++i)
949  if (i->first.det() != DetId::Ecal)
950  metaContains_noecal.push_back(*i);
951  metaContains.swap(metaContains_noecal);
952  }
953  if (id.ietaAbs() < theTowerTopology->firstHFRing() && E_had < theHcalThreshold) {
954  E -= E_had;
955 
956  if (theHOIsUsed && id.ietaAbs() <= theTowerTopology->lastHORing())
957  E -= E_outer; // not subtracted before, think it should be done
958 
959  E_had = 0;
960  E_outer = 0;
961  std::vector<std::pair<DetId, float> > metaContains_nohcal;
962 
963  for (std::vector<std::pair<DetId, float> >::iterator i = metaContains.begin(); i != metaContains.end(); ++i)
964  if (i->first.det() != DetId::Hcal)
965  metaContains_nohcal.push_back(*i);
966  metaContains.swap(metaContains_nohcal);
967  }
968 
969  if (metaContains.empty())
970  return;
971 
972  if (missingHcalRescaleFactorForEcal > 0 && E_had == 0 && E_em > 0) {
973  auto match = hcalDropChMap.find(id);
974  if (match != hcalDropChMap.end() && match->second.second) {
975  E_had = missingHcalRescaleFactorForEcal * E_em;
976  E += E_had;
977  }
978  }
979 
980  double E_had_tot = (theHOIsUsed && id.ietaAbs() <= theTowerTopology->lastHORing()) ? E_had + E_outer : E_had;
981 
982  // create CaloTower using the selected algorithm
983 
984  GlobalPoint emPoint, hadPoint;
985 
986  // this is actually a 4D vector
987  Basic3DVectorF towerP4;
988  bool massless = true;
989  // float mass1=0;
990  float mass2 = 0;
991 
992  // conditional assignment of depths for barrel/endcap
993  // Some additional tuning may be required in the transitional region
994  // 14<|iEta|<19
995  double momEmDepth = 0.;
996  double momHadDepth = 0.;
997  if (id.ietaAbs() <= 17) {
998  momHadDepth = theMomHBDepth;
999  momEmDepth = theMomEBDepth;
1000  } else {
1001  momHadDepth = theMomHEDepth;
1002  momEmDepth = theMomEEDepth;
1003  }
1004 
1005  switch (theMomConstrMethod) {
1006  // FIXME : move to simple cartesian algebra
1007  case 0: { // Simple 4-momentum assignment
1008  GlobalPoint p = theTowerGeometry->getGeometry(id)->getPosition();
1009  towerP4 = p.basicVector().unit();
1010  towerP4[3] = 1.f; // energy
1011  towerP4 *= E;
1012 
1013  // double pf=1.0/cosh(p.eta());
1014  // if (E>0) towerP4 = CaloTower::PolarLorentzVector(E*pf, p.eta(), p.phi(), 0);
1015 
1016  emPoint = p;
1017  hadPoint = p;
1018  } // end case 0
1019  break;
1020 
1021  case 1: { // separate 4-vectors for ECAL, HCAL, add to get the 4-vector of the tower (=>tower has mass!)
1022  if (id.ietaAbs() < theTowerTopology->firstHFRing()) {
1023  Basic3DVectorF emP4;
1024  if (E_em > 0) {
1025  emPoint = emShwrPos(metaContains, momEmDepth, E_em);
1026  emP4 = emPoint.basicVector().unit();
1027  emP4[3] = 1.f; // energy
1028  towerP4 = emP4 * E_em;
1029 
1030  // double emPf = 1.0/cosh(emPoint.eta());
1031  // towerP4 += CaloTower::PolarLorentzVector(E_em*emPf, emPoint.eta(), emPoint.phi(), 0);
1032  }
1033  if ((E_had + E_outer) > 0) {
1034  massless = (E_em <= 0);
1035  hadPoint = hadShwrPos(id, momHadDepth);
1036  auto lP4 = hadPoint.basicVector().unit();
1037  lP4[3] = 1.f; // energy
1038  if (!massless) {
1039  auto diff = lP4 - emP4;
1040  mass2 = std::sqrt(E_em * E_had_tot * diff.mag2());
1041  }
1042  lP4 *= E_had_tot;
1043  towerP4 += lP4;
1044  /*
1045  if (!massless) {
1046  auto p = towerP4;
1047  double m2 = double(p[3]*p[3]) - double(p[0]*p[0])+double(p[1]*p[1])+double(p[2]*p[2]); mass1 = m2>0 ? std::sqrt(m2) : 0;
1048  }
1049  */
1050  // double hadPf = 1.0/cosh(hadPoint.eta());
1051  // if (E_had_tot>0) {
1052  // towerP4 += CaloTower::PolarLorentzVector(E_had_tot*hadPf, hadPoint.eta(), hadPoint.phi(), 0);
1053  // }
1054  }
1055  } else { // forward detector: use the CaloTower position
1056  GlobalPoint p = theTowerGeometry->getGeometry(id)->getPosition();
1057  towerP4 = p.basicVector().unit();
1058  towerP4[3] = 1.f; // energy
1059  towerP4 *= E;
1060  // double pf=1.0/cosh(p.eta());
1061  // if (E>0) towerP4 = CaloTower::PolarLorentzVector(E*pf, p.eta(), p.phi(), 0); // simple momentum assignment, same position
1062  emPoint = p;
1063  hadPoint = p;
1064  }
1065  } // end case 1
1066  break;
1067 
1068  case 2: { // use ECAL position for the tower (when E_cal>0), else default CaloTower position (massless tower)
1069  if (id.ietaAbs() < theTowerTopology->firstHFRing()) {
1070  if (E_em > 0)
1071  emPoint = emShwrLogWeightPos(metaContains, momEmDepth, E_em);
1072  else
1073  emPoint = theTowerGeometry->getGeometry(id)->getPosition();
1074  towerP4 = emPoint.basicVector().unit();
1075  towerP4[3] = 1.f; // energy
1076  towerP4 *= E;
1077 
1078  // double sumPf = 1.0/cosh(emPoint.eta());
1080 
1081  hadPoint = emPoint;
1082  } else { // forward detector: use the CaloTower position
1083  GlobalPoint p = theTowerGeometry->getGeometry(id)->getPosition();
1084  towerP4 = p.basicVector().unit();
1085  towerP4[3] = 1.f; // energy
1086  towerP4 *= E;
1087 
1088  // double pf=1.0/cosh(p.eta());
1089  // if (E>0) towerP4 = CaloTower::PolarLorentzVector(E*pf, p.eta(), p.phi(), 0); // simple momentum assignment, same position
1090  emPoint = p;
1091  hadPoint = p;
1092  }
1093  } // end case 2
1094  break;
1095 
1096  } // end of decision on p4 reconstruction method
1097 
1098  // insert in collection (remove and return if below threshold)
1099  if UNLIKELY ((towerP4[3] == 0) & (E_outer > 0)) {
1100  float val = theHOIsUsed ? 0 : 1E-9; // to keep backwards compatibility for theHOIsUsed == true
1101  collection.emplace_back(id,
1102  E_em,
1103  E_had,
1104  E_outer,
1105  -1,
1106  -1,
1107  CaloTower::PolarLorentzVector(val, hadPoint.eta(), hadPoint.phi(), 0),
1108  emPoint,
1109  hadPoint);
1110  } else {
1111  collection.emplace_back(
1112  id, E_em, E_had, E_outer, -1, -1, GlobalVector(towerP4), towerP4[3], mass2, emPoint, hadPoint);
1113  }
1114  auto& caloTower = collection.back();
1115 
1116  // if (!massless) std::cout << "massive " << id <<' ' << mass1 <<' ' << mass2 <<' ' << caloTower.mass() << std::endl;
1117  // std::cout << "CaloTowerVI " <<theMomConstrMethod <<' ' << id <<' '<< E_em <<' '<< E_had <<' '<< E_outer <<' '<< GlobalVector(towerP4) <<' '<< towerP4[3] <<' '<< emPoint <<' '<< hadPoint << std::endl;
1118  //if (towerP4[3]==0) std::cout << "CaloTowerVIzero " << theEcutTower << ' ' << collection.back().eta() <<' '<< collection.back().phi() << std::endl;
1119 
1120  if (caloTower.energy() < theEcutTower) {
1121  collection.pop_back();
1122  return;
1123  }
1124 
1125  // set the timings
1126  float ecalTime = (mt.emSumEForTime > 0) ? mt.emSumTimeTimesE / mt.emSumEForTime : -9999;
1127  float hcalTime = (mt.hadSumEForTime > 0) ? mt.hadSumTimeTimesE / mt.hadSumEForTime : -9999;
1128  caloTower.setEcalTime(compactTime(ecalTime));
1129  caloTower.setHcalTime(compactTime(hcalTime));
1130  //add topology info
1131  caloTower.setHcalSubdet(theTowerTopology->lastHBRing(),
1135 
1136  // set the CaloTower status word =====================================
1137  // Channels must be counter exclusively in the defined cathegories
1138  // "Bad" channels (not used in energy assignment) can be flagged during
1139  // CaloTower creation only if specified in the configuration file
1140 
1141  unsigned int numBadHcalChan = mt.numBadHcalCells;
1142  // unsigned int numBadEcalChan = mt.numBadEcalCells;
1143  unsigned int numBadEcalChan = 0; //
1144 
1145  unsigned int numRecHcalChan = mt.numRecHcalCells;
1146  unsigned int numRecEcalChan = mt.numRecEcalCells;
1147  unsigned int numProbHcalChan = mt.numProbHcalCells;
1148  unsigned int numProbEcalChan = mt.numProbEcalCells;
1149 
1150  // now add dead/off/... channels not used in RecHit reconstruction for HCAL
1151  HcalDropChMap::iterator dropChItr = hcalDropChMap.find(id);
1152  if (dropChItr != hcalDropChMap.end())
1153  numBadHcalChan += dropChItr->second.first;
1154 
1155  // for ECAL the number of all bad channels is obtained here -----------------------
1156 
1157  /*
1158  // old hyper slow algorithm
1159  // get all possible constituents of the tower
1160  std::vector<DetId> allConstituents = theTowerConstituentsMap->constituentsOf(id);
1161 
1162  for (std::vector<DetId>::iterator ac_it=allConstituents.begin();
1163  ac_it!=allConstituents.end(); ++ac_it) {
1164 
1165  if (ac_it->det()!=DetId::Ecal) continue;
1166 
1167  int thisEcalSevLvl = -999;
1168 
1169  if (ac_it->subdetId() == EcalBarrel && theEbHandle.isValid()) {
1170  thisEcalSevLvl = theEcalSevLvlAlgo->severityLevel( *ac_it, *theEbHandle);//, *theEcalChStatus);
1171  }
1172  else if (ac_it->subdetId() == EcalEndcap && theEeHandle.isValid()) {
1173  thisEcalSevLvl = theEcalSevLvlAlgo->severityLevel( *ac_it, *theEeHandle);//, *theEcalChStatus);
1174  }
1175 
1176  // check if the Ecal severity is ok to keep
1177  std::vector<int>::const_iterator sevit = std::find(theEcalSeveritiesToBeExcluded.begin(),
1178  theEcalSeveritiesToBeExcluded.end(),
1179  thisEcalSevLvl);
1180  if (sevit!=theEcalSeveritiesToBeExcluded.end()) {
1181  ++numBadEcalChan;
1182  }
1183 
1184  }
1185 
1186  // compare with fast version
1187 
1188  // hcal:
1189  int inEcals[2] = {0,0};
1190  for (std::vector<std::pair<DetId,float> >::iterator i=metaContains.begin(); i!=metaContains.end(); ++i) {
1191  DetId detId = i->first;
1192  if(detId.det() == DetId::Ecal){
1193  if( detId.subdetId()==EcalBarrel ) inEcals[0] =1;
1194  else if( detId.subdetId()==EcalEndcap ) inEcals[1] =1;
1195  }
1196  }
1197 
1198  auto numBadEcalChanNew = ecalBadChs[theTowerTopology->denseIndex(id)]+mt.numBadEcalCells; // - mt.numRecEcalCells
1199  if (int(numBadEcalChanNew)!=int(numBadEcalChan)) {
1200  std::cout << "VI wrong " << ((inEcals[1]==1) ? "EE" : "" ) << id << " " << numBadEcalChanNew << " " << numBadEcalChan
1201  << " " << mt.numBadEcalCells << " " << mt.numRecEcalCells << std::endl;
1202  }
1203  */
1204 
1205  numBadEcalChan = ecalBadChs[theTowerTopology->denseIndex(id)] + mt.numBadEcalCells; // - mt.numRecEcalCells
1206 
1207  //--------------------------------------------------------------------------------------
1208 
1209  caloTower.setCaloTowerStatus(
1210  numBadHcalChan, numBadEcalChan, numRecHcalChan, numRecEcalChan, numProbHcalChan, numProbEcalChan);
1211 
1212  double maxCellE = -999.0; // for storing the hottest cell E in the calotower
1213 
1214  std::vector<DetId> contains;
1215  contains.reserve(metaContains.size());
1216  for (std::vector<std::pair<DetId, float> >::iterator i = metaContains.begin(); i != metaContains.end(); ++i) {
1217  contains.push_back(i->first);
1218 
1219  if (maxCellE < i->second) {
1220  // need an extra check because of the funny towers that are empty except for the presence of an HO
1221  // hit in the constituents (JetMET wanted them saved)
1222  // This constituent is only used for storing the tower, but should not be concidered as a hot cell canditate for
1223  // configurations with useHO = false
1224 
1225  if (i->first.det() == DetId::Ecal) { // ECAL
1226  maxCellE = i->second;
1227  } else { // HCAL
1228  if (HcalDetId(i->first).subdet() != HcalOuter)
1229  maxCellE = i->second;
1230  else if (theHOIsUsed)
1231  maxCellE = i->second;
1232  }
1233 
1234  } // found higher E cell
1235 
1236  } // loop over matacontains
1237 
1238  caloTower.setConstituents(std::move(contains));
1239  caloTower.setHottestCellE(maxCellE);
1240 
1241  // std::cout << "CaloTowerVI " << nalgo << ' ' << caloTower.id() << ((inEcals[1]==1) ? "EE " : " " ) << caloTower.pt() << ' ' << caloTower.et() << ' ' << caloTower.mass() << ' '
1242  // << caloTower.constituentsSize() <<' '<< caloTower.towerStatusWord() << std::endl;
1243 }
1244 
1245 void CaloTowersCreationAlgo::getThresholdAndWeight(const DetId& detId, double& threshold, double& weight) const {
1246  DetId::Detector det = detId.det();
1247  weight = 0; // in case the hit is not identified
1248 
1249  if (det == DetId::Ecal) {
1250  // may or may not be EB. We'll find out.
1251 
1252  EcalSubdetector subdet = (EcalSubdetector)(detId.subdetId());
1253  if (subdet == EcalBarrel) {
1254  threshold = theEBthreshold;
1255  weight = theEBweight;
1256  if (weight <= 0.) {
1257  ROOT::Math::Interpolator my(theEBGrid, theEBWeights, ROOT::Math::Interpolation::kAKIMA);
1258  weight = my.Eval(theEBEScale);
1259  }
1260  } else if (subdet == EcalEndcap) {
1261  threshold = theEEthreshold;
1262  weight = theEEweight;
1263  if (weight <= 0.) {
1264  ROOT::Math::Interpolator my(theEEGrid, theEEWeights, ROOT::Math::Interpolation::kAKIMA);
1265  weight = my.Eval(theEEEScale);
1266  }
1267  }
1268  } else if (det == DetId::Hcal) {
1269  HcalDetId hcalDetId(detId);
1270  HcalSubdetector subdet = hcalDetId.subdet();
1271  int depth = hcalDetId.depth();
1272 
1273  if (subdet == HcalBarrel) {
1274  threshold = (depth == 1) ? theHBthreshold1 : (depth == 2) ? theHBthreshold2 : theHBthreshold;
1275  weight = theHBweight;
1276  if (weight <= 0.) {
1277  ROOT::Math::Interpolator my(theHBGrid, theHBWeights, ROOT::Math::Interpolation::kAKIMA);
1278  weight = my.Eval(theHBEScale);
1279  }
1280  }
1281 
1282  else if (subdet == HcalEndcap) {
1283  // check if it's single or double tower
1284  if (hcalDetId.ietaAbs() < theHcalTopology->firstHEDoublePhiRing()) {
1285  threshold = (depth == 1) ? theHESthreshold1 : theHESthreshold;
1286  weight = theHESweight;
1287  if (weight <= 0.) {
1288  ROOT::Math::Interpolator my(theHESGrid, theHESWeights, ROOT::Math::Interpolation::kAKIMA);
1289  weight = my.Eval(theHESEScale);
1290  }
1291  } else {
1292  threshold = (depth == 1) ? theHEDthreshold1 : theHEDthreshold;
1293  weight = theHEDweight;
1294  if (weight <= 0.) {
1295  ROOT::Math::Interpolator my(theHEDGrid, theHEDWeights, ROOT::Math::Interpolation::kAKIMA);
1296  weight = my.Eval(theHEDEScale);
1297  }
1298  }
1299  }
1300 
1301  else if (subdet == HcalOuter) {
1302  //check if it's ring 0 or +1 or +2 or -1 or -2
1303  if (hcalDetId.ietaAbs() <= 4)
1304  threshold = theHOthreshold0;
1305  else if (hcalDetId.ieta() < 0) {
1306  // set threshold for ring -1 or -2
1307  threshold = (hcalDetId.ietaAbs() <= 10) ? theHOthresholdMinus1 : theHOthresholdMinus2;
1308  } else {
1309  // set threshold for ring +1 or +2
1310  threshold = (hcalDetId.ietaAbs() <= 10) ? theHOthresholdPlus1 : theHOthresholdPlus2;
1311  }
1312  weight = theHOweight;
1313  if (weight <= 0.) {
1314  ROOT::Math::Interpolator my(theHOGrid, theHOWeights, ROOT::Math::Interpolation::kAKIMA);
1315  weight = my.Eval(theHOEScale);
1316  }
1317  }
1318 
1319  else if (subdet == HcalForward) {
1320  if (hcalDetId.depth() == 1) {
1321  threshold = theHF1threshold;
1322  weight = theHF1weight;
1323  if (weight <= 0.) {
1324  ROOT::Math::Interpolator my(theHF1Grid, theHF1Weights, ROOT::Math::Interpolation::kAKIMA);
1325  weight = my.Eval(theHF1EScale);
1326  }
1327  } else {
1328  threshold = theHF2threshold;
1329  weight = theHF2weight;
1330  if (weight <= 0.) {
1331  ROOT::Math::Interpolator my(theHF2Grid, theHF2Weights, ROOT::Math::Interpolation::kAKIMA);
1332  weight = my.Eval(theHF2EScale);
1333  }
1334  }
1335  }
1336  } else {
1337  edm::LogError("CaloTowersCreationAlgo") << "Bad cell: " << det << std::endl;
1338  }
1339 }
1340 
1342  if (scale > 0.00001)
1343  *&theEBEScale = scale;
1344  else
1345  *&theEBEScale = 50.;
1346 }
1347 
1349  if (scale > 0.00001)
1350  *&theEEEScale = scale;
1351  else
1352  *&theEEEScale = 50.;
1353 }
1354 
1356  if (scale > 0.00001)
1357  *&theHBEScale = scale;
1358  else
1359  *&theHBEScale = 50.;
1360 }
1361 
1363  if (scale > 0.00001)
1364  *&theHESEScale = scale;
1365  else
1366  *&theHESEScale = 50.;
1367 }
1368 
1370  if (scale > 0.00001)
1371  *&theHEDEScale = scale;
1372  else
1373  *&theHEDEScale = 50.;
1374 }
1375 
1377  if (scale > 0.00001)
1378  *&theHOEScale = scale;
1379  else
1380  *&theHOEScale = 50.;
1381 }
1382 
1384  if (scale > 0.00001)
1385  *&theHF1EScale = scale;
1386  else
1387  *&theHF1EScale = 50.;
1388 }
1389 
1391  if (scale > 0.00001)
1392  *&theHF2EScale = scale;
1393  else
1394  *&theHF2EScale = 50.;
1395 }
1396 
1398  auto cellGeometry = theGeometry->getGeometry(detId);
1399  GlobalPoint point = cellGeometry->getPosition(); // face of the cell
1400 
1401  if (fracDepth <= 0)
1402  return point;
1403  if (fracDepth > 1)
1404  fracDepth = 1;
1405 
1406  const GlobalPoint& backPoint = cellGeometry->getBackPoint();
1407  point += fracDepth * (backPoint - point);
1408 
1409  return point;
1410 }
1411 
1413  // same code as above
1414  return emCrystalShwrPos(detId, fracDepth);
1415 }
1416 
1417 GlobalPoint CaloTowersCreationAlgo::hadShwrPos(const std::vector<std::pair<DetId, float> >& metaContains,
1418  float fracDepth,
1419  double hadE) {
1420  // this is based on available RecHits, can lead to different actual depths if
1421  // hits in multi-depth towers are not all there
1422 #ifdef EDM_ML_DEBUG
1423  std::cout << "hadShwrPos called with " << metaContains.size() << " elements and energy " << hadE << ":" << fracDepth
1424  << std::endl;
1425 #endif
1426  if (hadE <= 0)
1427  return GlobalPoint(0, 0, 0);
1428 
1429  double hadX = 0.0;
1430  double hadY = 0.0;
1431  double hadZ = 0.0;
1432 
1433  int nConst = 0;
1434 
1435  std::vector<std::pair<DetId, float> >::const_iterator mc_it = metaContains.begin();
1436  for (; mc_it != metaContains.end(); ++mc_it) {
1437  if (mc_it->first.det() != DetId::Hcal)
1438  continue;
1439  // do not use HO for deirection calculations for now
1440  if (HcalDetId(mc_it->first).subdet() == HcalOuter)
1441  continue;
1442  ++nConst;
1443 
1444  GlobalPoint p = hadSegmentShwrPos(mc_it->first, fracDepth);
1445 
1446  // longitudinal segmentation: do not weight by energy,
1447  // get the geometrical position
1448  hadX += p.x();
1449  hadY += p.y();
1450  hadZ += p.z();
1451  }
1452 
1453  return GlobalPoint(hadX / nConst, hadY / nConst, hadZ / nConst);
1454 }
1455 
1457  // set depth using geometry of cells that are associated with the
1458  // tower (regardless if they have non-zero energies)
1459 
1460  // if (hadE <= 0) return GlobalPoint(0, 0, 0);
1461 #ifdef EDM_ML_DEBUG
1462  std::cout << "hadShwrPos " << towerId << " frac " << fracDepth << std::endl;
1463 #endif
1464  if (fracDepth < 0)
1465  fracDepth = 0;
1466  else if (fracDepth > 1)
1467  fracDepth = 1;
1468 
1469  GlobalPoint point(0, 0, 0);
1470 
1471  int iEta = towerId.ieta();
1472  int iPhi = towerId.iphi();
1473 
1474  HcalDetId frontCellId, backCellId;
1475 
1476  if (towerId.ietaAbs() >= theTowerTopology->firstHFRing()) {
1477  // forward, take the geometry for long fibers
1478  frontCellId = HcalDetId(HcalForward, towerId.zside() * theTowerTopology->convertCTtoHcal(abs(iEta)), iPhi, 1);
1479  backCellId = HcalDetId(HcalForward, towerId.zside() * theTowerTopology->convertCTtoHcal(abs(iEta)), iPhi, 1);
1480  } else {
1481  //use constituents map
1482  std::vector<DetId> items = theTowerConstituentsMap->constituentsOf(towerId);
1483  int frontDepth = 1000;
1484  int backDepth = -1000;
1485  for (unsigned i = 0; i < items.size(); i++) {
1486  if (items[i].det() != DetId::Hcal)
1487  continue;
1488  HcalDetId hid(items[i]);
1489  if (hid.subdet() == HcalOuter)
1490  continue;
1491  if (!theHcalTopology->validHcal(hid, 2))
1492  continue;
1493 
1494  if (theHcalTopology->idFront(hid).depth() < frontDepth) {
1495  frontCellId = hid;
1496  frontDepth = theHcalTopology->idFront(hid).depth();
1497  }
1498  if (theHcalTopology->idBack(hid).depth() > backDepth) {
1499  backCellId = hid;
1500  backDepth = theHcalTopology->idBack(hid).depth();
1501  }
1502  }
1503 #ifdef EDM_ML_DEBUG
1504  std::cout << "Front " << frontCellId << " Back " << backCellId << " Depths " << frontDepth << ":" << backDepth
1505  << std::endl;
1506 #endif
1507  //fix for tower 28/29 - no tower 29 at highest depths
1508  if (towerId.ietaAbs() == theTowerTopology->lastHERing() && (theHcalPhase == 0 || theHcalPhase == 1)) {
1509  CaloTowerDetId towerId28(towerId.ieta() - towerId.zside(), towerId.iphi());
1510  std::vector<DetId> items28 = theTowerConstituentsMap->constituentsOf(towerId28);
1511 #ifdef EDM_ML_DEBUG
1512  std::cout << towerId28 << " with " << items28.size() << " constituents:";
1513  for (unsigned k = 0; k < items28.size(); ++k)
1514  if (items28[k].det() == DetId::Hcal)
1515  std::cout << " " << HcalDetId(items28[k]);
1516  std::cout << std::endl;
1517 #endif
1518  for (unsigned i = 0; i < items28.size(); i++) {
1519  if (items28[i].det() != DetId::Hcal)
1520  continue;
1521  HcalDetId hid(items28[i]);
1522  if (hid.subdet() == HcalOuter)
1523  continue;
1524 
1525  if (theHcalTopology->idBack(hid).depth() > backDepth) {
1526  backCellId = hid;
1527  backDepth = theHcalTopology->idBack(hid).depth();
1528  }
1529  }
1530  }
1531 #ifdef EDM_ML_DEBUG
1532  std::cout << "Back " << backDepth << " ID " << backCellId << std::endl;
1533 #endif
1534  }
1535  point = hadShwPosFromCells(DetId(frontCellId), DetId(backCellId), fracDepth);
1536 
1537  return point;
1538 }
1539 
1540 GlobalPoint CaloTowersCreationAlgo::hadShwPosFromCells(DetId frontCellId, DetId backCellId, float fracDepth) {
1541  // uses the "front" and "back" cells
1542  // to determine the axis. point set by the predefined depth.
1543 
1544  HcalDetId hid1(frontCellId), hid2(backCellId);
1546  hid1 = theHcalTopology->idFront(frontCellId);
1547 #ifdef EDM_ML_DEBUG
1548  std::cout << "Front " << HcalDetId(frontCellId) << " " << hid1 << "\n";
1549 #endif
1550  hid2 = theHcalTopology->idBack(backCellId);
1551 #ifdef EDM_ML_DEBUG
1552  std::cout << "Back " << HcalDetId(backCellId) << " " << hid2 << "\n";
1553 #endif
1554  }
1555 
1556  auto frontCellGeometry = theGeometry->getGeometry(DetId(hid1));
1557  auto backCellGeometry = theGeometry->getGeometry(DetId(hid2));
1558 
1559  GlobalPoint point = frontCellGeometry->getPosition();
1560  const GlobalPoint& backPoint = backCellGeometry->getBackPoint();
1561 
1562  point += fracDepth * (backPoint - point);
1563 
1564  return point;
1565 }
1566 
1567 GlobalPoint CaloTowersCreationAlgo::emShwrPos(const std::vector<std::pair<DetId, float> >& metaContains,
1568  float fracDepth,
1569  double emE) {
1570  if (emE <= 0)
1571  return GlobalPoint(0, 0, 0);
1572 
1573  double emX = 0.0;
1574  double emY = 0.0;
1575  double emZ = 0.0;
1576 
1577  double eSum = 0;
1578 
1579  std::vector<std::pair<DetId, float> >::const_iterator mc_it = metaContains.begin();
1580  for (; mc_it != metaContains.end(); ++mc_it) {
1581  if (mc_it->first.det() != DetId::Ecal)
1582  continue;
1583  GlobalPoint p = emCrystalShwrPos(mc_it->first, fracDepth);
1584  double e = mc_it->second;
1585 
1586  if (e > 0) {
1587  emX += p.x() * e;
1588  emY += p.y() * e;
1589  emZ += p.z() * e;
1590  eSum += e;
1591  }
1592  }
1593 
1594  return GlobalPoint(emX / eSum, emY / eSum, emZ / eSum);
1595 }
1596 
1597 GlobalPoint CaloTowersCreationAlgo::emShwrLogWeightPos(const std::vector<std::pair<DetId, float> >& metaContains,
1598  float fracDepth,
1599  double emE) {
1600  double emX = 0.0;
1601  double emY = 0.0;
1602  double emZ = 0.0;
1603 
1604  double weight = 0;
1605  double sumWeights = 0;
1606  double sumEmE = 0; // add crystals with E/E_EM > 1.5%
1607  double crystalThresh = 0.015 * emE;
1608 
1609  std::vector<std::pair<DetId, float> >::const_iterator mc_it = metaContains.begin();
1610  for (; mc_it != metaContains.end(); ++mc_it) {
1611  if (mc_it->second < 0)
1612  continue;
1613  if (mc_it->first.det() == DetId::Ecal && mc_it->second > crystalThresh)
1614  sumEmE += mc_it->second;
1615  }
1616 
1617  for (mc_it = metaContains.begin(); mc_it != metaContains.end(); ++mc_it) {
1618  if (mc_it->first.det() != DetId::Ecal || mc_it->second < crystalThresh)
1619  continue;
1620 
1621  GlobalPoint p = emCrystalShwrPos(mc_it->first, fracDepth);
1622 
1623  weight = 4.2 + log(mc_it->second / sumEmE);
1624  sumWeights += weight;
1625 
1626  emX += p.x() * weight;
1627  emY += p.y() * weight;
1628  emZ += p.z() * weight;
1629  }
1630 
1631  return GlobalPoint(emX / sumWeights, emY / sumWeights, emZ / sumWeights);
1632 }
1633 
1635  const float timeUnit = 0.01; // discretization (ns)
1636 
1637  if (time > 300.0)
1638  return 30000;
1639  if (time < -300.0)
1640  return -30000;
1641 
1642  return int(time / timeUnit + 0.5);
1643 }
1644 
1645 //========================================================
1646 //
1647 // Bad/anomolous cell handling
1648 
1650  // This method fills the map of number of dead channels for the calotower,
1651  // The key of the map is CaloTowerDetId.
1652  // By definition these channels are not going to be in the RecHit collections.
1653  hcalDropChMap.clear();
1654  std::vector<DetId> allChanInStatusCont = theHcalChStatus->getAllChannels();
1655 
1656 #ifdef EDM_ML_DEBUG
1657  std::cout << "DropChMap with " << allChanInStatusCont.size() << " channels" << std::endl;
1658 #endif
1659  for (std::vector<DetId>::iterator it = allChanInStatusCont.begin(); it != allChanInStatusCont.end(); ++it) {
1660  const uint32_t dbStatusFlag = theHcalChStatus->getValues(*it)->getValue();
1661  if (theHcalSevLvlComputer->dropChannel(dbStatusFlag)) {
1663 
1665 
1666  hcalDropChMap[twrId].first += 1;
1667 
1668  HcalDetId hid(*it);
1669 
1670  // special case for tower 29: if HCAL hit is in depth 3 add to twr 29 as well
1671  if (hid.subdet() == HcalEndcap && (theHcalPhase == 0 || theHcalPhase == 1) &&
1672  hid.ietaAbs() == theHcalTopology->lastHERing() - 1) {
1673  bool merge = theHcalTopology->mergedDepth29(hid);
1674  if (merge) {
1675  CaloTowerDetId twrId29(twrId.ieta() + twrId.zside(), twrId.iphi());
1676  hcalDropChMap[twrId29].first += 1;
1677  }
1678  }
1679  }
1680  }
1681  // now I know how many bad channels, but I also need to know if there's any good ones
1683  for (auto& pair : hcalDropChMap) {
1684  if (pair.second.first == 0)
1685  continue; // unexpected, but just in case
1686  int ngood = 0, nbad = 0;
1687  for (DetId id : theTowerConstituentsMap->constituentsOf(pair.first)) {
1688  if (id.det() != DetId::Hcal)
1689  continue;
1690  HcalDetId hid(id);
1691  if (hid.subdet() != HcalBarrel && hid.subdet() != HcalEndcap)
1692  continue;
1693  const uint32_t dbStatusFlag = theHcalChStatus->getValues(id)->getValue();
1694  if (dbStatusFlag == 0 || !theHcalSevLvlComputer->dropChannel(dbStatusFlag)) {
1695  ngood += 1;
1696  } else {
1697  nbad += 1; // recount, since pair.second.first may include HO
1698  }
1699  }
1700  if (nbad > 0 && nbad >= ngood) {
1701  //uncomment for debug (may be useful to tune the criteria above)
1702  //CaloTowerDetId id(pair.first);
1703  //std::cout << "CaloTower at ieta = " << id.ieta() << ", iphi " << id.iphi() << ": set Hcal as not efficient (ngood =" << ngood << ", nbad = " << nbad << ")" << std::endl;
1704  pair.second.second = true;
1705  }
1706  }
1707  }
1708 }
1709 
1711  // std::cout << "VI making EcalBadChs ";
1712 
1713  // for ECAL the number of all bad channels is obtained here -----------------------
1714 
1715  for (auto ind = 0U; ind < theTowerTopology->sizeForDenseIndexing(); ++ind) {
1716  auto& numBadEcalChan = ecalBadChs[ind];
1717  numBadEcalChan = 0;
1718  auto id = theTowerTopology->detIdFromDenseIndex(ind);
1719 
1720  // this is utterly slow... (can be optmized if really needed)
1721 
1722  // get all possible constituents of the tower
1723  std::vector<DetId> allConstituents = theTowerConstituentsMap->constituentsOf(id);
1724 
1725  for (std::vector<DetId>::iterator ac_it = allConstituents.begin(); ac_it != allConstituents.end(); ++ac_it) {
1726  if (ac_it->det() != DetId::Ecal)
1727  continue;
1728 
1729  auto thisEcalSevLvl = theEcalSevLvlAlgo->severityLevel(*ac_it);
1730 
1731  // check if the Ecal severity is ok to keep
1732  std::vector<int>::const_iterator sevit =
1734  if (sevit != theEcalSeveritiesToBeExcluded.end()) {
1735  ++numBadEcalChan;
1736  }
1737  }
1738 
1739  // if (0!=numBadEcalChan) std::cout << id << ":" << numBadEcalChan << ", ";
1740  }
1741 
1742  /*
1743  int tot=0;
1744  for (auto ind=0U; ind<theTowerTopology->sizeForDenseIndexing(); ++ind) {
1745  if (ecalBadChs[ind]!=0) ++tot;
1746  }
1747  std::cout << " | " << tot << std::endl;
1748  */
1749 }
1750 
1752 
1754  HcalDetId hid(hit->detid());
1755  DetId id = theHcalTopology->idFront(hid);
1756 #ifdef EDM_ML_DEBUG
1757  std::cout << "ChanStatusForCaloTower for " << hid << " to " << HcalDetId(id) << std::endl;
1758 #endif
1759  const uint32_t recHitFlag = hit->flags();
1760  const uint32_t dbStatusFlag = theHcalChStatus->getValues(id)->getValue();
1761 
1762  int severityLevel = theHcalSevLvlComputer->getSeverityLevel(id, recHitFlag, dbStatusFlag);
1763  bool isRecovered = theHcalSevLvlComputer->recoveredRecHit(id, recHitFlag);
1764 
1765  // For use with hits rejected in the default reconstruction
1766  if (useRejectedHitsOnly) {
1767  if (!isRecovered) {
1768  if (severityLevel <= int(theHcalAcceptSeverityLevel) ||
1769  severityLevel > int(theHcalAcceptSeverityLevelForRejectedHit))
1771  // this hit was either already accepted or is worse than
1772  } else {
1774  // skip recovered hits either because they were already used or because there was an explicit instruction
1776  } else if (useRejectedRecoveredHcalHits) {
1778  }
1779 
1780  } // recovered channels
1781 
1782  // clasify channels as problematic: no good hits are supposed to be present in the
1783  // extra rechit collections
1785 
1786  } // treatment of rejected hits
1787 
1788  // this is for the regular reconstruction sequence
1789 
1790  if (severityLevel == 0)
1792 
1793  if (isRecovered) {
1795  } else {
1796  if (severityLevel > int(theHcalAcceptSeverityLevel)) {
1798  } else {
1800  }
1801  }
1802 }
1803 
1805  // const DetId id = hit->detid();
1806 
1807  // uint16_t dbStatus = theEcalChStatus->find(id)->getStatusCode();
1808  // uint32_t rhFlags = hit->flags();
1809  // int severityLevel = theEcalSevLvlAlgo->severityLevel(rhFlags, dbStatus);
1810  // The methods above will become private and cannot be usef for flagging ecal spikes.
1811  // Use the recommended interface - we leave the parameters for spilke removal to be specified by ECAL.
1812 
1813  // int severityLevel = 999;
1814 
1815  EcalRecHit const& rh = *reinterpret_cast<EcalRecHit const*>(hit);
1816  int severityLevel = theEcalSevLvlAlgo->severityLevel(rh);
1817 
1818  // if (id.subdetId() == EcalBarrel) severityLevel = theEcalSevLvlAlgo->severityLevel( id, *theEbHandle);//, *theEcalChStatus);
1819  // else if (id.subdetId() == EcalEndcap) severityLevel = theEcalSevLvlAlgo->severityLevel( id, *theEeHandle);//, *theEcalChStatus);
1820 
1821  // there should be no other ECAL types used in this reconstruction
1822 
1823  // The definition of ECAL severity levels uses categories that
1824  // are similar to the defined for CaloTower. (However, the categorization
1825  // for CaloTowers depends on the specified maximum acceptabel severity and therefore cannnot
1826  // be exact correspondence between the two. ECAL has additional categories describing modes of failure.)
1827  // This approach is different from the initial idea and from
1828  // the implementation for HCAL. Still make the logic similar to HCAL so that one has the ability to
1829  // exclude problematic channels as defined by ECAL.
1830  // For definitions of ECAL severity levels see RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgo.h
1831 
1832  bool isBad = (severityLevel == EcalSeverityLevel::kBad);
1833 
1834  bool isRecovered = (severityLevel == EcalSeverityLevel::kRecovered);
1835 
1836  // check if the severity is compatible with our configuration
1837  // This applies to the "default" tower cleaning
1838  std::vector<int>::const_iterator sevit =
1840  bool accepted = (sevit == theEcalSeveritiesToBeExcluded.end());
1841 
1842  // For use with hits that were rejected in the regular reconstruction:
1843  // This is for creating calotowers with lower level of cleaning by merging
1844  // the information from the default towers and a collection of towers created from
1845  // bad rechits
1846 
1847  if (useRejectedHitsOnly) {
1848  if (!isRecovered) {
1849  if (accepted || std::find(theEcalSeveritiesToBeUsedInBadTowers.begin(),
1851  severityLevel) == theEcalSeveritiesToBeUsedInBadTowers.end())
1852  return std::make_tuple(CaloTowersCreationAlgo::IgnoredChan, isBad);
1853  // this hit was either already accepted, or is not eligible for inclusion
1854  } else {
1856  // skip recovered hits either because they were already used or because there was an explicit instruction
1857  return std::make_tuple(CaloTowersCreationAlgo::IgnoredChan, isBad);
1858  ;
1859  } else if (useRejectedRecoveredEcalHits) {
1860  return std::make_tuple(CaloTowersCreationAlgo::RecoveredChan, isBad);
1861  }
1862 
1863  } // recovered channels
1864 
1865  // clasify channels as problematic
1866  return std::make_tuple(CaloTowersCreationAlgo::ProblematicChan, isBad);
1867 
1868  } // treatment of rejected hits
1869 
1870  // for normal reconstruction
1871  if (severityLevel == EcalSeverityLevel::kGood)
1872  return std::make_tuple(CaloTowersCreationAlgo::GoodChan, false);
1873 
1874  if (isRecovered) {
1875  return std::make_tuple(
1877  } else {
1878  return std::make_tuple(accepted ? CaloTowersCreationAlgo::ProblematicChan : CaloTowersCreationAlgo::BadChan, isBad);
1879  }
1880 }
constexpr float energy() const
Definition: CaloRecHit.h:29
std::vector< double > theHBGrid
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:34
tuple missingHcalRescaleFactorForEcal
const HcalChannelQuality * theHcalChStatus
static std::vector< std::string > checklist log
constexpr int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.h:148
bool mergedDepth29(HcalDetId id) const
Definition: HcalTopology.h:111
size_t constituentsSize() const
Definition: CaloTower.h:125
std::vector< std::pair< DetId, float > > metaConstituents
bool contains(EventRange const &lh, EventID const &rh)
Definition: EventRange.cc:37
EcalSeverityLevel::SeverityLevel severityLevel(const DetId &id) const
Evaluate status from id use channelStatus from DB.
int ietaAbs() const
get the absolute value of the tower ieta
DetId constituent(size_t i) const
Definition: CaloTower.h:126
constexpr bool null() const
is this a null id ?
Definition: DetId.h:59
constexpr const DetId & detid() const
Definition: CaloRecHit.h:33
void setCaloTowerStatus(unsigned int numBadHcalChan, unsigned int numBadEcalChan, unsigned int numRecHcalChan, unsigned int numRecEcalChan, unsigned int numProbHcalChan, unsigned int numProbEcalChan)
Definition: CaloTower.cc:221
std::vector< double > theHESGrid
std::vector< double > theHEDGrid
GlobalPoint emCrystalShwrPos(DetId detId, float fracDepth)
float ecalTime() const
Definition: CaloTower.h:196
void assignHitHcal(const CaloRecHit *recHit)
std::vector< int > theEcalSeveritiesToBeUsedInBadTowers
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: LeafCandidate.h:25
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
Basic3DVector unit() const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
const DetId & detid() const
Definition: EcalRecHit.h:72
std::vector< T >::const_iterator const_iterator
T y() const
Definition: PV3DBase.h:60
void push_back(T const &t)
void finish(CaloTowerCollection &destCollection)
float time() const
Definition: EcalRecHit.h:70
const Item * getValues(DetId fId, bool throwOnFail=true) const
std::vector< double > theHOWeights
bool validHcal(const HcalDetId &id) const
MetaTower & find(const CaloTowerDetId &id)
looks for a given tower in the internal cache. If it can&#39;t find it, it makes it.
Log< level::Error, false > LogError
std::vector< double > theEEGrid
void rescale(const CaloTower *ct)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
void setHcalSubdet(int lastHB, int lastHE, int lastHF, int lastHO)
Definition: CaloTower.h:85
bool getMergePositionFlag() const
Definition: HcalTopology.h:167
int firstHERing() const
std::vector< DetId > constituentsOf(const CaloTowerDetId &id) const
Get the constituent detids for this tower id ( not yet implemented )
HcalDetId mergedDepthDetId(const HcalDetId &id) const
Definition: HcalTopology.h:166
tuple result
Definition: mps_fire.py:311
std::vector< double > theEEWeights
std::vector< double > theHESWeights
U second(std::pair< T, U > const &p)
void setGeometry(const CaloTowerTopology *cttopo, const CaloTowerConstituentsMap *ctmap, const HcalTopology *htopo, const CaloGeometry *geo)
constexpr HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:138
const CaloSubdetectorGeometry * theTowerGeometry
int lastHFRing() const
CaloTowerDetId detIdFromDenseIndex(uint32_t din) const
void addConstituents(const std::vector< DetId > &ids)
Definition: CaloTower.cc:199
unsigned int hcalChanStatusForCaloTower(const CaloRecHit *hit)
CaloTowerDetId towerOf(const DetId &id) const
Get the tower id for this det id (or null if not known)
double emEnergy() const
Definition: CaloTower.h:130
std::vector< double > theHF2Grid
std::vector< double > theHEDWeights
unsigned towerId(DetId const &, EcalElectronicsMapping const *)
void rescaleTowers(const CaloTowerCollection &ctInput, CaloTowerCollection &ctResult)
static const int SubdetId
std::vector< DetId > getAllChannels() const
T sqrt(T t)
Definition: SSEVec.h:19
T z() const
Definition: PV3DBase.h:61
bool recoveredRecHit(const DetId &myid, const uint32_t &myflag) const
if(conf_.getParameter< bool >("UseStripCablingDB"))
const CaloGeometry * theGeometry
def move
Definition: eostools.py:511
constexpr float time() const
Definition: CaloRecHit.h:31
tuple HcalThreshold
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
int iphi() const
get the tower iphi
HcalSubdetector
Definition: HcalAssistant.h:31
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
constexpr int ieta() const
get the cell ieta
Definition: HcalDetId.h:155
std::vector< double > theHOGrid
float energy() const
Definition: EcalRecHit.h:68
void assignHitEcal(const EcalRecHit *recHit)
adds a single hit to the tower
bool dropChannel(const uint32_t &mystatus) const
const CaloTowerConstituentsMap * theTowerConstituentsMap
void convert(const CaloTowerDetId &id, const MetaTower &mt, CaloTowerCollection &collection)
const CaloTowerTopology * theTowerTopology
std::vector< double > theHF1Weights
int firstHEDoublePhiRing() const
Definition: HcalTopology.h:101
GlobalPoint hadSegmentShwrPos(DetId detId, float fracDepth)
tuple EBSumThreshold
bool theHOIsUsed
only affects energy and ET calculation. HO is still recorded in the tower
tuple EESumThreshold
void process(const HBHERecHitCollection &hbhe)
double hadEnergy() const
Definition: CaloTower.h:131
const_iterator end() const
std::vector< double > theHBWeights
const HcalSeverityLevelComputer * theHcalSevLvlComputer
uint32_t denseIndex(const DetId &id) const
Definition: DetId.h:17
GlobalPoint hadShwrPos(const std::vector< std::pair< DetId, float >> &metaContains, float fracDepth, double hadE)
CaloTowerDetId id() const
Definition: CaloTower.h:123
float hcalTime() const
Definition: CaloTower.h:197
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.
Detector
Definition: DetId.h:24
GlobalPoint hadShwPosFromCells(DetId frontCell, DetId backCell, float fracDepth)
int zside() const
get the z-side of the tower (1/-1)
void getThresholdAndWeight(const DetId &detId, double &threshold, double &weight) const
helper method to look up the appropriate threshold &amp; weight
int getSeverityLevel(const DetId &myid, const uint32_t &myflag, const uint32_t &mystatus) const
const HcalTopology * theHcalTopology
std::vector< int > theEcalSeveritiesToBeExcluded
T eta() const
Definition: PV3DBase.h:73
std::vector< unsigned short > ecalBadChs
void setEcalTime(int t)
Definition: CaloTower.h:83
HcalDetId idBack(const HcalDetId &id) const
Definition: HcalTopology.h:171
int lastHERing() const
GlobalPoint emShwrPos(const std::vector< std::pair< DetId, float >> &metaContains, float fracDepth, double totEmE)
const EcalSeverityLevelAlgo * theEcalSevLvlAlgo
std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id.
Definition: CaloGeometry.cc:60
std::vector< double > theHF1Grid
void reserve(size_type n)
int convertCTtoHcal(int ct_ieta) const
int lastHORing() const
std::vector< double > theEBGrid
tuple cout
Definition: gather_cfg.py:144
int lastHBRing() const
HcalDetId idFront(const HcalDetId &id) const
Definition: HcalTopology.h:170
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
std::vector< double > theHF2Weights
constexpr int depth() const
get the tower depth
Definition: HcalDetId.h:164
#define UNLIKELY(x)
Definition: Likely.h:21
int ieta() const
get the tower ieta
int firstHFRing() const
int weight
Definition: histoStyle.py:51
uint32_t getValue() const
unsigned int theHcalAcceptSeverityLevelForRejectedHit
std::tuple< unsigned int, bool > ecalChanStatusForCaloTower(const EcalRecHit *hit)
void setHcalTime(int t)
Definition: CaloTower.h:84
EcalSubdetector
T x() const
Definition: PV3DBase.h:59
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:53
std::vector< double > theEBWeights
constexpr uint32_t flags() const
Definition: CaloRecHit.h:34
uint32_t sizeForDenseIndexing() const
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
double outerEnergy() const
Definition: CaloTower.h:132
int lastHERing() const
Definition: HcalTopology.h:94
const_iterator begin() const
const_reference back() const
Global3DVector GlobalVector
Definition: GlobalVector.h:10
GlobalPoint emShwrLogWeightPos(const std::vector< std::pair< DetId, float >> &metaContains, float fracDepth, double totEmE)
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Candidate.h:38