CMS 3D CMS Logo

PatternRecognitionbyCLUE3D.cc
Go to the documentation of this file.
1 // Author: Marco Rovere - marco.rovere@cern.ch
2 // Date: 04/2021
3 #include <algorithm>
4 #include <set>
5 #include <vector>
6 
12 
13 #include "TrackstersPCA.h"
17 
18 using namespace ticl;
19 
20 template <typename TILES>
22  : PatternRecognitionAlgoBaseT<TILES>(conf, iC),
23  caloGeomToken_(iC.esConsumes<CaloGeometry, CaloGeometryRecord>()),
24  criticalDensity_(conf.getParameter<double>("criticalDensity")),
25  criticalSelfDensity_(conf.getParameter<double>("criticalSelfDensity")),
26  densitySiblingLayers_(conf.getParameter<int>("densitySiblingLayers")),
27  densityEtaPhiDistanceSqr_(conf.getParameter<double>("densityEtaPhiDistanceSqr")),
28  densityXYDistanceSqr_(conf.getParameter<double>("densityXYDistanceSqr")),
29  kernelDensityFactor_(conf.getParameter<double>("kernelDensityFactor")),
30  densityOnSameLayer_(conf.getParameter<bool>("densityOnSameLayer")),
31  nearestHigherOnSameLayer_(conf.getParameter<bool>("nearestHigherOnSameLayer")),
32  useAbsoluteProjectiveScale_(conf.getParameter<bool>("useAbsoluteProjectiveScale")),
33  useClusterDimensionXY_(conf.getParameter<bool>("useClusterDimensionXY")),
34  rescaleDensityByZ_(conf.getParameter<bool>("rescaleDensityByZ")),
35  criticalEtaPhiDistance_(conf.getParameter<double>("criticalEtaPhiDistance")),
36  criticalXYDistance_(conf.getParameter<double>("criticalXYDistance")),
37  criticalZDistanceLyr_(conf.getParameter<int>("criticalZDistanceLyr")),
38  outlierMultiplier_(conf.getParameter<double>("outlierMultiplier")),
39  minNumLayerCluster_(conf.getParameter<int>("minNumLayerCluster")),
40  eidInputName_(conf.getParameter<std::string>("eid_input_name")),
41  eidOutputNameEnergy_(conf.getParameter<std::string>("eid_output_name_energy")),
42  eidOutputNameId_(conf.getParameter<std::string>("eid_output_name_id")),
43  eidMinClusterEnergy_(conf.getParameter<double>("eid_min_cluster_energy")),
44  eidNLayers_(conf.getParameter<int>("eid_n_layers")),
45  eidNClusters_(conf.getParameter<int>("eid_n_clusters")){};
46 
47 template <typename TILES>
48 void PatternRecognitionbyCLUE3D<TILES>::dumpTiles(const TILES &tiles) const {
51  auto lastLayerPerSide = static_cast<int>(rhtools_.lastLayer(false));
52  int maxLayer = 2 * lastLayerPerSide - 1;
53  for (int layer = 0; layer <= maxLayer; layer++) {
54  for (int ieta = 0; ieta < nEtaBin; ieta++) {
55  auto offset = ieta * nPhiBin;
56  for (int phi = 0; phi < nPhiBin; phi++) {
57  int iphi = ((phi % nPhiBin + nPhiBin) % nPhiBin);
58  if (!tiles[layer][offset + iphi].empty()) {
59  if (this->algo_verbosity_ > VerbosityLevel::Advanced) {
60  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Layer: " << layer << " ieta: " << ieta << " phi: " << phi
61  << " " << tiles[layer][offset + iphi].size();
62  }
63  }
64  }
65  }
66  }
67 }
68 
69 template <typename TILES>
70 void PatternRecognitionbyCLUE3D<TILES>::dumpTracksters(const std::vector<std::pair<int, int>> &layerIdx2layerandSoa,
71  const int eventNumber,
72  const std::vector<Trackster> &tracksters) const {
74  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
75  << "[evt, tracksterId, cells, prob_photon, prob_ele, prob_chad, prob_nhad, layer_i, x_i, y_i, eta_i, phi_i, "
76  "energy_i, radius_i, rho_i, z_extension, delta_tr, delta_lyr, isSeed_i";
77  }
78 
79  int num = 0;
80  const std::string sep(", ");
81  for (auto const &t : tracksters) {
82  for (auto v : t.vertices()) {
83  auto [lyrIdx, soaIdx] = layerIdx2layerandSoa[v];
84  auto const &thisLayer = clusters_[lyrIdx];
86  edm::LogVerbatim("PatternRecognitionbyCLUE3D_NTP")
87  << std::setw(4) << eventNumber << sep << std::setw(4) << num << sep << std::setw(4) << t.vertices().size()
88  << sep << std::setw(8) << t.id_probability(ticl::Trackster::ParticleType::photon) << sep << std::setw(8)
89  << t.id_probability(ticl::Trackster::ParticleType::electron) << sep << std::setw(8)
90  << t.id_probability(ticl::Trackster::ParticleType::charged_hadron) << sep << std::setw(8)
91  << t.id_probability(ticl::Trackster::ParticleType::neutral_hadron) << sep << std::setw(4) << lyrIdx << sep
92  << std::setw(10) << thisLayer.x[soaIdx] << sep << std::setw(10) << thisLayer.y[soaIdx] << sep
93  << std::setw(10) << thisLayer.eta[soaIdx] << sep << std::setw(10) << thisLayer.phi[soaIdx] << sep
94  << std::setw(10) << thisLayer.energy[soaIdx] << sep << std::setw(10) << thisLayer.radius[soaIdx] << sep
95  << std::setw(10) << thisLayer.rho[soaIdx] << sep << std::setw(10) << thisLayer.z_extension[soaIdx] << sep
96  << std::setw(10) << thisLayer.delta[soaIdx].first << sep << std::setw(10) << thisLayer.delta[soaIdx].second
97  << sep << std::setw(4) << thisLayer.isSeed[soaIdx];
98  }
99  }
100  num++;
101  }
102 }
103 
104 template <typename TILES>
106  const std::vector<std::pair<int, int>> &layerIdx2layerandSoa,
107  const int eventNumber) const {
109  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "[evt, lyr, Seed, x, y, z, r/|z|, eta, phi, "
110  "etab, phib, cells, enrgy, e/rho, rho, z_ext, "
111  " dlt_tr, dlt_lyr, "
112  " nestHL, nestHSoaIdx, radius, clIdx, lClOrigIdx, SOAidx";
113  }
114 
115  for (unsigned int layer = 0; layer < clusters_.size(); layer++) {
116  auto const &thisLayer = clusters_[layer];
117  int num = 0;
118  for (auto v : thisLayer.x) {
120  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
121  << std::setw(4) << eventNumber << ", " << std::setw(3) << layer << ", " << std::setw(4)
122  << thisLayer.isSeed[num] << ", " << std::setprecision(3) << std::fixed << v << ", " << thisLayer.y[num]
123  << ", " << thisLayer.z[num] << ", " << thisLayer.r_over_absz[num] << ", " << thisLayer.eta[num] << ", "
124  << thisLayer.phi[num] << ", " << std::setw(5) << tiles[layer].etaBin(thisLayer.eta[num]) << ", "
125  << std::setw(5) << tiles[layer].phiBin(thisLayer.phi[num]) << ", " << std::setw(4) << thisLayer.cells[num]
126  << ", " << std::setprecision(3) << thisLayer.energy[num] << ", "
127  << (thisLayer.energy[num] / thisLayer.rho[num]) << ", " << thisLayer.rho[num] << ", "
128  << thisLayer.z_extension[num] << ", " << std::scientific << thisLayer.delta[num].first << ", "
129  << std::setw(10) << thisLayer.delta[num].second << ", " << std::setw(5)
130  << thisLayer.nearestHigher[num].first << ", " << std::setw(10) << thisLayer.nearestHigher[num].second
131  << ", " << std::defaultfloat << std::setprecision(3) << thisLayer.radius[num] << ", " << std::setw(5)
132  << thisLayer.clusterIndex[num] << ", " << std::setw(4) << thisLayer.layerClusterOriginalIdx[num] << ", "
133  << std::setw(4) << num << ", ClusterInfo";
134  }
135  ++num;
136  }
137  }
138  for (unsigned int lcIdx = 0; lcIdx < layerIdx2layerandSoa.size(); lcIdx++) {
139  auto const &layerandSoa = layerIdx2layerandSoa[lcIdx];
140  // Skip masked layer clusters
141  if ((layerandSoa.first == -1) && (layerandSoa.second == -1))
142  continue;
144  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
145  << "lcIdx: " << lcIdx << " on Layer: " << layerandSoa.first << " SOA: " << layerandSoa.second;
146  }
147  }
148 }
149 
150 template <typename TILES>
153  std::vector<Trackster> &result,
154  std::unordered_map<int, std::vector<int>> &seedToTracksterAssociation) {
155  // Protect from events with no seeding regions
156  if (input.regions.empty())
157  return;
158 
159  const int eventNumber = input.ev.eventAuxiliary().event();
161  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "New Event";
162  }
163 
164  edm::EventSetup const &es = input.es;
165  const CaloGeometry &geom = es.getData(caloGeomToken_);
166  rhtools_.setGeometry(geom);
167 
168  // Assume identical Z-positioning between positive and negative sides.
169  // Also, layers inside the HGCAL geometry start from 1.
170  for (unsigned int i = 0; i < rhtools_.lastLayer(); ++i) {
171  layersPosZ_.push_back(rhtools_.getPositionLayer(i + 1).z());
173  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Layer " << i << " located at Z: " << layersPosZ_.back();
174  }
175  }
176 
177  clusters_.clear();
178  clusters_.resize(2 * rhtools_.lastLayer(false));
179  std::vector<std::pair<int, int>> layerIdx2layerandSoa; //used everywhere also to propagate cluster masking
180 
181  layerIdx2layerandSoa.reserve(input.layerClusters.size());
182  unsigned int layerIdx = 0;
183  for (auto const &lc : input.layerClusters) {
184  if (input.mask[layerIdx] == 0.) {
186  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Skipping masked cluster: " << layerIdx;
187  }
188  layerIdx2layerandSoa.emplace_back(-1, -1);
189  layerIdx++;
190  continue;
191  }
192  const auto firstHitDetId = lc.hitsAndFractions()[0].first;
193  int layer = rhtools_.getLayerWithOffset(firstHitDetId) - 1 +
194  rhtools_.lastLayer(false) * ((rhtools_.zside(firstHitDetId) + 1) >> 1);
195  assert(layer >= 0);
196  auto detId = lc.hitsAndFractions()[0].first;
197 
198  layerIdx2layerandSoa.emplace_back(layer, clusters_[layer].x.size());
199  float sum_x = 0.;
200  float sum_y = 0.;
201  float sum_sqr_x = 0.;
202  float sum_sqr_y = 0.;
203  float ref_x = lc.x();
204  float ref_y = lc.y();
205  float invClsize = 1. / lc.hitsAndFractions().size();
206  for (auto const &hitsAndFractions : lc.hitsAndFractions()) {
207  auto const &point = rhtools_.getPosition(hitsAndFractions.first);
208  sum_x += point.x() - ref_x;
209  sum_sqr_x += (point.x() - ref_x) * (point.x() - ref_x);
210  sum_y += point.y() - ref_y;
211  sum_sqr_y += (point.y() - ref_y) * (point.y() - ref_y);
212  }
213  // The variance of X for X uniform in circle of radius R is R^2/4,
214  // therefore we multiply the sqrt(var) by 2 to have a rough estimate of the
215  // radius. On the other hand, while averaging the x and y radius, we would
216  // end up dividing by 2. Hence we omit the value here and in the average
217  // below, too.
218  float radius_x = sqrt((sum_sqr_x - (sum_x * sum_x) * invClsize) * invClsize);
219  float radius_y = sqrt((sum_sqr_y - (sum_y * sum_y) * invClsize) * invClsize);
221  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
222  << "cluster rx: " << std::setw(5) << radius_x << ", ry: " << std::setw(5) << radius_y
223  << ", r: " << std::setw(5) << (radius_x + radius_y) << ", cells: " << std::setw(4)
224  << lc.hitsAndFractions().size();
225  }
226 
227  // The case of single cell layer clusters has to be handled differently.
228 
229  if (invClsize == 1.) {
230  // Silicon case
231  if (rhtools_.isSilicon(detId)) {
232  radius_x = radius_y = rhtools_.getRadiusToSide(detId);
234  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Single cell cluster in silicon, rx: " << std::setw(5)
235  << radius_x << ", ry: " << std::setw(5) << radius_y;
236  }
237  } else {
238  auto const &point = rhtools_.getPosition(detId);
239  auto const &eta_phi_window = rhtools_.getScintDEtaDPhi(detId);
240  radius_x = radius_y = point.perp() * eta_phi_window.second;
242  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
243  << "Single cell cluster in scintillator. rx: " << std::setw(5) << radius_x << ", ry: " << std::setw(5)
244  << radius_y << ", eta-span: " << std::setw(5) << eta_phi_window.first << ", phi-span: " << std::setw(5)
245  << eta_phi_window.second;
246  }
247  }
248  }
249  clusters_[layer].x.emplace_back(lc.x());
250  clusters_[layer].y.emplace_back(lc.y());
251  clusters_[layer].z.emplace_back(lc.z());
252  clusters_[layer].r_over_absz.emplace_back(sqrt(lc.x() * lc.x() + lc.y() * lc.y()) / std::abs(lc.z()));
253  clusters_[layer].radius.emplace_back(radius_x + radius_y);
254  clusters_[layer].eta.emplace_back(lc.eta());
255  clusters_[layer].phi.emplace_back(lc.phi());
256  clusters_[layer].cells.push_back(lc.hitsAndFractions().size());
257  clusters_[layer].isSilicon.push_back(rhtools_.isSilicon(detId));
258  clusters_[layer].energy.emplace_back(lc.energy());
259  clusters_[layer].isSeed.push_back(false);
260  clusters_[layer].clusterIndex.emplace_back(-1);
261  clusters_[layer].layerClusterOriginalIdx.emplace_back(layerIdx++);
262  clusters_[layer].nearestHigher.emplace_back(-1, -1);
263  clusters_[layer].rho.emplace_back(0.f);
264  clusters_[layer].z_extension.emplace_back(0.f);
265  clusters_[layer].delta.emplace_back(
267  }
268  for (unsigned int layer = 0; layer < clusters_.size(); layer++) {
269  clusters_[layer].followers.resize(clusters_[layer].x.size());
270  }
271 
272  auto lastLayerPerSide = static_cast<int>(rhtools_.lastLayer(false));
273  int maxLayer = 2 * lastLayerPerSide - 1;
274  std::vector<int> numberOfClustersPerLayer(maxLayer, 0);
275  for (int i = 0; i <= maxLayer; i++) {
276  calculateLocalDensity(input.tiles, i, layerIdx2layerandSoa);
277  }
278  for (int i = 0; i <= maxLayer; i++) {
279  calculateDistanceToHigher(input.tiles, i, layerIdx2layerandSoa);
280  }
281 
282  auto nTracksters = findAndAssignTracksters(input.tiles, layerIdx2layerandSoa);
284  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Reconstructed " << nTracksters << " tracksters" << std::endl;
285  dumpClusters(input.tiles, layerIdx2layerandSoa, eventNumber);
286  }
287 
288  // Build Trackster
289  result.resize(nTracksters);
290 
291  for (unsigned int layer = 0; layer < clusters_.size(); ++layer) {
292  const auto &thisLayer = clusters_[layer];
294  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Examining Layer: " << layer;
295  }
296  for (unsigned int lc = 0; lc < thisLayer.x.size(); ++lc) {
298  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Trackster " << thisLayer.clusterIndex[lc];
299  }
300  if (thisLayer.clusterIndex[lc] >= 0) {
302  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << " adding lcIdx: " << thisLayer.layerClusterOriginalIdx[lc];
303  }
304  result[thisLayer.clusterIndex[lc]].vertices().push_back(thisLayer.layerClusterOriginalIdx[lc]);
305  result[thisLayer.clusterIndex[lc]].vertex_multiplicity().push_back(1);
306  // loop over followers
307  for (auto [follower_lyrIdx, follower_soaIdx] : thisLayer.followers[lc]) {
308  std::array<unsigned int, 2> edge = {
309  {(unsigned int)thisLayer.layerClusterOriginalIdx[lc],
310  (unsigned int)clusters_[follower_lyrIdx].layerClusterOriginalIdx[follower_soaIdx]}};
311  result[thisLayer.clusterIndex[lc]].edges().push_back(edge);
312  }
313  }
314  }
315  }
316 
317  result.erase(
318  std::remove_if(std::begin(result),
319  std::end(result),
320  [&](auto const &v) { return static_cast<int>(v.vertices().size()) < minNumLayerCluster_; }),
321  result.end());
322  result.shrink_to_fit();
323 
325  input.layerClusters,
326  input.layerClustersTime,
327  rhtools_.getPositionLayer(rhtools_.lastLayerEE(false), false).z());
328 
329  // run energy regression and ID
330  energyRegressionAndID(input.layerClusters, input.tfSession, result);
332  for (auto const &t : result) {
333  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Barycenter: " << t.barycenter();
334  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "LCs: " << t.vertices().size();
335  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Energy: " << t.raw_energy();
336  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Regressed: " << t.regressed_energy();
337  }
338  }
339 
340  // Dump Tracksters information
342  dumpTracksters(layerIdx2layerandSoa, eventNumber, result);
343  }
344 
345  // Reset internal clusters_ structure of array for next event
346  reset();
348  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << std::endl;
349  }
350 }
351 
352 template <typename TILES>
354  const tensorflow::Session *eidSession,
355  std::vector<Trackster> &tracksters) {
356  // Energy regression and particle identification strategy:
357  //
358  // 1. Set default values for regressed energy and particle id for each trackster.
359  // 2. Store indices of tracksters whose total sum of cluster energies is above the
360  // eidMinClusterEnergy_ (GeV) threshold. Inference is not applied for soft tracksters.
361  // 3. When no trackster passes the selection, return.
362  // 4. Create input and output tensors. The batch dimension is determined by the number of
363  // selected tracksters.
364  // 5. Fill input tensors with layer cluster features. Per layer, clusters are ordered descending
365  // by energy. Given that tensor data is contiguous in memory, we can use pointer arithmetic to
366  // fill values, even with batching.
367  // 6. Zero-fill features for empty clusters in each layer.
368  // 7. Batched inference.
369  // 8. Assign the regressed energy and id probabilities to each trackster.
370  //
371  // Indices used throughout this method:
372  // i -> batch element / trackster
373  // j -> layer
374  // k -> cluster
375  // l -> feature
376 
377  // set default values per trackster, determine if the cluster energy threshold is passed,
378  // and store indices of hard tracksters
379  std::vector<int> tracksterIndices;
380  for (int i = 0; i < static_cast<int>(tracksters.size()); i++) {
381  // calculate the cluster energy sum (2)
382  // note: after the loop, sumClusterEnergy might be just above the threshold which is enough to
383  // decide whether to run inference for the trackster or not
384  float sumClusterEnergy = 0.;
385  for (const unsigned int &vertex : tracksters[i].vertices()) {
386  sumClusterEnergy += static_cast<float>(layerClusters[vertex].energy());
387  // there might be many clusters, so try to stop early
388  if (sumClusterEnergy >= eidMinClusterEnergy_) {
389  // set default values (1)
390  tracksters[i].setRegressedEnergy(0.f);
391  tracksters[i].zeroProbabilities();
392  tracksterIndices.push_back(i);
393  break;
394  }
395  }
396  }
397 
398  // do nothing when no trackster passes the selection (3)
399  int batchSize = static_cast<int>(tracksterIndices.size());
400  if (batchSize == 0) {
401  return;
402  }
403 
404  // create input and output tensors (4)
405  tensorflow::TensorShape shape({batchSize, eidNLayers_, eidNClusters_, eidNFeatures_});
406  tensorflow::Tensor input(tensorflow::DT_FLOAT, shape);
407  tensorflow::NamedTensorList inputList = {{eidInputName_, input}};
408 
409  std::vector<tensorflow::Tensor> outputs;
410  std::vector<std::string> outputNames;
411  if (!eidOutputNameEnergy_.empty()) {
412  outputNames.push_back(eidOutputNameEnergy_);
413  }
414  if (!eidOutputNameId_.empty()) {
415  outputNames.push_back(eidOutputNameId_);
416  }
417 
418  // fill input tensor (5)
419  for (int i = 0; i < batchSize; i++) {
420  const Trackster &trackster = tracksters[tracksterIndices[i]];
421 
422  // per layer, we only consider the first eidNClusters_ clusters in terms of energy, so in order
423  // to avoid creating large / nested structures to do the sorting for an unknown number of total
424  // clusters, create a sorted list of layer cluster indices to keep track of the filled clusters
425  std::vector<int> clusterIndices(trackster.vertices().size());
426  for (int k = 0; k < (int)trackster.vertices().size(); k++) {
427  clusterIndices[k] = k;
428  }
429  sort(clusterIndices.begin(), clusterIndices.end(), [&layerClusters, &trackster](const int &a, const int &b) {
430  return layerClusters[trackster.vertices(a)].energy() > layerClusters[trackster.vertices(b)].energy();
431  });
432 
433  // keep track of the number of seen clusters per layer
434  std::vector<int> seenClusters(eidNLayers_);
435 
436  // loop through clusters by descending energy
437  for (const int &k : clusterIndices) {
438  // get features per layer and cluster and store the values directly in the input tensor
439  const reco::CaloCluster &cluster = layerClusters[trackster.vertices(k)];
440  int j = rhtools_.getLayerWithOffset(cluster.hitsAndFractions()[0].first) - 1;
441  if (j < eidNLayers_ && seenClusters[j] < eidNClusters_) {
442  // get the pointer to the first feature value for the current batch, layer and cluster
443  float *features = &input.tensor<float, 4>()(i, j, seenClusters[j], 0);
444 
445  // fill features
446  *(features++) = float(cluster.energy() / float(trackster.vertex_multiplicity(k)));
447  *(features++) = float(std::abs(cluster.eta()));
448  *(features) = float(cluster.phi());
449 
450  // increment seen clusters
451  seenClusters[j]++;
452  }
453  }
454 
455  // zero-fill features of empty clusters in each layer (6)
456  for (int j = 0; j < eidNLayers_; j++) {
457  for (int k = seenClusters[j]; k < eidNClusters_; k++) {
458  float *features = &input.tensor<float, 4>()(i, j, k, 0);
459  for (int l = 0; l < eidNFeatures_; l++) {
460  *(features++) = 0.f;
461  }
462  }
463  }
464  }
465 
466  // run the inference (7)
468 
469  // store regressed energy per trackster (8)
470  if (!eidOutputNameEnergy_.empty()) {
471  // get the pointer to the energy tensor, dimension is batch x 1
472  float *energy = outputs[0].flat<float>().data();
473 
474  for (const int &i : tracksterIndices) {
475  tracksters[i].setRegressedEnergy(*(energy++));
476  }
477  }
478 
479  // store id probabilities per trackster (8)
480  if (!eidOutputNameId_.empty()) {
481  // get the pointer to the id probability tensor, dimension is batch x id_probabilities.size()
482  int probsIdx = eidOutputNameEnergy_.empty() ? 0 : 1;
483  float *probs = outputs[probsIdx].flat<float>().data();
484 
485  for (const int &i : tracksterIndices) {
486  tracksters[i].setProbabilities(probs);
487  probs += tracksters[i].id_probabilities().size();
488  }
489  }
490 }
491 
492 template <typename TILES>
494  const TILES &tiles, const int layerId, const std::vector<std::pair<int, int>> &layerIdx2layerandSoa) {
497  auto &clustersOnLayer = clusters_[layerId];
498  unsigned int numberOfClusters = clustersOnLayer.x.size();
499 
500  auto isReachable = [](float r0, float r1, float phi0, float phi1, float delta_sqr) -> bool {
501  auto delta_phi = reco::deltaPhi(phi0, phi1);
502  return (r0 - r1) * (r0 - r1) + r1 * r1 * delta_phi * delta_phi < delta_sqr;
503  };
504  auto distance_debug = [&](float x1, float x2, float y1, float y2) -> float {
505  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
506  };
507 
508  for (unsigned int i = 0; i < numberOfClusters; i++) {
509  // We need to partition the two sides of the HGCAL detector
510  auto lastLayerPerSide = static_cast<int>(rhtools_.lastLayer(false));
511  int minLayer = 0;
512  int maxLayer = 2 * lastLayerPerSide - 1;
513  if (layerId < lastLayerPerSide) {
514  minLayer = std::max(layerId - densitySiblingLayers_, minLayer);
515  maxLayer = std::min(layerId + densitySiblingLayers_, lastLayerPerSide - 1);
516  } else {
517  minLayer = std::max(layerId - densitySiblingLayers_, lastLayerPerSide);
518  maxLayer = std::min(layerId + densitySiblingLayers_, maxLayer);
519  }
520  float deltaLayersZ = std::abs(layersPosZ_[maxLayer % lastLayerPerSide] - layersPosZ_[minLayer % lastLayerPerSide]);
521 
522  for (int currentLayer = minLayer; currentLayer <= maxLayer; currentLayer++) {
524  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "RefLayer: " << layerId << " SoaIDX: " << i;
525  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "NextLayer: " << currentLayer;
526  }
527  const auto &tileOnLayer = tiles[currentLayer];
528  bool onSameLayer = (currentLayer == layerId);
530  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "onSameLayer: " << onSameLayer;
531  }
532  const int etaWindow = 2;
533  const int phiWindow = 2;
534  int etaBinMin = std::max(tileOnLayer.etaBin(clustersOnLayer.eta[i]) - etaWindow, 0);
535  int etaBinMax = std::min(tileOnLayer.etaBin(clustersOnLayer.eta[i]) + etaWindow, nEtaBin - 1);
536  int phiBinMin = tileOnLayer.phiBin(clustersOnLayer.phi[i]) - phiWindow;
537  int phiBinMax = tileOnLayer.phiBin(clustersOnLayer.phi[i]) + phiWindow;
539  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "eta: " << clustersOnLayer.eta[i];
540  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "phi: " << clustersOnLayer.phi[i];
541  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "etaBinMin: " << etaBinMin << ", etaBinMax: " << etaBinMax;
542  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "phiBinMin: " << phiBinMin << ", phiBinMax: " << phiBinMax;
543  }
544  for (int ieta = etaBinMin; ieta <= etaBinMax; ++ieta) {
545  auto offset = ieta * nPhiBin;
547  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "offset: " << offset;
548  }
549  for (int iphi_it = phiBinMin; iphi_it <= phiBinMax; ++iphi_it) {
550  int iphi = ((iphi_it % nPhiBin + nPhiBin) % nPhiBin);
552  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "iphi: " << iphi;
553  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
554  << "Entries in tileBin: " << tileOnLayer[offset + iphi].size();
555  }
556  for (auto otherClusterIdx : tileOnLayer[offset + iphi]) {
557  auto const &layerandSoa = layerIdx2layerandSoa[otherClusterIdx];
558  // Skip masked layer clusters
559  if ((layerandSoa.first == -1) && (layerandSoa.second == -1)) {
561  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Skipping masked layerIdx " << otherClusterIdx;
562  }
563  continue;
564  }
565  auto const &clustersLayer = clusters_[layerandSoa.first];
567  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
568  << "OtherLayer: " << layerandSoa.first << " SoaIDX: " << layerandSoa.second;
569  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "OtherEta: " << clustersLayer.eta[layerandSoa.second];
570  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "OtherPhi: " << clustersLayer.phi[layerandSoa.second];
571  }
572 
573  bool onSameCluster = clustersOnLayer.layerClusterOriginalIdx[i] == otherClusterIdx;
574  if (onSameLayer && !densityOnSameLayer_ && !onSameCluster) {
576  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
577  << "Skipping different cluster " << otherClusterIdx << "in the same layer " << currentLayer;
578  }
579  continue;
580  }
581 
582  bool reachable = false;
583  if (useAbsoluteProjectiveScale_) {
584  if (useClusterDimensionXY_) {
585  reachable = isReachable(clustersOnLayer.r_over_absz[i] * clustersOnLayer.z[i],
586  clustersLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[i],
587  clustersOnLayer.phi[i],
588  clustersLayer.phi[layerandSoa.second],
589  clustersOnLayer.radius[i] * clustersOnLayer.radius[i]);
590  } else {
591  // Still differentiate between silicon and Scintillator.
592  // Silicon has yet to be studied further.
593  if (clustersOnLayer.isSilicon[i]) {
594  reachable = isReachable(clustersOnLayer.r_over_absz[i] * clustersOnLayer.z[i],
595  clustersLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[i],
596  clustersOnLayer.phi[i],
597  clustersLayer.phi[layerandSoa.second],
598  densityXYDistanceSqr_);
599  } else {
600  reachable = isReachable(clustersOnLayer.r_over_absz[i] * clustersOnLayer.z[i],
601  clustersLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[i],
602  clustersOnLayer.phi[i],
603  clustersLayer.phi[layerandSoa.second],
604  clustersOnLayer.radius[i] * clustersOnLayer.radius[i]);
605  }
606  }
607  } else {
608  reachable = (reco::deltaR2(clustersOnLayer.eta[i],
609  clustersOnLayer.phi[i],
610  clustersLayer.eta[layerandSoa.second],
611  clustersLayer.phi[layerandSoa.second]) < densityEtaPhiDistanceSqr_);
612  }
614  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Distance[eta,phi]: "
615  << reco::deltaR2(clustersOnLayer.eta[i],
616  clustersOnLayer.phi[i],
617  clustersLayer.eta[layerandSoa.second],
618  clustersLayer.phi[layerandSoa.second]);
619  auto dist = distance_debug(
620  clustersOnLayer.r_over_absz[i],
621  clustersLayer.r_over_absz[layerandSoa.second],
622  clustersOnLayer.r_over_absz[i] * std::abs(clustersOnLayer.phi[i]),
623  clustersLayer.r_over_absz[layerandSoa.second] * std::abs(clustersLayer.phi[layerandSoa.second]));
624  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Distance[cm]: " << (dist * clustersOnLayer.z[i]);
625  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
626  << "Energy Other: " << clustersLayer.energy[layerandSoa.second];
627  edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Cluster radius: " << clustersOnLayer.radius[i];
628  }
629  if (reachable) {
630  auto energyToAdd =
631  (onSameCluster ? 1.f : kernelDensityFactor_) * clustersLayer.energy[layerandSoa.second];
632  clustersOnLayer.rho[i] += energyToAdd;
633  clustersOnLayer.z_extension[i] = deltaLayersZ;
635  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
636  << "Adding " << energyToAdd << " partial " << clustersOnLayer.rho[i];
637  }
638  }
639  } // end of loop on possible compatible clusters
640  } // end of loop over phi-bin region
641  } // end of loop over eta-bin region
642  } // end of loop on the sibling layers
643  if (rescaleDensityByZ_) {
645  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
646  << "Rescaling original density: " << clustersOnLayer.rho[i] << " by Z: " << deltaLayersZ
647  << " to final density/cm: " << clustersOnLayer.rho[i] / deltaLayersZ;
648  }
649  clustersOnLayer.rho[i] /= deltaLayersZ;
650  }
651  } // end of loop over clusters on this layer
652 }
653 
654 template <typename TILES>
656  const TILES &tiles, const int layerId, const std::vector<std::pair<int, int>> &layerIdx2layerandSoa) {
659  auto &clustersOnLayer = clusters_[layerId];
660  unsigned int numberOfClusters = clustersOnLayer.x.size();
661 
662  auto distanceSqr = [](float r0, float r1, float phi0, float phi1) -> float {
663  auto delta_phi = reco::deltaPhi(phi0, phi1);
664  return (r0 - r1) * (r0 - r1) + r1 * r1 * delta_phi * delta_phi;
665  };
666 
667  for (unsigned int i = 0; i < numberOfClusters; i++) {
669  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
670  << "Starting searching nearestHigher on " << layerId << " with rho: " << clustersOnLayer.rho[i]
671  << " at eta, phi: " << tiles[layerId].etaBin(clustersOnLayer.eta[i]) << ", "
672  << tiles[layerId].phiBin(clustersOnLayer.phi[i]);
673  }
674  // We need to partition the two sides of the HGCAL detector
675  auto lastLayerPerSide = static_cast<int>(rhtools_.lastLayer(false));
676  int minLayer = 0;
677  int maxLayer = 2 * lastLayerPerSide - 1;
678  if (layerId < lastLayerPerSide) {
679  minLayer = std::max(layerId - densitySiblingLayers_, minLayer);
680  maxLayer = std::min(layerId + densitySiblingLayers_, lastLayerPerSide - 1);
681  } else {
682  minLayer = std::max(layerId - densitySiblingLayers_, lastLayerPerSide + 1);
683  maxLayer = std::min(layerId + densitySiblingLayers_, maxLayer);
684  }
686  float i_delta = maxDelta;
687  std::pair<int, int> i_nearestHigher(-1, -1);
688  std::pair<float, int> nearest_distances(maxDelta, std::numeric_limits<int>::max());
689  for (int currentLayer = minLayer; currentLayer <= maxLayer; currentLayer++) {
690  if (!nearestHigherOnSameLayer_ && (layerId == currentLayer))
691  continue;
692  const auto &tileOnLayer = tiles[currentLayer];
693  int etaWindow = 1;
694  int phiWindow = 1;
695  int etaBinMin = std::max(tileOnLayer.etaBin(clustersOnLayer.eta[i]) - etaWindow, 0);
696  int etaBinMax = std::min(tileOnLayer.etaBin(clustersOnLayer.eta[i]) + etaWindow, nEtaBin - 1);
697  int phiBinMin = tileOnLayer.phiBin(clustersOnLayer.phi[i]) - phiWindow;
698  int phiBinMax = tileOnLayer.phiBin(clustersOnLayer.phi[i]) + phiWindow;
699  for (int ieta = etaBinMin; ieta <= etaBinMax; ++ieta) {
700  auto offset = ieta * nPhiBin;
701  for (int iphi_it = phiBinMin; iphi_it <= phiBinMax; ++iphi_it) {
702  int iphi = ((iphi_it % nPhiBin + nPhiBin) % nPhiBin);
704  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
705  << "Searching nearestHigher on " << currentLayer << " eta, phi: " << ieta << ", " << iphi_it << " "
706  << iphi << " " << offset << " " << (offset + iphi);
707  }
708  for (auto otherClusterIdx : tileOnLayer[offset + iphi]) {
709  auto const &layerandSoa = layerIdx2layerandSoa[otherClusterIdx];
710  // Skip masked layer clusters
711  if ((layerandSoa.first == -1) && (layerandSoa.second == -1))
712  continue;
713  auto const &clustersOnOtherLayer = clusters_[layerandSoa.first];
714  auto dist = maxDelta;
715  auto dist_transverse = maxDelta;
716  int dist_layers = std::abs(layerandSoa.first - layerId);
717  if (useAbsoluteProjectiveScale_) {
718  dist_transverse = distanceSqr(clustersOnLayer.r_over_absz[i] * clustersOnLayer.z[i],
719  clustersOnOtherLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[i],
720  clustersOnLayer.phi[i],
721  clustersOnOtherLayer.phi[layerandSoa.second]);
722  // Add Z-scale to the final distance
723  dist = dist_transverse;
724  } else {
725  dist = reco::deltaR2(clustersOnLayer.eta[i],
726  clustersOnLayer.phi[i],
727  clustersOnOtherLayer.eta[layerandSoa.second],
728  clustersOnOtherLayer.phi[layerandSoa.second]);
729  dist_transverse = dist;
730  }
731  bool foundHigher = (clustersOnOtherLayer.rho[layerandSoa.second] > clustersOnLayer.rho[i]) ||
732  (clustersOnOtherLayer.rho[layerandSoa.second] == clustersOnLayer.rho[i] &&
733  clustersOnOtherLayer.layerClusterOriginalIdx[layerandSoa.second] >
734  clustersOnLayer.layerClusterOriginalIdx[i]);
736  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
737  << "Searching nearestHigher on " << currentLayer
738  << " with rho: " << clustersOnOtherLayer.rho[layerandSoa.second]
739  << " on layerIdxInSOA: " << layerandSoa.first << ", " << layerandSoa.second
740  << " with distance: " << sqrt(dist) << " foundHigher: " << foundHigher;
741  }
742  if (foundHigher && dist <= i_delta) {
743  // update i_delta
744  i_delta = dist;
745  nearest_distances = std::make_pair(sqrt(dist_transverse), dist_layers);
746  // update i_nearestHigher
747  i_nearestHigher = layerandSoa;
748  }
749  } // End of loop on clusters
750  } // End of loop on phi bins
751  } // End of loop on eta bins
752  } // End of loop on layers
753 
754  clustersOnLayer.delta[i] = nearest_distances;
755  clustersOnLayer.nearestHigher[i] = i_nearestHigher;
756  } // End of loop on clusters
757 }
758 
759 template <typename TILES>
761  const TILES &tiles, const std::vector<std::pair<int, int>> &layerIdx2layerandSoa) {
762  unsigned int nTracksters = 0;
763 
764  std::vector<std::pair<int, int>> localStack;
765  auto critical_transverse_distance = useAbsoluteProjectiveScale_ ? criticalXYDistance_ : criticalEtaPhiDistance_;
766  // find cluster seeds and outlier
767  for (unsigned int layer = 0; layer < 2 * rhtools_.lastLayer(); layer++) {
768  auto &clustersOnLayer = clusters_[layer];
769  unsigned int numberOfClusters = clustersOnLayer.x.size();
770  for (unsigned int i = 0; i < numberOfClusters; i++) {
771  // initialize clusterIndex
772  clustersOnLayer.clusterIndex[i] = -1;
773  bool isSeed = (clustersOnLayer.delta[i].first > critical_transverse_distance ||
774  clustersOnLayer.delta[i].second > criticalZDistanceLyr_) &&
775  (clustersOnLayer.rho[i] >= criticalDensity_) &&
776  (clustersOnLayer.energy[i] / clustersOnLayer.rho[i] > criticalSelfDensity_);
777  if (!clustersOnLayer.isSilicon[i]) {
778  isSeed = (clustersOnLayer.delta[i].first > clustersOnLayer.radius[i] ||
779  clustersOnLayer.delta[i].second > criticalZDistanceLyr_) &&
780  (clustersOnLayer.rho[i] >= criticalDensity_) &&
781  (clustersOnLayer.energy[i] / clustersOnLayer.rho[i] > criticalSelfDensity_);
782  }
783  bool isOutlier = (clustersOnLayer.delta[i].first > outlierMultiplier_ * critical_transverse_distance) &&
784  (clustersOnLayer.rho[i] < criticalDensity_);
785  if (isSeed) {
787  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
788  << "Found seed on Layer " << layer << " SOAidx: " << i << " assigned ClusterIdx: " << nTracksters;
789  }
790  clustersOnLayer.clusterIndex[i] = nTracksters++;
791  clustersOnLayer.isSeed[i] = true;
792  localStack.emplace_back(layer, i);
793  } else if (!isOutlier) {
794  auto [lyrIdx, soaIdx] = clustersOnLayer.nearestHigher[i];
796  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
797  << "Found follower on Layer " << layer << " SOAidx: " << i << " attached to cluster on layer: " << lyrIdx
798  << " SOAidx: " << soaIdx;
799  }
800  if (lyrIdx >= 0)
801  clusters_[lyrIdx].followers[soaIdx].emplace_back(layer, i);
802  } else {
804  edm::LogVerbatim("PatternRecognitionbyCLUE3D")
805  << "Found Outlier on Layer " << layer << " SOAidx: " << i << " with rho: " << clustersOnLayer.rho[i]
806  << " and delta: " << clustersOnLayer.delta[i].first << ", " << clustersOnLayer.delta[i].second;
807  }
808  }
809  }
810  }
811 
812  // Propagate cluster index
813  while (!localStack.empty()) {
814  auto [lyrIdx, soaIdx] = localStack.back();
815  auto &thisSeed = clusters_[lyrIdx].followers[soaIdx];
816  localStack.pop_back();
817 
818  // loop over followers
819  for (auto [follower_lyrIdx, follower_soaIdx] : thisSeed) {
820  // pass id to a follower
821  clusters_[follower_lyrIdx].clusterIndex[follower_soaIdx] = clusters_[lyrIdx].clusterIndex[soaIdx];
822  // push this follower to localStack
823  localStack.emplace_back(follower_lyrIdx, follower_soaIdx);
824  }
825  }
826  return nTracksters;
827 }
828 
829 template <typename TILES>
831  iDesc.add<int>("algo_verbosity", 0);
832  iDesc.add<double>("criticalDensity", 4)->setComment("in GeV");
833  iDesc.add<double>("criticalSelfDensity", 0.15 /* roughly 1/(densitySiblingLayers+1) */)
834  ->setComment("Minimum ratio of self_energy/local_density to become a seed.");
835  iDesc.add<int>("densitySiblingLayers", 3)
836  ->setComment(
837  "inclusive, layers to consider while computing local density and searching for nearestHigher higher");
838  iDesc.add<double>("densityEtaPhiDistanceSqr", 0.0008);
839  iDesc.add<double>("densityXYDistanceSqr", 3.24 /*6.76*/)
840  ->setComment("in cm, 2.6*2.6, distance on the transverse plane to consider for local density");
841  iDesc.add<double>("kernelDensityFactor", 0.2)
842  ->setComment("Kernel factor to be applied to other LC while computing the local density");
843  iDesc.add<bool>("densityOnSameLayer", false);
844  iDesc.add<bool>("nearestHigherOnSameLayer", false)
845  ->setComment("Allow the nearestHigher to be located on the same layer");
846  iDesc.add<bool>("useAbsoluteProjectiveScale", true)
847  ->setComment("Express all cuts in terms of r/z*z_0{,phi} projective variables");
848  iDesc.add<bool>("useClusterDimensionXY", false)
849  ->setComment(
850  "Boolean. If true use the estimated cluster radius to determine the cluster compatibility while computing "
851  "the local density");
852  iDesc.add<bool>("rescaleDensityByZ", false)
853  ->setComment(
854  "Rescale local density by the extension of the Z 'volume' explored. The transvere dimension is, at present, "
855  "fixed and factored out.");
856  iDesc.add<double>("criticalEtaPhiDistance", 0.025)
857  ->setComment("Minimal distance in eta,phi space from nearestHigher to become a seed");
858  iDesc.add<double>("criticalXYDistance", 1.8)
859  ->setComment("Minimal distance in cm on the XY plane from nearestHigher to become a seed");
860  iDesc.add<int>("criticalZDistanceLyr", 5)
861  ->setComment("Minimal distance in layers along the Z axis from nearestHigher to become a seed");
862  iDesc.add<double>("outlierMultiplier", 2);
863  iDesc.add<int>("minNumLayerCluster", 2)->setComment("Not Inclusive");
864  iDesc.add<std::string>("eid_input_name", "input");
865  iDesc.add<std::string>("eid_output_name_energy", "output/regressed_energy");
866  iDesc.add<std::string>("eid_output_name_id", "output/id_probabilities");
867  iDesc.add<double>("eid_min_cluster_energy", 1.);
868  iDesc.add<int>("eid_n_layers", 50);
869  iDesc.add<int>("eid_n_clusters", 10);
870 }
871 
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
Log< level::Info, true > LogVerbatim
void setComment(std::string const &value)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
std::vector< NamedTensor > NamedTensorList
Definition: TensorFlow.h:31
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:209
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
void energyRegressionAndID(const std::vector< reco::CaloCluster > &layerClusters, const tensorflow::Session *, std::vector< Trackster > &result)
PatternRecognitionbyCLUE3D(const edm::ParameterSet &conf, edm::ConsumesCollector)
assert(be >=bs)
double phi() const
azimuthal angle of cluster centroid
Definition: CaloCluster.h:183
void calculateDistanceToHigher(const TILES &, const int layerId, const std::vector< std::pair< int, int >> &)
static std::string const input
Definition: EdmProvDump.cc:50
void assignPCAtoTracksters(std::vector< Trackster > &, const std::vector< reco::CaloCluster > &, const edm::ValueMap< std::pair< float, float >> &, double, bool energyWeight=true)
static void fillPSetDescription(edm::ParameterSetDescription &iDesc)
void makeTracksters(const typename PatternRecognitionAlgoBaseT< TILES >::Inputs &input, std::vector< Trackster > &result, std::unordered_map< int, std::vector< int >> &seedToTracksterAssociation) override
std::vector< float > features(const reco::PreId &ecal, const reco::PreId &hcal, double rho, const reco::BeamSpot &spot, noZS::EcalClusterLazyTools &ecalTools)
T sqrt(T t)
Definition: SSEVec.h:19
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Definition: TensorFlow.cc:272
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
int findAndAssignTracksters(const TILES &, const std::vector< std::pair< int, int >> &)
string inputList
Definition: crabTemplate.py:6
ParameterDescriptionBase * add(U const &iLabel, T const &value)
double energy() const
cluster energy
Definition: CaloCluster.h:148
std::vector< unsigned int > & vertices()
Definition: Trackster.h:56
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
void dumpClusters(const TILES &tiles, const std::vector< std::pair< int, int >> &layerIdx2layerandSoa, const int) const
std::vector< float > & vertex_multiplicity()
Definition: Trackster.h:57
double b
Definition: hdecay.h:120
void calculateLocalDensity(const TILES &, const int layerId, const std::vector< std::pair< int, int >> &)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
double a
Definition: hdecay.h:121
Definition: Common.h:8
float x
double eta() const
pseudorapidity of cluster centroid
Definition: CaloCluster.h:180
void reset(double vett[256])
Definition: TPedValues.cc:11
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
void dumpTracksters(const std::vector< std::pair< int, int >> &layerIdx2layerandSoa, const int, const std::vector< Trackster > &) const