12 #include "tbb/task_arena.h" 26 std::vector<bool> firstHit(2 * (maxlayer + 1),
true);
27 for (
unsigned int i = 0;
i < hits.
size(); ++
i) {
30 unsigned int layer = rhtools_.getLayerWithOffset(detid);
31 float thickness = 0.f;
34 float sigmaNoise = 1.f;
36 thickness = rhtools_.getSiThickness(detid);
37 int thickness_index = rhtools_.getSiThickIndex(detid);
38 if (thickness_index == -1) thickness_index = 3;
39 double storedThreshold = thresholds_[layer - 1][thickness_index];
40 sigmaNoise = v_sigmaNoise_[layer - 1][thickness_index];
42 if (hgrh.
energy() < storedThreshold)
46 if (!dependSensor_ && hgrh.
energy() < ecut_)
continue;
50 layer +=
int(rhtools_.zside(detid) > 0) * (maxlayer + 1);
53 bool isHalf = rhtools_.isHalfCell(detid);
58 points_[layer].emplace_back(
Hexel(hgrh, detid, isHalf, sigmaNoise, thickness, &rhtools_),
63 if (firstHit[layer]) {
68 firstHit[layer] =
false;
83 layerClustersPerLayer_.resize(2 * maxlayer + 2);
85 tbb::this_task_arena::isolate([&] {
86 tbb::parallel_for(
size_t(0),
size_t(2 * maxlayer + 2), [&](
size_t i) {
87 KDTreeBox bounds(minpos_[i][0], maxpos_[i][0], minpos_[i][1], maxpos_[i][1]);
89 hit_kdtree.
build(points_[i], bounds);
91 unsigned int actualLayer = i > maxlayer
92 ? (i - (maxlayer + 1))
95 double maxdensity = calculateLocalDensity(points_[i], hit_kdtree,
100 calculateDistanceToHigher(points_[i]);
101 findAndAssignClusters(points_[i], hit_kdtree, maxdensity, bounds, actualLayer,
102 layerClustersPerLayer_[i]);
106 for(
auto const&
p: points_) { setDensity(
p); }
111 std::vector<std::pair<DetId, float>> thisCluster;
112 for (
const auto &clsOnLayer : layerClustersPerLayer_) {
114 for (
const auto &
cl : clsOnLayer) {
120 for (
const auto &it :
cl) {
121 energy += it.data.weight;
122 thisCluster.emplace_back(it.data.detid, 1.f);
124 if (verbosity_ < pINFO) {
126 <<
"******** NEW CLUSTER (HGCIA) ********" 128 <<
"No. of cells = " << cl.size()
129 <<
" Energy = " << energy
130 <<
" Phi = " << position.phi()
131 <<
" Eta = " << position.eta()
132 <<
"*****************************" << std::endl;
134 clusters_v_.emplace_back(energy, position, caloID, thisCluster, algoId_);
135 if (!clusters_v_.empty()) {
136 clusters_v_.back().setSeed(cl[rsmax].
data.detid);
146 float total_weight = 0.f;
150 unsigned int v_size = v.size();
151 unsigned int maxEnergyIndex = 0;
152 float maxEnergyValue = 0;
156 for (
unsigned int i = 0;
i < v_size;
i++) {
157 if (v[
i].
data.weight > maxEnergyValue) {
158 maxEnergyValue = v[
i].data.weight;
164 int thick = rhtools_.getSiThickIndex(v[maxEnergyIndex].
data.detid);
169 std::vector<unsigned int> innerIndices;
170 for (
unsigned int i = 0;
i < v_size;
i++) {
171 if (thick == -1 || distance2(v[
i].
data, v[maxEnergyIndex].data) < positionDeltaRho_c_[thick]) {
172 innerIndices.push_back(
i);
174 float rhEnergy = v[
i].data.weight;
175 total_weight += rhEnergy;
179 x += v[
i].data.x * rhEnergy;
180 y += v[
i].data.y * rhEnergy;
186 if (thick != -1 && total_weight != 0.) {
187 float total_weight_log = 0.f;
190 for (
auto idx : innerIndices) {
191 float rhEnergy = v[
idx].data.weight;
192 if (rhEnergy == 0.)
continue;
193 float Wi =
std::max(thresholdW0_[thick] +
std::log(rhEnergy / total_weight), 0.);
194 x_log += v[
idx].data.x * Wi;
195 y_log += v[
idx].data.y * Wi;
196 total_weight_log += Wi;
198 total_weight = total_weight_log;
203 if (total_weight != 0.) {
204 auto inv_tot_weight = 1. / total_weight;
205 return math::XYZPoint(x * inv_tot_weight, y * inv_tot_weight, v[maxEnergyIndex].
data.z);
211 const unsigned int layer)
const {
212 double maxdensity = 0.;
215 if (layer <= lastLayerEE)
216 delta_c = vecDeltas_[0];
217 else if (layer <= lastLayerFH)
218 delta_c = vecDeltas_[1];
220 delta_c = vecDeltas_[2];
223 for (
unsigned int i = 0;
i < nd.size(); ++
i) {
225 KDTreeBox search_box(nd[
i].dims[0] - delta_c, nd[
i].dims[0] + delta_c, nd[
i].dims[1] - delta_c,
226 nd[
i].dims[1] + delta_c);
227 std::vector<KDNode>
found;
228 lp.
search(search_box, found);
229 const unsigned int found_size = found.size();
230 for (
unsigned int j = 0; j < found_size; j++) {
232 nd[
i].data.rho += (nd[
i].data.detid == found[j].data.detid ? 1. : 0.5) * found[j].data.weight;
233 maxdensity =
std::max(maxdensity, nd[
i].data.rho);
244 double maxdensity = 0.0;
245 int nearestHigher = -1;
248 maxdensity = nd[rs[0]].
data.rho;
255 for (
const auto &j : nd) {
256 double tmp = distance2(nd[rs[0]].
data, j.data);
257 if (tmp > dist2) dist2 =
tmp;
260 nd[rs[0]].data.nearestHigher = nearestHigher;
263 const double max_dist2 = dist2;
264 const unsigned int nd_size = nd.size();
266 for (
unsigned int oi = 1; oi < nd_size; ++oi) {
268 unsigned int i = rs[oi];
273 for (
unsigned int oj = 0; oj < oi; ++oj) {
274 unsigned int j = rs[oj];
275 double tmp = distance2(nd[i].
data, nd[j].data);
283 nd[
i].data.nearestHigher = nearestHigher;
288 KDTreeBox &bounds,
const unsigned int layer,
289 std::vector<std::vector<KDNode>> &clustersOnLayer)
const {
295 unsigned int nClustersOnLayer = 0;
297 if (layer <= lastLayerEE)
298 delta_c = vecDeltas_[0];
299 else if (layer <= lastLayerFH)
300 delta_c = vecDeltas_[1];
302 delta_c = vecDeltas_[2];
305 std::vector<size_t> ds = sort_by_delta(nd);
307 const unsigned int nd_size = nd.size();
308 for (
unsigned int i = 0;
i < nd_size; ++
i) {
309 if (nd[ds[
i]].
data.delta < delta_c)
break;
311 float rho_c = kappa_ * nd[ds[
i]].data.sigmaNoise;
312 if (nd[ds[
i]].
data.rho < rho_c)
continue;
314 }
else if (nd[ds[
i]].
data.rho * kappa_ < maxdensity)
317 nd[ds[
i]].data.clusterIndex = nClustersOnLayer;
318 if (verbosity_ < pINFO) {
320 <<
"Adding new cluster with index " << nClustersOnLayer
321 <<
"Cluster center is hit " << ds[
i] << std::endl;
328 if (nClustersOnLayer == 0)
return nClustersOnLayer;
333 for (
unsigned int oi = 1; oi < nd_size; ++oi) {
334 unsigned int i = rs[oi];
335 int ci = nd[
i].data.clusterIndex;
336 if (ci == -1 && nd[i].
data.delta < 2. * delta_c) {
337 nd[
i].data.clusterIndex = nd[nd[
i].data.nearestHigher].data.clusterIndex;
344 if (verbosity_ < pINFO) {
346 <<
"resizing cluster vector by " << nClustersOnLayer << std::endl;
348 clustersOnLayer.resize(nClustersOnLayer);
351 for (
unsigned int i = 0;
i < nd_size; ++
i) {
352 int ci = nd[
i].data.clusterIndex;
354 clustersOnLayer[ci].push_back(nd[
i]);
355 if (verbosity_ < pINFO) {
357 <<
"Pushing hit " << i <<
" into cluster with index " << ci << std::endl;
363 if (verbosity_ < pINFO) {
364 LogDebug(
"HGCalCLUEAlgo") <<
"moving cluster offset by " << nClustersOnLayer << std::endl;
366 return nClustersOnLayer;
377 if (initialized_)
return;
381 std::vector<double>
dummy;
382 const unsigned maxNumberOfThickIndices = 3;
383 dummy.resize(maxNumberOfThickIndices + 1, 0);
384 thresholds_.resize(maxlayer, dummy);
385 v_sigmaNoise_.resize(maxlayer, dummy);
387 for (
unsigned ilayer = 1; ilayer <= maxlayer; ++ilayer) {
388 for (
unsigned ithick = 0; ithick < maxNumberOfThickIndices; ++ithick) {
389 float sigmaNoise = 0.001f * fcPerEle_ * nonAgedNoises_[ithick] * dEdXweights_[ilayer] /
390 (fcPerMip_[ithick] * thicknessCorrection_[ithick]);
391 thresholds_[ilayer - 1][ithick] = sigmaNoise * ecut_;
392 v_sigmaNoise_[ilayer - 1][ithick] = sigmaNoise;
394 float scintillators_sigmaNoise = 0.001f * noiseMip_ * dEdXweights_[ilayer];
395 thresholds_[ilayer - 1][maxNumberOfThickIndices] = ecut_ * scintillators_sigmaNoise;
396 v_sigmaNoise_[ilayer - 1][maxNumberOfThickIndices] = scintillators_sigmaNoise;
404 density_[
i.data.detid ] =
i.data.rho ;
constexpr float energy() const
int findAndAssignClusters(std::vector< KDNode > &, KDTree &, double, KDTreeBox &, const unsigned int, std::vector< std::vector< KDNode > > &) const
constexpr const DetId & detid() const
void makeClusters() override
double calculateDistanceToHigher(std::vector< KDNode > &) const
std::vector< reco::BasicCluster > getClusters(bool) override
Density getDensity() override
hgcal_clustering::Density Density
std::pair< double, double > calculatePosition(TVirtualPad *myPad, int boundary)
std::vector< size_t > sorted_indices(const std::vector< T > &v)
void search(const KDTreeBox &searchBox, std::vector< DATA > &resRecHitList)
void populate(const HGCRecHitCollection &hits) override
double calculateLocalDensity(std::vector< KDNode > &, KDTree &, const unsigned int) const
void build(std::vector< KDTreeNodeInfo< DATA > > &eltList, const KDTreeBox ®ion)
XYZPointD XYZPoint
point in space with cartesian internal representation
std::vector< std::vector< double > > tmp
char data[epos_bytes_allocation]
Structure Point Contains parameters of Gaussian fits to DMRs.
static int position[264][3]
size_t max_index(const std::vector< T > &v)
math::XYZPoint calculatePosition(const std::vector< KDNode > &) const
void setDensity(const std::vector< KDNode > &nd)