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 if (thickness_index == -1)
39 double storedThreshold =
thresholds_[layer - 1][thickness_index];
42 if (hgrh.
energy() < storedThreshold)
65 if (firstHit[layer]) {
70 firstHit[layer] =
false;
87 tbb::this_task_arena::isolate([&] {
88 tbb::parallel_for(
size_t(0),
size_t(2 *
maxlayer + 2), [&](
size_t i) {
93 unsigned int actualLayer =
99 points_[i], hit_kdtree, actualLayer);
113 std::vector<std::pair<DetId, float>> thisCluster;
115 for (
unsigned int i = 0;
i < clsOnLayer.size(); ++
i) {
124 std::vector<std::vector<double>> fractions;
131 for (
unsigned isub = 0; isub < fractions.size(); ++isub) {
132 double effective_hits = 0.0;
138 for (
unsigned ihit = 0; ihit < fractions[isub].size(); ++ihit) {
139 const double fraction = fractions[isub][ihit];
140 if (fraction > 1
e-7) {
142 thisCluster.emplace_back(clsOnLayer[i][ihit].
data.detid,
148 std::cout <<
"\t******** NEW CLUSTER (SHARING) ********" 150 std::cout <<
"\tEff. No. of cells = " << effective_hits
152 std::cout <<
"\t Energy = " << energy << std::endl;
153 std::cout <<
"\t Phi = " << position.phi()
155 std::cout <<
"\t Eta = " << position.eta()
157 std::cout <<
"\t*****************************" << std::endl;
159 clusters_v_.emplace_back(energy, position, caloID, thisCluster,
166 for (
auto &it : clsOnLayer[i]) {
167 energy += it.data.isHalo ? 0. : it.data.weight;
169 thisCluster.emplace_back(it.data.detid, (it.data.isHalo ? 0.f : 1.f));
172 std::cout <<
"******** NEW CLUSTER (HGCIA) ********" << std::endl;
174 std::cout <<
"No. of cells = " << clsOnLayer[
i].size() << std::endl;
175 std::cout <<
" Energy = " << energy << std::endl;
176 std::cout <<
" Phi = " << position.phi() << std::endl;
177 std::cout <<
" Eta = " << position.eta() << std::endl;
178 std::cout <<
"*****************************" << std::endl;
190 float total_weight = 0.f;
194 unsigned int v_size = v.size();
195 unsigned int maxEnergyIndex = 0;
196 float maxEnergyValue = 0;
197 bool haloOnlyCluster =
true;
202 for (
unsigned int i = 0;
i < v_size;
i++) {
203 if (!v[
i].
data.isHalo) {
204 haloOnlyCluster =
false;
205 total_weight += v[
i].data.weight;
206 x += v[
i].data.x * v[
i].data.weight;
207 y += v[
i].data.y * v[
i].data.weight;
208 z += v[
i].data.z * v[
i].data.weight;
210 if (v[i].
data.weight > maxEnergyValue) {
211 maxEnergyValue = v[
i].data.weight;
217 if (!haloOnlyCluster) {
218 if (total_weight != 0) {
219 auto inv_tot_weight = 1. / total_weight;
223 }
else if (v_size > 0) {
226 v[maxEnergyIndex].data.z);
233 const unsigned int layer)
const {
235 double maxdensity = 0.;
246 for (
unsigned int i = 0;
i < nd.size(); ++
i) {
248 KDTreeBox search_box(nd[
i].dims[0] - delta_c, nd[
i].dims[0] + delta_c,
249 nd[
i].dims[1] - delta_c, nd[
i].dims[1] + delta_c);
250 std::vector<KDNode>
found;
251 lp.
search(search_box, found);
252 const unsigned int found_size = found.size();
253 for (
unsigned int j = 0; j < found_size; j++) {
255 nd[
i].data.rho += found[j].data.weight;
256 maxdensity =
std::max(maxdensity, nd[
i].data.rho);
269 double maxdensity = 0.0;
270 int nearestHigher = -1;
273 maxdensity = nd[rs[0]].
data.rho;
286 nd[rs[0]].data.nearestHigher = nearestHigher;
289 const double max_dist2 = dist2;
290 const unsigned int nd_size = nd.size();
292 for (
unsigned int oi = 1; oi < nd_size;
295 unsigned int i = rs[oi];
300 for (
unsigned int oj = 0; oj < oi; ++oj) {
301 unsigned int j = rs[oj];
310 nd[
i].data.nearestHigher =
316 std::vector<KDNode> &nd,
KDTree &lp,
double maxdensity,
KDTreeBox &bounds,
317 const unsigned int layer,
318 std::vector<std::vector<KDNode>> &clustersOnLayer)
const {
325 unsigned int nClustersOnLayer = 0;
334 std::vector<size_t> rs =
336 std::vector<size_t> ds =
339 const unsigned int nd_size = nd.size();
340 for (
unsigned int i = 0;
i < nd_size; ++
i) {
342 if (nd[ds[
i]].
data.delta < delta_c)
346 float rho_c =
kappa_ * nd[ds[
i]].data.sigmaNoise;
347 if (nd[ds[
i]].
data.rho < rho_c)
350 }
else if (nd[ds[
i]].
data.rho *
kappa_ < maxdensity)
353 nd[ds[
i]].data.clusterIndex = nClustersOnLayer;
355 std::cout <<
"Adding new cluster with index " << nClustersOnLayer
357 std::cout <<
"Cluster center is hit " << ds[
i] << std::endl;
364 if (nClustersOnLayer == 0)
365 return nClustersOnLayer;
370 for (
unsigned int oi = 1; oi < nd_size; ++oi) {
371 unsigned int i = rs[oi];
372 int ci = nd[
i].data.clusterIndex;
375 nd[
i].data.clusterIndex = nd[nd[
i].data.nearestHigher].data.clusterIndex;
383 std::cout <<
"resizing cluster vector by " << nClustersOnLayer << std::endl;
385 clustersOnLayer.resize(nClustersOnLayer);
389 std::vector<double> rho_b(nClustersOnLayer, 0.);
391 lp.
build(nd, bounds);
394 for (
unsigned int i = 0;
i < nd_size; ++
i) {
395 int ci = nd[
i].data.clusterIndex;
396 bool flag_isolated =
true;
398 KDTreeBox search_box(nd[
i].dims[0] - delta_c, nd[
i].dims[0] + delta_c,
399 nd[
i].dims[1] - delta_c, nd[
i].dims[1] + delta_c);
400 std::vector<KDNode>
found;
401 lp.
search(search_box, found);
403 const unsigned int found_size = found.size();
404 for (
unsigned int j = 0; j < found_size;
407 if (found[j].
data.clusterIndex != -1) {
409 if (dist < delta_c && found[j].data.clusterIndex != ci) {
411 nd[
i].data.isBorder =
true;
417 if (dist < delta_c && dist != 0. &&
418 found[j].data.clusterIndex == ci) {
422 flag_isolated =
false;
427 nd[
i].data.isBorder =
432 if (nd[
i].
data.isBorder && rho_b[ci] < nd[
i].data.rho)
433 rho_b[ci] = nd[
i].data.rho;
438 for (
unsigned int i = 0;
i < nd_size; ++
i) {
439 int ci = nd[
i].data.clusterIndex;
441 if (nd[
i].
data.rho <= rho_b[ci])
442 nd[
i].data.isHalo =
true;
443 clustersOnLayer[ci].push_back(nd[
i]);
445 std::cout <<
"Pushing hit " << i <<
" into cluster with index " << ci
453 std::cout <<
"moving cluster offset by " << nClustersOnLayer << std::endl;
455 return nClustersOnLayer;
459 std::vector<unsigned>
461 std::vector<unsigned>
result;
462 std::vector<bool>
seed(cluster.size(),
true);
465 for (
unsigned i = 0;
i < cluster.size(); ++
i) {
466 for (
unsigned j = 0; j < cluster.size(); ++j) {
467 if (
i != j and
distance(cluster[
i].
data, cluster[j].data) < delta_c) {
468 if (cluster[
i].data.weight < cluster[j].data.weight) {
476 for (
unsigned i = 0;
i < cluster.size(); ++
i) {
489 const std::vector<KDNode> &
hits,
const std::vector<double> &fractions) {
490 double norm(0.0),
x(0.0),
y(0.0),
z(0.0);
491 for (
unsigned i = 0;
i < hits.size(); ++
i) {
492 const double weight = fractions[
i] * hits[
i].data.weight;
494 x += weight * hits[
i].data.x;
495 y += weight * hits[
i].data.y;
496 z += weight * hits[
i].data.z;
504 const std::vector<KDNode> &
hits,
const std::vector<double> &fractions) {
506 for (
unsigned i = 0;
i < hits.size(); ++
i) {
507 result += fractions[
i] * hits[
i].data.weight;
513 const std::vector<KDNode> &incluster,
const std::vector<unsigned> &seeds,
514 std::vector<std::vector<double>> &outclusters) {
515 std::vector<bool> isaseed(incluster.size(),
false);
517 outclusters.resize(seeds.size());
518 std::vector<Point> centroids(seeds.size());
519 std::vector<double> energies(seeds.size());
521 if (seeds.size() == 1) {
522 outclusters[0].clear();
523 outclusters[0].resize(incluster.size(), 1.0);
530 for (
unsigned i = 0;
i < seeds.size(); ++
i) {
531 isaseed[seeds[
i]] =
true;
538 for (
unsigned i = 0;
i < seeds.size(); ++
i) {
539 outclusters[
i].resize(incluster.size(), 0.0);
540 for (
unsigned j = 0; j < incluster.size(); ++j) {
542 outclusters[
i][j] = 1.0;
544 incluster[j].data.z);
545 energies[
i] = incluster[j].data.weight;
554 const unsigned iterMax = 50;
557 const auto numberOfSeeds = seeds.size();
558 auto toleranceScaling =
559 numberOfSeeds > 2 ? (numberOfSeeds - 1) * (numberOfSeeds - 1) : 1;
560 std::vector<Point> prevCentroids;
561 std::vector<double>
frac(numberOfSeeds), dist2(numberOfSeeds);
562 while (iter++ < iterMax && diff > stoppingTolerance * toleranceScaling) {
563 for (
unsigned i = 0;
i < incluster.size(); ++
i) {
564 const Hexel &ihit = incluster[
i].data;
566 for (
unsigned j = 0; j < numberOfSeeds; ++j) {
568 double d2 = (
std::pow(ihit.
x - centroids[j].x(), 2.0) +
569 std::pow(ihit.
y - centroids[j].y(), 2.0) +
570 std::pow(ihit.
z - centroids[j].z(), 2.0)) /
576 }
else if (isaseed[
i]) {
579 fraction = energies[j] *
std::exp(-0.5 * d2);
586 for (
unsigned j = 0; j < numberOfSeeds; ++j) {
587 if (fracTot > minFracTot || (
i == seeds[j] && fracTot > 0.0)) {
588 outclusters[j][
i] =
frac[j] / fracTot;
590 outclusters[j][
i] = 0.0;
598 centroids.resize(numberOfSeeds);
600 for (
unsigned i = 0;
i < numberOfSeeds; ++
i) {
604 const double delta2 = (prevCentroids[
i] - centroids[
i]).
perp2();
625 std::vector<double>
dummy;
626 const unsigned maxNumberOfThickIndices = 3;
627 dummy.resize(maxNumberOfThickIndices + 1, 0);
631 for (
unsigned ilayer = 1; ilayer <=
maxlayer; ++ilayer) {
632 for (
unsigned ithick = 0; ithick < maxNumberOfThickIndices; ++ithick) {
640 thresholds_[ilayer - 1][maxNumberOfThickIndices] =
ecut_ * scintillators_sigmaNoise;
641 v_sigmaNoise_[ilayer -1][maxNumberOfThickIndices] = scintillators_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 > &)
static const unsigned int maxlayer
double calculateLocalDensity(std::vector< KDNode > &, KDTree &, const unsigned int) const
std::vector< std::vector< double > > thresholds_
void build(std::vector< KDTreeNodeInfoT< DATA, DIM > > &eltList, const KDTreeBoxT< DIM > ®ion)
constexpr const DetId & detid() const
std::vector< std::vector< double > > v_sigmaNoise_
math::XYZPoint Point
point in the space
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< reco::BasicCluster > clusters_v_
reco::CaloCluster::AlgoId algoId_
std::vector< std::vector< KDNode > > points_
std::vector< double > vecDeltas_
std::vector< double > dEdXweights_
std::vector< size_t > sorted_indices(const std::vector< T > &v)
std::vector< std::vector< std::vector< KDNode > > > layerClustersPerLayer_
std::vector< reco::BasicCluster > getClusters(bool)
std::vector< unsigned > findLocalMaximaInCluster(const std::vector< KDNode > &)
std::vector< std::array< float, 2 > > minpos_
std::vector< double > thicknessCorrection_
XYZPointD XYZPoint
point in space with cartesian internal representation
T perp2() const
Squared magnitude of transverse component.
std::vector< double > fcPerMip_
std::vector< double > nonAgedNoises_
std::vector< std::vector< double > > tmp
char data[epos_bytes_allocation]
double calculateDistanceToHigher(std::vector< KDNode > &) const
static int position[264][3]
VerbosityLevel verbosity_
math::XYZPoint calculatePosition(std::vector< KDNode > &) const
std::vector< std::array< float, 2 > > maxpos_
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)
int findAndAssignClusters(std::vector< KDNode > &, KDTree &, double, KDTreeBox &, const unsigned int, std::vector< std::vector< KDNode > > &) const