CMS 3D CMS Logo

HGCalCLUEAlgo.cc
Go to the documentation of this file.
2 
3 // Geometry
8 
10 //
12 #include "tbb/task_arena.h"
13 #include "tbb/tbb.h"
14 #include <limits>
15 
16 using namespace hgcal_clustering;
17 
19  cells_.clear();
20  numberOfClustersPerLayer_.clear();
21  cells_.resize(2 * (maxlayer_ + 1));
22  numberOfClustersPerLayer_.resize(2 * (maxlayer_ + 1), 0);
23 }
24 
26  // loop over all hits and create the Hexel structure, skip energies below ecut
27 
28  if (dependSensor_) {
29  // for each layer and wafer calculate the thresholds (sigmaNoise and energy)
30  // once
31  computeThreshold();
32  }
33 
34  for (unsigned int i = 0; i < hits.size(); ++i) {
35  const HGCRecHit& hgrh = hits[i];
36  DetId detid = hgrh.detid();
37  unsigned int layerOnSide = (rhtools_.getLayerWithOffset(detid) - 1);
38 
39  // set sigmaNoise default value 1 to use kappa value directly in case of
40  // sensor-independent thresholds
41  float sigmaNoise = 1.f;
42  if (dependSensor_) {
43  int thickness_index = rhtools_.getSiThickIndex(detid);
44  if (thickness_index == -1)
45  thickness_index = 3;
46  double storedThreshold = thresholds_[layerOnSide][thickness_index];
47  sigmaNoise = v_sigmaNoise_[layerOnSide][thickness_index];
48 
49  if (hgrh.energy() < storedThreshold)
50  continue; // this sets the ZS threshold at ecut times the sigma noise
51  // for the sensor
52  }
53  if (!dependSensor_ && hgrh.energy() < ecut_)
54  continue;
55  const GlobalPoint position(rhtools_.getPosition(detid));
56  int offset = ((rhtools_.zside(detid) + 1) >> 1) * maxlayer_;
57  int layer = layerOnSide + offset;
58 
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());
66  } // else, isSilicon == true and eta phi values will not be used
67  cells_[layer].weight.emplace_back(hgrh.energy());
68  cells_[layer].sigmaNoise.emplace_back(sigmaNoise);
69  }
70 }
71 
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);
84  }
85 }
86 
87 // Create a vector of Hexels associated to one cluster from a collection of
88 // HGCalRecHits - this can be used directly to make the final cluster list -
89 // this method can be invoked multiple times for the same event with different
90 // input (reset should be called between events)
92  // assign all hits in each layer to a cluster core
93  tbb::this_task_arena::isolate([&] {
94  tbb::parallel_for(size_t(0), size_t(2 * maxlayer_ + 2), [&](size_t i) {
95  prepareDataStructures(i);
96  HGCalLayerTiles lt;
97  lt.clear();
98  lt.fill(cells_[i].x, cells_[i].y, cells_[i].eta, cells_[i].phi, cells_[i].isSi);
99  float delta_c; // maximum search distance (critical distance) for local
100  // density calculation
101  if (i % maxlayer_ < lastLayerEE_)
102  delta_c = vecDeltas_[0];
103  else if (i % maxlayer_ < (firstLayerBH_ - 1))
104  delta_c = vecDeltas_[1];
105  else
106  delta_c = vecDeltas_[2];
107  float delta_r = vecDeltas_[3];
108  LogDebug("HGCalCLUEAlgo") << "maxlayer: " << maxlayer_ << " lastLayerEE: " << lastLayerEE_
109  << " firstLayerBH: " << firstLayerBH_ << "\n";
110 
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);
114  });
115  });
116  //Now that we have the density per point we can store it
117  for (unsigned int i = 0; i < 2 * maxlayer_ + 2; ++i) {
118  setDensity(i);
119  }
120 }
121 
122 std::vector<reco::BasicCluster> HGCalCLUEAlgo::getClusters(bool) {
123  std::vector<int> offsets(numberOfClustersPerLayer_.size(), 0);
124 
125  int maxClustersOnLayer = numberOfClustersPerLayer_[0];
126 
127  for (unsigned layerId = 1; layerId < offsets.size(); ++layerId) {
128  offsets[layerId] = offsets[layerId - 1] + numberOfClustersPerLayer_[layerId - 1];
129 
130  maxClustersOnLayer = std::max(maxClustersOnLayer, numberOfClustersPerLayer_[layerId]);
131  }
132 
133  auto totalNumberOfClusters = offsets.back() + numberOfClustersPerLayer_.back();
134  clusters_v_.resize(totalNumberOfClusters);
135  std::vector<std::vector<int>> cellsIdInCluster;
136  cellsIdInCluster.reserve(maxClustersOnLayer);
137 
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];
143 
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);
148  }
149 
150  std::vector<std::pair<DetId, float>> thisCluster;
151 
152  for (auto& cl : cellsIdInCluster) {
153  auto position = calculatePosition(cl, layerId);
154  float energy = 0.f;
155  int seedDetId = -1;
156 
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];
162  }
163  }
164  auto globalClusterIndex = cellsOnLayer.clusterIndex[cl[0]] + firstClusterIdx;
165 
166  clusters_v_[globalClusterIndex] =
167  reco::BasicCluster(energy, position, reco::CaloID::DET_HGCAL_ENDCAP, thisCluster, algoId_);
168  clusters_v_[globalClusterIndex].setSeed(seedDetId);
169  thisCluster.clear();
170  }
171 
172  cellsIdInCluster.clear();
173  }
174  return clusters_v_;
175 }
176 
177 math::XYZPoint HGCalCLUEAlgo::calculatePosition(const std::vector<int>& v, const unsigned int layerId) const {
178  float total_weight = 0.f;
179  float x = 0.f;
180  float y = 0.f;
181 
182  unsigned int maxEnergyIndex = 0;
183  float maxEnergyValue = 0.f;
184 
185  auto& cellsOnLayer = cells_[layerId];
186 
187  // loop over hits in cluster candidate
188  // determining the maximum energy hit
189  for (auto i : v) {
190  total_weight += cellsOnLayer.weight[i];
191  if (cellsOnLayer.weight[i] > maxEnergyValue) {
192  maxEnergyValue = cellsOnLayer.weight[i];
193  maxEnergyIndex = i;
194  }
195  }
196 
197  // Si cell or Scintillator. Used to set approach and parameters
198  auto thick = rhtools_.getSiThickIndex(cellsOnLayer.detid[maxEnergyIndex]);
199  bool isSiliconCell = (thick != -1);
200 
201  // TODO: this is recomputing everything twice and overwriting the position with log weighting position
202  if (isSiliconCell) {
203  float total_weight_log = 0.f;
204  float x_log = 0.f;
205  float y_log = 0.f;
206  for (auto i : v) {
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;
212  }
213 
214  total_weight = total_weight_log;
215  x = x_log;
216  y = y_log;
217  } else {
218  for (auto i : v) {
219  float rhEnergy = cellsOnLayer.weight[i];
220 
221  x += cellsOnLayer.x[i] * rhEnergy;
222  y += cellsOnLayer.y[i] * rhEnergy;
223  }
224  }
225  if (total_weight != 0.) {
226  float inv_tot_weight = 1.f / total_weight;
227  return math::XYZPoint(
228  x * inv_tot_weight, y * inv_tot_weight, rhtools_.getPosition(cellsOnLayer.detid[maxEnergyIndex]).z());
229  } else
230  return math::XYZPoint(0.f, 0.f, 0.f);
231 }
232 
234  const unsigned int layerId,
235  float delta_c,
236  float delta_r) {
237  auto& cellsOnLayer = cells_[layerId];
238  unsigned int numberOfCells = cellsOnLayer.detid.size();
239  bool isOnlySi(false);
240  if (rhtools_.isOnlySilicon(layerId))
241  isOnlySi = true;
242 
243  for (unsigned int i = 0; i < numberOfCells; i++) {
244  bool isSi = isOnlySi || cellsOnLayer.isSi[i];
245  if (isSi) {
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);
249 
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) {
252  int binId = lt.getGlobalBinByBin(xBin, yBin);
253  size_t binSize = lt[binId].size();
254 
255  for (unsigned int j = 0; j < binSize; j++) {
256  unsigned int otherId = lt[binId][j];
257  bool otherSi = isOnlySi || cellsOnLayer.isSi[otherId];
258  if (otherSi) { //silicon cells cannot talk to scintillator cells
259  if (distance(i, otherId, layerId, false) < delta) {
260  cellsOnLayer.rho[i] += (i == otherId ? 1.f : 0.5f) * cellsOnLayer.weight[otherId];
261  }
262  }
263  }
264  }
265  }
266  } else {
267  float delta = delta_r;
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);
274 
275  for (int etaBin = search_box[0]; etaBin < search_box[1] + 1; ++etaBin) {
276  for (int phiBin = search_box[2]; phiBin < search_box[3] + 1; ++phiBin) {
277  int binId = lt.getGlobalBinByBinEtaPhi(etaBin, phiBin);
278  size_t binSize = lt[binId].size();
279 
280  for (unsigned int j = 0; j < binSize; j++) {
281  unsigned int otherId = lt[binId][j];
282  if (!cellsOnLayer.isSi[otherId]) { //scintillator cells cannot talk to silicon cells
283  if (distance(i, otherId, layerId, true) < delta) {
284  int iPhi = HGCScintillatorDetId(cellsOnLayer.detid[i]).iphi();
285  int otherIPhi = HGCScintillatorDetId(cellsOnLayer.detid[otherId]).iphi();
286  int iEta = HGCScintillatorDetId(cellsOnLayer.detid[i]).ieta();
287  int otherIEta = HGCScintillatorDetId(cellsOnLayer.detid[otherId]).ieta();
288  int dIPhi = otherIPhi - iPhi;
289  dIPhi += abs(dIPhi) < 2
290  ? 0
291  : dIPhi < 0 ? scintMaxIphi_
292  : -scintMaxIphi_; // cells with iPhi=288 and iPhi=1 should be neiboring cells
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";
298 
299  if (otherId != i) {
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;
310  }
311  LogDebug("HGCalCLUEAlgo") << " Debugging calculateLocalDensity for Scintillator: \n"
312  << " northeast: " << northeast << " southeast: " << southeast
313  << " northwest: " << northwest << " southwest: " << southwest << "\n";
314  }
315  }
316  }
317  }
318  }
319  float neighborsval = (std::max(northeast, northwest) > std::max(southeast, southwest))
320  ? std::max(northeast, northwest)
321  : std::max(southeast, southwest);
322  if (use2x2_)
323  cellsOnLayer.rho[i] += neighborsval;
324  else
325  cellsOnLayer.rho[i] += all;
326  }
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";
331  }
332 }
333 
335  const unsigned int layerId,
336  float delta_c,
337  float delta_r) {
338  auto& cellsOnLayer = cells_[layerId];
339  unsigned int numberOfCells = cellsOnLayer.detid.size();
340  bool isOnlySi(false);
341  if (rhtools_.isOnlySilicon(layerId))
342  isOnlySi = true;
343 
344  for (unsigned int i = 0; i < numberOfCells; i++) {
345  bool isSi = isOnlySi || cellsOnLayer.isSi[i];
346  // initialize delta and nearest higher for i
348  float i_delta = maxDelta;
349  int i_nearestHigher = -1;
350  if (isSi) {
351  float delta = delta_c;
352  // get search box for ith hit
353  // guarantee to cover a range "outlierDeltaFactor_*delta_c"
354  auto range = outlierDeltaFactor_ * delta;
355  std::array<int, 4> search_box = lt.searchBox(
356  cellsOnLayer.x[i] - range, cellsOnLayer.x[i] + range, cellsOnLayer.y[i] - range, cellsOnLayer.y[i] + range);
357  // loop over all bins in the search box
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) {
360  // get the id of this bin
361  size_t binId = lt.getGlobalBinByBin(xBin, yBin);
362  // get the size of this bin
363  size_t binSize = lt[binId].size();
364 
365  // loop over all hits in this bin
366  for (unsigned int j = 0; j < binSize; j++) {
367  unsigned int otherId = lt[binId][j];
368  bool otherSi = isOnlySi || cellsOnLayer.isSi[otherId];
369  if (otherSi) { //silicon cells cannot talk to scintillator cells
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]);
374  // if dist == i_delta, then last comer being the nearest higher
375  if (foundHigher && dist <= i_delta) {
376  // update i_delta
377  i_delta = dist;
378  // update i_nearestHigher
379  i_nearestHigher = otherId;
380  }
381  }
382  }
383  }
384  }
385 
386  bool foundNearestHigherInSearchBox = (i_delta != maxDelta);
387  if (foundNearestHigherInSearchBox) {
388  cellsOnLayer.delta[i] = i_delta;
389  cellsOnLayer.nearestHigher[i] = i_nearestHigher;
390  } else {
391  // otherwise delta is guaranteed to be larger outlierDeltaFactor_*delta_c
392  // we can safely maximize delta to be maxDelta
393  cellsOnLayer.delta[i] = maxDelta;
394  cellsOnLayer.nearestHigher[i] = -1;
395  }
396  } else {
397  //similar to silicon
398  float delta = delta_r;
399  auto range = outlierDeltaFactor_ * delta;
400  std::array<int, 4> search_box = lt.searchBoxEtaPhi(cellsOnLayer.eta[i] - range,
401  cellsOnLayer.eta[i] + range,
402  cellsOnLayer.phi[i] - range,
403  cellsOnLayer.phi[i] + range);
404  // loop over all bins in the search box
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) {
407  // get the id of this bin
408  size_t binId = lt.getGlobalBinByBinEtaPhi(xBin, yBin);
409  // get the size of this bin
410  size_t binSize = lt[binId].size();
411 
412  // loop over all hits in this bin
413  for (unsigned int j = 0; j < binSize; j++) {
414  unsigned int otherId = lt[binId][j];
415  if (!cellsOnLayer.isSi[otherId]) { //scintillator cells cannot talk to silicon cells
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]);
420  // if dist == i_delta, then last comer being the nearest higher
421  if (foundHigher && dist <= i_delta) {
422  // update i_delta
423  i_delta = dist;
424  // update i_nearestHigher
425  i_nearestHigher = otherId;
426  }
427  }
428  }
429  }
430  }
431 
432  bool foundNearestHigherInSearchBox = (i_delta != maxDelta);
433  if (foundNearestHigherInSearchBox) {
434  cellsOnLayer.delta[i] = i_delta;
435  cellsOnLayer.nearestHigher[i] = i_nearestHigher;
436  } else {
437  // otherwise delta is guaranteed to be larger outlierDeltaFactor_*delta_c
438  // we can safely maximize delta to be maxDelta
439  cellsOnLayer.delta[i] = maxDelta;
440  cellsOnLayer.nearestHigher[i] = -1;
441  }
442  }
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";
449  }
450 }
451 
452 int HGCalCLUEAlgo::findAndAssignClusters(const unsigned int layerId, float delta_c, float delta_r) {
453  // this is called once per layer and endcap...
454  // so when filling the cluster temporary vector of Hexels we resize each time
455  // by the number of clusters found. This is always equal to the number of
456  // cluster centers...
457  unsigned int nClustersOnLayer = 0;
458  auto& cellsOnLayer = cells_[layerId];
459  unsigned int numberOfCells = cellsOnLayer.detid.size();
460  std::vector<int> localStack;
461  // find cluster seeds and outlier
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];
465  float delta = isSi ? delta_c : delta_r;
466 
467  // initialize clusterIndex
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);
471  if (isSeed) {
472  cellsOnLayer.clusterIndex[i] = nClustersOnLayer;
473  cellsOnLayer.isSeed[i] = true;
474  nClustersOnLayer++;
475  localStack.push_back(i);
476 
477  } else if (!isOutlier) {
478  cellsOnLayer.followers[cellsOnLayer.nearestHigher[i]].push_back(i);
479  }
480  }
481 
482  // need to pass clusterIndex to their followers
483  while (!localStack.empty()) {
484  int endStack = localStack.back();
485  auto& thisSeed = cellsOnLayer.followers[endStack];
486  localStack.pop_back();
487 
488  // loop over followers
489  for (int j : thisSeed) {
490  // pass id to a follower
491  cellsOnLayer.clusterIndex[j] = cellsOnLayer.clusterIndex[endStack];
492  // push this follower to localStack
493  localStack.push_back(j);
494  }
495  }
496  return nClustersOnLayer;
497 }
498 
500  // To support the TDR geometry and also the post-TDR one (v9 onwards), we
501  // need to change the logic of the vectors containing signal to noise and
502  // thresholds. The first 3 indices will keep on addressing the different
503  // thicknesses of the Silicon detectors, while the last one, number 3 (the
504  // fourth) will address the Scintillators. This change will support both
505  // geometries at the same time.
506 
507  if (initialized_)
508  return; // only need to calculate thresholds once
509 
510  initialized_ = true;
511 
512  std::vector<double> dummy;
513  const unsigned maxNumberOfThickIndices = 3;
514  dummy.resize(maxNumberOfThickIndices + 1, 0); // +1 to accomodate for the Scintillators
515  thresholds_.resize(maxlayer_, dummy);
516  v_sigmaNoise_.resize(maxlayer_, dummy);
517 
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";
528  }
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";
534  }
535 }
536 
537 void HGCalCLUEAlgo::setDensity(const unsigned int layerId) {
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];
542 }
543 
544 Density HGCalCLUEAlgo::getDensity() { return density_; }
#define LogDebug(id)
constexpr float energy() const
Definition: CaloRecHit.h:29
constexpr const DetId & detid() const
Definition: CaloRecHit.h:33
void prepareDataStructures(const unsigned int layerId)
int getGlobalBinByBinEtaPhi(int etaBin, int phiBin) const
CaloCluster BasicCluster
Definition: BasicCluster.h:21
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 &lt, 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
Definition: HGCalCLUEAlgo.h:27
void computeThreshold()
double delta_r(const Fourvec &a, const Fourvec &b)
Find the distance between two four-vectors in the two-dimensional space .
Definition: fourvec.cc:238
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
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
Definition: DetId.h:17
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::pair< double, double > calculatePosition(TVirtualPad *myPad, int boundary)
int findAndAssignClusters(const unsigned int layerId, float delta_c, float delta_r)
size_type size() const
static int position[264][3]
Definition: ReadPGInfo.cc:289
void getEventSetupPerAlgorithm(const edm::EventSetup &es) override
void calculateLocalDensity(const HGCalLayerTiles &lt, const unsigned int layerId, float delta_c, float delta_r)