12 #include "oneapi/tbb/task_arena.h" 13 #include "oneapi/tbb.h" 19 template <
typename T,
typename STRATEGY>
22 numberOfClustersPerLayer_.clear();
23 cells_.resize(2 * (maxlayer_ + 1));
24 numberOfClustersPerLayer_.resize(2 * (maxlayer_ + 1), 0);
27 template <
typename T,
typename STRATEGY>
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;
66 cells_[layer].layerDim3 =
position.z();
68 cells_[layer].detid.emplace_back(detid);
69 if constexpr (std::is_same_v<STRATEGY, HGCalScintillatorStrategy>) {
70 cells_[layer].dim1.emplace_back(
position.eta());
71 cells_[layer].dim2.emplace_back(
position.phi());
74 cells_[layer].dim1.emplace_back(
position.x());
75 cells_[layer].dim2.emplace_back(
position.y());
77 cells_[layer].weight.emplace_back(hgrh.
energy());
78 cells_[layer].sigmaNoise.emplace_back(sigmaNoise);
82 template <
typename T,
typename STRATEGY>
84 auto cellsSize = cells_[
l].detid.size();
85 cells_[
l].rho.resize(cellsSize, 0.
f);
86 cells_[
l].delta.resize(cellsSize, 9999999);
87 cells_[
l].nearestHigher.resize(cellsSize, -1);
88 cells_[
l].clusterIndex.resize(cellsSize, -1);
89 cells_[
l].followers.resize(cellsSize);
90 cells_[
l].isSeed.resize(cellsSize,
false);
97 template <
typename T,
typename STRATEGY>
100 tbb::this_task_arena::isolate([&] {
101 tbb::parallel_for(
size_t(0),
size_t(2 * maxlayer_ + 2), [&](
size_t i) {
102 prepareDataStructures(
i);
105 lt.fill(cells_[
i].dim1, cells_[
i].dim2);
108 if constexpr (std::is_same_v<STRATEGY, HGCalSiliconStrategy>) {
111 if (
i % maxlayer_ < lastLayerEE_)
112 delta_c = vecDeltas_[0];
113 else if (
i % maxlayer_ < (firstLayerBH_ - 1))
114 delta_c = vecDeltas_[1];
116 delta_c = vecDeltas_[2];
122 LogDebug(
"HGCalCLUEAlgo") <<
"maxlayer: " << maxlayer_ <<
" lastLayerEE: " << lastLayerEE_
123 <<
" firstLayerBH: " << firstLayerBH_ <<
"\n";
125 calculateLocalDensity(lt,
i,
delta);
126 calculateDistanceToHigher(lt,
i,
delta);
127 numberOfClustersPerLayer_[
i] = findAndAssignClusters(
i,
delta);
130 #if DEBUG_CLUSTERS_ALPAKA 132 dumperLegacySoA.
dumpInfos(cells_, moduleType_);
136 template <
typename T,
typename STRATEGY>
138 std::vector<int>
offsets(numberOfClustersPerLayer_.size(), 0);
140 int maxClustersOnLayer = numberOfClustersPerLayer_[0];
142 for (
unsigned layerId = 1; layerId <
offsets.size(); ++layerId) {
143 offsets[layerId] =
offsets[layerId - 1] + numberOfClustersPerLayer_[layerId - 1];
145 maxClustersOnLayer =
std::max(maxClustersOnLayer, numberOfClustersPerLayer_[layerId]);
148 auto totalNumberOfClusters =
offsets.back() + numberOfClustersPerLayer_.back();
149 clusters_v_.resize(totalNumberOfClusters);
150 std::vector<std::vector<int>> cellsIdInCluster;
151 cellsIdInCluster.reserve(maxClustersOnLayer);
153 for (
unsigned int layerId = 0; layerId < 2 * maxlayer_ + 2; ++layerId) {
154 cellsIdInCluster.resize(numberOfClustersPerLayer_[layerId]);
155 auto& cellsOnLayer = cells_[layerId];
156 unsigned int numberOfCells = cellsOnLayer.detid.size();
157 auto firstClusterIdx =
offsets[layerId];
159 for (
unsigned int i = 0;
i < numberOfCells; ++
i) {
160 auto clusterIndex = cellsOnLayer.clusterIndex[
i];
161 if (clusterIndex != -1)
162 cellsIdInCluster[clusterIndex].push_back(
i);
165 std::vector<std::pair<DetId, float>> thisCluster;
167 for (
auto&
cl : cellsIdInCluster) {
169 int maxEnergyCellIndex = -1;
170 DetId maxEnergyDetId;
175 float z = cellsOnLayer.layerDim3;
177 for (
auto cellIdx :
cl) {
178 energy += cellsOnLayer.weight[cellIdx];
179 if (cellsOnLayer.weight[cellIdx] > maxEnergyValue) {
180 maxEnergyValue = cellsOnLayer.weight[cellIdx];
181 maxEnergyCellIndex = cellIdx;
182 maxEnergyDetId = cellsOnLayer.detid[cellIdx];
184 thisCluster.emplace_back(cellsOnLayer.detid[cellIdx], 1.f);
185 if (cellsOnLayer.isSeed[cellIdx]) {
186 seedDetId = cellsOnLayer.detid[cellIdx];
190 float total_weight_log = 0.f;
191 float total_weight =
energy;
193 if constexpr (std::is_same_v<STRATEGY, HGCalSiliconStrategy>) {
194 auto thick = rhtools_.getSiThickIndex(maxEnergyDetId);
195 for (
auto cellIdx :
cl) {
196 const float d1 = cellsOnLayer.dim1[cellIdx] - cellsOnLayer.dim1[maxEnergyCellIndex];
197 const float d2 = cellsOnLayer.dim2[cellIdx] - cellsOnLayer.dim2[maxEnergyCellIndex];
198 if ((
d1 *
d1 + d2 * d2) < positionDeltaRho2_) {
200 x += cellsOnLayer.dim1[cellIdx] * Wi;
201 y += cellsOnLayer.dim2[cellIdx] * Wi;
202 total_weight_log += Wi;
206 for (
auto cellIdx :
cl) {
207 auto position = rhtools_.getPosition(cellsOnLayer.detid[cellIdx]);
208 x +=
position.x() * cellsOnLayer.weight[cellIdx];
209 y +=
position.y() * cellsOnLayer.weight[cellIdx];
213 if constexpr (std::is_same_v<STRATEGY, HGCalSiliconStrategy>) {
214 total_weight = total_weight_log;
217 if (total_weight != 0.) {
218 float inv_tot_weight = 1.f / total_weight;
222 x = cellsOnLayer.dim1[maxEnergyCellIndex];
223 y = cellsOnLayer.dim2[maxEnergyCellIndex];
227 auto globalClusterIndex = cellsOnLayer.clusterIndex[
cl[0]] + firstClusterIdx;
229 clusters_v_[globalClusterIndex] =
231 clusters_v_[globalClusterIndex].setSeed(seedDetId);
235 cellsIdInCluster.clear();
239 template <
typename T,
typename STRATEGY>
241 const unsigned int layerId,
244 auto& cellsOnLayer = cells_[layerId];
245 unsigned int numberOfCells = cellsOnLayer.detid.size();
246 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
247 std::array<int, 4> search_box = lt.searchBox(cellsOnLayer.dim1[
i] -
delta,
248 cellsOnLayer.dim1[
i] +
delta,
249 cellsOnLayer.dim2[
i] -
delta,
250 cellsOnLayer.dim2[
i] +
delta);
252 for (
int xBin = search_box[0];
xBin < search_box[1] + 1; ++
xBin) {
253 for (
int yBin = search_box[2];
yBin < search_box[3] + 1; ++
yBin) {
254 int binId = lt.getGlobalBinByBin(
xBin,
yBin);
255 size_t binSize = lt[binId].size();
257 for (
unsigned int j = 0;
j < binSize;
j++) {
258 unsigned int otherId = lt[binId][
j];
260 cellsOnLayer.rho[
i] += (
i == otherId ? 1.f : 0.5f) * cellsOnLayer.weight[otherId];
265 LogDebug(
"HGCalCLUEAlgo") <<
"Debugging calculateLocalDensity: \n" 266 <<
" cell: " <<
i <<
" eta: " << cellsOnLayer.dim1[
i] <<
" phi: " << cellsOnLayer.dim2[
i]
267 <<
" energy: " << cellsOnLayer.weight[
i] <<
" density: " << cellsOnLayer.rho[
i] <<
"\n";
270 template <
typename T,
typename STRATEGY>
272 const unsigned int layerId,
275 auto& cellsOnLayer = cells_[layerId];
276 unsigned int numberOfCells = cellsOnLayer.detid.size();
277 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
278 std::array<int, 4> search_box = lt.searchBox(cellsOnLayer.dim1[
i] -
delta,
279 cellsOnLayer.dim1[
i] +
delta,
280 cellsOnLayer.dim2[
i] -
delta,
281 cellsOnLayer.dim2[
i] +
delta);
282 cellsOnLayer.rho[
i] += cellsOnLayer.weight[
i];
283 float northeast(0), northwest(0), southeast(0), southwest(0),
all(0);
287 int binId = lt.getGlobalBinByBin(
etaBin, phi);
288 size_t binSize = lt[binId].size();
289 for (
unsigned int j = 0;
j < binSize;
j++) {
290 unsigned int otherId = lt[binId][
j];
296 int dIPhi = otherIPhi - iPhi;
297 dIPhi +=
abs(dIPhi) < 2 ? 0
298 : dIPhi < 0 ? scintMaxIphi_
300 int dIEta = otherIEta -
iEta;
301 LogDebug(
"HGCalCLUEAlgo") <<
" Debugging calculateLocalDensity for Scintillator: \n" 302 <<
" cell: " << otherId <<
" energy: " << cellsOnLayer.weight[otherId]
303 <<
" otherIPhi: " << otherIPhi <<
" iPhi: " << iPhi <<
" otherIEta: " << otherIEta
304 <<
" iEta: " <<
iEta <<
"\n";
307 auto neighborCellContribution = 0.5f * cellsOnLayer.weight[otherId];
308 all += neighborCellContribution;
309 if (dIPhi >= 0 && dIEta >= 0)
310 northeast += neighborCellContribution;
311 if (dIPhi <= 0 && dIEta >= 0)
312 southeast += neighborCellContribution;
313 if (dIPhi >= 0 && dIEta <= 0)
314 northwest += neighborCellContribution;
315 if (dIPhi <= 0 && dIEta <= 0)
316 southwest += neighborCellContribution;
318 LogDebug(
"HGCalCLUEAlgo") <<
" Debugging calculateLocalDensity for Scintillator: \n" 319 <<
" northeast: " << northeast <<
" southeast: " << southeast
320 <<
" northwest: " << northwest <<
" southwest: " << southwest <<
"\n";
325 float neighborsval = (
std::max(northeast, northwest) >
std::max(southeast, southwest))
329 cellsOnLayer.rho[
i] += neighborsval;
331 cellsOnLayer.rho[
i] +=
all;
332 LogDebug(
"HGCalCLUEAlgo") <<
"Debugging calculateLocalDensity: \n" 333 <<
" cell: " <<
i <<
" eta: " << cellsOnLayer.dim1[
i] <<
" phi: " << cellsOnLayer.dim2[
i]
334 <<
" energy: " << cellsOnLayer.weight[
i] <<
" density: " << cellsOnLayer.rho[
i] <<
"\n";
337 template <
typename T,
typename STRATEGY>
339 if constexpr (std::is_same_v<STRATEGY, HGCalSiliconStrategy>) {
346 template <
typename T,
typename STRATEGY>
348 auto& cellsOnLayer = cells_[layerId];
349 unsigned int numberOfCells = cellsOnLayer.detid.size();
351 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
355 int i_nearestHigher = -1;
358 std::array<int, 4> search_box = lt.searchBox(cellsOnLayer.dim1[
i] -
range,
359 cellsOnLayer.dim1[
i] +
range,
360 cellsOnLayer.dim2[
i] -
range,
361 cellsOnLayer.dim2[
i] +
range);
363 for (
int dim1Bin = search_box[0]; dim1Bin < search_box[1] + 1; ++dim1Bin) {
364 for (
int dim2Bin = search_box[2]; dim2Bin < search_box[3] + 1; ++dim2Bin) {
366 size_t binId = lt.getGlobalBinByBin(dim1Bin, dim2Bin);
367 if constexpr (std::is_same_v<STRATEGY, HGCalScintillatorStrategy>)
368 binId = lt.getGlobalBinByBin(dim1Bin, (dim2Bin % T::type::nRows));
370 size_t binSize = lt[binId].size();
373 for (
unsigned int j = 0;
j < binSize;
j++) {
374 unsigned int otherId = lt[binId][
j];
375 float dist = distance2(lt,
i, otherId, layerId);
377 (cellsOnLayer.rho[otherId] > cellsOnLayer.rho[
i]) ||
378 (cellsOnLayer.rho[otherId] == cellsOnLayer.rho[
i] && cellsOnLayer.detid[otherId] > cellsOnLayer.detid[
i]);
382 if ((dist < i_delta) || ((dist == i_delta) && (cellsOnLayer.rho[otherId] > rho_max)) ||
383 ((dist == i_delta) && (cellsOnLayer.rho[otherId] == rho_max) &&
384 (cellsOnLayer.detid[otherId] > cellsOnLayer.detid[
i]))) {
385 rho_max = cellsOnLayer.rho[otherId];
387 i_nearestHigher = otherId;
392 bool foundNearestHigherInSearchBox = (i_delta !=
maxDelta);
393 if (foundNearestHigherInSearchBox) {
395 cellsOnLayer.nearestHigher[
i] = i_nearestHigher;
400 cellsOnLayer.nearestHigher[
i] = -1;
403 LogDebug(
"HGCalCLUEAlgo") <<
"Debugging calculateDistanceToHigher: \n" 404 <<
" cell: " <<
i <<
" eta: " << cellsOnLayer.dim1[
i] <<
" phi: " << cellsOnLayer.dim2[
i]
405 <<
" energy: " << cellsOnLayer.weight[
i] <<
" density: " << cellsOnLayer.rho[
i]
406 <<
" nearest higher: " << cellsOnLayer.nearestHigher[
i]
407 <<
" distance: " << cellsOnLayer.delta[
i] <<
"\n";
411 template <
typename T,
typename STRATEGY>
417 unsigned int nClustersOnLayer = 0;
418 auto& cellsOnLayer = cells_[layerId];
419 unsigned int numberOfCells = cellsOnLayer.detid.size();
420 std::vector<int> localStack;
422 for (
unsigned int i = 0;
i < numberOfCells;
i++) {
423 float rho_c = kappa_ * cellsOnLayer.sigmaNoise[
i];
425 cellsOnLayer.clusterIndex[
i] = -1;
426 bool isSeed = (cellsOnLayer.delta[
i] >
delta) && (cellsOnLayer.rho[
i] >= rho_c);
427 bool isOutlier = (cellsOnLayer.delta[
i] > outlierDeltaFactor_ *
delta) && (cellsOnLayer.rho[
i] < rho_c);
429 cellsOnLayer.clusterIndex[
i] = nClustersOnLayer;
430 cellsOnLayer.isSeed[
i] =
true;
432 localStack.push_back(
i);
434 }
else if (!isOutlier) {
435 cellsOnLayer.followers[cellsOnLayer.nearestHigher[
i]].push_back(
i);
440 while (!localStack.empty()) {
441 int endStack = localStack.back();
442 auto& thisSeed = cellsOnLayer.followers[endStack];
443 localStack.pop_back();
446 for (
int j : thisSeed) {
448 cellsOnLayer.clusterIndex[
j] = cellsOnLayer.clusterIndex[endStack];
450 localStack.push_back(
j);
453 return nClustersOnLayer;
456 template <
typename T,
typename STRATEGY>
471 std::vector<double>
dummy;
473 dummy.resize(maxNumberOfThickIndices_ + !isNose_, 0);
474 thresholds_.resize(maxlayer_,
dummy);
475 v_sigmaNoise_.resize(maxlayer_,
dummy);
477 for (
unsigned ilayer = 1; ilayer <= maxlayer_; ++ilayer) {
478 for (
unsigned ithick = 0; ithick < maxNumberOfThickIndices_; ++ithick) {
479 float sigmaNoise = 0.001f * fcPerEle_ * nonAgedNoises_[ithick] * dEdXweights_[ilayer] /
480 (fcPerMip_[ithick] * thicknessCorrection_[ithick]);
481 thresholds_[ilayer - 1][ithick] = sigmaNoise * ecut_;
482 v_sigmaNoise_[ilayer - 1][ithick] = sigmaNoise;
483 LogDebug(
"HGCalCLUEAlgo") <<
"ilayer: " << ilayer <<
" nonAgedNoises: " << nonAgedNoises_[ithick]
484 <<
" fcPerEle: " << fcPerEle_ <<
" fcPerMip: " << fcPerMip_[ithick]
485 <<
" noiseMip: " << fcPerEle_ * nonAgedNoises_[ithick] / fcPerMip_[ithick]
486 <<
" sigmaNoise: " << sigmaNoise <<
"\n";
490 float scintillators_sigmaNoise = 0.001f * noiseMip_ * dEdXweights_[ilayer] / sciThicknessCorrection_;
491 thresholds_[ilayer - 1][maxNumberOfThickIndices_] = ecut_ * scintillators_sigmaNoise;
492 v_sigmaNoise_[ilayer - 1][maxNumberOfThickIndices_] = scintillators_sigmaNoise;
493 LogDebug(
"HGCalCLUEAlgo") <<
"ilayer: " << ilayer <<
" noiseMip: " << noiseMip_
494 <<
" scintillators_sigmaNoise: " << scintillators_sigmaNoise <<
"\n";
constexpr int ieta() const
constexpr int iphi() const
get the phi index
constexpr const DetId & detid() const
void calculateDistanceToHigher(const TILE <, const unsigned int layerId, float delta)
constexpr Detector det() const
get the detector field from this detid
void populate(const HGCRecHitCollection &hits) override
constexpr float energy() const
void dumpInfos(const T &cells, const std::string &moduleType) const
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)
void makeClusters() override
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum) ...
void getEventSetupPerAlgorithm(const edm::EventSetup &es) override
void calculateLocalDensity(const TILE <, const unsigned int layerId, float delta)
XYZPointD XYZPoint
point in space with cartesian internal representation
void prepareDataStructures(const unsigned int layerId)
static int position[264][3]
static constexpr float d1
int findAndAssignClusters(const unsigned int layerId, float delta)
std::vector< reco::BasicCluster > getClusters(bool) override