ATLAS Offline Software
WFSClusterMaker.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 #include "./WFSClusterMaker.h"
6 #include <stdexcept>
7 #include <cmath>
8 
9 std::vector<Gep::Cluster>
10 Gep::WFSClusterMaker::makeClusters(const pGepCellMap& caloCellsMap) const {
11 
12  std::vector<Gep::Cluster> clusters;
13 
14  // Loop over all cells
15  for (auto const& cell_itr : *caloCellsMap) {
16 
17  // Select only seed cells
18  if (!isSeedCell(cell_itr.second)) continue;
19 
20  // Clustering
21  std::vector<Gep::GepCaloCell> cluster_cells = clusterFromCells(cell_itr.second, caloCellsMap);
22  clusters.push_back(getClusterFromListOfCells(cluster_cells));
23  }
24 
25  // Order topo clusters according to their et
27 
28  return clusters;
29 }
30 
31 
33 
34  if (cell.isBadCell()) return false;
35  if (std::fabs(cell.sigma) < m_seed_threshold) return false;
36  if (!isInAllowedSampling(cell.sampling, m_allowed_seed_samplings)) return false;
37 
38  return true;
39 }
40 
41 
42 bool Gep::WFSClusterMaker::isInAllowedSampling(int sampling, const std::vector<int>& list_of_samplings) const {
43 
44  for (unsigned int i = 0; i < list_of_samplings.size(); ++i) {
45  if (list_of_samplings[i] == sampling) return true;
46  }
47  return false;
48 }
49 
50 
51 bool Gep::WFSClusterMaker::isNewCell(unsigned int id, const std::vector<unsigned int>& seenCells) const {
52 
53  for (unsigned int i = 0; i < seenCells.size(); ++i) {
54  if (id == seenCells[i]) return false;
55  }
56 
57  return true;
58 }
59 
60 
61 std::vector<Gep::GepCaloCell>
63  const pGepCellMap& caloCellsMap) const {
64 
65  std::vector<Gep::GepCaloCell> v_clusterCells;
66 
67  std::vector<Gep::GepCaloCell> cellsNextLayer, cellsThisLayer;
68  std::vector<unsigned int> seenCells;
69 
70  // Fill seed into supporting vectors
71  v_clusterCells.push_back(seed);
72  cellsNextLayer.push_back(seed);
73  seenCells.push_back(seed.id);
74 
75  int i_shell = 1;
76 
77  while (!cellsNextLayer.empty() && i_shell <= m_max_shells) {
78 
79  cellsThisLayer = cellsNextLayer;
80  cellsNextLayer.clear();
81  ++i_shell;
82 
83  // Loop over all cells in this shell
84  for (unsigned int i_cell = 0; i_cell < cellsThisLayer.size(); ++i_cell) {
85 
86  // Go through list of neighbouring cells and check whether they are part of the cluster
87  for (unsigned int i_neighbour = 0; i_neighbour < (cellsThisLayer[i_cell]).neighbours.size(); ++i_neighbour) {
88 
89  // Check whether this neighbouring cell was sent to the GEP
90  auto const& nghbr_itr = caloCellsMap->find((cellsThisLayer[i_cell]).neighbours[i_neighbour]);
91  if (nghbr_itr == caloCellsMap->end()) continue;
92 
93  Gep::GepCaloCell neighbour = nghbr_itr->second;//caloCellsMap->at((cellsThisLayer[i_cell]).neighbours[i_neighbour]);
94 
95  // reject if bad cell
96  if (neighbour.isBadCell()) continue;
97 
98  // Reject if cell is not above clustering threshold
99  if (std::fabs(neighbour.sigma) < m_clustering_threshold) continue;
100 
101  // Reject if cell was already considered
102  if (!isNewCell(neighbour.id, seenCells)) continue;
103 
104  // Ignore cells in disallowed samplings
105  if (!isInAllowedSampling(neighbour.sampling, m_allowed_clustering_samplings)) continue;
106 
107  seenCells.push_back(neighbour.id);
108  cellsNextLayer.push_back(neighbour);
109  v_clusterCells.push_back(std::move(neighbour));
110  }
111  }
112  cellsThisLayer.clear();
113  }
114 
115  return v_clusterCells;
116 }
117 
118 
119 Gep::Cluster Gep::WFSClusterMaker::getClusterFromListOfCells(const std::vector<Gep::GepCaloCell>& cells) const {
120 
121  Gep::Cluster cluster;
122 
123  std::vector<unsigned int> v_cellIDs;
124  double cluster_e = 0.0;
125  double etaSum = 0.0;
126  double phiSum = 0.0;
127  double abs_e = 0.0;
128  float weight = 0.0;
129 
130  double seed_phi = cells[0].phi;
131  for (unsigned int i_cell = 0; i_cell < cells.size(); ++i_cell) {
132  float cell_e = cells[i_cell].et * TMath::CosH(cells[i_cell].eta);
133  cluster_e += cell_e;
134  abs_e += std::fabs(cell_e);
135  v_cellIDs.push_back(cells[i_cell].id);
136  etaSum += std::fabs(cell_e) * cells[i_cell].eta;
137  phiSum += std::fabs(cell_e) * getDeltaPhi(cells[i_cell].phi, seed_phi);
138  if (std::fabs(cells[i_cell].sigma) > m_seed_threshold) weight += 1.0;
139  }
140 
141  cluster.ncells = cells.size();
142  cluster.time = cells[0].time; // Take time of seed cell
143  cluster.cell_id = std::move(v_cellIDs);
144  if (abs_e == 0.) [[unlikely]] throw std::runtime_error("Gep::WFSClusterMaker::getClusterFromListOfCells: abs_e is zero");
145  double cluster_eta = etaSum / abs_e;
146  double cluster_phi = calculateClusterPhi(seed_phi, phiSum / abs_e);
147  if (weight == 0.) [[unlikely]] throw std::runtime_error("Gep::WFSClusterMaker::getClusterFromListOfCells: weight is zero");
148  double cluster_et = (cluster_e * (1.0 / std::cosh(cluster_eta))) / weight;
149  cluster.setEtEtaPhi(cluster_et, cluster_eta, cluster_phi);
150 
151  return cluster;
152 }
153 
154 
155 double Gep::WFSClusterMaker::getDeltaPhi(double phi, double seed_phi) const {
156  double delta_phi = std::fabs(std::fabs( std::fabs( phi - seed_phi ) - TMath::Pi() ) - TMath::Pi());
157  if (phi < seed_phi) delta_phi *= -1.00;
158  // Taking care of the -pi/pi split
159  if ((std::fabs(phi + seed_phi) < TMath::Pi()) && (std::fabs(phi) + std::fabs(seed_phi) > 5.0)) delta_phi *= -1.00;
160  return delta_phi;
161 }
162 
163 double Gep::WFSClusterMaker::calculateClusterPhi(double seed_phi, double delta_phi) const {
164  double phi = seed_phi + delta_phi;
165  if (phi > TMath::Pi()) phi = -1.0*TMath::Pi() + (phi - TMath::Pi());
166  if (phi < (-1.0)*TMath::Pi()) phi = TMath::Pi() + (phi + TMath::Pi());
167  return phi;
168 }
169 
170 
171 void Gep::WFSClusterMaker::orderClustersInEt(std::vector<Gep::Cluster> &v_clusters) const {
172 
173  std::vector<Gep::Cluster> v_ordered;
174  for (unsigned int i_cluster = 0; i_cluster < v_clusters.size(); ++i_cluster) {
175  float et = v_clusters[i_cluster].et();
176 
177  // Fill first cluster
178  if (v_ordered.empty()) {
179  v_ordered.push_back(v_clusters[i_cluster]);
180  continue;
181  }
182 
183  // Find correct position for filling
184  for (unsigned int i = 0; i < v_ordered.size(); ++i) {
185  if (v_ordered[i].et() < et) {
186  v_ordered.insert(v_ordered.begin()+i, v_clusters[i_cluster]);
187  break;
188  }
189  }
190 
191  // If cluster has smallest et so far, it wasn't filled at all so we need to take care of it
192  if (v_ordered.size() != i_cluster+1) v_ordered.push_back(v_clusters[i_cluster]);
193  }
194 
195  v_clusters = std::move(v_ordered);
196 
197  return;
198 
199 }
200 
201 
202 std::string Gep::WFSClusterMaker::getName() const {
203  return "CaloWFS";
204 }
Gep::GepCaloCell::sigma
float sigma
Definition: GepCaloCell.h:22
RunTileCalibRec.cells
cells
Definition: RunTileCalibRec.py:281
et
Extra patterns decribing particle interation process.
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
Gep::GepCaloCell::isBadCell
bool isBadCell() const
Definition: GepCaloCell.h:59
xAOD::et
et
Definition: TrigEMCluster_v1.cxx:25
Gep::Cluster::setEtEtaPhi
void setEtEtaPhi(double et, double eta, double phi)
Definition: Trigger/TrigT1/TrigGepPerf/src/Cluster.h:28
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
Gep::Cluster::ncells
int ncells
Definition: Trigger/TrigT1/TrigGepPerf/src/Cluster.h:33
Gep::Cluster
Definition: Trigger/TrigT1/TrigGepPerf/src/Cluster.h:13
Gep::GepCaloCell::sampling
unsigned int sampling
Definition: GepCaloCell.h:49
WFSClusterMaker.h
muCombUtil::getDeltaPhi
double getDeltaPhi(double phi1, double phi2)
Get DeltaPhi.
Definition: muCombUtil.cxx:345
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:190
Gep::WFSClusterMaker::isNewCell
bool isNewCell(unsigned int id, const std::vector< unsigned int > &seenCells) const
Definition: WFSClusterMaker.cxx:51
Gep::WFSClusterMaker::getClusterFromListOfCells
Gep::Cluster getClusterFromListOfCells(const std::vector< Gep::GepCaloCell > &cells) const
Definition: WFSClusterMaker.cxx:119
Gep::WFSClusterMaker::makeClusters
std::vector< Gep::Cluster > makeClusters(const pGepCellMap &) const override
Definition: WFSClusterMaker.cxx:10
pGepCellMap
std::unique_ptr< GepCellMap > pGepCellMap
Definition: IClusterMaker.h:17
lumiFormat.i
int i
Definition: lumiFormat.py:85
Gep::GepCaloCell::id
unsigned int id
Definition: GepCaloCell.h:50
Gep::Cluster::cell_id
std::vector< unsigned int > cell_id
Definition: Trigger/TrigT1/TrigGepPerf/src/Cluster.h:36
Gep::GepCaloCell
Definition: GepCaloCell.h:13
Gep::WFSClusterMaker::calculateClusterPhi
double calculateClusterPhi(double seed_phi, double delta_phi) const
Definition: WFSClusterMaker.cxx:163
Gep::WFSClusterMaker::isInAllowedSampling
bool isInAllowedSampling(int sampling, const std::vector< int > &list_of_samplings) const
Definition: WFSClusterMaker.cxx:42
unlikely
#define unlikely(x)
Definition: dictionary.h:41
Gep::WFSClusterMaker::orderClustersInEt
void orderClustersInEt(std::vector< Gep::Cluster > &v_clusters) const
Definition: WFSClusterMaker.cxx:171
eFEXNTuple.delta_phi
def delta_phi(phi1, phi2)
Definition: eFEXNTuple.py:14
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
Gep::WFSClusterMaker::isSeedCell
bool isSeedCell(const Gep::GepCaloCell &cell) const
Definition: WFSClusterMaker.cxx:32
Gep::WFSClusterMaker::getDeltaPhi
double getDeltaPhi(double phi, double seed_phi) const
Definition: WFSClusterMaker.cxx:155
Gep::WFSClusterMaker::getName
std::string getName() const override
Definition: WFSClusterMaker.cxx:202
Gep::Cluster::time
float time
Definition: Trigger/TrigT1/TrigGepPerf/src/Cluster.h:34
Gep::WFSClusterMaker::clusterFromCells
std::vector< Gep::GepCaloCell > clusterFromCells(const Gep::GepCaloCell &seed, const pGepCellMap &) const
Definition: WFSClusterMaker.cxx:62