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