CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Basic2DGenericPFlowPositionCalc.cc
Go to the documentation of this file.
2 
5 
6 #include <cmath>
7 #include <unordered_map>
8 
9 #include "vdt/vdtMath.h"
10 
14 }
15 
18  for( reco::PFCluster& cluster : clusters ) {
20  }
21 }
22 
25  if( !cluster.seed() ) {
26  throw cms::Exception("ClusterWithNoSeed")
27  << " Found a cluster with no seed: " << cluster;
28  }
29  double cl_energy = 0;
30  double cl_time = 0;
31  double cl_timeweight=0.0;
32  double max_e = 0.0;
33  PFLayer::Layer max_e_layer = PFLayer::NONE;
34  reco::PFRecHitRef refseed;
35  // find the seed and max layer and also calculate time
36  //Michalis : Even if we dont use timing in clustering here we should fill
37  //the time information for the cluster. This should use the timing resolution(1/E)
38  //so the weight should be fraction*E^2
39  //calculate a simplistic depth now. The log weighted will be done
40  //in different stage
41  for( const reco::PFRecHitFraction& rhf : cluster.recHitFractions() ) {
42  const reco::PFRecHitRef& refhit = rhf.recHitRef();
43  if( refhit->detId() == cluster.seed() ) refseed = refhit;
44  const double rh_fraction = rhf.fraction();
45  const double rh_rawenergy = refhit->energy();
46  const double rh_energy = rh_rawenergy * rh_fraction;
47  if( edm::isNotFinite(rh_energy) ) {
48  throw cms::Exception("PFClusterAlgo")
49  <<"rechit " << refhit->detId() << " has a NaN energy... "
50  << "The input of the particle flow clustering seems to be corrupted.";
51  }
52  cl_energy += rh_energy;
53  // If time resolution is given, calculated weighted average
55  double res2 = 10000.;
56  int cell_layer = (int)refhit->layer();
57  if (cell_layer == PFLayer::HCAL_BARREL1 ||
58  cell_layer == PFLayer::HCAL_BARREL2 ||
59  cell_layer == PFLayer::ECAL_BARREL)
60  res2 = _timeResolutionCalcBarrel->timeResolution2(rh_rawenergy);
61  else
62  res2 = _timeResolutionCalcEndcap->timeResolution2(rh_rawenergy);
63  cl_time += rh_fraction*refhit->time()/res2;
64  cl_timeweight += rh_fraction/res2;
65  }
66  else { // assume resolution = 1/E**2
67  const double rh_rawenergy2 = rh_rawenergy*rh_rawenergy;
68  cl_timeweight+=rh_rawenergy2*rh_fraction;
69  cl_time += rh_rawenergy2*rh_fraction*refhit->time();
70  }
71 
72  if( rh_energy > max_e ) {
73  max_e = rh_energy;
74  max_e_layer = rhf.recHitRef()->layer();
75  }
76  }
77  cluster.setEnergy(cl_energy);
78  cluster.setTime(cl_time/cl_timeweight);
79  cluster.setLayer(max_e_layer);
80  // calculate the position
81 
82  double depth = 0.0;
83  double position_norm = 0.0;
84  double x(0.0),y(0.0),z(0.0);
85  const reco::PFRecHitRefVector* seedNeighbours = nullptr;
86  switch( _posCalcNCrystals ) {
87  case 5:
88  seedNeighbours = &refseed->neighbours4();
89  break;
90  case 9:
91  seedNeighbours = &refseed->neighbours8();
92  break;
93  case -1:
94  break;
95  default:
96  assert(0); //bug
97  }
98 
99  for( const reco::PFRecHitFraction& rhf : cluster.recHitFractions() ) {
100  const reco::PFRecHitRef& refhit = rhf.recHitRef();
101 
102  if( refhit != refseed && _posCalcNCrystals != -1 ) {
103  auto pos = std::find(seedNeighbours->begin(),seedNeighbours->end(),
104  refhit);
105  if( pos == seedNeighbours->end() ) continue;
106  }
107 
108  const double rh_energy = refhit->energy() * ((float)rhf.fraction());
109  const double norm = ( rhf.fraction() < _minFractionInCalc ?
110  0.0 :
111  std::max(0.0,vdt::fast_log(rh_energy/_logWeightDenom)) );
112  const math::XYZPoint& rhpos_xyz = refhit->position();
113  x += rhpos_xyz.X() * norm;
114  y += rhpos_xyz.Y() * norm;
115  z += rhpos_xyz.Z() * norm;
116  depth += refhit->depth()*norm;
117 
118  position_norm += norm;
119  }
120  if( position_norm < _minAllowedNorm ) {
121  edm::LogError("WeirdClusterNormalization")
122  << "PFCluster too far from seeding cell: set position to (0,0,0).";
123  cluster.setPosition(math::XYZPoint(0,0,0));
124  cluster.calculatePositionREP();
125  } else {
126  const double norm_inverse = 1.0/position_norm;
127  x *= norm_inverse;
128  y *= norm_inverse;
129  z *= norm_inverse;
130  depth *= norm_inverse;
131  cluster.setPosition(math::XYZPoint(x,y,z));
132  cluster.setDepth(depth);
133  cluster.calculatePositionREP();
134  }
135 }
void setLayer(PFLayer::Layer layer)
set layer
Definition: PFCluster.cc:78
void calculateAndSetPositionActual(reco::PFCluster &) const
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
void setPosition(const math::XYZPoint &p)
Definition: CaloCluster.h:112
assert(m_qm.get())
Fraction of a PFRecHit (rechits can be shared between several PFCluster&#39;s)
void setEnergy(double energy)
Definition: CaloCluster.h:108
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:255
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:250
void calculateAndSetPositions(reco::PFClusterCollection &)
bool isNotFinite(T x)
Definition: isFinite.h:10
void setTime(double time)
Definition: PFCluster.h:89
void calculatePositionREP()
computes posrep_ once and for all
Definition: PFCluster.h:96
Layer
layer definition
Definition: PFLayer.h:31
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:202
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::unique_ptr< CaloRecHitResolutionProvider > _timeResolutionCalcBarrel
std::unique_ptr< CaloRecHitResolutionProvider > _timeResolutionCalcEndcap
void setDepth(double depth)
Definition: PFCluster.h:90
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