CMS 3D CMS Logo

List of all members | Classes | Public Member Functions | Private Types | Static Private Member Functions | Private Attributes
RealisticHitToClusterAssociator Class Reference

#include <RealisticHitToClusterAssociator.h>

Classes

struct  RealisticHit
 

Public Member Functions

void computeAssociation (float exclusiveFraction, bool useMCFractionsForExclEnergy, unsigned int fhOffset, unsigned int bhOffset)
 
void filterHitsByDistance (float maxDistance)
 
void findAndMergeInvisibleClusters (float invisibleFraction, float exclusiveFraction)
 
void findCentersOfGravity ()
 
void init (std::size_t numberOfHits, std::size_t numberOfSimClusters, std::size_t numberOfLayers)
 
void insertHitEnergy (float energy, unsigned int hitIndex)
 
void insertHitPosition (float x, float y, float z, unsigned int hitIndex)
 
void insertLayerId (unsigned int layerId, unsigned int hitIndex)
 
void insertSimClusterIdAndFraction (unsigned int scIdx, float fraction, unsigned int hitIndex, float associatedEnergy)
 
const std::vector< RealisticCluster > & realisticClusters () const
 
float XYdistanceFromMaxHit (unsigned int hitId, unsigned int clusterId)
 
float XYdistanceFromPointOnSameLayer (unsigned int hitId, const Hit3DPosition &point)
 

Private Types

using Hit3DPosition = std::array< float, 3 >
 

Static Private Member Functions

static float getDecayLength (unsigned int layer, unsigned int fhOffset, unsigned int bhOffset)
 

Private Attributes

std::vector< RealisticHitrealisticHits_
 
std::vector< RealisticClusterrealisticSimClusters_
 

Detailed Description

Definition at line 13 of file RealisticHitToClusterAssociator.h.

Member Typedef Documentation

◆ Hit3DPosition

using RealisticHitToClusterAssociator::Hit3DPosition = std::array<float, 3>
private

Definition at line 14 of file RealisticHitToClusterAssociator.h.

Member Function Documentation

◆ computeAssociation()

void RealisticHitToClusterAssociator::computeAssociation ( float  exclusiveFraction,
bool  useMCFractionsForExclEnergy,
unsigned int  fhOffset,
unsigned int  bhOffset 
)
inline

Definition at line 66 of file RealisticHitToClusterAssociator.h.

References MillePedeFileConverter_cfg::e, particleFlowClusterHGC_cfi::exclusiveFraction, JetChargeProducer_cfi::exp, f, getDecayLength(), nano_mu_digi_cff::layer, or, realisticHits_, realisticSimClusters_, particleFlowClusterHGC_cfi::useMCFractionsForExclEnergy, x, and XYdistanceFromMaxHit().

Referenced by RealisticSimClusterMapper::buildClusters().

69  {
70  //if more than exclusiveFraction of a hit's energy belongs to a cluster, that rechit is not counted as shared
71  unsigned int numberOfHits = realisticHits_.size();
72  std::vector<float> partialEnergies;
73  for (unsigned int hitId = 0; hitId < numberOfHits; ++hitId) {
74  partialEnergies.clear();
75  std::vector<unsigned int> removeAssociation;
76  auto& realisticHit = realisticHits_[hitId];
77  unsigned int numberOfClusters = realisticHit.hitToCluster_.size();
78  if (numberOfClusters == 1) {
79  unsigned int simClusterId = realisticHit.hitToCluster_[0].simClusterId_;
80  float assignedFraction = 1.f;
81  realisticHit.hitToCluster_[0].realisticEnergyFraction_ = assignedFraction;
82  float assignedEnergy = realisticHit.totalEnergy_;
83  realisticSimClusters_[simClusterId].increaseEnergy(assignedEnergy);
84  realisticSimClusters_[simClusterId].addHitAndFraction(hitId, assignedFraction);
85  realisticSimClusters_[simClusterId].increaseExclusiveEnergy(assignedEnergy);
86  } else {
87  partialEnergies.resize(numberOfClusters, 0.f);
88  unsigned int layer = realisticHit.layerId_;
89  float sumE = 0.f;
90  float energyDecayLength = getDecayLength(layer, fhOffset, bhOffset);
91  for (unsigned int clId = 0; clId < numberOfClusters; ++clId) {
92  auto simClusterId = realisticHit.hitToCluster_[clId].simClusterId_;
93  realisticHit.hitToCluster_[clId].distanceFromMaxHit_ = XYdistanceFromMaxHit(hitId, simClusterId);
94  // partial energy is computed based on the distance from the maximum energy hit and its energy
95  // partial energy is only needed to compute a fraction and it's not the energy assigned to the cluster
96  auto maxEnergyOnLayer = realisticSimClusters_[simClusterId].getMaxEnergy(layer);
97  if (maxEnergyOnLayer > 0.f) {
98  partialEnergies[clId] =
99  maxEnergyOnLayer * std::exp(-realisticHit.hitToCluster_[clId].distanceFromMaxHit_ / energyDecayLength);
100  }
101  sumE += partialEnergies[clId];
102  }
103  if (sumE > 0.f) {
104  float invSumE = 1.f / sumE;
105  for (unsigned int clId = 0; clId < numberOfClusters; ++clId) {
106  unsigned int simClusterIndex = realisticHit.hitToCluster_[clId].simClusterId_;
107  float assignedFraction = partialEnergies[clId] * invSumE;
108  if (assignedFraction > 1e-3) {
109  realisticHit.hitToCluster_[clId].realisticEnergyFraction_ = assignedFraction;
110  float assignedEnergy = assignedFraction * realisticHit.totalEnergy_;
111  realisticSimClusters_[simClusterIndex].increaseEnergy(assignedEnergy);
112  realisticSimClusters_[simClusterIndex].addHitAndFraction(hitId, assignedFraction);
113  // if the hits energy belongs for more than exclusiveFraction to a cluster, also the cluster's
114  // exclusive energy is increased. The exclusive energy will be needed to evaluate if
115  // a realistic cluster will be invisible, i.e. absorbed by other clusters
117  realisticHit.hitToCluster_[clId].mcEnergyFraction_ > exclusiveFraction) or
118  (!useMCFractionsForExclEnergy and assignedFraction > exclusiveFraction)) {
119  realisticSimClusters_[simClusterIndex].increaseExclusiveEnergy(assignedEnergy);
120  }
121  } else {
122  removeAssociation.push_back(simClusterIndex);
123  }
124  }
125  }
126  }
127 
128  while (!removeAssociation.empty()) {
129  auto clusterToRemove = removeAssociation.back();
130  removeAssociation.pop_back();
131 
132  realisticHit.hitToCluster_.erase(std::remove_if(realisticHit.hitToCluster_.begin(),
133  realisticHit.hitToCluster_.end(),
134  [clusterToRemove](const RealisticHit::HitToCluster& x) {
135  return x.simClusterId_ == clusterToRemove;
136  }),
137  realisticHit.hitToCluster_.end());
138  }
139  }
140  }
std::vector< RealisticCluster > realisticSimClusters_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
static float getDecayLength(unsigned int layer, unsigned int fhOffset, unsigned int bhOffset)
double f[11][100]
float XYdistanceFromMaxHit(unsigned int hitId, unsigned int clusterId)

◆ filterHitsByDistance()

void RealisticHitToClusterAssociator::filterHitsByDistance ( float  maxDistance)
inline

Definition at line 250 of file RealisticHitToClusterAssociator.h.

References f, mps_fire::i, particleFlowClusterHGC_cfi::maxDistance, realisticHits_, realisticSimClusters_, and XYdistanceFromPointOnSameLayer().

Referenced by RealisticSimClusterMapper::buildClusters().

250  {
251  for (auto& cluster : realisticSimClusters_) {
252  if (cluster.isVisible()) {
253  auto& hAndF = cluster.hitsIdsAndFractions();
254  for (unsigned int i = 0; i < hAndF.size(); ++i) {
255  auto hitId = hAndF[i].first;
256  const auto& hit = realisticHits_[hitId];
257  auto layerId = hit.layerId_;
258  if (XYdistanceFromPointOnSameLayer(hitId, cluster.getCenterOfGravity(layerId)) > maxDistance) {
259  cluster.increaseEnergy(-hit.totalEnergy_ * hAndF[i].second);
260  cluster.modifyFractionByIndex(0.f, i);
261  }
262  }
263  }
264  }
265  }
std::vector< RealisticCluster > realisticSimClusters_
double f[11][100]
float XYdistanceFromPointOnSameLayer(unsigned int hitId, const Hit3DPosition &point)

◆ findAndMergeInvisibleClusters()

void RealisticHitToClusterAssociator::findAndMergeInvisibleClusters ( float  invisibleFraction,
float  exclusiveFraction 
)
inline

Definition at line 142 of file RealisticHitToClusterAssociator.h.

References pfMETCorrectionType0_cfi::correction, MillePedeFileConverter_cfg::e, particleFlowClusterHGC_cfi::exclusiveFraction, f, HLT_2023v12_cff::fraction, mps_fire::i, particleFlowClusterHGC_cfi::invisibleFraction, realisticHits_, realisticSimClusters_, and egamma::sharedEnergy().

Referenced by RealisticSimClusterMapper::buildClusters().

142  {
143  unsigned int numberOfRealSimClusters = realisticSimClusters_.size();
144 
145  for (unsigned int clId = 0; clId < numberOfRealSimClusters; ++clId) {
146  if (realisticSimClusters_[clId].getExclusiveEnergyFraction() < invisibleFraction) {
147  realisticSimClusters_[clId].setVisible(false);
148  auto& hAndF = realisticSimClusters_[clId].hitsIdsAndFractions();
149  std::unordered_map<unsigned int, float> energyInNeighbors;
150  float totalSharedEnergy = 0.f;
151 
152  for (auto& elt : hAndF) {
153  unsigned int hitId = elt.first;
154  float fraction = elt.second;
155  auto& realisticHit = realisticHits_[hitId];
156 
157  if (realisticHit.hitToCluster_.size() > 1 && fraction < 1.f) {
158  float correction = 1.f - fraction;
159  unsigned int numberOfClusters = realisticHit.hitToCluster_.size();
160  int clusterToRemove = -1;
161  for (unsigned int i = 0; i < numberOfClusters; ++i) {
162  auto simClusterIndex = realisticHit.hitToCluster_[i].simClusterId_;
163  if (simClusterIndex == clId) {
164  clusterToRemove = i;
165  } else if (realisticSimClusters_[simClusterIndex].isVisible()) {
166  float oldFraction = realisticHit.hitToCluster_[i].realisticEnergyFraction_;
167  float newFraction = oldFraction / correction;
168  float oldEnergy = oldFraction * realisticHit.totalEnergy_;
169  float newEnergy = newFraction * realisticHit.totalEnergy_;
170  float sharedEnergy = newEnergy - oldEnergy;
171  energyInNeighbors[simClusterIndex] += sharedEnergy;
172  totalSharedEnergy += sharedEnergy;
173  realisticSimClusters_[simClusterIndex].increaseEnergy(sharedEnergy);
174  realisticSimClusters_[simClusterIndex].modifyFractionForHitId(newFraction, hitId);
175  realisticHit.hitToCluster_[i].realisticEnergyFraction_ = newFraction;
176  if (newFraction > exclusiveFraction) {
177  realisticSimClusters_[simClusterIndex].increaseExclusiveEnergy(sharedEnergy);
178  if (oldFraction <= exclusiveFraction) {
179  realisticSimClusters_[simClusterIndex].increaseExclusiveEnergy(oldEnergy);
180  }
181  }
182  }
183  }
184  realisticSimClusters_[realisticHit.hitToCluster_[clusterToRemove].simClusterId_].modifyFractionForHitId(
185  0.f, hitId);
186  realisticHit.hitToCluster_.erase(realisticHit.hitToCluster_.begin() + clusterToRemove);
187  }
188  }
189 
190  for (auto& elt : hAndF) {
191  unsigned int hitId = elt.first;
192  auto& realisticHit = realisticHits_[hitId];
193  if (realisticHit.hitToCluster_.size() == 1 and realisticHit.hitToCluster_[0].simClusterId_ == clId and
194  totalSharedEnergy > 0.f) {
195  for (auto& pair : energyInNeighbors) {
196  // hits that belonged completely to the absorbed cluster are redistributed
197  // based on the fraction of energy shared in the shared hits
198  float sharedFraction = pair.second / totalSharedEnergy;
199  if (sharedFraction > 1e-6) {
200  float assignedEnergy = realisticHit.totalEnergy_ * sharedFraction;
201  realisticSimClusters_[pair.first].increaseEnergy(assignedEnergy);
202  realisticSimClusters_[pair.first].addHitAndFraction(hitId, sharedFraction);
203  realisticHit.hitToCluster_.emplace_back(
204  RealisticHit::HitToCluster{pair.first, 0.f, -1.f, sharedFraction});
205  if (sharedFraction > exclusiveFraction)
206  realisticSimClusters_[pair.first].increaseExclusiveEnergy(assignedEnergy);
207  }
208  }
209  }
210  }
211  }
212  }
213  }
std::vector< RealisticCluster > realisticSimClusters_
double f[11][100]
float sharedEnergy(reco::CaloCluster const &clu1, reco::CaloCluster const &clu2, EcalRecHitCollection const &barrelRecHits, EcalRecHitCollection const &endcapRecHits)

◆ findCentersOfGravity()

void RealisticHitToClusterAssociator::findCentersOfGravity ( )
inline

Definition at line 215 of file RealisticHitToClusterAssociator.h.

References f, HLT_2023v12_cff::fraction, realisticHits_, and realisticSimClusters_.

Referenced by RealisticSimClusterMapper::buildClusters().

215  {
216  for (auto& cluster : realisticSimClusters_) {
217  if (cluster.isVisible()) {
218  unsigned int layersNum = cluster.getLayersNum();
219  std::vector<float> totalEnergyPerLayer(layersNum, 0.f);
220  std::vector<float> xEnergyPerLayer(layersNum, 0.f);
221  std::vector<float> yEnergyPerLayer(layersNum, 0.f);
222  std::vector<float> zPositionPerLayer(layersNum, 0.f);
223  const auto& hAndF = cluster.hitsIdsAndFractions();
224  for (auto& elt : hAndF) {
225  auto hitId = elt.first;
226  auto fraction = elt.second;
227  const auto& hit = realisticHits_[hitId];
228  const auto& hitPos = hit.hitPosition_;
229  auto layerId = hit.layerId_;
230  auto hitEinCluster = hit.totalEnergy_ * fraction;
231  totalEnergyPerLayer[layerId] += hitEinCluster;
232  xEnergyPerLayer[layerId] += hitPos[0] * hitEinCluster;
233  yEnergyPerLayer[layerId] += hitPos[1] * hitEinCluster;
234  zPositionPerLayer[layerId] = hitPos[2];
235  }
236  Hit3DPosition centerOfGravity;
237  for (unsigned int layerId = 0; layerId < layersNum; layerId++) {
238  auto energyOnLayer = totalEnergyPerLayer[layerId];
239  if (energyOnLayer > 0.f) {
240  centerOfGravity = {{xEnergyPerLayer[layerId] / energyOnLayer,
241  yEnergyPerLayer[layerId] / energyOnLayer,
242  zPositionPerLayer[layerId]}};
243  cluster.setCenterOfGravity(layerId, centerOfGravity);
244  }
245  }
246  }
247  }
248  }
std::vector< RealisticCluster > realisticSimClusters_
double f[11][100]

◆ getDecayLength()

static float RealisticHitToClusterAssociator::getDecayLength ( unsigned int  layer,
unsigned int  fhOffset,
unsigned int  bhOffset 
)
inlinestaticprivate

Definition at line 270 of file RealisticHitToClusterAssociator.h.

References nano_mu_digi_cff::layer.

Referenced by computeAssociation().

270  {
271  constexpr float eeDecayLengthInLayer = 2.f;
272  constexpr float fhDecayLengthInLayer = 1.5f;
273  constexpr float bhDecayLengthInLayer = 1.f;
274 
275  if (layer <= fhOffset)
276  return eeDecayLengthInLayer;
277  else if (layer > fhOffset && layer <= bhOffset)
278  return fhDecayLengthInLayer;
279  else
280  return bhDecayLengthInLayer;
281  }

◆ init()

void RealisticHitToClusterAssociator::init ( std::size_t  numberOfHits,
std::size_t  numberOfSimClusters,
std::size_t  numberOfLayers 
)
inline

Definition at line 31 of file RealisticHitToClusterAssociator.h.

References phase1PixelTopology::numberOfLayers, realisticHits_, and realisticSimClusters_.

Referenced by RealisticSimClusterMapper::buildClusters().

31  {
32  realisticHits_.resize(numberOfHits);
33  realisticSimClusters_.resize(numberOfSimClusters);
34  for (auto& sc : realisticSimClusters_)
35  sc.setLayersNum(numberOfLayers);
36  }
constexpr uint32_t numberOfLayers
std::vector< RealisticCluster > realisticSimClusters_

◆ insertHitEnergy()

void RealisticHitToClusterAssociator::insertHitEnergy ( float  energy,
unsigned int  hitIndex 
)
inline

◆ insertHitPosition()

void RealisticHitToClusterAssociator::insertHitPosition ( float  x,
float  y,
float  z,
unsigned int  hitIndex 
)
inline

Definition at line 38 of file RealisticHitToClusterAssociator.h.

References realisticHits_, x, y, and z.

Referenced by RealisticSimClusterMapper::buildClusters().

38  {
39  realisticHits_[hitIndex].hitPosition_ = {{x, y, z}};
40  }

◆ insertLayerId()

void RealisticHitToClusterAssociator::insertLayerId ( unsigned int  layerId,
unsigned int  hitIndex 
)
inline

Definition at line 42 of file RealisticHitToClusterAssociator.h.

References realisticHits_.

Referenced by RealisticSimClusterMapper::buildClusters().

42 { realisticHits_[hitIndex].layerId_ = layerId; }

◆ insertSimClusterIdAndFraction()

void RealisticHitToClusterAssociator::insertSimClusterIdAndFraction ( unsigned int  scIdx,
float  fraction,
unsigned int  hitIndex,
float  associatedEnergy 
)
inline

Definition at line 46 of file RealisticHitToClusterAssociator.h.

References HLT_2023v12_cff::fraction, realisticHits_, and realisticSimClusters_.

Referenced by RealisticSimClusterMapper::buildClusters().

46  {
47  realisticHits_[hitIndex].hitToCluster_.emplace_back(RealisticHit::HitToCluster{scIdx, fraction, 0.f, 0.f});
48  realisticSimClusters_[scIdx].setMaxEnergyHit(
49  realisticHits_[hitIndex].layerId_, associatedEnergy, realisticHits_[hitIndex].hitPosition_);
50  }
std::vector< RealisticCluster > realisticSimClusters_

◆ realisticClusters()

const std::vector<RealisticCluster>& RealisticHitToClusterAssociator::realisticClusters ( ) const
inline

Definition at line 267 of file RealisticHitToClusterAssociator.h.

References realisticSimClusters_.

Referenced by RealisticSimClusterMapper::buildClusters().

267 { return realisticSimClusters_; }
std::vector< RealisticCluster > realisticSimClusters_

◆ XYdistanceFromMaxHit()

float RealisticHitToClusterAssociator::XYdistanceFromMaxHit ( unsigned int  hitId,
unsigned int  clusterId 
)
inline

Definition at line 52 of file RealisticHitToClusterAssociator.h.

References gpuClustering::clusterId, MainPageGenerator::l, conifer::pow(), realisticHits_, realisticSimClusters_, and mathSSE::sqrt().

Referenced by computeAssociation().

52  {
53  auto l = realisticHits_[hitId].layerId_;
54  const auto& maxHitPosition = realisticSimClusters_[clusterId].getMaxEnergyPosition(l);
55  float distanceSquared = std::pow((realisticHits_[hitId].hitPosition_[0] - maxHitPosition[0]), 2) +
56  std::pow((realisticHits_[hitId].hitPosition_[1] - maxHitPosition[1]), 2);
57  return std::sqrt(distanceSquared);
58  }
constexpr int pow(int x)
Definition: conifer.h:24
std::vector< RealisticCluster > realisticSimClusters_
T sqrt(T t)
Definition: SSEVec.h:19
uint16_t *__restrict__ uint16_t const *__restrict__ uint32_t const *__restrict__ uint32_t *__restrict__ uint32_t const *__restrict__ int32_t *__restrict__ clusterId

◆ XYdistanceFromPointOnSameLayer()

float RealisticHitToClusterAssociator::XYdistanceFromPointOnSameLayer ( unsigned int  hitId,
const Hit3DPosition point 
)
inline

Definition at line 60 of file RealisticHitToClusterAssociator.h.

References point, conifer::pow(), realisticHits_, and mathSSE::sqrt().

Referenced by filterHitsByDistance().

60  {
61  float distanceSquared = std::pow((realisticHits_[hitId].hitPosition_[0] - point[0]), 2) +
62  std::pow((realisticHits_[hitId].hitPosition_[1] - point[1]), 2);
63  return std::sqrt(distanceSquared);
64  }
constexpr int pow(int x)
Definition: conifer.h:24
T sqrt(T t)
Definition: SSEVec.h:19
*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

Member Data Documentation

◆ realisticHits_

std::vector<RealisticHit> RealisticHitToClusterAssociator::realisticHits_
private

◆ realisticSimClusters_

std::vector<RealisticCluster> RealisticHitToClusterAssociator::realisticSimClusters_
private