CMS 3D CMS Logo

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