12 #include "tbb/task_arena.h" 24 std::vector<bool> firstHit(2 * (
maxlayer + 1),
true);
25 for (
unsigned int i = 0;
i < hits.
size(); ++
i) {
30 float thickness = 0.f;
33 float sigmaNoise = 1.f;
37 double storedThreshold =
44 if (hgrh.
energy() < storedThreshold)
61 points[layer].emplace_back(
67 if (firstHit[layer]) {
72 firstHit[layer] =
false;
89 tbb::this_task_arena::isolate([&] {
90 tbb::parallel_for(
size_t(0),
size_t(2 *
maxlayer + 2), [&](
size_t i) {
95 unsigned int actualLayer =
101 points[i], hit_kdtree, actualLayer);
115 std::vector<std::pair<DetId, float>> thisCluster;
117 for (
unsigned int i = 0;
i < clsOnLayer.size(); ++
i) {
126 std::vector<std::vector<double>> fractions;
133 for (
unsigned isub = 0; isub < fractions.size(); ++isub) {
134 double effective_hits = 0.0;
140 for (
unsigned ihit = 0; ihit < fractions[isub].size(); ++ihit) {
141 const double fraction = fractions[isub][ihit];
142 if (fraction > 1
e-7) {
144 thisCluster.emplace_back(clsOnLayer[i][ihit].
data.detid,
150 std::cout <<
"\t******** NEW CLUSTER (SHARING) ********" 152 std::cout <<
"\tEff. No. of cells = " << effective_hits
154 std::cout <<
"\t Energy = " << energy << std::endl;
155 std::cout <<
"\t Phi = " << position.phi()
157 std::cout <<
"\t Eta = " << position.eta()
159 std::cout <<
"\t*****************************" << std::endl;
161 clusters_v.emplace_back(energy, position, caloID, thisCluster,
168 for (
auto &it : clsOnLayer[i]) {
169 energy += it.data.isHalo ? 0. : it.data.weight;
171 thisCluster.emplace_back(it.data.detid, (it.data.isHalo ? 0.f : 1.f));
174 std::cout <<
"******** NEW CLUSTER (HGCIA) ********" << std::endl;
176 std::cout <<
"No. of cells = " << clsOnLayer[
i].size() << std::endl;
177 std::cout <<
" Energy = " << energy << std::endl;
178 std::cout <<
" Phi = " << position.phi() << std::endl;
179 std::cout <<
" Eta = " << position.eta() << std::endl;
180 std::cout <<
"*****************************" << std::endl;
192 float total_weight = 0.f;
196 unsigned int v_size = v.size();
197 unsigned int maxEnergyIndex = 0;
198 float maxEnergyValue = 0;
199 bool haloOnlyCluster =
true;
204 for (
unsigned int i = 0;
i < v_size;
i++) {
205 if (!v[
i].
data.isHalo) {
206 haloOnlyCluster =
false;
207 total_weight += v[
i].data.weight;
208 x += v[
i].data.x * v[
i].data.weight;
209 y += v[
i].data.y * v[
i].data.weight;
210 z += v[
i].data.z * v[
i].data.weight;
212 if (v[i].
data.weight > maxEnergyValue) {
213 maxEnergyValue = v[
i].data.weight;
219 if (!haloOnlyCluster) {
220 if (total_weight != 0) {
221 auto inv_tot_weight = 1. / total_weight;
225 }
else if (v_size > 0) {
228 v[maxEnergyIndex].data.z);
235 const unsigned int layer)
const {
237 double maxdensity = 0.;
248 for (
unsigned int i = 0;
i < nd.size(); ++
i) {
250 KDTreeBox search_box(nd[
i].dims[0] - delta_c, nd[
i].dims[0] + delta_c,
251 nd[
i].dims[1] - delta_c, nd[
i].dims[1] + delta_c);
252 std::vector<KDNode>
found;
253 lp.
search(search_box, found);
254 const unsigned int found_size = found.size();
255 for (
unsigned int j = 0; j < found_size; j++) {
257 nd[
i].data.rho += found[j].data.weight;
258 maxdensity =
std::max(maxdensity, nd[
i].data.rho);
271 double maxdensity = 0.0;
272 int nearestHigher = -1;
275 maxdensity = nd[rs[0]].
data.rho;
288 nd[rs[0]].data.nearestHigher = nearestHigher;
291 const double max_dist2 = dist2;
292 const unsigned int nd_size = nd.size();
294 for (
unsigned int oi = 1; oi < nd_size;
297 unsigned int i = rs[oi];
302 for (
unsigned int oj = 0; oj < oi; ++oj) {
303 unsigned int j = rs[oj];
312 nd[
i].data.nearestHigher =
318 std::vector<KDNode> &nd,
KDTree &lp,
double maxdensity,
KDTreeBox &bounds,
319 const unsigned int layer,
320 std::vector<std::vector<KDNode>> &clustersOnLayer)
const {
327 unsigned int nClustersOnLayer = 0;
336 std::vector<size_t> rs =
338 std::vector<size_t> ds =
341 const unsigned int nd_size = nd.size();
342 for (
unsigned int i = 0;
i < nd_size; ++
i) {
344 if (nd[ds[
i]].
data.delta < delta_c)
348 float rho_c =
kappa * nd[ds[
i]].data.sigmaNoise;
349 if (nd[ds[
i]].
data.rho < rho_c)
352 }
else if (nd[ds[
i]].
data.rho *
kappa < maxdensity)
355 nd[ds[
i]].data.clusterIndex = nClustersOnLayer;
357 std::cout <<
"Adding new cluster with index " << nClustersOnLayer
359 std::cout <<
"Cluster center is hit " << ds[
i] << std::endl;
366 if (nClustersOnLayer == 0)
367 return nClustersOnLayer;
372 for (
unsigned int oi = 1; oi < nd_size; ++oi) {
373 unsigned int i = rs[oi];
374 int ci = nd[
i].data.clusterIndex;
377 nd[
i].data.clusterIndex = nd[nd[
i].data.nearestHigher].data.clusterIndex;
385 std::cout <<
"resizing cluster vector by " << nClustersOnLayer << std::endl;
387 clustersOnLayer.resize(nClustersOnLayer);
391 std::vector<double> rho_b(nClustersOnLayer, 0.);
393 lp.
build(nd, bounds);
396 for (
unsigned int i = 0;
i < nd_size; ++
i) {
397 int ci = nd[
i].data.clusterIndex;
398 bool flag_isolated =
true;
400 KDTreeBox search_box(nd[
i].dims[0] - delta_c, nd[
i].dims[0] + delta_c,
401 nd[
i].dims[1] - delta_c, nd[
i].dims[1] + delta_c);
402 std::vector<KDNode>
found;
403 lp.
search(search_box, found);
405 const unsigned int found_size = found.size();
406 for (
unsigned int j = 0; j < found_size;
409 if (found[j].
data.clusterIndex != -1) {
411 if (dist < delta_c && found[j].data.clusterIndex != ci) {
413 nd[
i].data.isBorder =
true;
419 if (dist < delta_c && dist != 0. &&
420 found[j].data.clusterIndex == ci) {
424 flag_isolated =
false;
429 nd[
i].data.isBorder =
434 if (nd[
i].
data.isBorder && rho_b[ci] < nd[
i].data.rho)
435 rho_b[ci] = nd[
i].data.rho;
440 for (
unsigned int i = 0;
i < nd_size; ++
i) {
441 int ci = nd[
i].data.clusterIndex;
443 if (nd[
i].
data.rho <= rho_b[ci])
444 nd[
i].data.isHalo =
true;
445 clustersOnLayer[ci].push_back(nd[
i]);
447 std::cout <<
"Pushing hit " << i <<
" into cluster with index " << ci
455 std::cout <<
"moving cluster offset by " << nClustersOnLayer << std::endl;
457 return nClustersOnLayer;
461 std::vector<unsigned>
463 std::vector<unsigned>
result;
464 std::vector<bool>
seed(cluster.size(),
true);
467 for (
unsigned i = 0;
i < cluster.size(); ++
i) {
468 for (
unsigned j = 0; j < cluster.size(); ++j) {
469 if (
i != j and
distance(cluster[
i].
data, cluster[j].data) < delta_c) {
470 if (cluster[
i].data.weight < cluster[j].data.weight) {
478 for (
unsigned i = 0;
i < cluster.size(); ++
i) {
491 const std::vector<KDNode> &
hits,
const std::vector<double> &fractions) {
492 double norm(0.0),
x(0.0),
y(0.0),
z(0.0);
493 for (
unsigned i = 0;
i < hits.size(); ++
i) {
494 const double weight = fractions[
i] * hits[
i].data.weight;
496 x += weight * hits[
i].data.x;
497 y += weight * hits[
i].data.y;
498 z += weight * hits[
i].data.z;
506 const std::vector<KDNode> &
hits,
const std::vector<double> &fractions) {
508 for (
unsigned i = 0;
i < hits.size(); ++
i) {
509 result += fractions[
i] * hits[
i].data.weight;
515 const std::vector<KDNode> &incluster,
const std::vector<unsigned> &seeds,
516 std::vector<std::vector<double>> &outclusters) {
517 std::vector<bool> isaseed(incluster.size(),
false);
519 outclusters.resize(seeds.size());
520 std::vector<Point> centroids(seeds.size());
521 std::vector<double> energies(seeds.size());
523 if (seeds.size() == 1) {
524 outclusters[0].clear();
525 outclusters[0].resize(incluster.size(), 1.0);
532 for (
unsigned i = 0;
i < seeds.size(); ++
i) {
533 isaseed[seeds[
i]] =
true;
540 for (
unsigned i = 0;
i < seeds.size(); ++
i) {
541 outclusters[
i].resize(incluster.size(), 0.0);
542 for (
unsigned j = 0; j < incluster.size(); ++j) {
544 outclusters[
i][j] = 1.0;
546 incluster[j].data.z);
547 energies[
i] = incluster[j].data.weight;
556 const unsigned iterMax = 50;
559 const auto numberOfSeeds = seeds.size();
560 auto toleranceScaling =
561 numberOfSeeds > 2 ? (numberOfSeeds - 1) * (numberOfSeeds - 1) : 1;
562 std::vector<Point> prevCentroids;
563 std::vector<double>
frac(numberOfSeeds), dist2(numberOfSeeds);
564 while (iter++ < iterMax && diff > stoppingTolerance * toleranceScaling) {
565 for (
unsigned i = 0;
i < incluster.size(); ++
i) {
566 const Hexel &ihit = incluster[
i].data;
568 for (
unsigned j = 0; j < numberOfSeeds; ++j) {
570 double d2 = (
std::pow(ihit.
x - centroids[j].x(), 2.0) +
571 std::pow(ihit.
y - centroids[j].y(), 2.0) +
572 std::pow(ihit.
z - centroids[j].z(), 2.0)) /
578 }
else if (isaseed[
i]) {
581 fraction = energies[j] *
std::exp(-0.5 * d2);
588 for (
unsigned j = 0; j < numberOfSeeds; ++j) {
589 if (fracTot > minFracTot || (
i == seeds[j] && fracTot > 0.0)) {
590 outclusters[j][
i] =
frac[j] / fracTot;
592 outclusters[j][
i] = 0.0;
600 centroids.resize(numberOfSeeds);
602 for (
unsigned i = 0;
i < numberOfSeeds; ++
i) {
606 const double delta2 = (prevCentroids[
i] - centroids[
i]).
perp2();
619 std::vector<double>
dummy;
620 const unsigned maxNumberOfThickIndices = 3;
621 dummy.resize(maxNumberOfThickIndices, 0);
625 for (
unsigned ilayer = 1; ilayer <=
maxlayer; ++ilayer) {
626 for (
unsigned ithick = 0; ithick < maxNumberOfThickIndices; ++ithick) {
638 std::vector<double> bhDummy_thresholds;
639 std::vector<double> bhDummy_sigmaNoise;
640 bhDummy_thresholds.push_back(sigmaNoise *
ecut);
641 bhDummy_sigmaNoise.push_back(sigmaNoise);
constexpr float energy() const
double calculateEnergyWithFraction(const std::vector< KDNode > &, const std::vector< double > &)
hgcal::RecHitTools rhtools_
math::XYZPoint calculatePositionWithFraction(const std::vector< KDNode > &, const std::vector< double > &)
std::vector< double > dEdXweights
reco::CaloCluster::AlgoId algoId
static const unsigned int maxlayer
double calculateLocalDensity(std::vector< KDNode > &, KDTree &, const unsigned int) const
std::vector< std::array< float, 2 > > minpos
std::vector< double > vecDeltas
std::vector< std::vector< double > > thresholds
std::vector< std::array< float, 2 > > maxpos
void build(std::vector< KDTreeNodeInfoT< DATA, DIM > > &eltList, const KDTreeBoxT< DIM > ®ion)
constexpr const DetId & detid() const
math::XYZPoint Point
point in the space
std::vector< double > thicknessCorrection
std::vector< double > nonAgedNoises
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM > > &resRecHitList)
double distance2(const Hexel &pt1, const Hexel &pt2) const
void shareEnergy(const std::vector< KDNode > &, const std::vector< unsigned > &, std::vector< std::vector< double > > &)
static const unsigned int lastLayerEE
double distance(const Hexel &pt1, const Hexel &pt2) const
static const unsigned int lastLayerFH
std::vector< size_t > sorted_indices(const std::vector< T > &v)
std::vector< reco::BasicCluster > getClusters(bool)
std::vector< unsigned > findLocalMaximaInCluster(const std::vector< KDNode > &)
std::vector< std::vector< KDNode > > points
XYZPointD XYZPoint
point in space with cartesian internal representation
T perp2() const
Squared magnitude of transverse component.
std::vector< std::vector< double > > v_sigmaNoise
std::vector< std::vector< double > > tmp
char data[epos_bytes_allocation]
double calculateDistanceToHigher(std::vector< KDNode > &) const
static int position[264][3]
math::XYZPoint calculatePosition(std::vector< KDNode > &) const
std::vector< std::vector< std::vector< KDNode > > > layerClustersPerLayer
std::vector< double > fcPerMip
void populate(const HGCRecHitCollection &hits)
std::vector< size_t > sort_by_delta(const std::vector< KDNode > &v) const
Power< A, B >::type pow(const A &a, const B &b)
std::vector< reco::BasicCluster > clusters_v
int findAndAssignClusters(std::vector< KDNode > &, KDTree &, double, KDTreeBox &, const unsigned int, std::vector< std::vector< KDNode > > &) const