CMS 3D CMS Logo

ECAL2DPositionCalcWithDepthCorr.cc
Go to the documentation of this file.
2 
5 
6 #include <cmath>
7 #include <unordered_map>
8 
12 
13 #include "vdt/vdtMath.h"
14 
15 // faithful reimplementation of RecoEcal/EgammaCoreTools PositionCalc
16 // sorry Stefano
17 
19 update(const edm::EventSetup& es) {
20 
21  const CaloGeometryRecord& caloGeom = es.get<CaloGeometryRecord>();
23  caloGeom.get(geohandle);
24  _ebGeom = geohandle->getSubdetectorGeometry(DetId::Ecal,EcalBarrel);
25  _eeGeom = geohandle->getSubdetectorGeometry(DetId::Ecal,EcalEndcap);
26  _esGeom = geohandle->getSubdetectorGeometry(DetId::Ecal,EcalPreshower);
27  if(_esGeom){
28  // ripped from RecoEcal/EgammaCoreTools
29  for( uint32_t ic = 0;
30  ic < _esGeom->getValidDetIds().size() &&
31  ( !_esPlus || !_esMinus ); ++ic ) {
32  const double z = _esGeom->getGeometry( _esGeom->getValidDetIds()[ic] )->getPosition().z();
33  _esPlus = _esPlus || ( 0 < z ) ;
34  _esMinus = _esMinus || ( 0 > z ) ;
35  }
36  }
37 }
38 
42 }
43 
46  for( reco::PFCluster& cluster : clusters ) {
48  }
49 }
50 
53  constexpr double preshowerStartEta = 1.653;
54  constexpr double preshowerEndEta = 2.6;
55  if( !cluster.seed() ) {
56  throw cms::Exception("ClusterWithNoSeed")
57  << " Found a cluster with no seed: " << cluster;
58  }
59  double cl_energy = 0;
60  double cl_energy_float = 0;
61  double cl_time = 0;
62  double cl_timeweight=0.0;
63  double max_e = 0.0;
64  double clusterT0 = 0.0;
65  PFLayer::Layer max_e_layer = PFLayer::NONE;
66  reco::PFRecHitRef refmax;
67  // find the seed and max layer
68  for( const reco::PFRecHitFraction& rhf : cluster.recHitFractions() ) {
69  const reco::PFRecHitRef& refhit = rhf.recHitRef();
70  const double rh_fraction = rhf.fraction();
71  const double rh_rawenergy = refhit->energy();
72  const double rh_energy = rh_rawenergy * rh_fraction;
73  const double rh_energyf = ((float)rh_rawenergy) * ((float) rh_fraction);
74  if( !edm::isFinite(rh_energy) ) {
75  throw cms::Exception("PFClusterAlgo")
76  <<"rechit " << refhit->detId() << " has non-finite energy... "
77  << "The input of the particle flow clustering seems to be corrupted.";
78  }
79  cl_energy += rh_energy;
80  cl_energy_float += rh_energyf;
81  // If time resolution is given, calculate weighted average
82  if (_timeResolutionCalc) {
83  const double res2 = 1./_timeResolutionCalc->timeResolution2(rh_rawenergy);
84  cl_time += rh_fraction*refhit->time()*res2;
85  cl_timeweight += rh_fraction*res2;
86  }
87  else { // assume resolution ~ 1/E**2
88  const double rh_rawenergy2 = rh_rawenergy*rh_rawenergy;
89  cl_timeweight+=rh_rawenergy2*rh_fraction;
90  cl_time += rh_rawenergy2*rh_fraction*refhit->time();
91  }
92  if( rh_energy > max_e ) {
93  max_e = rh_energy;
94  max_e_layer = rhf.recHitRef()->layer();
95  refmax = refhit;
96  }
97  }
98  cluster.setEnergy(cl_energy);
99  cluster.setTime(cl_time/cl_timeweight);
100  if (_timeResolutionCalc) {
101  cluster.setTimeError(std::sqrt(1.0f/float(cl_timeweight)));
102  }
103  cluster.setLayer(max_e_layer);
104  const CaloSubdetectorGeometry* ecal_geom = nullptr;
105  // get seed geometry information
106  switch(max_e_layer){
108  ecal_geom = _ebGeom;
109  clusterT0 = _param_T0_EB;
110  break;
112  ecal_geom = _eeGeom;
113  clusterT0 = _param_T0_EE;
114  break;
115  default:
116  throw cms::Exception("InvalidLayer")
117  << "ECAL Position Calc only accepts ECAL_BARREL or ECAL_ENDCAP";
118  }
119 
120  auto center_cell = ecal_geom->getGeometry(refmax->detId());
121  const double ctreta = center_cell->etaPos();
122  const double actreta = std::abs(ctreta);
123  // need to change T0 if in ES
124  if( actreta > preshowerStartEta && actreta < preshowerEndEta ) {
125  if(ctreta > 0 && _esPlus ) clusterT0 = _param_T0_ES;
126  if(ctreta < 0 && _esMinus) clusterT0 = _param_T0_ES;
127  }
128  // floats to reproduce exactly the EGM code
129  const float maxDepth = _param_X0*(clusterT0 + vdt::fast_log(cl_energy_float));
130  const float maxToFront = center_cell->getPosition().mag();
131  // calculate the position
132  const double logETot_inv = -vdt::fast_log(cl_energy_float);
133  double position_norm = 0.0;
134  double x(0.0),y(0.0),z(0.0);
135  for( const reco::PFRecHitFraction& rhf : cluster.recHitFractions() ) {
136  double weight = 0.0;
137  const reco::PFRecHitRef& refhit = rhf.recHitRef();
138  const double rh_energy = ((float)refhit->energy()) * ((float)rhf.fraction());
139  if( rh_energy > 0.0 ) weight = std::max(0.0,( _param_W0 +
140  vdt::fast_log(rh_energy) +
141  logETot_inv ));
142  auto cell = ecal_geom->getGeometry(refhit->detId());
143  const float depth = maxDepth + maxToFront - cell->getPosition().mag();
144  const GlobalPoint pos =
145  static_cast<const TruncatedPyramid*>(cell.get())->getPosition(depth);
146 
147  x += weight*pos.x() ;
148  y += weight*pos.y() ;
149  z += weight*pos.z() ;
150 
151  position_norm += weight ;
152  }
153 
154  // FALL BACK to LINEAR WEIGHTS
155  if (position_norm == 0.) {
156  for( const reco::PFRecHitFraction& rhf : cluster.recHitFractions() ) {
157  double weight = 0.0;
158  const reco::PFRecHitRef& refhit = rhf.recHitRef();
159  const double rh_energy = ((float)refhit->energy()) * ((float)rhf.fraction());
160  if( rh_energy > 0.0 )
161  weight = rh_energy/cluster.energy();
162 
163  auto cell = ecal_geom->getGeometry(refhit->detId());
164  const float depth = maxDepth + maxToFront - cell->getPosition().mag();
165  const GlobalPoint pos = cell->getPosition(depth);
166 
167  x += weight*pos.x() ;
168  y += weight*pos.y() ;
169  z += weight*pos.z() ;
170 
171  position_norm += weight ;
172  }
173  }
174 
175  if( position_norm < _minAllowedNorm ) {
176  edm::LogError("WeirdClusterNormalization")
177  << "PFCluster too far from seeding cell: set position to (0,0,0).";
178  cluster.setPosition(math::XYZPoint(0,0,0));
179  } else {
180  const double norm_inverse = 1.0/position_norm;
181  x *= norm_inverse;
182  y *= norm_inverse;
183  z *= norm_inverse;
184 
185  cluster.setPosition(math::XYZPoint(x,y,z));
186  cluster.calculatePositionREP();
187  }
188 }
void setLayer(PFLayer::Layer layer)
set layer
Definition: PFCluster.cc:112
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
void setPosition(const math::XYZPoint &p)
Definition: CaloCluster.h:117
void setTime(float time, float timeError=0)
Definition: PFCluster.h:92
T y() const
Definition: PV3DBase.h:63
Fraction of a PFRecHit (rechits can be shared between several PFCluster&#39;s)
std::unique_ptr< CaloRecHitResolutionProvider > _timeResolutionCalc
void setEnergy(double energy)
Definition: CaloCluster.h:113
Definition: weight.py:1
constexpr bool isFinite(T x)
void calculateAndSetPositionActual(reco::PFCluster &) const
virtual const std::vector< DetId > & getValidDetIds(DetId::Detector det=DetId::Detector(0), int subdet=0) const
Get a list of valid detector ids (for the given subdetector)
void update(const edm::EventSetup &es) override
void calculateAndSetPosition(reco::PFCluster &) override
ProductT const & get(ESGetToken< ProductT, DepRecordT > const &iToken) const
void calculatePositionREP()
computes posrep_ once and for all
Definition: PFCluster.h:100
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
double energy() const
cluster energy
Definition: PFCluster.h:82
Layer
layer definition
Definition: PFLayer.h:31
void setTimeError(float timeError)
Definition: PFCluster.h:93
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:207
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
const CaloSubdetectorGeometry * _ebGeom
void calculateAndSetPositions(reco::PFClusterCollection &) override
const CaloSubdetectorGeometry * _esGeom
A base class to handle the particular shape of Ecal Xtals. Taken from ORCA Calorimetry Code...
T get() const
Definition: EventSetup.h:71
const CaloSubdetectorGeometry * _eeGeom
std::vector< PFCluster > PFClusterCollection
collection of PFCluster objects
Definition: PFClusterFwd.h:9
const std::vector< reco::PFRecHitFraction > & recHitFractions() const
vector of rechit fractions
Definition: PFCluster.h:72
T x() const
Definition: PV3DBase.h:62
#define constexpr