CMS 3D CMS Logo

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