20 template <
typename TILES>
24 criticalDensity_(conf.getParameter<
std::
vector<double>>(
"criticalDensity")),
25 criticalSelfDensity_(conf.getParameter<
std::
vector<double>>(
"criticalSelfDensity")),
26 densitySiblingLayers_(conf.getParameter<
std::
vector<
int>>(
"densitySiblingLayers")),
27 densityEtaPhiDistanceSqr_(conf.getParameter<
std::
vector<double>>(
"densityEtaPhiDistanceSqr")),
28 densityXYDistanceSqr_(conf.getParameter<
std::
vector<double>>(
"densityXYDistanceSqr")),
29 kernelDensityFactor_(conf.getParameter<
std::
vector<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<
std::
vector<double>>(
"criticalEtaPhiDistance")),
36 criticalXYDistance_(conf.getParameter<
std::
vector<double>>(
"criticalXYDistance")),
37 criticalZDistanceLyr_(conf.getParameter<
std::
vector<
int>>(
"criticalZDistanceLyr")),
38 outlierMultiplier_(conf.getParameter<
std::
vector<double>>(
"outlierMultiplier")),
39 minNumLayerCluster_(conf.getParameter<
std::
vector<
int>>(
"minNumLayerCluster")),
40 doPidCut_(conf.getParameter<
bool>(
"doPidCut")),
41 cutHadProb_(conf.getParameter<double>(
"cutHadProb")),
42 eidInputName_(conf.getParameter<
std::
string>(
"eid_input_name")),
43 eidOutputNameEnergy_(conf.getParameter<
std::
string>(
"eid_output_name_energy")),
44 eidOutputNameId_(conf.getParameter<
std::
string>(
"eid_output_name_id")),
45 eidMinClusterEnergy_(conf.getParameter<double>(
"eid_min_cluster_energy")),
46 eidNLayers_(conf.getParameter<
int>(
"eid_n_layers")),
47 eidNClusters_(conf.getParameter<
int>(
"eid_n_clusters")),
48 computeLocalTime_(conf.getParameter<
bool>(
"computeLocalTime")),
49 usePCACleaning_(conf.getParameter<
bool>(
"usePCACleaning")){};
51 template <
typename TILES>
55 auto lastLayerPerSide =
static_cast<int>(rhtools_.lastLayer(
false));
56 int maxLayer = 2 * lastLayerPerSide - 1;
57 for (
int layer = 0; layer <= maxLayer; layer++) {
60 for (
int phi = 0; phi < nPhiBin; phi++) {
61 int iphi = ((phi % nPhiBin + nPhiBin) % nPhiBin);
64 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Layer: " << layer <<
" ieta: " <<
ieta <<
" phi: " << phi
73 template <
typename TILES>
75 const int eventNumber,
76 const std::vector<Trackster> &tracksters)
const {
79 <<
"[evt, tracksterId, cells, prob_photon, prob_ele, prob_chad, prob_nhad, layer_i, x_i, y_i, eta_i, phi_i, " 80 "energy_i, radius_i, rho_i, z_extension, delta_tr, delta_lyr, isSeed_i";
85 for (
auto const &
t : tracksters) {
86 for (
auto v :
t.vertices()) {
87 auto [lyrIdx, soaIdx] = layerIdx2layerandSoa[
v];
88 auto const &thisLayer = clusters_[lyrIdx];
91 << std::setw(4) << eventNumber << sep << std::setw(4) <<
num << sep << std::setw(4) <<
t.vertices().size()
96 << std::setw(10) << thisLayer.x[soaIdx] << sep << std::setw(10) << thisLayer.y[soaIdx] << sep
97 << std::setw(10) << thisLayer.eta[soaIdx] << sep << std::setw(10) << thisLayer.phi[soaIdx] << sep
98 << std::setw(10) << thisLayer.energy[soaIdx] << sep << std::setw(10) << thisLayer.radius[soaIdx] << sep
99 << std::setw(10) << thisLayer.rho[soaIdx] << sep << std::setw(10) << thisLayer.z_extension[soaIdx] << sep
100 << std::setw(10) << thisLayer.delta[soaIdx].first << sep << std::setw(10) << thisLayer.delta[soaIdx].second
101 << sep << std::setw(4) << thisLayer.isSeed[soaIdx];
108 template <
typename TILES>
110 const std::vector<std::pair<int, int>> &layerIdx2layerandSoa,
111 const int eventNumber)
const {
113 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"[evt, lyr, Seed, x, y, z, r/|z|, eta, phi, " 114 "etab, phib, cells, enrgy, e/rho, rho, z_ext, " 116 " nestHL, nestHSoaIdx, radius, clIdx, lClOrigIdx, SOAidx";
119 for (
unsigned int layer = 0; layer < clusters_.size(); layer++) {
120 auto const &thisLayer = clusters_[layer];
122 for (
auto v : thisLayer.x) {
125 << std::setw(4) << eventNumber <<
", " << std::setw(3) << layer <<
", " << std::setw(4)
126 << thisLayer.isSeed[
num] <<
", " << std::setprecision(3) <<
std::fixed <<
v <<
", " << thisLayer.y[
num]
127 <<
", " << thisLayer.z[
num] <<
", " << thisLayer.r_over_absz[
num] <<
", " << thisLayer.eta[
num] <<
", " 128 << thisLayer.phi[
num] <<
", " << std::setw(5) << tiles[layer].etaBin(thisLayer.eta[
num]) <<
", " 129 << std::setw(5) << tiles[layer].phiBin(thisLayer.phi[
num]) <<
", " << std::setw(4) << thisLayer.cells[
num]
130 <<
", " << std::setprecision(3) << thisLayer.energy[
num] <<
", " 131 << (thisLayer.energy[
num] / thisLayer.rho[
num]) <<
", " << thisLayer.rho[
num] <<
", " 132 << thisLayer.z_extension[
num] <<
", " << std::scientific << thisLayer.delta[
num].first <<
", " 133 << std::setw(10) << thisLayer.delta[
num].second <<
", " << std::setw(5)
134 << thisLayer.nearestHigher[
num].first <<
", " << std::setw(10) << thisLayer.nearestHigher[
num].second
135 <<
", " << std::defaultfloat << std::setprecision(3) << thisLayer.radius[
num] <<
", " << std::setw(5)
136 << thisLayer.clusterIndex[
num] <<
", " << std::setw(4) << thisLayer.layerClusterOriginalIdx[
num] <<
", " 137 << std::setw(4) <<
num <<
", ClusterInfo";
142 for (
unsigned int lcIdx = 0; lcIdx < layerIdx2layerandSoa.size(); lcIdx++) {
143 auto const &layerandSoa = layerIdx2layerandSoa[lcIdx];
145 if ((layerandSoa.first == -1) && (layerandSoa.second == -1))
149 <<
"lcIdx: " << lcIdx <<
" on Layer: " << layerandSoa.first <<
" SOA: " << layerandSoa.second;
154 template <
typename TILES>
157 std::vector<Trackster> &
result,
158 std::unordered_map<
int, std::vector<int>> &seedToTracksterAssociation) {
160 if (
input.regions.empty())
163 const int eventNumber =
input.ev.eventAuxiliary().event();
170 rhtools_.setGeometry(
geom);
174 for (
unsigned int i = 0;
i < rhtools_.lastLayer(); ++
i) {
175 layersPosZ_.push_back(rhtools_.getPositionLayer(
i + 1).z());
177 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Layer " <<
i <<
" located at Z: " << layersPosZ_.back();
182 tracksterSeedAlgoId_.clear();
184 clusters_.resize(2 * rhtools_.lastLayer(
false));
185 std::vector<std::pair<int, int>> layerIdx2layerandSoa;
187 layerIdx2layerandSoa.reserve(
input.layerClusters.size());
188 unsigned int layerIdx = 0;
189 for (
auto const &lc :
input.layerClusters) {
190 if (
input.mask[layerIdx] == 0.) {
192 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Skipping masked cluster: " << layerIdx;
194 layerIdx2layerandSoa.emplace_back(-1, -1);
198 const auto firstHitDetId = lc.hitsAndFractions()[0].first;
199 int layer = rhtools_.getLayerWithOffset(firstHitDetId) - 1 +
200 rhtools_.lastLayer(
false) * ((rhtools_.zside(firstHitDetId) + 1) >> 1);
202 auto detId = lc.hitsAndFractions()[0].first;
203 int layerClusterIndexInLayer = clusters_[layer].x.size();
204 layerIdx2layerandSoa.emplace_back(layer, layerClusterIndexInLayer);
207 float sum_sqr_x = 0.;
208 float sum_sqr_y = 0.;
209 float ref_x = lc.x();
210 float ref_y = lc.y();
211 float invClsize = 1. / lc.hitsAndFractions().size();
212 for (
auto const &hitsAndFractions : lc.hitsAndFractions()) {
213 auto const &
point = rhtools_.getPosition(hitsAndFractions.first);
215 sum_sqr_x += (
point.x() - ref_x) * (
point.x() - ref_x);
217 sum_sqr_y += (
point.y() - ref_y) * (
point.y() - ref_y);
224 float radius_x =
sqrt((sum_sqr_x - (
sum_x *
sum_x) * invClsize) * invClsize);
225 float radius_y =
sqrt((sum_sqr_y - (
sum_y *
sum_y) * invClsize) * invClsize);
228 <<
"cluster rx: " << std::setw(5) << radius_x <<
", ry: " << std::setw(5) << radius_y
229 <<
", r: " << std::setw(5) << (radius_x + radius_y) <<
", cells: " << std::setw(4)
230 << lc.hitsAndFractions().size();
235 if (invClsize == 1.) {
237 if (rhtools_.isSilicon(
detId)) {
238 radius_x = radius_y = rhtools_.getRadiusToSide(
detId);
240 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Single cell cluster in silicon, rx: " << std::setw(5)
241 << radius_x <<
", ry: " << std::setw(5) << radius_y;
244 auto const &
point = rhtools_.getPosition(
detId);
245 auto const &eta_phi_window = rhtools_.getScintDEtaDPhi(
detId);
246 radius_x = radius_y =
point.perp() * eta_phi_window.second;
249 <<
"Single cell cluster in scintillator. rx: " << std::setw(5) << radius_x <<
", ry: " << std::setw(5)
250 << radius_y <<
", eta-span: " << std::setw(5) << eta_phi_window.first <<
", phi-span: " << std::setw(5)
251 << eta_phi_window.second;
257 clusters_[layer].x.emplace_back(lc.x());
258 clusters_[layer].y.emplace_back(lc.y());
259 clusters_[layer].z.emplace_back(lc.z());
260 clusters_[layer].r_over_absz.emplace_back(
sqrt(lc.x() * lc.x() + lc.y() * lc.y()) /
std::abs(lc.z()));
261 clusters_[layer].radius.emplace_back(radius_x + radius_y);
262 clusters_[layer].eta.emplace_back(lc.eta());
263 clusters_[layer].phi.emplace_back(lc.phi());
264 clusters_[layer].cells.push_back(lc.hitsAndFractions().size());
266 clusters_[layer].isSilicon.push_back(rhtools_.isSilicon(
detId));
267 clusters_[layer].energy.emplace_back(lc.energy());
268 clusters_[layer].isSeed.push_back(
false);
269 clusters_[layer].clusterIndex.emplace_back(-1);
270 clusters_[layer].layerClusterOriginalIdx.emplace_back(layerIdx++);
271 clusters_[layer].nearestHigher.emplace_back(-1, -1);
272 clusters_[layer].rho.emplace_back(0.
f);
273 clusters_[layer].z_extension.emplace_back(0.
f);
274 clusters_[layer].delta.emplace_back(
277 for (
unsigned int layer = 0; layer < clusters_.size(); layer++) {
278 clusters_[layer].followers.resize(clusters_[layer].
x.size());
281 auto lastLayerPerSide =
static_cast<int>(rhtools_.lastLayer(
false));
282 int maxLayer = 2 * lastLayerPerSide - 1;
283 std::vector<int> numberOfClustersPerLayer(maxLayer, 0);
284 for (
int i = 0;
i <= maxLayer;
i++) {
285 calculateLocalDensity(
input.tiles,
i, layerIdx2layerandSoa);
287 for (
int i = 0;
i <= maxLayer;
i++) {
288 calculateDistanceToHigher(
input.tiles,
i, layerIdx2layerandSoa);
291 auto nTracksters = findAndAssignTracksters(
input.tiles, layerIdx2layerandSoa);
293 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Reconstructed " << nTracksters <<
" tracksters" << std::endl;
294 dumpClusters(
input.tiles, layerIdx2layerandSoa, eventNumber);
298 result.resize(nTracksters);
300 for (
unsigned int layer = 0; layer < clusters_.size(); ++layer) {
301 const auto &thisLayer = clusters_[layer];
303 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Examining Layer: " << layer;
305 for (
unsigned int lc = 0; lc < thisLayer.x.size(); ++lc) {
307 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Trackster " << thisLayer.clusterIndex[lc];
309 if (thisLayer.clusterIndex[lc] >= 0) {
311 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
" adding lcIdx: " << thisLayer.layerClusterOriginalIdx[lc];
313 result[thisLayer.clusterIndex[lc]].vertices().push_back(thisLayer.layerClusterOriginalIdx[lc]);
314 result[thisLayer.clusterIndex[lc]].vertex_multiplicity().push_back(1);
316 for (
auto [follower_lyrIdx, follower_soaIdx] : thisLayer.followers[lc]) {
317 std::array<unsigned int, 2> edge = {
318 {(
unsigned int)thisLayer.layerClusterOriginalIdx[lc],
319 (
unsigned int)clusters_[follower_lyrIdx].layerClusterOriginalIdx[follower_soaIdx]}};
320 result[thisLayer.clusterIndex[lc]].edges().push_back(edge);
325 size_t tracksterIndex = 0;
329 return static_cast<int>(
v.vertices().size()) <
330 minNumLayerCluster_[tracksterSeedAlgoId_[tracksterIndex++]];
338 auto const &hadProb =
341 return hadProb >= cutHadProb_;
349 input.layerClustersTime,
350 rhtools_.getPositionLayer(rhtools_.lastLayerEE(
false),
false).z(),
358 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Barycenter: " <<
t.barycenter();
359 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"LCs: " <<
t.vertices().size();
361 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Regressed: " <<
t.regressed_energy();
367 dumpTracksters(layerIdx2layerandSoa, eventNumber,
result);
377 template <
typename TILES>
379 const tensorflow::Session *eidSession,
380 std::vector<Trackster> &tracksters) {
404 std::vector<int> tracksterIndices;
405 for (
int i = 0; i < static_cast<int>(tracksters.size());
i++) {
409 float sumClusterEnergy = 0.;
413 if (sumClusterEnergy >= eidMinClusterEnergy_) {
415 tracksters[
i].setRegressedEnergy(0.
f);
416 tracksters[
i].zeroProbabilities();
417 tracksterIndices.push_back(
i);
424 int batchSize =
static_cast<int>(tracksterIndices.size());
430 tensorflow::TensorShape
shape({
batchSize, eidNLayers_, eidNClusters_, eidNFeatures_});
431 tensorflow::Tensor
input(tensorflow::DT_FLOAT,
shape);
434 std::vector<tensorflow::Tensor>
outputs;
436 if (!eidOutputNameEnergy_.empty()) {
439 if (!eidOutputNameId_.empty()) {
445 const Trackster &trackster = tracksters[tracksterIndices[
i]];
450 std::vector<int> clusterIndices(trackster.
vertices().size());
452 clusterIndices[
k] =
k;
454 sort(clusterIndices.begin(), clusterIndices.end(), [&
layerClusters, &trackster](
const int &
a,
const int &
b) {
459 std::vector<int> seenClusters(eidNLayers_);
462 for (
const int &
k : clusterIndices) {
466 if (
j < eidNLayers_ && seenClusters[
j] < eidNClusters_) {
481 for (
int j = 0;
j < eidNLayers_;
j++) {
482 for (
int k = seenClusters[
j];
k < eidNClusters_;
k++) {
484 for (
int l = 0;
l < eidNFeatures_;
l++) {
495 if (!eidOutputNameEnergy_.empty()) {
499 for (
const int &
i : tracksterIndices) {
500 tracksters[
i].setRegressedEnergy(*(
energy++));
505 if (!eidOutputNameId_.empty()) {
507 int probsIdx = eidOutputNameEnergy_.empty() ? 0 : 1;
508 float *probs =
outputs[probsIdx].flat<
float>().
data();
510 for (
const int &
i : tracksterIndices) {
511 tracksters[
i].setProbabilities(probs);
512 probs += tracksters[
i].id_probabilities().size();
517 template <
typename TILES>
519 const TILES &tiles,
const int layerId,
const std::vector<std::pair<int, int>> &layerIdx2layerandSoa) {
522 auto &clustersOnLayer = clusters_[layerId];
525 auto isReachable = [](
float r0,
float r1,
float phi0,
float phi1,
float delta_sqr) ->
bool {
529 auto distance_debug = [&](
float x1,
float x2,
float y1,
float y2) ->
float {
530 return sqrt((x1 - x2) * (x1 - x2) + (
y1 -
y2) * (
y1 -
y2));
534 auto algoId = clustersOnLayer.algoId[
i];
536 auto lastLayerPerSide =
static_cast<int>(rhtools_.lastLayer(
false));
538 int maxLayer = 2 * lastLayerPerSide - 1;
539 if (layerId < lastLayerPerSide) {
541 maxLayer =
std::min(layerId + densitySiblingLayers_[
algoId], lastLayerPerSide - 1);
544 maxLayer =
std::min(layerId + densitySiblingLayers_[
algoId], maxLayer);
546 float deltaLayersZ =
std::abs(layersPosZ_[maxLayer % lastLayerPerSide] - layersPosZ_[
minLayer % lastLayerPerSide]);
548 for (
int currentLayer =
minLayer; currentLayer <= maxLayer; currentLayer++) {
550 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"RefLayer: " << layerId <<
" SoaIDX: " <<
i;
551 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"NextLayer: " << currentLayer;
553 const auto &tileOnLayer = tiles[currentLayer];
554 bool onSameLayer = (currentLayer == layerId);
556 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"onSameLayer: " << onSameLayer;
558 const int etaWindow = 2;
560 int etaBinMin =
std::max(tileOnLayer.etaBin(clustersOnLayer.eta[
i]) - etaWindow, 0);
561 int etaBinMax =
std::min(tileOnLayer.etaBin(clustersOnLayer.eta[
i]) + etaWindow, nEtaBin - 1);
562 int phiBinMin = tileOnLayer.phiBin(clustersOnLayer.phi[
i]) -
phiWindow;
563 int phiBinMax = tileOnLayer.phiBin(clustersOnLayer.phi[
i]) +
phiWindow;
565 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"eta: " << clustersOnLayer.eta[
i];
566 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"phi: " << clustersOnLayer.phi[
i];
567 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"etaBinMin: " << etaBinMin <<
", etaBinMax: " << etaBinMax;
568 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"phiBinMin: " << phiBinMin <<
", phiBinMax: " << phiBinMax;
575 for (
int iphi_it = phiBinMin; iphi_it <= phiBinMax; ++iphi_it) {
576 int iphi = ((iphi_it % nPhiBin + nPhiBin) % nPhiBin);
580 <<
"Entries in tileBin: " << tileOnLayer[
offset +
iphi].size();
582 for (
auto otherClusterIdx : tileOnLayer[
offset +
iphi]) {
583 auto const &layerandSoa = layerIdx2layerandSoa[otherClusterIdx];
585 if ((layerandSoa.first == -1) && (layerandSoa.second == -1)) {
587 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Skipping masked layerIdx " << otherClusterIdx;
591 auto const &clustersLayer = clusters_[layerandSoa.first];
594 <<
"OtherLayer: " << layerandSoa.first <<
" SoaIDX: " << layerandSoa.second;
595 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"OtherEta: " << clustersLayer.eta[layerandSoa.second];
596 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"OtherPhi: " << clustersLayer.phi[layerandSoa.second];
599 bool onSameCluster = clustersOnLayer.layerClusterOriginalIdx[
i] == otherClusterIdx;
600 if (onSameLayer && !densityOnSameLayer_ && !onSameCluster) {
603 <<
"Skipping different cluster " << otherClusterIdx <<
"in the same layer " << currentLayer;
608 bool reachable =
false;
609 if (useAbsoluteProjectiveScale_) {
610 if (useClusterDimensionXY_) {
611 reachable = isReachable(clustersOnLayer.r_over_absz[
i] * clustersOnLayer.z[
i],
612 clustersLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[
i],
613 clustersOnLayer.phi[
i],
614 clustersLayer.phi[layerandSoa.second],
615 clustersOnLayer.radius[
i] * clustersOnLayer.radius[
i]);
619 if (clustersOnLayer.isSilicon[
i]) {
620 reachable = isReachable(clustersOnLayer.r_over_absz[
i] * clustersOnLayer.z[
i],
621 clustersLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[
i],
622 clustersOnLayer.phi[
i],
623 clustersLayer.phi[layerandSoa.second],
624 densityXYDistanceSqr_[
algoId]);
626 reachable = isReachable(clustersOnLayer.r_over_absz[
i] * clustersOnLayer.z[
i],
627 clustersLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[
i],
628 clustersOnLayer.phi[
i],
629 clustersLayer.phi[layerandSoa.second],
630 clustersOnLayer.radius[
i] * clustersOnLayer.radius[
i]);
635 clustersOnLayer.phi[
i],
636 clustersLayer.eta[layerandSoa.second],
637 clustersLayer.phi[layerandSoa.second]) < densityEtaPhiDistanceSqr_[
algoId]);
642 clustersOnLayer.phi[
i],
643 clustersLayer.eta[layerandSoa.second],
644 clustersLayer.phi[layerandSoa.second]);
645 auto dist = distance_debug(
646 clustersOnLayer.r_over_absz[
i],
647 clustersLayer.r_over_absz[layerandSoa.second],
648 clustersOnLayer.r_over_absz[
i] *
std::abs(clustersOnLayer.phi[
i]),
649 clustersLayer.r_over_absz[layerandSoa.second] *
std::abs(clustersLayer.phi[layerandSoa.second]));
650 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Distance[cm]: " << (dist * clustersOnLayer.z[
i]);
652 <<
"Energy Other: " << clustersLayer.energy[layerandSoa.second];
653 edm::LogVerbatim(
"PatternRecognitionbyCLUE3D") <<
"Cluster radius: " << clustersOnLayer.radius[
i];
656 float factor_same_layer_different_cluster = (onSameLayer && !densityOnSameLayer_) ? 0.
f : 1.
f;
657 auto energyToAdd = (clustersOnLayer.layerClusterOriginalIdx[
i] == otherClusterIdx
659 : kernelDensityFactor_[
algoId] * factor_same_layer_different_cluster) *
660 clustersLayer.energy[layerandSoa.second];
661 clustersOnLayer.rho[
i] += energyToAdd;
662 clustersOnLayer.z_extension[
i] = deltaLayersZ;
665 <<
"Adding " << energyToAdd <<
" partial " << clustersOnLayer.rho[
i];
672 if (rescaleDensityByZ_) {
675 <<
"Rescaling original density: " << clustersOnLayer.rho[
i] <<
" by Z: " << deltaLayersZ
676 <<
" to final density/cm: " << clustersOnLayer.rho[
i] / deltaLayersZ;
678 clustersOnLayer.rho[
i] /= deltaLayersZ;
683 template <
typename TILES>
685 const TILES &tiles,
const int layerId,
const std::vector<std::pair<int, int>> &layerIdx2layerandSoa) {
688 auto &clustersOnLayer = clusters_[layerId];
691 auto distanceSqr = [](
float r0,
float r1,
float phi0,
float phi1) ->
float {
699 <<
"Starting searching nearestHigher on " << layerId <<
" with rho: " << clustersOnLayer.rho[
i]
700 <<
" at eta, phi: " << tiles[layerId].etaBin(clustersOnLayer.eta[
i]) <<
", " 701 << tiles[layerId].phiBin(clustersOnLayer.phi[
i]);
704 auto lastLayerPerSide =
static_cast<int>(rhtools_.lastLayer(
false));
706 int maxLayer = 2 * lastLayerPerSide - 1;
707 auto algoId = clustersOnLayer.algoId[
i];
708 if (layerId < lastLayerPerSide) {
710 maxLayer =
std::min(layerId + densitySiblingLayers_[
algoId], lastLayerPerSide - 1);
713 maxLayer =
std::min(layerId + densitySiblingLayers_[
algoId], maxLayer);
717 std::pair<int, int> i_nearestHigher(-1, -1);
719 for (
int currentLayer =
minLayer; currentLayer <= maxLayer; currentLayer++) {
720 if (!nearestHigherOnSameLayer_ && (layerId == currentLayer))
722 const auto &tileOnLayer = tiles[currentLayer];
725 int etaBinMin =
std::max(tileOnLayer.etaBin(clustersOnLayer.eta[
i]) - etaWindow, 0);
726 int etaBinMax =
std::min(tileOnLayer.etaBin(clustersOnLayer.eta[
i]) + etaWindow, nEtaBin - 1);
727 int phiBinMin = tileOnLayer.phiBin(clustersOnLayer.phi[
i]) -
phiWindow;
728 int phiBinMax = tileOnLayer.phiBin(clustersOnLayer.phi[
i]) +
phiWindow;
731 for (
int iphi_it = phiBinMin; iphi_it <= phiBinMax; ++iphi_it) {
732 int iphi = ((iphi_it % nPhiBin + nPhiBin) % nPhiBin);
735 <<
"Searching nearestHigher on " << currentLayer <<
" eta, phi: " <<
ieta <<
", " << iphi_it <<
" " 738 for (
auto otherClusterIdx : tileOnLayer[
offset +
iphi]) {
739 auto const &layerandSoa = layerIdx2layerandSoa[otherClusterIdx];
741 if ((layerandSoa.first == -1) && (layerandSoa.second == -1))
743 auto const &clustersOnOtherLayer = clusters_[layerandSoa.first];
746 int dist_layers =
std::abs(layerandSoa.first - layerId);
747 if (useAbsoluteProjectiveScale_) {
748 dist_transverse = distanceSqr(clustersOnLayer.r_over_absz[
i] * clustersOnLayer.z[
i],
749 clustersOnOtherLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[
i],
750 clustersOnLayer.phi[
i],
751 clustersOnOtherLayer.phi[layerandSoa.second]);
753 dist = dist_transverse;
756 clustersOnLayer.phi[
i],
757 clustersOnOtherLayer.eta[layerandSoa.second],
758 clustersOnOtherLayer.phi[layerandSoa.second]);
759 dist_transverse = dist;
761 bool foundHigher = (clustersOnOtherLayer.rho[layerandSoa.second] > clustersOnLayer.rho[
i]) ||
762 (clustersOnOtherLayer.rho[layerandSoa.second] == clustersOnLayer.rho[
i] &&
763 clustersOnOtherLayer.layerClusterOriginalIdx[layerandSoa.second] >
764 clustersOnLayer.layerClusterOriginalIdx[
i]);
767 <<
"Searching nearestHigher on " << currentLayer
768 <<
" with rho: " << clustersOnOtherLayer.rho[layerandSoa.second]
769 <<
" on layerIdxInSOA: " << layerandSoa.first <<
", " << layerandSoa.second
770 <<
" with distance: " <<
sqrt(dist) <<
" foundHigher: " << foundHigher;
772 if (foundHigher && dist <= i_delta) {
775 nearest_distances = std::make_pair(
sqrt(dist_transverse), dist_layers);
777 i_nearestHigher = layerandSoa;
784 clustersOnLayer.delta[
i] = nearest_distances;
785 clustersOnLayer.nearestHigher[
i] = i_nearestHigher;
789 template <
typename TILES>
791 const TILES &tiles,
const std::vector<std::pair<int, int>> &layerIdx2layerandSoa) {
792 unsigned int nTracksters = 0;
793 std::vector<std::pair<int, int>> localStack;
794 const auto &critical_transverse_distance =
795 useAbsoluteProjectiveScale_ ? criticalXYDistance_ : criticalEtaPhiDistance_;
797 for (
unsigned int layer = 0; layer < 2 * rhtools_.lastLayer(); layer++) {
798 auto &clustersOnLayer = clusters_[layer];
802 clustersOnLayer.clusterIndex[
i] = -1;
803 auto algoId = clustersOnLayer.algoId[
i];
804 bool isSeed = (clustersOnLayer.delta[
i].first > critical_transverse_distance[
algoId] ||
805 clustersOnLayer.delta[
i].second > criticalZDistanceLyr_[
algoId]) &&
806 (clustersOnLayer.rho[
i] >= criticalDensity_[
algoId]) &&
807 (clustersOnLayer.energy[
i] / clustersOnLayer.rho[
i] > criticalSelfDensity_[
algoId]);
808 if (!clustersOnLayer.isSilicon[
i]) {
809 isSeed = (clustersOnLayer.delta[
i].first > clustersOnLayer.radius[
i] ||
810 clustersOnLayer.delta[
i].second > criticalZDistanceLyr_[
algoId]) &&
811 (clustersOnLayer.rho[
i] >= criticalDensity_[
algoId]) &&
812 (clustersOnLayer.energy[
i] / clustersOnLayer.rho[
i] > criticalSelfDensity_[
algoId]);
815 (clustersOnLayer.delta[
i].first > outlierMultiplier_[
algoId] * critical_transverse_distance[
algoId]) &&
816 (clustersOnLayer.rho[
i] < criticalDensity_[
algoId]);
820 <<
"Found seed on Layer " << layer <<
" SOAidx: " <<
i <<
" assigned ClusterIdx: " << nTracksters;
822 clustersOnLayer.clusterIndex[
i] = nTracksters++;
823 tracksterSeedAlgoId_.push_back(
algoId);
824 clustersOnLayer.isSeed[
i] =
true;
825 localStack.emplace_back(layer,
i);
826 }
else if (!isOutlier) {
827 auto [lyrIdx, soaIdx] = clustersOnLayer.nearestHigher[
i];
830 <<
"Found follower on Layer " << layer <<
" SOAidx: " <<
i <<
" attached to cluster on layer: " << lyrIdx
831 <<
" SOAidx: " << soaIdx;
834 clusters_[lyrIdx].followers[soaIdx].emplace_back(layer,
i);
838 <<
"Found Outlier on Layer " << layer <<
" SOAidx: " <<
i <<
" with rho: " << clustersOnLayer.rho[
i]
839 <<
" and delta: " << clustersOnLayer.delta[
i].first <<
", " << clustersOnLayer.delta[
i].second;
846 while (!localStack.empty()) {
847 auto [lyrIdx, soaIdx] = localStack.back();
848 auto &thisSeed = clusters_[lyrIdx].followers[soaIdx];
849 localStack.pop_back();
852 for (
auto [follower_lyrIdx, follower_soaIdx] : thisSeed) {
854 clusters_[follower_lyrIdx].clusterIndex[follower_soaIdx] = clusters_[lyrIdx].clusterIndex[soaIdx];
856 localStack.emplace_back(follower_lyrIdx, follower_soaIdx);
862 template <
typename TILES>
864 iDesc.
add<
int>(
"algo_verbosity", 0);
865 iDesc.
add<std::vector<double>>(
"criticalDensity", {4, 4, 4})->setComment(
"in GeV");
866 iDesc.
add<std::vector<double>>(
"criticalSelfDensity", {0.15, 0.15, 0.15} )
867 ->setComment(
"Minimum ratio of self_energy/local_density to become a seed.");
868 iDesc.
add<std::vector<int>>(
"densitySiblingLayers", {3, 3, 3})
870 "inclusive, layers to consider while computing local density and searching for nearestHigher higher");
871 iDesc.
add<std::vector<double>>(
"densityEtaPhiDistanceSqr", {0.0008, 0.0008, 0.0008})
872 ->setComment(
"in eta,phi space, distance to consider for local density");
873 iDesc.
add<std::vector<double>>(
"densityXYDistanceSqr", {3.24, 3.24, 3.24})
874 ->setComment(
"in cm, distance on the transverse plane to consider for local density");
875 iDesc.
add<std::vector<double>>(
"kernelDensityFactor", {0.2, 0.2, 0.2})
876 ->setComment(
"Kernel factor to be applied to other LC while computing the local density");
877 iDesc.
add<
bool>(
"densityOnSameLayer",
false);
878 iDesc.
add<
bool>(
"nearestHigherOnSameLayer",
false)
879 ->setComment(
"Allow the nearestHigher to be located on the same layer");
880 iDesc.
add<
bool>(
"useAbsoluteProjectiveScale",
true)
881 ->setComment(
"Express all cuts in terms of r/z*z_0{,phi} projective variables");
882 iDesc.
add<
bool>(
"useClusterDimensionXY",
false)
884 "Boolean. If true use the estimated cluster radius to determine the cluster compatibility while computing " 885 "the local density");
886 iDesc.
add<
bool>(
"rescaleDensityByZ",
false)
888 "Rescale local density by the extension of the Z 'volume' explored. The transvere dimension is, at present, " 889 "fixed and factored out.");
890 iDesc.
add<std::vector<double>>(
"criticalEtaPhiDistance", {0.025, 0.025, 0.025})
891 ->setComment(
"Minimal distance in eta,phi space from nearestHigher to become a seed");
892 iDesc.
add<std::vector<double>>(
"criticalXYDistance", {1.8, 1.8, 1.8})
893 ->setComment(
"Minimal distance in cm on the XY plane from nearestHigher to become a seed");
894 iDesc.
add<std::vector<int>>(
"criticalZDistanceLyr", {5, 5, 5})
895 ->setComment(
"Minimal distance in layers along the Z axis from nearestHigher to become a seed");
896 iDesc.
add<std::vector<double>>(
"outlierMultiplier", {2, 2, 2})
897 ->setComment(
"Minimal distance in transverse space from nearestHigher to become an outlier");
898 iDesc.
add<std::vector<int>>(
"minNumLayerCluster", {2, 2, 2})->setComment(
"Not Inclusive");
899 iDesc.
add<
bool>(
"doPidCut",
false);
900 iDesc.
add<
double>(
"cutHadProb", 0.5);
902 iDesc.
add<
std::string>(
"eid_output_name_energy",
"output/regressed_energy");
903 iDesc.
add<
std::string>(
"eid_output_name_id",
"output/id_probabilities");
904 iDesc.
add<
double>(
"eid_min_cluster_energy", 1.);
905 iDesc.
add<
int>(
"eid_n_layers", 50);
906 iDesc.
add<
int>(
"eid_n_clusters", 10);
907 iDesc.
add<
bool>(
"computeLocalTime",
false);
908 iDesc.
add<
bool>(
"usePCACleaning",
false)->setComment(
"Enable PCA cleaning alorithm");
constexpr double deltaPhi(double phi1, double phi2)
Log< level::Info, true > LogVerbatim
std::vector< NamedTensor > NamedTensorList
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
void energyRegressionAndID(const std::vector< reco::CaloCluster > &layerClusters, const tensorflow::Session *, std::vector< Trackster > &result)
void dumpTiles(const TILES &) const
void assignPCAtoTracksters(std::vector< Trackster > &tracksters, const std::vector< reco::CaloCluster > &layerClusters, const edm::ValueMap< std::pair< float, float >> &layerClustersTime, double z_limit_em, hgcal::RecHitTools const &rhTools, bool computeLocalTime=false, bool energyWeight=true, bool clean=false, int minLayer=10, int maxLayer=10)
PatternRecognitionbyCLUE3D(const edm::ParameterSet &conf, edm::ConsumesCollector)
double phi() const
azimuthal angle of cluster centroid
void calculateDistanceToHigher(const TILES &, const int layerId, const std::vector< std::pair< int, int >> &)
static std::string const input
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)
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Abs< T >::type abs(const T &t)
int findAndAssignTracksters(const TILES &, const std::vector< std::pair< int, int >> &)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
double energy() const
cluster energy
std::vector< unsigned int > & vertices()
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
void dumpClusters(const TILES &tiles, const std::vector< std::pair< int, int >> &layerIdx2layerandSoa, const int) const
std::vector< float > & vertex_multiplicity()
void calculateLocalDensity(const TILES &, const int layerId, const std::vector< std::pair< int, int >> &)
char data[epos_bytes_allocation]
static constexpr int nPhiBins
double eta() const
pseudorapidity of cluster centroid
void reset(double vett[256])
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
int sum_x
More diagnostics.
*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
void dumpTracksters(const std::vector< std::pair< int, int >> &layerIdx2layerandSoa, const int, const std::vector< Trackster > &) const