CMS 3D CMS Logo

HGCalHistoSeedingImpl.cc
Go to the documentation of this file.
5 #include <numeric>
6 
8  : seedingAlgoType_(conf.getParameter<std::string>("type_histoalgo")),
9  nBins1_(conf.getParameter<unsigned>("nBins_X1_histo_multicluster")),
10  nBins2_(conf.getParameter<unsigned>("nBins_X2_histo_multicluster")),
11  binsSumsHisto_(conf.getParameter<std::vector<unsigned>>("binSumsHisto")),
12  histoThreshold_(conf.getParameter<double>("threshold_histo_multicluster")),
13  neighbour_weights_(conf.getParameter<std::vector<double>>("neighbour_weights")),
14  smoothing_ecal_(conf.getParameter<std::vector<double>>("seed_smoothing_ecal")),
15  smoothing_hcal_(conf.getParameter<std::vector<double>>("seed_smoothing_hcal")),
16  seeds_norm_by_area_(conf.getParameter<bool>("seeds_norm_by_area")),
17  kROverZMin_(conf.getParameter<double>("kROverZMin")),
18  kROverZMax_(conf.getParameter<double>("kROverZMax")) {
19  if (seedingAlgoType_ == "HistoMaxC3d") {
21  } else if (seedingAlgoType_ == "HistoSecondaryMaxC3d") {
23  } else if (seedingAlgoType_ == "HistoThresholdC3d") {
25  } else if (seedingAlgoType_ == "HistoInterpolatedMaxC3d") {
27  } else {
28  throw cms::Exception("HGCTriggerParameterError") << "Unknown Multiclustering type '" << seedingAlgoType_;
29  }
30 
31  if (conf.getParameter<std::string>("seed_position") == "BinCentre") {
33  } else if (conf.getParameter<std::string>("seed_position") == "TCWeighted") {
35  } else {
36  throw cms::Exception("HGCTriggerParameterError")
37  << "Unknown Seed Position option '" << conf.getParameter<std::string>("seed_position");
38  }
39  if (conf.getParameter<std::string>("seeding_space") == "RPhi") {
42  } else if (conf.getParameter<std::string>("seeding_space") == "XY") {
43  seedingSpace_ = XY;
45  } else {
46  throw cms::Exception("HGCTriggerParameterError")
47  << "Unknown seeding space '" << conf.getParameter<std::string>("seeding_space");
48  }
49 
50  edm::LogInfo("HGCalMulticlusterParameters")
51  << "\nMulticluster number of X1-bins for the histo algorithm: " << nBins1_
52  << "\nMulticluster number of X2-bins for the histo algorithm: " << nBins2_
53  << "\nMulticluster MIPT threshold for histo threshold algorithm: " << histoThreshold_
54  << "\nMulticluster type of multiclustering algortihm: " << seedingAlgoType_;
55 
56  if (seedingAlgoType_.find("Histo") != std::string::npos && seedingSpace_ == RPhi &&
57  nBins1_ != binsSumsHisto_.size()) {
58  throw cms::Exception("Inconsistent bin size")
59  << "Inconsistent nBins_X1_histo_multicluster ( " << nBins1_ << " ) and binSumsHisto ( " << binsSumsHisto_.size()
60  << " ) size in HGCalMulticlustering\n";
61  }
62 
64  throw cms::Exception("Inconsistent vector size")
65  << "Inconsistent size of neighbour weights vector in HGCalMulticlustering ( " << neighbour_weights_.size()
66  << " ). Should be " << neighbour_weights_size_ << "\n";
67  }
68 
69  // compute quantities for non-normalised-by-area histoMax
70  int bin1_10pct = 0;
71  // FIXME: Originally was supposed to be:
72  // int bin1_10pct = (int) (0.1 * nBins1_);
73  // The 0.1 factor in bin1_10pct was an attempt to keep the same rough scale for seeds. The exact value is arbitrary.
74  // But due to a typo, things were optimised and validated with bin1_10pct=0
75  // So keep this value until updated optimizations are done
76  float R1_10pct = kROverZMin_ + bin1_10pct * (kROverZMax_ - kROverZMin_) / nBins1_;
77  float R2_10pct = R1_10pct + (kROverZMax_ - kROverZMin_) / nBins1_;
78  area_10pct_ = M_PI * (pow(R2_10pct, 2) - pow(R1_10pct, 2)) / nBins2_;
79 }
80 
82  const std::vector<edm::Ptr<l1t::HGCalCluster>>& clustersPtrs) {
83  Histogram histoClusters(nBins1_, nBins2_);
84  std::array<double, 4> bounds = boundaries();
85  double minx1 = std::get<0>(bounds);
86  double maxx1 = std::get<1>(bounds);
87  double minx2 = std::get<2>(bounds);
88  double maxx2 = std::get<3>(bounds);
89 
90  for (auto& clu : clustersPtrs) {
91  float x1 = 0., x2 = 0;
92  switch (seedingSpace_) {
93  case RPhi:
94  x1 = sqrt(pow(clu->centreProj().x(), 2) + pow(clu->centreProj().y(), 2));
95  x2 = reco::reduceRange(clu->phi());
96  break;
97  case XY:
98  x1 = clu->centreProj().x();
99  x2 = clu->centreProj().y();
100  break;
101  };
102  if (x1 < minx1 || x1 >= maxx1) {
103  throw cms::Exception("OutOfBound") << "TC X1 = " << x1 << " out of the seeding histogram bounds " << minx1
104  << " - " << maxx1;
105  }
106  if (x2 < minx2 || x2 >= maxx2) {
107  throw cms::Exception("OutOfBound") << "TC X2 = " << x2 << " out of the seeding histogram bounds " << minx2
108  << " - " << maxx2;
109  }
110  unsigned bin1 = unsigned((x1 - minx1) * nBins1_ / (maxx1 - minx1));
111  unsigned bin2 = unsigned((x2 - minx2) * nBins2_ / (maxx2 - minx2));
112 
113  auto& bin = histoClusters.at(triggerTools_.zside(clu->detId()), bin1, bin2);
114  bin.values[Bin::Content::Sum] += clu->mipPt();
115  if (triggerTools_.isEm(clu->detId())) {
116  bin.values[Bin::Content::Ecal] += clu->mipPt();
117  } else {
118  bin.values[Bin::Content::Hcal] += clu->mipPt();
119  }
120  bin.weighted_x += (clu->centreProj().x()) * clu->mipPt();
121  bin.weighted_y += (clu->centreProj().y()) * clu->mipPt();
122  }
123 
124  for (auto& bin : histoClusters) {
125  bin.weighted_x /= bin.values[Bin::Content::Sum];
126  bin.weighted_y /= bin.values[Bin::Content::Sum];
127  }
128 
129  return histoClusters;
130 }
131 
133  const vector<double>& kernel,
134  Bin::Content binContent) {
135  Histogram histoSmooth(histoClusters);
136 
137  unsigned kernel_size = std::sqrt(kernel.size());
138  if (kernel_size * kernel_size != kernel.size()) {
139  throw cms::Exception("HGCTriggerParameterError") << "Only square kernels can be used.";
140  }
141  if (kernel_size % 2 != 1) {
142  throw cms::Exception("HGCTriggerParameterError") << "The kernel size must be an odd value.";
143  }
144  int shift_max = (kernel_size - 1) / 2;
145  double normalization = std::accumulate(kernel.begin(), kernel.end(), 0.);
146  for (int z_side : {-1, 1}) {
147  for (unsigned x1 = 0; x1 < nBins1_; x1++) {
148  for (unsigned x2 = 0; x2 < nBins2_; x2++) {
149  const auto& bin_orig = histoClusters.at(z_side, x1, x2);
150  double smooth = 0.;
152  for (int x1_shift = -shift_max; x1_shift <= shift_max; x1_shift++) {
153  int index1 = x1_shift + shift_max;
154  for (int x2_shift = -shift_max; x2_shift <= shift_max; x2_shift++) {
155  auto shifted = navigator_.move(x1_shift, x2_shift);
156  int index2 = x2_shift + shift_max;
157  double kernel_value = kernel.at(index1 * kernel_size + index2);
158  bool out = shifted[0] == -1 || shifted[1] == -1;
159  double content = (out ? 0. : histoClusters.at(z_side, shifted[0], shifted[1]).values[binContent]);
160  smooth += content * kernel_value;
161  }
162  }
163  auto& bin = histoSmooth.at(z_side, x1, x2);
164  bin.values[binContent] = smooth / normalization;
165  bin.weighted_x = bin_orig.weighted_x;
166  bin.weighted_y = bin_orig.weighted_y;
167  }
168  }
169  }
170 
171  return histoSmooth;
172 }
173 
175  const vector<unsigned>& binSums) {
176  Histogram histoSumPhiClusters(nBins1_, nBins2_);
177 
178  for (int z_side : {-1, 1}) {
179  for (unsigned bin1 = 0; bin1 < nBins1_; bin1++) {
180  int nBinsSide = (binSums[bin1] - 1) / 2;
181  // Takes into account different area of bins in different R-rings + sum of quadratic weights used
182  double area = (1 + 2.0 * (1 - pow(0.5, nBinsSide)));
183 
184  if (seeds_norm_by_area_) {
185  float R1 = kROverZMin_ + bin1 * (kROverZMax_ - kROverZMin_) / nBins1_;
186  float R2 = R1 + (kROverZMax_ - kROverZMin_) / nBins1_;
187  area = area * M_PI * (pow(R2, 2) - pow(R1, 2)) / nBins2_;
188  } else {
189  area = area * area_10pct_;
190  }
191 
192  for (unsigned bin2 = 0; bin2 < nBins2_; bin2++) {
193  const auto& bin_orig = histoClusters.at(z_side, bin1, bin2);
194  float content = bin_orig.values[Bin::Content::Sum];
195 
196  for (int bin22 = 1; bin22 <= nBinsSide; bin22++) {
197  int binToSumLeft = bin2 - bin22;
198  if (binToSumLeft < 0)
199  binToSumLeft += nBins2_;
200  unsigned binToSumRight = bin2 + bin22;
201  if (binToSumRight >= nBins2_)
202  binToSumRight -= nBins2_;
203 
204  content += histoClusters.at(z_side, bin1, binToSumLeft).values[Bin::Content::Sum] /
205  pow(2, bin22); // quadratic kernel
206 
207  content += histoClusters.at(z_side, bin1, binToSumRight).values[Bin::Content::Sum] /
208  pow(2, bin22); // quadratic kernel
209  }
210 
211  auto& bin = histoSumPhiClusters.at(z_side, bin1, bin2);
213  bin.weighted_x = bin_orig.weighted_x;
214  bin.weighted_y = bin_orig.weighted_y;
215  }
216  }
217  }
218 
219  return histoSumPhiClusters;
220 }
221 
223  Histogram histoSumRPhiClusters(nBins1_, nBins2_);
224 
225  for (int z_side : {-1, 1}) {
226  for (unsigned bin1 = 0; bin1 < nBins1_; bin1++) {
227  float weight =
228  (bin1 == 0 || bin1 == nBins1_ - 1) ? 1.5 : 2.; //Take into account edges with only one side up or down
229 
230  for (unsigned bin2 = 0; bin2 < nBins2_; bin2++) {
231  const auto& bin_orig = histoClusters.at(z_side, bin1, bin2);
232  float content = bin_orig.values[Bin::Content::Sum];
233  float contentDown = bin1 > 0 ? histoClusters.at(z_side, bin1 - 1, bin2).values[Bin::Content::Sum] : 0;
234  float contentUp = bin1 < (nBins1_ - 1) ? histoClusters.at(z_side, bin1 + 1, bin2).values[Bin::Content::Sum] : 0;
235 
236  auto& bin = histoSumRPhiClusters.at(z_side, bin1, bin2);
237  bin.values[Bin::Content::Sum] = (content + 0.5 * contentDown + 0.5 * contentUp) / weight;
238  bin.weighted_x = bin_orig.weighted_x;
239  bin.weighted_y = bin_orig.weighted_y;
240  }
241  }
242  }
243 
244  return histoSumRPhiClusters;
245 }
246 
247 void HGCalHistoSeedingImpl::setSeedEnergyAndPosition(std::vector<std::pair<GlobalPoint, double>>& seedPositionsEnergy,
248  int z_side,
249  unsigned bin1,
250  unsigned bin2,
251  const Bin& histBin) {
252  float x_seed = 0;
253  float y_seed = 0;
254  std::array<double, 4> bounds = boundaries();
255  double minx1 = std::get<0>(bounds);
256  double maxx1 = std::get<1>(bounds);
257  double minx2 = std::get<2>(bounds);
258  double maxx2 = std::get<3>(bounds);
259 
260  if (seedingPosition_ == BinCentre) {
261  float x1_seed = minx1 + (bin1 + 0.5) * (maxx1 - minx1) / nBins1_;
262  float x2_seed = minx2 + (bin2 + 0.5) * (maxx2 - minx2) / nBins2_;
263  switch (seedingSpace_) {
264  case RPhi:
265  x_seed = x1_seed * cos(x2_seed);
266  y_seed = x1_seed * sin(x2_seed);
267  break;
268  case XY:
269  x_seed = x1_seed;
270  y_seed = x2_seed;
271  };
272  } else if (seedingPosition_ == TCWeighted) {
273  x_seed = histBin.weighted_x;
274  y_seed = histBin.weighted_y;
275  }
276 
277  seedPositionsEnergy.emplace_back(GlobalPoint(x_seed, y_seed, z_side), histBin.values[Bin::Content::Sum]);
278 }
279 
280 std::vector<std::pair<GlobalPoint, double>> HGCalHistoSeedingImpl::computeMaxSeeds(const Histogram& histoClusters) {
281  std::vector<std::pair<GlobalPoint, double>> seedPositionsEnergy;
282 
283  for (int z_side : {-1, 1}) {
284  for (unsigned bin1 = 0; bin1 < nBins1_; bin1++) {
285  for (unsigned bin2 = 0; bin2 < nBins2_; bin2++) {
286  float MIPT_seed = histoClusters.at(z_side, bin1, bin2).values[Bin::Content::Sum];
287  bool isMax = MIPT_seed > histoThreshold_;
288  if (!isMax)
289  continue;
290 
291  navigator_.setHome(bin1, bin2);
292  auto pos_N = navigator_.move(1, 0);
293  auto pos_S = navigator_.move(-1, 0);
294  auto pos_W = navigator_.move(0, -1);
295  auto pos_E = navigator_.move(0, 1);
296  auto pos_NW = navigator_.move(1, -1);
297  auto pos_NE = navigator_.move(1, 1);
298  auto pos_SW = navigator_.move(-1, -1);
299  auto pos_SE = navigator_.move(-1, 1);
300 
301  float MIPT_N = (pos_N[0] != -1 && pos_N[1] != -1)
302  ? histoClusters.at(z_side, pos_N[0], pos_N[1]).values[Bin::Content::Sum]
303  : 0;
304  float MIPT_S = (pos_S[0] != -1 && pos_S[1] != -1)
305  ? histoClusters.at(z_side, pos_S[0], pos_S[1]).values[Bin::Content::Sum]
306  : 0;
307  float MIPT_W = (pos_W[0] != -1 && pos_W[1] != -1)
308  ? histoClusters.at(z_side, pos_W[0], pos_W[1]).values[Bin::Content::Sum]
309  : 0;
310  float MIPT_E = (pos_E[0] != -1 && pos_E[1] != -1)
311  ? histoClusters.at(z_side, pos_E[0], pos_E[1]).values[Bin::Content::Sum]
312  : 0;
313  float MIPT_NW = (pos_NW[0] != -1 && pos_NW[1] != -1)
314  ? histoClusters.at(z_side, pos_NW[0], pos_NW[1]).values[Bin::Content::Sum]
315  : 0;
316  float MIPT_NE = (pos_NE[0] != -1 && pos_NE[1] != -1)
317  ? histoClusters.at(z_side, pos_NE[0], pos_NE[1]).values[Bin::Content::Sum]
318  : 0;
319  float MIPT_SW = (pos_SW[0] != -1 && pos_SW[1] != -1)
320  ? histoClusters.at(z_side, pos_SW[0], pos_SW[1]).values[Bin::Content::Sum]
321  : 0;
322  float MIPT_SE = (pos_SE[0] != -1 && pos_SE[1] != -1)
323  ? histoClusters.at(z_side, pos_SE[0], pos_SE[1]).values[Bin::Content::Sum]
324  : 0;
325 
326  isMax &= MIPT_seed >= MIPT_S && MIPT_seed > MIPT_N && MIPT_seed >= MIPT_E && MIPT_seed >= MIPT_SE &&
327  MIPT_seed >= MIPT_NE && MIPT_seed > MIPT_W && MIPT_seed > MIPT_SW && MIPT_seed > MIPT_NW;
328 
329  if (isMax) {
330  setSeedEnergyAndPosition(seedPositionsEnergy, z_side, bin1, bin2, histoClusters.at(z_side, bin1, bin2));
331  }
332  }
333  }
334  }
335 
336  return seedPositionsEnergy;
337 }
338 
339 std::vector<std::pair<GlobalPoint, double>> HGCalHistoSeedingImpl::computeInterpolatedMaxSeeds(
340  const Histogram& histoClusters) {
341  std::vector<std::pair<GlobalPoint, double>> seedPositionsEnergy;
342 
343  for (int z_side : {-1, 1}) {
344  for (unsigned bin1 = 0; bin1 < nBins1_; bin1++) {
345  for (unsigned bin2 = 0; bin2 < nBins2_; bin2++) {
346  float MIPT_seed = histoClusters.at(z_side, bin1, bin2).values[Bin::Content::Sum];
347 
348  navigator_.setHome(bin1, bin2);
349  auto pos_N = navigator_.move(1, 0);
350  auto pos_S = navigator_.move(-1, 0);
351  auto pos_W = navigator_.move(0, -1);
352  auto pos_E = navigator_.move(0, 1);
353  auto pos_NW = navigator_.move(1, -1);
354  auto pos_NE = navigator_.move(1, 1);
355  auto pos_SW = navigator_.move(-1, -1);
356  auto pos_SE = navigator_.move(-1, 1);
357 
358  float MIPT_N = (pos_N[0] != -1 && pos_N[1] != -1)
359  ? histoClusters.at(z_side, pos_N[0], pos_N[1]).values[Bin::Content::Sum]
360  : 0;
361  float MIPT_S = (pos_S[0] != -1 && pos_S[1] != -1)
362  ? histoClusters.at(z_side, pos_S[0], pos_S[1]).values[Bin::Content::Sum]
363  : 0;
364  float MIPT_W = (pos_W[0] != -1 && pos_W[1] != -1)
365  ? histoClusters.at(z_side, pos_W[0], pos_W[1]).values[Bin::Content::Sum]
366  : 0;
367  float MIPT_E = (pos_E[0] != -1 && pos_E[1] != -1)
368  ? histoClusters.at(z_side, pos_E[0], pos_E[1]).values[Bin::Content::Sum]
369  : 0;
370  float MIPT_NW = (pos_NW[0] != -1 && pos_NW[1] != -1)
371  ? histoClusters.at(z_side, pos_NW[0], pos_NW[1]).values[Bin::Content::Sum]
372  : 0;
373  float MIPT_NE = (pos_NE[0] != -1 && pos_NE[1] != -1)
374  ? histoClusters.at(z_side, pos_NE[0], pos_NE[1]).values[Bin::Content::Sum]
375  : 0;
376  float MIPT_SW = (pos_SW[0] != -1 && pos_SW[1] != -1)
377  ? histoClusters.at(z_side, pos_SW[0], pos_SW[1]).values[Bin::Content::Sum]
378  : 0;
379  float MIPT_SE = (pos_SE[0] != -1 && pos_SE[1] != -1)
380  ? histoClusters.at(z_side, pos_SE[0], pos_SE[1]).values[Bin::Content::Sum]
381  : 0;
382 
383  float MIPT_pred = neighbour_weights_.at(0) * MIPT_NW + neighbour_weights_.at(1) * MIPT_N +
384  neighbour_weights_.at(2) * MIPT_NE + neighbour_weights_.at(3) * MIPT_W +
385  neighbour_weights_.at(5) * MIPT_E + neighbour_weights_.at(6) * MIPT_SW +
386  neighbour_weights_.at(7) * MIPT_S + neighbour_weights_.at(8) * MIPT_SE;
387 
388  bool isMax = MIPT_seed >= (MIPT_pred + histoThreshold_);
389 
390  if (isMax) {
391  setSeedEnergyAndPosition(seedPositionsEnergy, z_side, bin1, bin2, histoClusters.at(z_side, bin1, bin2));
392  }
393  }
394  }
395  }
396 
397  return seedPositionsEnergy;
398 }
399 
400 std::vector<std::pair<GlobalPoint, double>> HGCalHistoSeedingImpl::computeThresholdSeeds(
401  const Histogram& histoClusters) {
402  std::vector<std::pair<GlobalPoint, double>> seedPositionsEnergy;
403 
404  for (int z_side : {-1, 1}) {
405  for (unsigned bin1 = 0; bin1 < nBins1_; bin1++) {
406  for (unsigned bin2 = 0; bin2 < nBins2_; bin2++) {
407  float MIPT_seed = histoClusters.at(z_side, bin1, bin2).values[Bin::Content::Sum];
408  bool isSeed = MIPT_seed > histoThreshold_;
409 
410  if (isSeed) {
411  setSeedEnergyAndPosition(seedPositionsEnergy, z_side, bin1, bin2, histoClusters.at(z_side, bin1, bin2));
412  }
413  }
414  }
415  }
416 
417  return seedPositionsEnergy;
418 }
419 
420 std::vector<std::pair<GlobalPoint, double>> HGCalHistoSeedingImpl::computeSecondaryMaxSeeds(
421  const Histogram& histoClusters) {
422  std::vector<std::pair<GlobalPoint, double>> seedPositionsEnergy;
423 
424  HistogramT<uint8_t> primarySeedPositions(nBins1_, nBins2_);
425  HistogramT<uint8_t> vetoPositions(nBins1_, nBins2_);
426 
427  //Search for primary seeds
428  for (int z_side : {-1, 1}) {
429  for (unsigned bin1 = 0; bin1 < nBins1_; bin1++) {
430  for (unsigned bin2 = 0; bin2 < nBins2_; bin2++) {
431  float MIPT_seed = histoClusters.at(z_side, bin1, bin2).values[Bin::Content::Sum];
432  bool isMax = MIPT_seed > histoThreshold_;
433 
434  if (!isMax)
435  continue;
436 
437  float MIPT_S = bin1 < (nBins1_ - 1) ? histoClusters.at(z_side, bin1 + 1, bin2).values[Bin::Content::Sum] : 0;
438  float MIPT_N = bin1 > 0 ? histoClusters.at(z_side, bin1 - 1, bin2).values[Bin::Content::Sum] : 0;
439 
440  int binLeft = bin2 - 1;
441  if (binLeft < 0)
442  binLeft += nBins2_;
443  unsigned binRight = bin2 + 1;
444  if (binRight >= nBins2_)
445  binRight -= nBins2_;
446 
447  float MIPT_W = histoClusters.at(z_side, bin1, binLeft).values[Bin::Content::Sum];
448  float MIPT_E = histoClusters.at(z_side, bin1, binRight).values[Bin::Content::Sum];
449  float MIPT_NW = bin1 > 0 ? histoClusters.at(z_side, bin1 - 1, binLeft).values[Bin::Content::Sum] : 0;
450  float MIPT_NE = bin1 > 0 ? histoClusters.at(z_side, bin1 - 1, binRight).values[Bin::Content::Sum] : 0;
451  float MIPT_SW =
452  bin1 < (nBins1_ - 1) ? histoClusters.at(z_side, bin1 + 1, binLeft).values[Bin::Content::Sum] : 0;
453  float MIPT_SE =
454  bin1 < (nBins1_ - 1) ? histoClusters.at(z_side, bin1 + 1, binRight).values[Bin::Content::Sum] : 0;
455 
456  isMax &= MIPT_seed >= MIPT_S && MIPT_seed > MIPT_N && MIPT_seed >= MIPT_E && MIPT_seed >= MIPT_SE &&
457  MIPT_seed >= MIPT_NE && MIPT_seed > MIPT_W && MIPT_seed > MIPT_SW && MIPT_seed > MIPT_NW;
458 
459  if (isMax) {
460  setSeedEnergyAndPosition(seedPositionsEnergy, z_side, bin1, bin2, histoClusters.at(z_side, bin1, bin2));
461 
462  primarySeedPositions.at(z_side, bin1, bin2) = true;
463 
464  vetoPositions.at(z_side, bin1, binLeft) = true;
465  vetoPositions.at(z_side, bin1, binRight) = true;
466  if (bin1 > 0) {
467  vetoPositions.at(z_side, bin1 - 1, bin2) = true;
468  vetoPositions.at(z_side, bin1 - 1, binRight) = true;
469  vetoPositions.at(z_side, bin1 - 1, binLeft) = true;
470  }
471  if (bin1 < (nBins1_ - 1)) {
472  vetoPositions.at(z_side, bin1 + 1, bin2) = true;
473  vetoPositions.at(z_side, bin1 + 1, binRight) = true;
474  vetoPositions.at(z_side, bin1 + 1, binLeft) = true;
475  }
476  }
477  }
478  }
479  }
480 
481  //Search for secondary seeds
482 
483  for (int z_side : {-1, 1}) {
484  for (unsigned bin1 = 0; bin1 < nBins1_; bin1++) {
485  for (unsigned bin2 = 0; bin2 < nBins2_; bin2++) {
486  //Cannot be a secondary seed if already a primary seed, or adjacent to primary seed
487  if (primarySeedPositions.at(z_side, bin1, bin2) || vetoPositions.at(z_side, bin1, bin2))
488  continue;
489 
490  float MIPT_seed = histoClusters.at(z_side, bin1, bin2).values[Bin::Content::Sum];
491  bool isMax = MIPT_seed > histoThreshold_;
492 
493  float MIPT_S = bin1 < (nBins1_ - 1) ? histoClusters.at(z_side, bin1 + 1, bin2).values[Bin::Content::Sum] : 0;
494  float MIPT_N = bin1 > 0 ? histoClusters.at(z_side, bin1 - 1, bin2).values[Bin::Content::Sum] : 0;
495 
496  int binLeft = bin2 - 1;
497  if (binLeft < 0)
498  binLeft += nBins2_;
499  unsigned binRight = bin2 + 1;
500  if (binRight >= nBins2_)
501  binRight -= nBins2_;
502 
503  float MIPT_W = histoClusters.at(z_side, bin1, binLeft).values[Bin::Content::Sum];
504  float MIPT_E = histoClusters.at(z_side, bin1, binRight).values[Bin::Content::Sum];
505  float MIPT_NW = bin1 > 0 ? histoClusters.at(z_side, bin1 - 1, binLeft).values[Bin::Content::Sum] : 0;
506  float MIPT_NE = bin1 > 0 ? histoClusters.at(z_side, bin1 - 1, binRight).values[Bin::Content::Sum] : 0;
507  float MIPT_SW =
508  bin1 < (nBins1_ - 1) ? histoClusters.at(z_side, bin1 + 1, binLeft).values[Bin::Content::Sum] : 0;
509  float MIPT_SE =
510  bin1 < (nBins1_ - 1) ? histoClusters.at(z_side, bin1 + 1, binRight).values[Bin::Content::Sum] : 0;
511 
512  isMax &= (((bin1 < nBins1_ - 1) && vetoPositions.at(z_side, bin1 + 1, bin2)) or MIPT_seed >= MIPT_S) &&
513  (((bin1 > 0) && vetoPositions.at(z_side, bin1 - 1, bin2)) or MIPT_seed > MIPT_N) &&
514  ((vetoPositions.at(z_side, bin1, binRight)) or MIPT_seed >= MIPT_E) &&
515  (((bin1 < nBins1_ - 1) && vetoPositions.at(z_side, bin1 + 1, binRight)) or MIPT_seed >= MIPT_SE) &&
516  (((bin1 > 0) && vetoPositions.at(z_side, bin1 - 1, binRight)) or MIPT_seed >= MIPT_NE) &&
517  ((vetoPositions.at(z_side, bin1, binLeft)) or MIPT_seed > MIPT_W) &&
518  (((bin1 < nBins1_ - 1) && vetoPositions.at(z_side, bin1 + 1, binLeft)) or MIPT_seed > MIPT_SW) &&
519  (((bin1 > 0) && vetoPositions.at(z_side, bin1 - 1, binLeft)) or MIPT_seed > MIPT_NW);
520 
521  if (isMax) {
522  setSeedEnergyAndPosition(seedPositionsEnergy, z_side, bin1, bin2, histoClusters.at(z_side, bin1, bin2));
523  }
524  }
525  }
526  }
527 
528  return seedPositionsEnergy;
529 }
530 
532  std::vector<std::pair<GlobalPoint, double>>& seedPositionsEnergy) {
533  /* put clusters into an r/z x phi histogram */
534  Histogram histoCluster = fillHistoClusters(clustersPtrs);
535 
536  Histogram smoothHistoCluster;
537  if (seedingSpace_ == RPhi) {
538  /* smoothen along the phi direction + normalize each bin to same area */
539  Histogram smoothPhiHistoCluster = fillSmoothPhiHistoClusters(histoCluster, binsSumsHisto_);
540 
541  /* smoothen along the r/z direction */
542  smoothHistoCluster = fillSmoothRPhiHistoClusters(smoothPhiHistoCluster);
543  } else if (seedingSpace_ == XY) {
544  smoothHistoCluster = fillSmoothHistoClusters(histoCluster, smoothing_ecal_, Bin::Content::Ecal);
545  smoothHistoCluster = fillSmoothHistoClusters(smoothHistoCluster, smoothing_hcal_, Bin::Content::Hcal);
546  // Update sum with smoothen ECAL + HCAL
547  for (int z_side : {-1, 1}) {
548  for (unsigned x1 = 0; x1 < nBins1_; x1++) {
549  for (unsigned x2 = 0; x2 < nBins2_; x2++) {
550  auto& bin = smoothHistoCluster.at(z_side, x1, x2);
551  bin.values[Bin::Content::Sum] = bin.values[Bin::Content::Ecal] + bin.values[Bin::Content::Hcal];
552  }
553  }
554  }
555  }
556 
557  /* seeds determined with local maximum criteria */
558  if (seedingType_ == HistoMaxC3d)
559  seedPositionsEnergy = computeMaxSeeds(smoothHistoCluster);
560  else if (seedingType_ == HistoThresholdC3d)
561  seedPositionsEnergy = computeThresholdSeeds(smoothHistoCluster);
563  seedPositionsEnergy = computeInterpolatedMaxSeeds(smoothHistoCluster);
565  seedPositionsEnergy = computeSecondaryMaxSeeds(smoothHistoCluster);
566 }
567 
568 std::array<double, 4> HGCalHistoSeedingImpl::boundaries() {
569  switch (seedingSpace_) {
570  case RPhi:
571  return {{kROverZMin_, kROverZMax_, -M_PI, M_PI}};
572  case XY:
573  return {{-kXYMax_, kXYMax_, -kXYMax_, kXYMax_}};
574  }
575  return {{0., 0., 0., 0.}};
576 }
std::vector< std::pair< GlobalPoint, double > > computeInterpolatedMaxSeeds(const Histogram &histoClusters)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
static constexpr unsigned neighbour_weights_size_
std::vector< unsigned > binsSumsHisto_
constexpr T reduceRange(T x)
Definition: deltaPhi.h:18
Histogram fillSmoothPhiHistoClusters(const Histogram &histoClusters, const vector< unsigned > &binSums)
Histogram fillSmoothRPhiHistoClusters(const Histogram &histoClusters)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
Definition: weight.py:1
SeedingPosition seedingPosition_
std::vector< std::pair< GlobalPoint, double > > computeMaxSeeds(const Histogram &histoClusters)
HGCalTriggerTools triggerTools_
std::vector< std::pair< GlobalPoint, double > > computeSecondaryMaxSeeds(const Histogram &histoClusters)
int zside(const DetId &) const
void findHistoSeeds(const std::vector< edm::Ptr< l1t::HGCalCluster >> &clustersPtr, std::vector< std::pair< GlobalPoint, double >> &seedPositionsEnergy)
T sqrt(T t)
Definition: SSEVec.h:19
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void setSeedEnergyAndPosition(std::vector< std::pair< GlobalPoint, double >> &seedPositionsEnergy, int z_side, unsigned bin_R, unsigned bin_phi, const Bin &histBin)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Histogram fillSmoothHistoClusters(const Histogram &, const vector< double > &, Bin::Content)
std::array< int, 2 > move(int offset1, int offset2)
bool isEm(const DetId &) const
std::array< double, 4 > boundaries()
std::vector< double > smoothing_ecal_
#define M_PI
std::vector< std::pair< GlobalPoint, double > > computeThresholdSeeds(const Histogram &histoClusters)
Log< level::Info, false > LogInfo
std::array< float, 3 > values
std::vector< double > neighbour_weights_
Histogram fillHistoClusters(const std::vector< edm::Ptr< l1t::HGCalCluster >> &clustersPtrs)
static constexpr double kXYMax_
T & at(int zside, unsigned x1, unsigned x2)
std::vector< double > smoothing_hcal_
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
static constexpr double area_per_triggercell_
HGCalHistoSeedingImpl(const edm::ParameterSet &conf)