CMS 3D CMS Logo

Basic2DGenericPFlowPositionCalc.cc
Go to the documentation of this file.
2 
5 
6 #include <cmath>
8 #include <iterator>
9 #include <boost/iterator/function_output_iterator.hpp>
10 
11 #include "vdt/vdtMath.h"
12 
13 namespace {
14  inline bool isBarrel(int cell_layer) {
15  return (cell_layer == PFLayer::HCAL_BARREL1 || cell_layer == PFLayer::HCAL_BARREL2 ||
16  cell_layer == PFLayer::ECAL_BARREL);
17  }
18 } // namespace
19 
22 }
23 
25  for (reco::PFCluster& cluster : clusters) {
27  }
28 }
29 
31  if (!cluster.seed()) {
32  throw cms::Exception("ClusterWithNoSeed") << " Found a cluster with no seed: " << cluster;
33  }
34  double cl_energy = 0;
35  double cl_time = 0;
36  double cl_timeweight = 0.0;
37  double max_e = 0.0;
38  PFLayer::Layer max_e_layer = PFLayer::NONE;
39  // find the seed and max layer and also calculate time
40  //Michalis : Even if we dont use timing in clustering here we should fill
41  //the time information for the cluster. This should use the timing resolution(1/E)
42  //so the weight should be fraction*E^2
43  //calculate a simplistic depth now. The log weighted will be done
44  //in different stage
45 
46  auto const recHitCollection =
47  &(*cluster.recHitFractions()[0].recHitRef()) - cluster.recHitFractions()[0].recHitRef().key();
48  auto nhits = cluster.recHitFractions().size();
49  struct LHit {
50  reco::PFRecHit const* hit;
51  float energy;
52  float fraction;
53  };
54  declareDynArray(LHit, nhits, hits);
55  for (auto i = 0U; i < nhits; ++i) {
56  auto const& hf = cluster.recHitFractions()[i];
57  auto k = hf.recHitRef().key();
58  auto p = recHitCollection + k;
59  hits[i] = {p, (*p).energy(), float(hf.fraction())};
60  }
61 
63  LHit mySeed = {};
64  for (auto const& rhf : hits) {
65  const reco::PFRecHit& refhit = *rhf.hit;
66  if (refhit.detId() == cluster.seed())
67  mySeed = rhf;
68  const auto rh_fraction = rhf.fraction;
69  const auto rh_rawenergy = rhf.energy;
70  const auto rh_energy = rh_rawenergy * rh_fraction;
71 #ifdef PF_DEBUG
72  if UNLIKELY (edm::isNotFinite(rh_energy)) {
73  throw cms::Exception("PFClusterAlgo") << "rechit " << refhit.detId() << " has a NaN energy... "
74  << "The input of the particle flow clustering seems to be corrupted.";
75  }
76 #endif
77  cl_energy += rh_energy;
78  // If time resolution is given, calculated weighted average
79  if (resGiven) {
80  double res2 = 1.e-4;
81  int cell_layer = (int)refhit.layer();
82  res2 = isBarrel(cell_layer) ? 1. / _timeResolutionCalcBarrel->timeResolution2(rh_rawenergy)
83  : 1. / _timeResolutionCalcEndcap->timeResolution2(rh_rawenergy);
84  cl_time += rh_fraction * refhit.time() * res2;
85  cl_timeweight += rh_fraction * res2;
86  } else { // assume resolution = 1/E**2
87  const double rh_rawenergy2 = rh_rawenergy * rh_rawenergy;
88  cl_timeweight += rh_rawenergy2 * rh_fraction;
89  cl_time += rh_rawenergy2 * rh_fraction * refhit.time();
90  }
91 
92  if (rh_energy > max_e) {
93  max_e = rh_energy;
94  max_e_layer = refhit.layer();
95  }
96  }
97 
98  cluster.setEnergy(cl_energy);
99  cluster.setTime(cl_time / cl_timeweight);
100  if (resGiven) {
101  cluster.setTimeError(std::sqrt(1.0f / float(cl_timeweight)));
102  }
103  cluster.setLayer(max_e_layer);
104 
105  // calculate the position
106  double depth = 0.0;
107  double position_norm = 0.0;
108  double x(0.0), y(0.0), z(0.0);
109  if (nullptr != mySeed.hit) {
110  auto seedNeighbours = mySeed.hit->neighbours();
111  switch (_posCalcNCrystals) {
112  case 5:
113  seedNeighbours = mySeed.hit->neighbours4();
114  break;
115  case 9:
116  seedNeighbours = mySeed.hit->neighbours8();
117  break;
118  default:
119  break;
120  }
121 
122  auto compute = [&](LHit const& rhf) {
123  const reco::PFRecHit& refhit = *rhf.hit;
124 
125  int cell_layer = (int)refhit.layer();
126  float threshold = 0;
127 
128  for (unsigned int j = 0; j < (std::get<2>(_logWeightDenom)).size(); ++j) {
129  // barrel is detecor type1
130  int detectorEnum = std::get<0>(_logWeightDenom)[j];
131  int depth = std::get<1>(_logWeightDenom)[j];
132 
133  if ((cell_layer == PFLayer::HCAL_BARREL1 && detectorEnum == 1 && refhit.depth() == depth) ||
134  (cell_layer == PFLayer::HCAL_ENDCAP && detectorEnum == 2 && refhit.depth() == depth) || detectorEnum == 0)
135  threshold = std::get<2>(_logWeightDenom)[j];
136  }
137 
138  const auto rh_energy = rhf.energy * rhf.fraction;
139  const auto norm =
140  (rhf.fraction < _minFractionInCalc ? 0.0f : std::max(0.0f, vdt::fast_logf(rh_energy * threshold)));
141  const auto rhpos_xyz = refhit.position() * norm;
142  x += rhpos_xyz.x();
143  y += rhpos_xyz.y();
144  z += rhpos_xyz.z();
145  depth += refhit.depth() * norm;
146  position_norm += norm;
147  };
148 
149  if (_posCalcNCrystals != -1) // sorted to make neighbour search faster (maybe)
150  std::sort(hits.begin(), hits.end(), [](LHit const& a, LHit const& b) { return a.hit < b.hit; });
151 
152  if (_posCalcNCrystals == -1)
153  for (auto const& rhf : hits)
154  compute(rhf);
155  else { // only seed and its neighbours
156  compute(mySeed);
157  // search seedNeighbours to find energy fraction in cluster (sic)
158  unInitDynArray(reco::PFRecHit const*, seedNeighbours.size(), nei);
159  for (auto k : seedNeighbours) {
160  nei.push_back(recHitCollection + k);
161  }
162  std::sort(nei.begin(), nei.end());
163  struct LHitLess {
164  auto operator()(LHit const& a, reco::PFRecHit const* b) const { return a.hit < b; }
165  auto operator()(reco::PFRecHit const* b, LHit const& a) const { return b < a.hit; }
166  };
167  std::set_intersection(
168  hits.begin(), hits.end(), nei.begin(), nei.end(), boost::make_function_output_iterator(compute), LHitLess());
169  }
170  } else {
171  throw cms::Exception("Basic2DGenerticPFlowPositionCalc")
172  << "Cluster seed hit is null, something is wrong with PFlow RecHit!";
173  }
174 
175  if (position_norm < _minAllowedNorm) {
176  edm::LogError("WeirdClusterNormalization") << "PFCluster too far from seeding cell: set position to (0,0,0).";
177  cluster.setPosition(math::XYZPoint(0, 0, 0));
178  cluster.calculatePositionREP();
179  } else {
180  const double norm_inverse = 1.0 / position_norm;
181  x *= norm_inverse;
182  y *= norm_inverse;
183  z *= norm_inverse;
184  depth *= norm_inverse;
185  cluster.setPosition(math::XYZPoint(x, y, z));
186  cluster.setDepth(depth);
187  cluster.calculatePositionREP();
188  }
189 }
reco::PFClusterCollection
std::vector< PFCluster > PFClusterCollection
collection of PFCluster objects
Definition: PFClusterFwd.h:9
PFCPositionCalculatorBase::_minFractionInCalc
const float _minFractionInCalc
Definition: PFCPositionCalculatorBase.h:36
Basic2DGenericPFlowPositionCalc::_timeResolutionCalcBarrel
std::unique_ptr< CaloRecHitResolutionProvider > _timeResolutionCalcBarrel
Definition: Basic2DGenericPFlowPositionCalc.h:97
DDAxes::y
Basic2DGenericPFlowPositionCalc::calculateAndSetPositionActual
void calculateAndSetPositionActual(reco::PFCluster &) const
Definition: Basic2DGenericPFlowPositionCalc.cc:30
electrons_cff.bool
bool
Definition: electrons_cff.py:366
mps_fire.i
i
Definition: mps_fire.py:428
reco::PFCluster::setTime
void setTime(float time, float timeError=0)
Definition: PFCluster.h:84
Basic2DGenericPFlowPositionCalc::_posCalcNCrystals
const int _posCalcNCrystals
Definition: Basic2DGenericPFlowPositionCalc.h:93
MessageLogger.h
dqmMemoryStats.float
float
Definition: dqmMemoryStats.py:127
HLT_FULL_cff.detectorEnum
detectorEnum
Definition: HLT_FULL_cff.py:13142
hfClusterShapes_cfi.hits
hits
Definition: hfClusterShapes_cfi.py:5
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
edm::isNotFinite
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
reco::PFCluster::setLayer
void setLayer(PFLayer::Layer layer)
set layer
Definition: PFCluster.cc:49
PFLayer::HCAL_ENDCAP
Definition: PFLayer.h:37
reco::PFCluster::recHitFractions
const std::vector< reco::PFRecHitFraction > & recHitFractions() const
vector of rechit fractions
Definition: PFCluster.h:65
Basic2DGenericPFlowPositionCalc::calculateAndSetPosition
void calculateAndSetPosition(reco::PFCluster &) override
Definition: Basic2DGenericPFlowPositionCalc.cc:20
bookConverter.compute
def compute(min, max)
Definition: bookConverter.py:106
DDAxes::x
Basic2DGenericPFlowPositionCalc::_logWeightDenom
std::tuple< std::vector< int >, std::vector< int >, std::vector< float > > _logWeightDenom
Definition: Basic2DGenericPFlowPositionCalc.h:94
Basic2DGenericPFlowPositionCalc::_timeResolutionCalcEndcap
std::unique_ptr< CaloRecHitResolutionProvider > _timeResolutionCalcEndcap
Definition: Basic2DGenericPFlowPositionCalc.h:98
ecalTB2006H4_GenSimDigiReco_cfg.mySeed
mySeed
Definition: ecalTB2006H4_GenSimDigiReco_cfg.py:8
PFLayer::ECAL_BARREL
Definition: PFLayer.h:33
reco::PFRecHit::depth
int depth() const
depth for segemntation
Definition: PFRecHit.h:105
UNLIKELY
#define UNLIKELY(x)
Definition: Likely.h:21
photonIsolationHIProducer_cfi.hf
hf
Definition: photonIsolationHIProducer_cfi.py:9
PFLayer::HCAL_BARREL2
Definition: PFLayer.h:36
HLT_FULL_cff.fraction
fraction
Definition: HLT_FULL_cff.py:52806
myMath::fast_logf
float fast_logf(float x)
Definition: EcalUncalibRecHitRatioMethodAlgo.h:28
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
PFLayer::HCAL_BARREL1
Definition: PFLayer.h:35
DDAxes::z
declareDynArray
#define declareDynArray(T, n, x)
Definition: DynArray.h:91
HCALHighEnergyHPDFilter_cfi.energy
energy
Definition: HCALHighEnergyHPDFilter_cfi.py:5
PFLayer::NONE
Definition: PFLayer.h:34
dqmdumpme.k
k
Definition: dqmdumpme.py:60
Basic2DGenericPFlowPositionCalc::_minAllowedNorm
const float _minAllowedNorm
Definition: Basic2DGenericPFlowPositionCalc.h:95
nhits
Definition: HIMultiTrackSelector.h:42
b
double b
Definition: hdecay.h:118
reco::CaloCluster::setPosition
void setPosition(const math::XYZPoint &p)
Definition: CaloCluster.h:140
LEDCalibrationChannels.depth
depth
Definition: LEDCalibrationChannels.py:65
mitigatedMETSequence_cff.U
U
Definition: mitigatedMETSequence_cff.py:36
PFLayer::Layer
Layer
layer definition
Definition: PFLayer.h:29
bsc_activity_cfg.clusters
clusters
Definition: bsc_activity_cfg.py:36
PixelPluginsPhase0_cfi.isBarrel
isBarrel
Definition: PixelPluginsPhase0_cfi.py:17
math::XYZPoint
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
a
double a
Definition: hdecay.h:119
Basic2DGenericPFlowPositionCalc::calculateAndSetPositions
void calculateAndSetPositions(reco::PFClusterCollection &) override
Definition: Basic2DGenericPFlowPositionCalc.cc:24
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
jetUpdater_cfi.sort
sort
Definition: jetUpdater_cfi.py:29
reco::PFCluster::calculatePositionREP
void calculatePositionREP()
computes posrep_ once and for all
Definition: PFCluster.h:95
createfilelist.int
int
Definition: createfilelist.py:10
Basic2DGenericPFlowPositionCalc.h
edm::LogError
Log< level::Error, false > LogError
Definition: MessageLogger.h:123
reco::CaloCluster::seed
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:219
DynArray.h
reco::PFRecHit::time
float time() const
timing for cleaned hits
Definition: PFRecHit.h:102
reco::PFRecHit::detId
unsigned detId() const
rechit detId
Definition: PFRecHit.h:93
reco::CaloCluster::setEnergy
void setEnergy(double energy)
Definition: CaloCluster.h:136
isFinite.h
Exception
Definition: hltDiff.cc:245
reco::PFCluster
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:42
reco::PFCluster::setTimeError
void setTimeError(float timeError)
Definition: PFCluster.h:88
reco::PFRecHit::position
PositionType const & position() const
rechit cell centre x, y, z
Definition: PFRecHit.h:117
reco::PFRecHit
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
reco::PFRecHit::layer
PFLayer::Layer layer() const
rechit layer
Definition: PFRecHit.h:96
reco::PFCluster::setDepth
void setDepth(double depth)
Definition: PFCluster.h:89
dqmiolumiharvest.j
j
Definition: dqmiolumiharvest.py:66
remoteMonitoring_LED_IterMethod_cfg.threshold
threshold
Definition: remoteMonitoring_LED_IterMethod_cfg.py:430
unInitDynArray
#define unInitDynArray(T, n, x)
Definition: DynArray.h:88
hit
Definition: SiStripHitEffFromCalibTree.cc:88
findQualityFiles.size
size
Write out results.
Definition: findQualityFiles.py:443