1 #ifndef __RecoParticleFlow_PFClusterProducer_RealisticHitToClusterAssociator_H__ 2 #define __RecoParticleFlow_PFClusterProducer_RealisticHitToClusterAssociator_H__ 10 #include <unordered_map> 16 float getDecayLength(
unsigned int layer,
unsigned int fhOffset,
unsigned int bhOffset)
18 constexpr float eeDecayLengthInLayer = 2.f;
19 constexpr float fhDecayLengthInLayer = 1.5f;
20 constexpr float bhDecayLengthInLayer = 1.f;
22 if (layer <= fhOffset)
23 return eeDecayLengthInLayer;
24 else if (layer > fhOffset && layer <= bhOffset)
25 return fhDecayLengthInLayer;
27 return bhDecayLengthInLayer;
54 void init(std::size_t numberOfHits, std::size_t numberOfSimClusters,
55 std::size_t numberOfLayers)
60 sc.setLayersNum(numberOfLayers);
79 unsigned int hitIndex,
float associatedEnergy)
103 std::vector<float> partialEnergies;
104 for(
unsigned int hitId = 0; hitId < numberOfHits; ++hitId)
106 partialEnergies.clear();
107 std::vector<unsigned int> removeAssociation;
109 unsigned int numberOfClusters = realisticHit.hitToCluster_.size();
110 if(numberOfClusters == 1)
112 unsigned int simClusterId = realisticHit.hitToCluster_[0].simClusterId_;
113 float assignedFraction = 1.f;
114 realisticHit.hitToCluster_[0].realisticEnergyFraction_ = assignedFraction;
115 float assignedEnergy = realisticHit.totalEnergy_;
122 partialEnergies.resize(numberOfClusters,0.
f);
123 unsigned int layer = realisticHit.layerId_;
125 float energyDecayLength = getDecayLength(layer, fhOffset, bhOffset);
126 for(
unsigned int clId = 0; clId < numberOfClusters; ++clId )
128 auto simClusterId = realisticHit.hitToCluster_[clId].simClusterId_;
129 realisticHit.hitToCluster_[clId].distanceFromMaxHit_ =
XYdistanceFromMaxHit(hitId,simClusterId);
133 if(maxEnergyOnLayer>0.
f)
135 partialEnergies[clId] = maxEnergyOnLayer *
std::exp(-realisticHit.hitToCluster_[clId].distanceFromMaxHit_/energyDecayLength);
137 sumE += partialEnergies[clId];
141 float invSumE = 1.f/sumE;
142 for(
unsigned int clId = 0; clId < numberOfClusters; ++clId )
144 unsigned int simClusterIndex = realisticHit.hitToCluster_[clId].simClusterId_;
145 float assignedFraction = partialEnergies[clId]*invSumE;
146 if(assignedFraction > 1
e-3)
148 realisticHit.hitToCluster_[clId].realisticEnergyFraction_ = assignedFraction;
149 float assignedEnergy = assignedFraction *realisticHit.totalEnergy_;
155 if( (useMCFractionsForExclEnergy and realisticHit.hitToCluster_[clId].mcEnergyFraction_ > exclusiveFraction)
or 156 (!useMCFractionsForExclEnergy and assignedFraction > exclusiveFraction) )
163 removeAssociation.push_back(simClusterIndex);
169 while(!removeAssociation.empty())
171 auto clusterToRemove = removeAssociation.back();
172 removeAssociation.pop_back();
174 realisticHit.hitToCluster_.erase(std::remove_if(realisticHit.hitToCluster_.begin(), realisticHit.hitToCluster_.end(), [clusterToRemove](
const RealisticHit::HitToCluster&
x)
176 return x.simClusterId_ == clusterToRemove;
177 }), realisticHit.hitToCluster_.end());
186 for(
unsigned int clId= 0; clId < numberOfRealSimClusters; ++clId)
192 std::unordered_map < unsigned int, float> energyInNeighbors;
193 float totalSharedEnergy=0.f;
195 for(
auto& elt : hAndF)
197 unsigned int hitId = elt.first;
201 if(realisticHit.hitToCluster_.size() >1 && fraction < 1.f)
204 unsigned int numberOfClusters = realisticHit.hitToCluster_.size();
205 int clusterToRemove = -1;
206 for(
unsigned int i = 0;
i< numberOfClusters; ++
i)
208 auto simClusterIndex = realisticHit.hitToCluster_[
i].simClusterId_;
209 if(simClusterIndex == clId)
216 float oldFraction = realisticHit.hitToCluster_[
i].realisticEnergyFraction_;
217 float newFraction = oldFraction/correction;
218 float oldEnergy = oldFraction*realisticHit.totalEnergy_;
219 float newEnergy= newFraction*realisticHit.totalEnergy_;
225 realisticHit.hitToCluster_[
i].realisticEnergyFraction_ = newFraction;
226 if(newFraction > exclusiveFraction)
229 if(oldFraction <=exclusiveFraction)
236 realisticSimClusters_[realisticHit.hitToCluster_[clusterToRemove].simClusterId_].modifyFractionForHitId(0.
f, hitId);
237 realisticHit.hitToCluster_.erase(realisticHit.hitToCluster_.begin()+clusterToRemove);
241 for(
auto& elt : hAndF)
243 unsigned int hitId = elt.first;
245 if(realisticHit.hitToCluster_.size()==1 and realisticHit.hitToCluster_[0].simClusterId_ == clId and totalSharedEnergy > 0.f)
247 for (
auto& pair: energyInNeighbors)
251 float sharedFraction = pair.second/totalSharedEnergy;
252 float assignedEnergy = realisticHit.totalEnergy_*sharedFraction;
256 if(sharedFraction > exclusiveFraction)
270 if(cluster.isVisible())
272 unsigned int layersNum = cluster.getLayersNum();
273 std::vector<float> totalEnergyPerLayer(layersNum, 0.
f);
274 std::vector<float> xEnergyPerLayer(layersNum, 0.
f);
275 std::vector<float> yEnergyPerLayer(layersNum, 0.
f);
276 std::vector<float> zPositionPerLayer(layersNum, 0.
f);
277 const auto& hAndF = cluster.hitsIdsAndFractions();
278 for(
auto& elt : hAndF)
280 auto hitId = elt.first;
283 const auto & hitPos =
hit.hitPosition_;
284 auto layerId =
hit.layerId_;
286 totalEnergyPerLayer[layerId]+= hitEinCluster;
287 xEnergyPerLayer[layerId] += hitPos[0]*hitEinCluster;
288 yEnergyPerLayer[layerId] += hitPos[1]*hitEinCluster;
289 zPositionPerLayer[layerId] = hitPos[2];
292 for(
unsigned int layerId=0; layerId<layersNum; layerId++)
294 auto energyOnLayer = totalEnergyPerLayer[layerId];
295 if(energyOnLayer > 0.
f)
297 centerOfGravity = {{xEnergyPerLayer[layerId]/energyOnLayer,yEnergyPerLayer[layerId]/energyOnLayer, zPositionPerLayer[layerId] }};
298 cluster.setCenterOfGravity(layerId,centerOfGravity );
309 if(cluster.isVisible())
311 auto& hAndF = cluster.hitsIdsAndFractions();
312 for(
unsigned int i = 0;
i<hAndF.size(); ++
i)
314 auto hitId = hAndF[
i].first;
316 auto layerId =
hit.layerId_;
319 cluster.increaseEnergy(-
hit.totalEnergy_*hAndF[
i].second);
320 cluster.modifyFractionByIndex(0.
f, i);
unsigned int simClusterId_
void insertLayerId(unsigned int layerId, unsigned int hitIndex)
float distanceFromMaxHit_
std::vector< RealisticHit > realisticHits_
std::array< float, 3 > Hit3DPosition
std::vector< HitToCluster > hitToCluster_
useMCFractionsForExclEnergy
void init(std::size_t numberOfHits, std::size_t numberOfSimClusters, std::size_t numberOfLayers)
void insertSimClusterIdAndFraction(unsigned int scIdx, float fraction, unsigned int hitIndex, float associatedEnergy)
void computeAssociation(float exclusiveFraction, bool useMCFractionsForExclEnergy, unsigned int fhOffset, unsigned int bhOffset)
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
void findAndMergeInvisibleClusters(float invisibleFraction, float exclusiveFraction)
void insertHitPosition(float x, float y, float z, unsigned int hitIndex)
float realisticEnergyFraction_
Hit3DPosition hitPosition_
void insertHitEnergy(float energy, unsigned int hitIndex)
const std::vector< RealisticCluster > & realisticClusters() const
void findCentersOfGravity()
std::vector< RealisticCluster > realisticSimClusters_
float XYdistanceFromMaxHit(unsigned int hitId, unsigned int clusterId)
void filterHitsByDistance(float maxDistance)
Power< A, B >::type pow(const A &a, const B &b)
float XYdistanceFromPointOnSameLayer(unsigned int hitId, const Hit3DPosition &point)
*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