12 #include "tbb/task_arena.h" 20 numberOfClustersPerLayer_.clear();
21 cells_.resize(2 * (maxlayer_ + 1));
22 numberOfClustersPerLayer_.resize(2 * (maxlayer_ + 1), 0);
34 for (
unsigned int i = 0;
i < hits.
size(); ++
i) {
37 unsigned int layerOnSide = (rhtools_.getLayerWithOffset(detid) - 1);
41 float sigmaNoise = 1.f;
43 int thickness_index = rhtools_.getSiThickIndex(detid);
44 if (thickness_index == -1)
46 double storedThreshold = thresholds_[layerOnSide][thickness_index];
47 sigmaNoise = v_sigmaNoise_[layerOnSide][thickness_index];
49 if (hgrh.
energy() < storedThreshold)
53 if (!dependSensor_ && hgrh.
energy() < ecut_)
56 int offset = ((rhtools_.zside(detid) + 1) >> 1) * maxlayer_;
57 int layer = layerOnSide +
offset;
59 cells_[layer].detid.emplace_back(detid);
60 cells_[layer].x.emplace_back(
position.x());
61 cells_[layer].y.emplace_back(
position.y());
62 if (!rhtools_.isOnlySilicon(layer)) {
63 cells_[layer].isSi.emplace_back(rhtools_.isSilicon(detid));
64 cells_[layer].eta.emplace_back(
position.eta());
65 cells_[layer].phi.emplace_back(
position.phi());
67 cells_[layer].weight.emplace_back(hgrh.
energy());
68 cells_[layer].sigmaNoise.emplace_back(sigmaNoise);
73 auto cellsSize = cells_[
l].detid.size();
74 cells_[
l].rho.resize(cellsSize, 0.
f);
75 cells_[
l].delta.resize(cellsSize, 9999999);
76 cells_[
l].nearestHigher.resize(cellsSize, -1);
77 cells_[
l].clusterIndex.resize(cellsSize, -1);
78 cells_[
l].followers.resize(cellsSize);
79 cells_[
l].isSeed.resize(cellsSize,
false);
80 if (rhtools_.isOnlySilicon(l)) {
81 cells_[
l].isSi.resize(cellsSize,
true);
82 cells_[
l].eta.resize(cellsSize, 0.
f);
83 cells_[
l].phi.resize(cellsSize, 0.
f);
93 tbb::this_task_arena::isolate([&] {
94 tbb::parallel_for(
size_t(0),
size_t(2 * maxlayer_ + 2), [&](
size_t i) {
95 prepareDataStructures(i);
98 lt.
fill(cells_[i].x, cells_[i].y, cells_[i].
eta, cells_[i].phi, cells_[i].isSi);
101 if (i % maxlayer_ < lastLayerEE_)
102 delta_c = vecDeltas_[0];
103 else if (i % maxlayer_ < (firstLayerBH_ - 1))
104 delta_c = vecDeltas_[1];
106 delta_c = vecDeltas_[2];
108 LogDebug(
"HGCalCLUEAlgo") <<
"maxlayer: " << maxlayer_ <<
" lastLayerEE: " << lastLayerEE_
109 <<
" firstLayerBH: " << firstLayerBH_ <<
"\n";
111 calculateLocalDensity(lt, i, delta_c, delta_r);
112 calculateDistanceToHigher(lt, i, delta_c, delta_r);
113 numberOfClustersPerLayer_[
i] = findAndAssignClusters(i, delta_c, delta_r);
117 for (
unsigned int i = 0;
i < 2 * maxlayer_ + 2; ++
i) {
123 std::vector<int>
offsets(numberOfClustersPerLayer_.size(), 0);
125 int maxClustersOnLayer = numberOfClustersPerLayer_[0];
127 for (
unsigned layerId = 1; layerId <
offsets.size(); ++layerId) {
128 offsets[layerId] =
offsets[layerId - 1] + numberOfClustersPerLayer_[layerId - 1];
130 maxClustersOnLayer =
std::max(maxClustersOnLayer, numberOfClustersPerLayer_[layerId]);
133 auto totalNumberOfClusters =
offsets.back() + numberOfClustersPerLayer_.back();
134 clusters_v_.resize(totalNumberOfClusters);
135 std::vector<std::vector<int>> cellsIdInCluster;
136 cellsIdInCluster.reserve(maxClustersOnLayer);
138 for (
unsigned int layerId = 0; layerId < 2 * maxlayer_ + 2; ++layerId) {
139 cellsIdInCluster.resize(numberOfClustersPerLayer_[layerId]);
140 auto& cellsOnLayer = cells_[layerId];
141 unsigned int numberOfCells = cellsOnLayer.detid.size();
142 auto firstClusterIdx =
offsets[layerId];
144 for (
unsigned int i = 0;
i < numberOfCells; ++
i) {
145 auto clusterIndex = cellsOnLayer.clusterIndex[
i];
146 if (clusterIndex != -1)
147 cellsIdInCluster[clusterIndex].push_back(
i);
150 std::vector<std::pair<DetId, float>> thisCluster;
152 for (
auto&
cl : cellsIdInCluster) {
157 for (
auto cellIdx :
cl) {
158 energy += cellsOnLayer.weight[cellIdx];
159 thisCluster.emplace_back(cellsOnLayer.detid[cellIdx], 1.f);
160 if (cellsOnLayer.isSeed[cellIdx]) {
161 seedDetId = cellsOnLayer.detid[cellIdx];
164 auto globalClusterIndex = cellsOnLayer.clusterIndex[cl[0]] + firstClusterIdx;
166 clusters_v_[globalClusterIndex] =
168 clusters_v_[globalClusterIndex].setSeed(seedDetId);
172 cellsIdInCluster.clear();
178 float total_weight = 0.f;
182 unsigned int maxEnergyIndex = 0;
183 float maxEnergyValue = 0.f;
185 auto& cellsOnLayer = cells_[layerId];
190 total_weight += cellsOnLayer.weight[
i];
191 if (cellsOnLayer.weight[
i] > maxEnergyValue) {
192 maxEnergyValue = cellsOnLayer.weight[
i];
198 auto thick = rhtools_.getSiThickIndex(cellsOnLayer.detid[maxEnergyIndex]);
199 bool isSiliconCell = (thick != -1);
203 float total_weight_log = 0.f;
207 float rhEnergy = cellsOnLayer.weight[
i];
208 float Wi =
std::max(thresholdW0_[thick] +
std::log(rhEnergy / total_weight), 0.);
209 x_log += cellsOnLayer.x[
i] * Wi;
210 y_log += cellsOnLayer.y[
i] * Wi;
211 total_weight_log += Wi;
214 total_weight = total_weight_log;
219 float rhEnergy = cellsOnLayer.weight[
i];
221 x += cellsOnLayer.x[
i] * rhEnergy;
222 y += cellsOnLayer.y[
i] * rhEnergy;
225 if (total_weight != 0.) {
226 float inv_tot_weight = 1.f / total_weight;
228 x * inv_tot_weight, y * inv_tot_weight, rhtools_.getPosition(cellsOnLayer.detid[maxEnergyIndex]).z());
234 const unsigned int layerId,
237 auto& cellsOnLayer = cells_[layerId];
238 unsigned int numberOfCells = cellsOnLayer.detid.size();
239 bool isOnlySi(
false);
240 if (rhtools_.isOnlySilicon(layerId))
243 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
244 bool isSi = isOnlySi || cellsOnLayer.isSi[
i];
246 float delta = delta_c;
247 std::array<int, 4> search_box = lt.
searchBox(
248 cellsOnLayer.x[
i] - delta, cellsOnLayer.x[
i] + delta, cellsOnLayer.y[
i] - delta, cellsOnLayer.y[
i] + delta);
250 for (
int xBin = search_box[0];
xBin < search_box[1] + 1; ++
xBin) {
251 for (
int yBin = search_box[2];
yBin < search_box[3] + 1; ++
yBin) {
253 size_t binSize = lt[binId].size();
255 for (
unsigned int j = 0;
j < binSize;
j++) {
256 unsigned int otherId = lt[binId][
j];
257 bool otherSi = isOnlySi || cellsOnLayer.isSi[otherId];
259 if (
distance(
i, otherId, layerId,
false) < delta) {
260 cellsOnLayer.rho[
i] += (
i == otherId ? 1.f : 0.5f) * cellsOnLayer.weight[otherId];
268 std::array<int, 4> search_box = lt.
searchBoxEtaPhi(cellsOnLayer.eta[
i] - delta,
269 cellsOnLayer.eta[
i] + delta,
270 cellsOnLayer.phi[
i] - delta,
271 cellsOnLayer.phi[
i] + delta);
272 cellsOnLayer.rho[
i] += cellsOnLayer.weight[
i];
273 float northeast(0), northwest(0), southeast(0), southwest(0),
all(0);
278 size_t binSize = lt[binId].size();
280 for (
unsigned int j = 0;
j < binSize;
j++) {
281 unsigned int otherId = lt[binId][
j];
282 if (!cellsOnLayer.isSi[otherId]) {
283 if (
distance(
i, otherId, layerId,
true) < delta) {
288 int dIPhi = otherIPhi - iPhi;
289 dIPhi +=
abs(dIPhi) < 2
291 : dIPhi < 0 ? scintMaxIphi_
293 int dIEta = otherIEta - iEta;
294 LogDebug(
"HGCalCLUEAlgo") <<
" Debugging calculateLocalDensity for Scintillator: \n" 295 <<
" cell: " << otherId <<
" energy: " << cellsOnLayer.weight[otherId]
296 <<
" otherIPhi: " << otherIPhi <<
" iPhi: " << iPhi
297 <<
" otherIEta: " << otherIEta <<
" iEta: " << iEta <<
"\n";
300 auto neighborCellContribution = 0.5f * cellsOnLayer.weight[otherId];
301 all += neighborCellContribution;
302 if (dIPhi >= 0 && dIEta >= 0)
303 northeast += neighborCellContribution;
304 if (dIPhi <= 0 && dIEta >= 0)
305 southeast += neighborCellContribution;
306 if (dIPhi >= 0 && dIEta <= 0)
307 northwest += neighborCellContribution;
308 if (dIPhi <= 0 && dIEta <= 0)
309 southwest += neighborCellContribution;
311 LogDebug(
"HGCalCLUEAlgo") <<
" Debugging calculateLocalDensity for Scintillator: \n" 312 <<
" northeast: " << northeast <<
" southeast: " << southeast
313 <<
" northwest: " << northwest <<
" southwest: " << southwest <<
"\n";
319 float neighborsval = (
std::max(northeast, northwest) >
std::max(southeast, southwest))
323 cellsOnLayer.rho[
i] += neighborsval;
325 cellsOnLayer.rho[
i] +=
all;
327 LogDebug(
"HGCalCLUEAlgo") <<
"Debugging calculateLocalDensity: \n" 328 <<
" cell: " <<
i <<
" isSilicon: " << cellsOnLayer.isSi[
i]
329 <<
" eta: " << cellsOnLayer.eta[
i] <<
" phi: " << cellsOnLayer.phi[
i]
330 <<
" energy: " << cellsOnLayer.weight[
i] <<
" density: " << cellsOnLayer.rho[
i] <<
"\n";
335 const unsigned int layerId,
338 auto& cellsOnLayer = cells_[layerId];
339 unsigned int numberOfCells = cellsOnLayer.detid.size();
340 bool isOnlySi(
false);
341 if (rhtools_.isOnlySilicon(layerId))
344 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
345 bool isSi = isOnlySi || cellsOnLayer.isSi[
i];
349 int i_nearestHigher = -1;
351 float delta = delta_c;
355 std::array<int, 4> search_box = lt.
searchBox(
358 for (
int xBin = search_box[0];
xBin < search_box[1] + 1; ++
xBin) {
359 for (
int yBin = search_box[2];
yBin < search_box[3] + 1; ++
yBin) {
363 size_t binSize = lt[binId].size();
366 for (
unsigned int j = 0;
j < binSize;
j++) {
367 unsigned int otherId = lt[binId][
j];
368 bool otherSi = isOnlySi || cellsOnLayer.isSi[otherId];
370 float dist =
distance(
i, otherId, layerId,
false);
371 bool foundHigher = (cellsOnLayer.rho[otherId] > cellsOnLayer.rho[
i]) ||
372 (cellsOnLayer.rho[otherId] == cellsOnLayer.rho[
i] &&
373 cellsOnLayer.detid[otherId] > cellsOnLayer.detid[
i]);
375 if (foundHigher && dist <= i_delta) {
379 i_nearestHigher = otherId;
386 bool foundNearestHigherInSearchBox = (i_delta !=
maxDelta);
387 if (foundNearestHigherInSearchBox) {
388 cellsOnLayer.delta[
i] = i_delta;
389 cellsOnLayer.nearestHigher[
i] = i_nearestHigher;
394 cellsOnLayer.nearestHigher[
i] = -1;
401 cellsOnLayer.eta[
i] +
range,
402 cellsOnLayer.phi[
i] -
range,
403 cellsOnLayer.phi[
i] +
range);
405 for (
int xBin = search_box[0];
xBin < search_box[1] + 1; ++
xBin) {
406 for (
int yBin = search_box[2];
yBin < search_box[3] + 1; ++
yBin) {
410 size_t binSize = lt[binId].size();
413 for (
unsigned int j = 0;
j < binSize;
j++) {
414 unsigned int otherId = lt[binId][
j];
415 if (!cellsOnLayer.isSi[otherId]) {
416 float dist =
distance(
i, otherId, layerId,
true);
417 bool foundHigher = (cellsOnLayer.rho[otherId] > cellsOnLayer.rho[
i]) ||
418 (cellsOnLayer.rho[otherId] == cellsOnLayer.rho[
i] &&
419 cellsOnLayer.detid[otherId] > cellsOnLayer.detid[
i]);
421 if (foundHigher && dist <= i_delta) {
425 i_nearestHigher = otherId;
432 bool foundNearestHigherInSearchBox = (i_delta !=
maxDelta);
433 if (foundNearestHigherInSearchBox) {
434 cellsOnLayer.delta[
i] = i_delta;
435 cellsOnLayer.nearestHigher[
i] = i_nearestHigher;
440 cellsOnLayer.nearestHigher[
i] = -1;
443 LogDebug(
"HGCalCLUEAlgo") <<
"Debugging calculateDistanceToHigher: \n" 444 <<
" cell: " <<
i <<
" isSilicon: " << cellsOnLayer.isSi[
i]
445 <<
" eta: " << cellsOnLayer.eta[
i] <<
" phi: " << cellsOnLayer.phi[
i]
446 <<
" energy: " << cellsOnLayer.weight[
i] <<
" density: " << cellsOnLayer.rho[
i]
447 <<
" nearest higher: " << cellsOnLayer.nearestHigher[
i]
448 <<
" distance: " << cellsOnLayer.delta[
i] <<
"\n";
457 unsigned int nClustersOnLayer = 0;
458 auto& cellsOnLayer = cells_[layerId];
459 unsigned int numberOfCells = cellsOnLayer.detid.size();
460 std::vector<int> localStack;
462 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
463 float rho_c = kappa_ * cellsOnLayer.sigmaNoise[
i];
464 bool isSi = rhtools_.isOnlySilicon(layerId) || cellsOnLayer.isSi[
i];
468 cellsOnLayer.clusterIndex[
i] = -1;
469 bool isSeed = (cellsOnLayer.delta[
i] >
delta) && (cellsOnLayer.rho[
i] >= rho_c);
470 bool isOutlier = (cellsOnLayer.delta[
i] > outlierDeltaFactor_ *
delta) && (cellsOnLayer.rho[
i] < rho_c);
472 cellsOnLayer.clusterIndex[
i] = nClustersOnLayer;
473 cellsOnLayer.isSeed[
i] =
true;
475 localStack.push_back(
i);
477 }
else if (!isOutlier) {
478 cellsOnLayer.followers[cellsOnLayer.nearestHigher[
i]].push_back(
i);
483 while (!localStack.empty()) {
484 int endStack = localStack.back();
485 auto& thisSeed = cellsOnLayer.followers[endStack];
486 localStack.pop_back();
489 for (
int j : thisSeed) {
491 cellsOnLayer.clusterIndex[
j] = cellsOnLayer.clusterIndex[endStack];
493 localStack.push_back(
j);
496 return nClustersOnLayer;
512 std::vector<double>
dummy;
513 const unsigned maxNumberOfThickIndices = 3;
514 dummy.resize(maxNumberOfThickIndices + 1, 0);
515 thresholds_.resize(maxlayer_, dummy);
516 v_sigmaNoise_.resize(maxlayer_, dummy);
518 for (
unsigned ilayer = 1; ilayer <= maxlayer_; ++ilayer) {
519 for (
unsigned ithick = 0; ithick < maxNumberOfThickIndices; ++ithick) {
520 float sigmaNoise = 0.001f * fcPerEle_ * nonAgedNoises_[ithick] * dEdXweights_[ilayer] /
521 (fcPerMip_[ithick] * thicknessCorrection_[ithick]);
522 thresholds_[ilayer - 1][ithick] = sigmaNoise * ecut_;
523 v_sigmaNoise_[ilayer - 1][ithick] = sigmaNoise;
524 LogDebug(
"HGCalCLUEAlgo") <<
"ilayer: " << ilayer <<
" nonAgedNoises: " << nonAgedNoises_[ithick]
525 <<
" fcPerEle: " << fcPerEle_ <<
" fcPerMip: " << fcPerMip_[ithick]
526 <<
" noiseMip: " << fcPerEle_ * nonAgedNoises_[ithick] / fcPerMip_[ithick]
527 <<
" sigmaNoise: " << sigmaNoise <<
"\n";
529 float scintillators_sigmaNoise = 0.001f * noiseMip_ * dEdXweights_[ilayer];
530 thresholds_[ilayer - 1][maxNumberOfThickIndices] = ecut_ * scintillators_sigmaNoise;
531 v_sigmaNoise_[ilayer - 1][maxNumberOfThickIndices] = scintillators_sigmaNoise;
532 LogDebug(
"HGCalCLUEAlgo") <<
"ilayer: " << ilayer <<
" noiseMip: " << noiseMip_
533 <<
" scintillators_sigmaNoise: " << scintillators_sigmaNoise <<
"\n";
538 auto& cellsOnLayer = cells_[layerId];
539 unsigned int numberOfCells = cellsOnLayer.detid.size();
540 for (
unsigned int i = 0;
i < numberOfCells; ++
i)
541 density_[cellsOnLayer.detid[
i]] = cellsOnLayer.rho[
i];
constexpr float energy() const
constexpr const DetId & detid() const
void prepareDataStructures(const unsigned int layerId)
int getGlobalBinByBinEtaPhi(int etaBin, int phiBin) const
void makeClusters() override
void setDensity(const unsigned int layerId)
std::array< int, 4 > searchBox(float xMin, float xMax, float yMin, float yMax) const
std::vector< reco::BasicCluster > getClusters(bool) override
void fill(const std::vector< float > &x, const std::vector< float > &y, const std::vector< float > &eta, const std::vector< float > &phi, const std::vector< bool > &isSi)
Density getDensity() override
int getGlobalBinByBin(int xBin, int yBin) const
void calculateDistanceToHigher(const HGCalLayerTiles <, const unsigned int layerId, float delta_c, float delta_r)
math::XYZPoint calculatePosition(const std::vector< int > &v, const unsigned int layerId) const
hgcal_clustering::Density Density
double delta_r(const Fourvec &a, const Fourvec &b)
Find the distance between two four-vectors in the two-dimensional space .
Abs< T >::type abs(const T &t)
int iphi() const
get the phi index
std::array< int, 4 > searchBoxEtaPhi(float etaMin, float etaMax, float phiMin, float phiMax) const
void populate(const HGCRecHitCollection &hits) override
XYZPointD XYZPoint
point in space with cartesian internal representation
std::pair< double, double > calculatePosition(TVirtualPad *myPad, int boundary)
int findAndAssignClusters(const unsigned int layerId, float delta_c, float delta_r)
static int position[264][3]
void getEventSetupPerAlgorithm(const edm::EventSetup &es) override
void calculateLocalDensity(const HGCalLayerTiles <, const unsigned int layerId, float delta_c, float delta_r)