12 #include "oneapi/tbb/task_arena.h" 13 #include "oneapi/tbb.h" 21 numberOfClustersPerLayer_.clear();
22 cells_.resize(2 * (maxlayer_ + 1));
23 numberOfClustersPerLayer_.resize(2 * (maxlayer_ + 1), 0);
36 for (
unsigned int i = 0;
i <
hits.size(); ++
i) {
39 unsigned int layerOnSide = (rhtools_.getLayerWithOffset(detid) - 1);
43 float sigmaNoise = 1.f;
45 int thickness_index = rhtools_.getSiThickIndex(detid);
46 if (thickness_index == -1)
47 thickness_index = maxNumberOfThickIndices_;
49 double storedThreshold = thresholds_[layerOnSide][thickness_index];
51 storedThreshold = thresholds_[layerOnSide][thickness_index + deltasi_index_regemfac_];
53 sigmaNoise = v_sigmaNoise_[layerOnSide][thickness_index];
55 if (hgrh.
energy() < storedThreshold)
59 if (!dependSensor_ && hgrh.
energy() < ecut_)
62 int offset = ((rhtools_.zside(detid) + 1) >> 1) * maxlayer_;
63 int layer = layerOnSide +
offset;
65 cells_[layer].detid.emplace_back(detid);
66 cells_[layer].x.emplace_back(
position.x());
67 cells_[layer].y.emplace_back(
position.y());
68 if (!rhtools_.isOnlySilicon(layer)) {
69 cells_[layer].isSi.emplace_back(rhtools_.isSilicon(detid));
70 cells_[layer].eta.emplace_back(
position.eta());
71 cells_[layer].phi.emplace_back(
position.phi());
73 cells_[layer].weight.emplace_back(hgrh.
energy());
74 cells_[layer].sigmaNoise.emplace_back(sigmaNoise);
80 auto cellsSize = cells_[
l].detid.size();
81 cells_[
l].rho.resize(cellsSize, 0.
f);
82 cells_[
l].delta.resize(cellsSize, 9999999);
83 cells_[
l].nearestHigher.resize(cellsSize, -1);
84 cells_[
l].clusterIndex.resize(cellsSize, -1);
85 cells_[
l].followers.resize(cellsSize);
86 cells_[
l].isSeed.resize(cellsSize,
false);
87 if (rhtools_.isOnlySilicon(
l)) {
88 cells_[
l].isSi.resize(cellsSize,
true);
89 cells_[
l].eta.resize(cellsSize, 0.
f);
90 cells_[
l].phi.resize(cellsSize, 0.
f);
101 tbb::this_task_arena::isolate([&] {
102 tbb::parallel_for(
size_t(0),
size_t(2 * maxlayer_ + 2), [&](
size_t i) {
103 prepareDataStructures(
i);
106 lt.fill(cells_[
i].
x, cells_[
i].y, cells_[
i].
eta, cells_[
i].phi, cells_[
i].isSi);
109 if (
i % maxlayer_ < lastLayerEE_)
110 delta_c = vecDeltas_[0];
111 else if (
i % maxlayer_ < (firstLayerBH_ - 1))
112 delta_c = vecDeltas_[1];
114 delta_c = vecDeltas_[2];
116 LogDebug(
"HGCalCLUEAlgo") <<
"maxlayer: " << maxlayer_ <<
" lastLayerEE: " << lastLayerEE_
117 <<
" firstLayerBH: " << firstLayerBH_ <<
"\n";
119 calculateLocalDensity(lt,
i, delta_c,
delta_r);
120 calculateDistanceToHigher(lt,
i, delta_c,
delta_r);
121 numberOfClustersPerLayer_[
i] = findAndAssignClusters(
i, delta_c,
delta_r);
125 for (
unsigned int i = 0;
i < 2 * maxlayer_ + 2; ++
i) {
130 template <
typename T>
132 std::vector<int>
offsets(numberOfClustersPerLayer_.size(), 0);
134 int maxClustersOnLayer = numberOfClustersPerLayer_[0];
136 for (
unsigned layerId = 1; layerId <
offsets.size(); ++layerId) {
137 offsets[layerId] =
offsets[layerId - 1] + numberOfClustersPerLayer_[layerId - 1];
139 maxClustersOnLayer =
std::max(maxClustersOnLayer, numberOfClustersPerLayer_[layerId]);
142 auto totalNumberOfClusters =
offsets.back() + numberOfClustersPerLayer_.back();
143 clusters_v_.resize(totalNumberOfClusters);
144 std::vector<std::vector<int>> cellsIdInCluster;
145 cellsIdInCluster.reserve(maxClustersOnLayer);
147 for (
unsigned int layerId = 0; layerId < 2 * maxlayer_ + 2; ++layerId) {
148 cellsIdInCluster.resize(numberOfClustersPerLayer_[layerId]);
149 auto& cellsOnLayer = cells_[layerId];
150 unsigned int numberOfCells = cellsOnLayer.detid.size();
151 auto firstClusterIdx =
offsets[layerId];
153 for (
unsigned int i = 0;
i < numberOfCells; ++
i) {
154 auto clusterIndex = cellsOnLayer.clusterIndex[
i];
155 if (clusterIndex != -1)
156 cellsIdInCluster[clusterIndex].push_back(
i);
159 std::vector<std::pair<DetId, float>> thisCluster;
161 for (
auto&
cl : cellsIdInCluster) {
166 for (
auto cellIdx :
cl) {
167 energy += cellsOnLayer.weight[cellIdx];
168 thisCluster.emplace_back(cellsOnLayer.detid[cellIdx], 1.f);
169 if (cellsOnLayer.isSeed[cellIdx]) {
170 seedDetId = cellsOnLayer.detid[cellIdx];
173 auto globalClusterIndex = cellsOnLayer.clusterIndex[
cl[0]] + firstClusterIdx;
175 clusters_v_[globalClusterIndex] =
177 clusters_v_[globalClusterIndex].setSeed(seedDetId);
181 cellsIdInCluster.clear();
186 template <
typename T>
188 float total_weight = 0.f;
192 unsigned int maxEnergyIndex = 0;
193 float maxEnergyValue = 0.f;
195 auto& cellsOnLayer = cells_[layerId];
200 total_weight += cellsOnLayer.weight[
i];
201 if (cellsOnLayer.weight[
i] > maxEnergyValue) {
202 maxEnergyValue = cellsOnLayer.weight[
i];
208 auto thick = rhtools_.getSiThickIndex(cellsOnLayer.detid[maxEnergyIndex]);
209 bool isSiliconCell = (thick != -1);
213 float total_weight_log = 0.f;
218 if (distance2(
i, maxEnergyIndex, layerId,
false) > positionDeltaRho2_)
220 float rhEnergy = cellsOnLayer.weight[
i];
221 float Wi =
std::max(thresholdW0_[thick] +
std::log(rhEnergy / total_weight), 0.);
222 x_log += cellsOnLayer.x[
i] * Wi;
223 y_log += cellsOnLayer.y[
i] * Wi;
224 total_weight_log += Wi;
227 total_weight = total_weight_log;
232 float rhEnergy = cellsOnLayer.weight[
i];
234 x += cellsOnLayer.x[
i] * rhEnergy;
235 y += cellsOnLayer.y[
i] * rhEnergy;
238 if (total_weight != 0.) {
239 float inv_tot_weight = 1.f / total_weight;
241 x * inv_tot_weight, y * inv_tot_weight, rhtools_.getPosition(cellsOnLayer.detid[maxEnergyIndex]).z());
246 template <
typename T>
248 auto& cellsOnLayer = cells_[layerId];
249 unsigned int numberOfCells = cellsOnLayer.detid.size();
250 bool isOnlySi(
false);
251 if (rhtools_.isOnlySilicon(layerId))
254 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
255 bool isSi = isOnlySi || cellsOnLayer.isSi[
i];
257 float delta = delta_c;
258 std::array<int, 4> search_box = lt.searchBox(
261 for (
int xBin = search_box[0];
xBin < search_box[1] + 1; ++
xBin) {
262 for (
int yBin = search_box[2];
yBin < search_box[3] + 1; ++
yBin) {
263 int binId = lt.getGlobalBinByBin(
xBin,
yBin);
264 size_t binSize = lt[binId].size();
266 for (
unsigned int j = 0;
j < binSize;
j++) {
267 unsigned int otherId = lt[binId][
j];
268 bool otherSi = isOnlySi || cellsOnLayer.isSi[otherId];
271 cellsOnLayer.rho[
i] += (
i == otherId ? 1.f : 0.5f) * cellsOnLayer.weight[otherId];
279 std::array<int, 4> search_box = lt.searchBoxEtaPhi(cellsOnLayer.eta[
i] -
delta,
280 cellsOnLayer.eta[
i] +
delta,
281 cellsOnLayer.phi[
i] -
delta,
282 cellsOnLayer.phi[
i] +
delta);
283 cellsOnLayer.rho[
i] += cellsOnLayer.weight[
i];
284 float northeast(0), northwest(0), southeast(0), southwest(0),
all(0);
288 int phi = (
phiBin % T::type::nRowsPhi);
289 int binId = lt.getGlobalBinByBinEtaPhi(
etaBin, phi);
290 size_t binSize = lt[binId].size();
292 for (
unsigned int j = 0;
j < binSize;
j++) {
293 unsigned int otherId = lt[binId][
j];
294 if (!cellsOnLayer.isSi[otherId]) {
300 int dIPhi = otherIPhi - iPhi;
301 dIPhi +=
abs(dIPhi) < 2 ? 0
302 : dIPhi < 0 ? scintMaxIphi_
304 int dIEta = otherIEta -
iEta;
305 LogDebug(
"HGCalCLUEAlgo") <<
" Debugging calculateLocalDensity for Scintillator: \n" 306 <<
" cell: " << otherId <<
" energy: " << cellsOnLayer.weight[otherId]
307 <<
" otherIPhi: " << otherIPhi <<
" iPhi: " << iPhi
308 <<
" otherIEta: " << otherIEta <<
" iEta: " <<
iEta <<
"\n";
311 auto neighborCellContribution = 0.5f * cellsOnLayer.weight[otherId];
312 all += neighborCellContribution;
313 if (dIPhi >= 0 && dIEta >= 0)
314 northeast += neighborCellContribution;
315 if (dIPhi <= 0 && dIEta >= 0)
316 southeast += neighborCellContribution;
317 if (dIPhi >= 0 && dIEta <= 0)
318 northwest += neighborCellContribution;
319 if (dIPhi <= 0 && dIEta <= 0)
320 southwest += neighborCellContribution;
322 LogDebug(
"HGCalCLUEAlgo") <<
" Debugging calculateLocalDensity for Scintillator: \n" 323 <<
" northeast: " << northeast <<
" southeast: " << southeast
324 <<
" northwest: " << northwest <<
" southwest: " << southwest <<
"\n";
330 float neighborsval = (
std::max(northeast, northwest) >
std::max(southeast, southwest))
334 cellsOnLayer.rho[
i] += neighborsval;
336 cellsOnLayer.rho[
i] +=
all;
338 LogDebug(
"HGCalCLUEAlgo") <<
"Debugging calculateLocalDensity: \n" 339 <<
" cell: " <<
i <<
" isSilicon: " << cellsOnLayer.isSi[
i]
340 <<
" eta: " << cellsOnLayer.eta[
i] <<
" phi: " << cellsOnLayer.phi[
i]
341 <<
" energy: " << cellsOnLayer.weight[
i] <<
" density: " << cellsOnLayer.rho[
i] <<
"\n";
345 template <
typename T>
347 const unsigned int layerId,
350 auto& cellsOnLayer = cells_[layerId];
351 unsigned int numberOfCells = cellsOnLayer.detid.size();
352 bool isOnlySi(
false);
353 if (rhtools_.isOnlySilicon(layerId))
356 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
357 bool isSi = isOnlySi || cellsOnLayer.isSi[
i];
361 int i_nearestHigher = -1;
363 float delta = delta_c;
367 std::array<int, 4> search_box = lt.searchBox(
370 for (
int xBin = search_box[0];
xBin < search_box[1] + 1; ++
xBin) {
371 for (
int yBin = search_box[2];
yBin < search_box[3] + 1; ++
yBin) {
373 size_t binId = lt.getGlobalBinByBin(
xBin,
yBin);
375 size_t binSize = lt[binId].size();
378 for (
unsigned int j = 0;
j < binSize;
j++) {
379 unsigned int otherId = lt[binId][
j];
380 bool otherSi = isOnlySi || cellsOnLayer.isSi[otherId];
382 float dist =
distance(
i, otherId, layerId,
false);
383 bool foundHigher = (cellsOnLayer.rho[otherId] > cellsOnLayer.rho[
i]) ||
384 (cellsOnLayer.rho[otherId] == cellsOnLayer.rho[
i] &&
385 cellsOnLayer.detid[otherId] > cellsOnLayer.detid[
i]);
387 if (foundHigher && dist <= i_delta) {
391 i_nearestHigher = otherId;
398 bool foundNearestHigherInSearchBox = (i_delta !=
maxDelta);
399 if (foundNearestHigherInSearchBox) {
400 cellsOnLayer.delta[
i] = i_delta;
401 cellsOnLayer.nearestHigher[
i] = i_nearestHigher;
406 cellsOnLayer.nearestHigher[
i] = -1;
412 std::array<int, 4> search_box = lt.searchBoxEtaPhi(cellsOnLayer.eta[
i] -
range,
413 cellsOnLayer.eta[
i] +
range,
414 cellsOnLayer.phi[
i] -
range,
415 cellsOnLayer.phi[
i] +
range);
417 for (
int xBin = search_box[0];
xBin < search_box[1] + 1; ++
xBin) {
418 for (
int yBin = search_box[2];
yBin < search_box[3] + 1; ++
yBin) {
420 int phi = (
yBin % T::type::nRowsPhi);
421 size_t binId = lt.getGlobalBinByBinEtaPhi(
xBin, phi);
423 size_t binSize = lt[binId].size();
426 for (
unsigned int j = 0;
j < binSize;
j++) {
427 unsigned int otherId = lt[binId][
j];
428 if (!cellsOnLayer.isSi[otherId]) {
429 float dist =
distance(
i, otherId, layerId,
true);
430 bool foundHigher = (cellsOnLayer.rho[otherId] > cellsOnLayer.rho[
i]) ||
431 (cellsOnLayer.rho[otherId] == cellsOnLayer.rho[
i] &&
432 cellsOnLayer.detid[otherId] > cellsOnLayer.detid[
i]);
434 if (foundHigher && dist <= i_delta) {
438 i_nearestHigher = otherId;
445 bool foundNearestHigherInSearchBox = (i_delta !=
maxDelta);
446 if (foundNearestHigherInSearchBox) {
447 cellsOnLayer.delta[
i] = i_delta;
448 cellsOnLayer.nearestHigher[
i] = i_nearestHigher;
453 cellsOnLayer.nearestHigher[
i] = -1;
456 LogDebug(
"HGCalCLUEAlgo") <<
"Debugging calculateDistanceToHigher: \n" 457 <<
" cell: " <<
i <<
" isSilicon: " << cellsOnLayer.isSi[
i]
458 <<
" eta: " << cellsOnLayer.eta[
i] <<
" phi: " << cellsOnLayer.phi[
i]
459 <<
" energy: " << cellsOnLayer.weight[
i] <<
" density: " << cellsOnLayer.rho[
i]
460 <<
" nearest higher: " << cellsOnLayer.nearestHigher[
i]
461 <<
" distance: " << cellsOnLayer.delta[
i] <<
"\n";
465 template <
typename T>
471 unsigned int nClustersOnLayer = 0;
472 auto& cellsOnLayer = cells_[layerId];
473 unsigned int numberOfCells = cellsOnLayer.detid.size();
474 std::vector<int> localStack;
476 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
477 float rho_c = kappa_ * cellsOnLayer.sigmaNoise[
i];
478 bool isSi = rhtools_.isOnlySilicon(layerId) || cellsOnLayer.isSi[
i];
482 cellsOnLayer.clusterIndex[
i] = -1;
483 bool isSeed = (cellsOnLayer.delta[
i] >
delta) && (cellsOnLayer.rho[
i] >= rho_c);
484 bool isOutlier = (cellsOnLayer.delta[
i] > outlierDeltaFactor_ *
delta) && (cellsOnLayer.rho[
i] < rho_c);
486 cellsOnLayer.clusterIndex[
i] = nClustersOnLayer;
487 cellsOnLayer.isSeed[
i] =
true;
489 localStack.push_back(
i);
491 }
else if (!isOutlier) {
492 cellsOnLayer.followers[cellsOnLayer.nearestHigher[
i]].push_back(
i);
497 while (!localStack.empty()) {
498 int endStack = localStack.back();
499 auto& thisSeed = cellsOnLayer.followers[endStack];
500 localStack.pop_back();
503 for (
int j : thisSeed) {
505 cellsOnLayer.clusterIndex[
j] = cellsOnLayer.clusterIndex[endStack];
507 localStack.push_back(
j);
510 return nClustersOnLayer;
513 template <
typename T>
528 std::vector<double>
dummy;
530 dummy.resize(maxNumberOfThickIndices_ + !isNose_, 0);
531 thresholds_.resize(maxlayer_,
dummy);
532 v_sigmaNoise_.resize(maxlayer_,
dummy);
534 for (
unsigned ilayer = 1; ilayer <= maxlayer_; ++ilayer) {
535 for (
unsigned ithick = 0; ithick < maxNumberOfThickIndices_; ++ithick) {
536 float sigmaNoise = 0.001f * fcPerEle_ * nonAgedNoises_[ithick] * dEdXweights_[ilayer] /
537 (fcPerMip_[ithick] * thicknessCorrection_[ithick]);
538 thresholds_[ilayer - 1][ithick] = sigmaNoise * ecut_;
539 v_sigmaNoise_[ilayer - 1][ithick] = sigmaNoise;
540 LogDebug(
"HGCalCLUEAlgo") <<
"ilayer: " << ilayer <<
" nonAgedNoises: " << nonAgedNoises_[ithick]
541 <<
" fcPerEle: " << fcPerEle_ <<
" fcPerMip: " << fcPerMip_[ithick]
542 <<
" noiseMip: " << fcPerEle_ * nonAgedNoises_[ithick] / fcPerMip_[ithick]
543 <<
" sigmaNoise: " << sigmaNoise <<
"\n";
547 float scintillators_sigmaNoise = 0.001f * noiseMip_ * dEdXweights_[ilayer] / sciThicknessCorrection_;
548 thresholds_[ilayer - 1][maxNumberOfThickIndices_] = ecut_ * scintillators_sigmaNoise;
549 v_sigmaNoise_[ilayer - 1][maxNumberOfThickIndices_] = scintillators_sigmaNoise;
550 LogDebug(
"HGCalCLUEAlgo") <<
"ilayer: " << ilayer <<
" noiseMip: " << noiseMip_
551 <<
" scintillators_sigmaNoise: " << scintillators_sigmaNoise <<
"\n";
556 template <
typename T>
558 auto& cellsOnLayer = cells_[layerId];
559 unsigned int numberOfCells = cellsOnLayer.detid.size();
560 for (
unsigned int i = 0;
i < numberOfCells; ++
i)
561 density_[cellsOnLayer.detid[
i]] = cellsOnLayer.rho[
i];
564 template <
typename T>
constexpr const DetId & detid() const
int findAndAssignClusters(const unsigned int layerId, float delta_c, float delta_r)
Density getDensity() override
void setDensity(const unsigned int layerId)
void prepareDataStructures(const unsigned int layerId)
void populate(const HGCRecHitCollection &hits) override
constexpr Detector det() const
get the detector field from this detid
constexpr float energy() const
std::map< DetId, float > Density
void calculateDistanceToHigher(const TILE <, const unsigned int layerId, float delta_c, float delta_r)
void calculateLocalDensity(const TILE <, const unsigned int layerId, float delta_c, float delta_r)
int iphi() const
get the phi index
void getEventSetupPerAlgorithm(const edm::EventSetup &es) override
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)
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum) ...
std::vector< reco::BasicCluster > getClusters(bool) override
XYZPointD XYZPoint
point in space with cartesian internal representation
std::pair< double, double > calculatePosition(TVirtualPad *myPad, int boundary)
static int position[264][3]
void makeClusters() override
math::XYZPoint calculatePosition(const std::vector< int > &v, const unsigned int layerId) const