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