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  for( const reco::PFRecHitFraction& rhf : cluster.recHitFractions() ) {
40  const reco::PFRecHitRef& refhit = rhf.recHitRef();
41  if( refhit->detId() == cluster.seed() ) refseed = refhit;
42  const double rh_fraction = rhf.fraction();
43  const double rh_rawenergy = refhit->energy();
44  const double rh_energy = rh_rawenergy * rh_fraction;
45  if( edm::isNotFinite(rh_energy) ) {
46  throw cms::Exception("PFClusterAlgo")
47  <<"rechit " << refhit->detId() << " has a NaN energy... "
48  << "The input of the particle flow clustering seems to be corrupted.";
49  }
50  cl_energy += rh_energy;
51 
52  // If time resolution is given, calculated weighted average
54  double res2 = 10000.;
55  int cell_layer = (int)refhit->layer();
56  if (cell_layer == PFLayer::HCAL_BARREL1 ||
57  cell_layer == PFLayer::HCAL_BARREL2 ||
58  cell_layer == PFLayer::ECAL_BARREL)
59  res2 = _timeResolutionCalcBarrel->timeResolution2(rh_rawenergy);
60  else
61  res2 = _timeResolutionCalcEndcap->timeResolution2(rh_rawenergy);
62  cl_time += rh_fraction*refhit->time()/res2;
63  cl_timeweight += rh_fraction/res2;
64  }
65  else { // assume resolution = 1/E**2
66  const double rh_rawenergy2 = rh_rawenergy*rh_rawenergy;
67  cl_timeweight+=rh_rawenergy2*rh_fraction;
68  cl_time += rh_rawenergy2*rh_fraction*refhit->time();
69  }
70 
71  if( rh_energy > max_e ) {
72  max_e = rh_energy;
73  max_e_layer = rhf.recHitRef()->layer();
74  }
75  }
76  cluster.setEnergy(cl_energy);
77  cluster.setTime(cl_time/cl_timeweight);
78  cluster.setLayer(max_e_layer);
79  // calculate the position
80  double position_norm = 0.0;
81  double x(0.0),y(0.0),z(0.0);
82  const reco::PFRecHitRefVector* seedNeighbours = NULL;
83  switch( _posCalcNCrystals ) {
84  case 5:
85  seedNeighbours = &refseed->neighbours4();
86  break;
87  case 9:
88  seedNeighbours = &refseed->neighbours8();
89  break;
90  default:
91  break;
92  }
93 
94  for( const reco::PFRecHitFraction& rhf : cluster.recHitFractions() ) {
95  const reco::PFRecHitRef& refhit = rhf.recHitRef();
96 
97  if( refhit != refseed && _posCalcNCrystals != -1 ) {
98  auto pos = std::find(seedNeighbours->begin(),seedNeighbours->end(),
99  refhit);
100  if( pos == seedNeighbours->end() ) continue;
101  }
102 
103  const double rh_energy = refhit->energy() * ((float)rhf.fraction());
104  const double norm = ( rhf.fraction() < _minFractionInCalc ?
105  0.0 :
106  std::max(0.0,vdt::fast_log(rh_energy/_logWeightDenom)) );
107  const math::XYZPoint& rhpos_xyz = refhit->position();
108  x += rhpos_xyz.X() * norm;
109  y += rhpos_xyz.Y() * norm;
110  z += rhpos_xyz.Z() * norm;
111  position_norm += norm;
112  }
113  if( position_norm < _minAllowedNorm ) {
114  edm::LogError("WeirdClusterNormalization")
115  << "PFCluster too far from seeding cell: set position to (0,0,0).";
116  cluster.setPosition(math::XYZPoint(0,0,0));
117  cluster.calculatePositionREP();
118  } else {
119  const double norm_inverse = 1.0/position_norm;
120  x *= norm_inverse;
121  y *= norm_inverse;
122  z *= norm_inverse;
123  cluster.setPosition(math::XYZPoint(x,y,z));
124  cluster.calculatePositionREP();
125  }
126 }
void setLayer(PFLayer::Layer layer)
set layer
Definition: PFCluster.cc:77
std::unique_ptr< ECALRecHitResolutionProvider > _timeResolutionCalcEndcap
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:111
Fraction of a PFRecHit (rechits can be shared between several PFCluster&#39;s)
void setEnergy(double energy)
Definition: CaloCluster.h:108
#define NULL
Definition: scimark2.h:8
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:249
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
float float float z
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:244
void calculateAndSetPositions(reco::PFClusterCollection &)
bool isNotFinite(T x)
Definition: isFinite.h:10
void setTime(double time)
Definition: PFCluster.h:84
void calculatePositionREP()
computes posrep_ once and for all
Definition: PFCluster.h:90
Layer
layer definition
Definition: PFLayer.h:31
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:200
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
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:69
Definition: DDAxes.h:10
std::unique_ptr< ECALRecHitResolutionProvider > _timeResolutionCalcBarrel