Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
PixelClusteringTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "PixelClusteringTool.h"
6 
7 #include <Acts/Clusterization/Clusterization.hpp>
8 
13 
14 #include <unordered_set>
15 #include <stdexcept>
16 
17 using CLHEP::micrometer;
18 
19 // Helper functions for use with ACTS clusterization
20 // Put these in the InDet namespace so that ACTS can find them
21 // via ADL.
22 //
23 namespace InDet {
24  static inline int getCellRow(const InDet::UnpackedPixelRDO& cell) { return cell.ROW; }
25  static inline int getCellColumn(const InDet::UnpackedPixelRDO& cell) { return cell.COL; }
26  static inline int& getCellLabel(InDet::UnpackedPixelRDO& cell) { return cell.NCL; }
27 }
28 
29 namespace ActsTrk {
30 
31 static inline void clusterAddCell(PixelClusteringTool::Cluster& cl,
33 {
34  cl.ids.push_back(cell.ID.get_compact());
35  cl.tots.push_back(cell.TOT);
36  if (cell.LVL1 < cl.lvl1min)
37  cl.lvl1min = cell.LVL1;
38 }
39 
41 {
42  ATH_MSG_DEBUG("Initializing " << name() << " ...");
43  ATH_CHECK(m_pixelRDOTool.retrieve());
45  if (not m_chargeDataKey.empty()) ATH_CHECK(m_pixelReadout.retrieve());
46 
48 
49  ATH_MSG_DEBUG(name() << " successfully initialized");
50  return StatusCode::SUCCESS;
51 }
52 
54  const std::string& type, const std::string& name, const IInterface* parent)
55  : base_class(type,name,parent)
56 {}
57 
59 PixelClusteringTool::makeCluster(const EventContext& ctx,
61  const PixelID& pixelID,
62  const InDetDD::SiDetectorElement* element,
63  const InDetDD::PixelModuleDesign& design,
64  const PixelChargeCalibCondData *calibData,
66  xAOD::PixelCluster& xaodcluster) const
67 {
68 
69  InDetDD::SiLocalPosition pos_acc(0,0);
70  int tot_acc = 0;
71 
72  std::vector<float> chargeList;
73  if (calibData) chargeList.reserve(cluster.ids.size());
74 
75  int colmax = std::numeric_limits<int>::min();
76  int rowmax = std::numeric_limits<int>::min();
77  int colmin = std::numeric_limits<int>::max();
78  int rowmin = std::numeric_limits<int>::max();
79 
80  float qRowMin = 0.f;
81  float qRowMax = 0.f;
82  float qColMin = 0.f;
83  float qColMax = 0.f;
84 
85  bool hasGanged = false;
86 
87  Identifier moduleID = element->identify();
88  IdentifierHash moduleHash = element->identifyHash();
89 
90  // This could be moved outside the cluster loop
91  bool multiChip = design.numberOfCircuits() > 1 ? true : false;
92 
93  for (size_t i = 0; i < cluster.ids.size(); i++) {
94 
95  //Construct the identifier class
96  Identifier id = Identifier(cluster.ids[i]);
97 
98  //Single chip modules do not have ganged pixels in ITk
99  if (multiChip) {
100  hasGanged = hasGanged ||
101  m_pixelRDOTool->isGanged(id, element).has_value();
102  }
103 
104  int tot = cluster.tots.at(i);
105  float charge = tot;
106 
107  if (calibData) {
108 
109  // The calibration strategy is updated for each element
110  // Retrieving the calibration only depends on FE and not per cell (can be further optimized)
111  // Single FE modules could have an optimized getCharge function where the calib constants are cached
112  int feValue = multiChip ? m_pixelReadout->getFE(id, moduleID, element) : 0;
113  charge = calibData->getCharge(m_pixelReadout->getDiodeType(id,element),
114  calibStrategy,
115  moduleHash,
116  feValue,
117  tot);
118 
119  // These numbers are taken from the Cluster Maker Tool
120  if (design.getReadoutTechnology() != InDetDD::PixelReadoutTechnology::RD53 && (moduleHash < 12 or moduleHash > 2035)) {
121  charge = tot/8.0*(8000.0-1200.0)+1200.0;
122  }
123  chargeList.push_back(charge);
124  }
125 
126  const int row = pixelID.phi_index(id);
127  if (row > rowmax) {
128  rowmax = row;
129  qRowMax = charge;
130  } else if (row == rowmax) {
131  qRowMax += charge;
132  }
133 
134  if (row < rowmin) {
135  rowmin = row;
136  qRowMin = charge;
137  } else if (row == rowmin) {
138  qRowMin += charge;
139  }
140 
141  const int col = pixelID.eta_index(id);
142  if (col > colmax) {
143  colmax = col;
144  qColMax = charge;
145  } else if (col == colmax) {
146  qColMax += charge;
147  }
148 
149  if (col < colmin) {
150  colmin = col;
151  qColMin = charge;
152  } else if (col == colmin) {
153  qColMin += charge;
154  }
155 
156  InDetDD::SiCellId si_cell = element->cellIdFromIdentifier(id);
158 
159  if (m_useWeightedPos) {
160  pos_acc += tot * pos;
161  tot_acc += tot;
162  } else {
163  pos_acc += pos;
164  tot_acc += 1;
165  }
166  }
167 
168  if (tot_acc > 0)
169  pos_acc /= tot_acc;
170 
171  // Compute omega for charge interpolation correction (if required)
172  // Two pixels may have charge=0 (very rarely, hopefully)
173  float omegax = -1.f;
174  float omegay = -1.f;
175  if(qRowMin + qRowMax > 0) omegax = qRowMax/(qRowMin + qRowMax);
176  if(qColMin + qColMax > 0) omegay = qColMax/(qColMin + qColMax);
177 
178 
179  const int colWidth = colmax - colmin + 1;
180  const int rowWidth = rowmax - rowmin + 1;
181  double etaWidth = design.widthFromColumnRange(colmin, colmax);
182  double phiWidth = design.widthFromRowRange(rowmin, rowmax);
183  InDet::SiWidth siWidth(Amg::Vector2D(rowWidth,colWidth), Amg::Vector2D(phiWidth,etaWidth));
184 
185  // ask for Lorentz correction, get global position
186  double shift = m_pixelLorentzAngleTool->getLorentzShift(moduleHash, ctx);
187  const Amg::Vector2D localPos = pos_acc;
188  Amg::Vector2D locpos(localPos[Trk::locX]+shift, localPos[Trk::locY]);
189  // find global position of element
190  const Amg::Transform3D& T = element->surface().transform();
191  double Ax[3] = {T(0,0),T(1,0),T(2,0)};
192  double Ay[3] = {T(0,1),T(1,1),T(2,1)};
193  double R [3] = {T(0,3),T(1,3),T(2,3)};
194 
195  const Amg::Vector2D& M = locpos;
196  Amg::Vector3D globalPos(M[0]*Ax[0]+M[1]*Ay[0]+R[0],M[0]*Ax[1]+M[1]*Ay[1]+R[1],M[0]*Ax[2]+M[1]*Ay[2]+R[2]);
197 
198  // Compute error matrix
199  float width0, width1;
200  if (m_broadErrors) {
201  // Use cluster width
202  width0 = siWidth.phiR();
203  width1 = siWidth.z();
204  } else {
205  // Use pixel width
206  width0 = siWidth.phiR() / siWidth.colRow().x();
207  width1 = siWidth.z() / siWidth.colRow().y();
208  }
209 
210  // Actually create the cluster (i.e. fill the values)
211 
212  Eigen::Matrix<float,2,1> localPosition(locpos.x(), locpos.y());
213  Eigen::Matrix<float,2,2> localCovariance = Eigen::Matrix<float,2,2>::Zero();
214  localCovariance(0, 0) = width0 * width0 / 12.0;
215  localCovariance(1, 1) = width1 * width1 / 12.0;
216 
217  xaodcluster.setMeasurement<2>(moduleHash, localPosition, localCovariance);
218  xaodcluster.setIdentifier( element->identifierOfPosition(locpos).get_compact() );
219  xaodcluster.setRDOlist(std::move(cluster.ids));
220  xaodcluster.globalPosition() = globalPos.cast<float>();
222  xaodcluster.setToTlist(std::move(cluster.tots));
224  xaodcluster.setChargelist(std::move(chargeList));
225  xaodcluster.setLVL1A(cluster.lvl1min);
226  xaodcluster.setChannelsInPhiEta(siWidth.colRow()[0],
227  siWidth.colRow()[1]);
228  xaodcluster.setWidthInEta(static_cast<float>(siWidth.widthPhiRZ()[1]));
229  xaodcluster.setOmegas(omegax, omegay);
230  xaodcluster.setIsSplit(false);
231  xaodcluster.setSplitProbabilities(0.0, 0.0);
232 
233  return StatusCode::SUCCESS;
234 }
235 
236 
238 PixelClusteringTool::clusterize(const RawDataCollection& RDOs,
239  const PixelID& pixelID,
240  const EventContext& ctx,
241  ClusterContainer& container) const
242 {
243 
244  // Retrieve the detector element
245  const InDetDD::SiDetectorElement* element = m_pixelRDOTool->checkCollection(RDOs, ctx);
246  if (element == nullptr) {
247  // the RDO tool will return nullptr if the module is flagged bad, which is not a failure.
248  return StatusCode::SUCCESS;
249  }
250 
251  // Retrieve the calibration data
252  const PixelChargeCalibCondData *calibData = nullptr;
253  if (not m_chargeDataKey.empty()) {
255  calibData = calibDataHandle.cptr();
256 
257  if (!calibData) {
258  ATH_MSG_ERROR("PixelChargeCalibCondData requested but couldn't be retrieved from " << m_chargeDataKey.key());
259  return StatusCode::FAILURE;
260  }
261  }
262 
263  // Retrieve the cells from the detector element
264  std::vector<InDet::UnpackedPixelRDO> cells =
265  m_pixelRDOTool->getUnpackedPixelRDOs(RDOs, pixelID, element, ctx);
266 
267  // Get the calibration strategy for this module.
268  // Default to RD53 if the calibData is not available. That is fine because it won't be used anyway
269  auto calibrationStrategy = calibData ? calibData->getCalibrationStrategy(element->identifyHash()) : PixelChargeCalibCondData::CalibrationStrategy::RD53;
270 
271  // Get the element design
272  const InDetDD::PixelModuleDesign& design =
273  static_cast<const InDetDD::PixelModuleDesign&>(element->design());
274 
276  Acts::Ccl::createClusters<CellCollection, ClusterCollection, 2>
277  (cells, Acts::Ccl::DefaultConnect<Cell, 2>(m_addCorners));
278 
279 
280  std::size_t previousSizeContainer = container.size();
281  // Fast insertion trick
282  std::vector<xAOD::PixelCluster*> toAddCollection;
283  toAddCollection.reserve(clusters.size());
284  for (std::size_t i(0); i<clusters.size(); ++i)
285  toAddCollection.push_back(new xAOD::PixelCluster());
286  container.insert(container.end(), toAddCollection.begin(), toAddCollection.end());
287 
288  for (std::size_t i(0); i<clusters.size(); ++i) {
289  Cluster& cluster = clusters[i];
290 
292  cluster,
293  pixelID,
294  element,
295  design,
296  calibData,
297  calibrationStrategy,
298  *container[previousSizeContainer+i]));
299  }
300 
301  return StatusCode::SUCCESS;
302 }
303 
304 } // namespace ActsTrk
ActsTrk::PixelClusteringTool::m_broadErrors
Gaudi::Property< bool > m_broadErrors
Definition: PixelClusteringTool.h:74
InDetDD::SolidStateDetectorElementBase::identifierOfPosition
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift)
Definition: SolidStateDetectorElementBase.cxx:217
query_example.row
row
Definition: query_example.py:24
RunTileCalibRec.cells
cells
Definition: RunTileCalibRec.py:271
xAOD::PixelCluster_v1::setTotalCharge
void setTotalCharge(float totalCharge)
Sets the total charge.
PixelID::phi_index
int phi_index(const Identifier &id) const
Definition: PixelID.h:658
ActsTrk::PixelClusteringTool::makeCluster
StatusCode makeCluster(const EventContext &ctx, PixelClusteringTool::Cluster &cluster, const PixelID &pixelID, const InDetDD::SiDetectorElement *element, const InDetDD::PixelModuleDesign &design, const PixelChargeCalibCondData *calibData, const PixelChargeCalibCondData::CalibrationStrategy calibStrategy, xAOD::PixelCluster &container) const
Definition: PixelClusteringTool.cxx:59
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
ActsTrk::PixelClusteringTool::m_pixelLorentzAngleTool
ToolHandle< ISiLorentzAngleTool > m_pixelLorentzAngleTool
Definition: PixelClusteringTool.h:67
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
Trk::locX
@ locX
Definition: ParamDefs.h:37
InDetDD::PixelModuleDesign::widthFromRowRange
double widthFromRowRange(const int rowMin, const int rowMax) const
Method to calculate phi width from a row range.
Definition: PixelModuleDesign.cxx:167
InDetDD::PixelModuleDesign
Definition: PixelModuleDesign.h:48
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:38
PixelClusteringTool.h
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
InDet::SiWidth::widthPhiRZ
const Amg::Vector2D & widthPhiRZ() const
Definition: SiWidth.h:121
InDet
Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
xAOD::xAODInDetMeasurement::Utilities::computeTotalToT
int computeTotalToT(const SG::AuxElement &cluster)
Definition: Event/xAOD/xAODInDetMeasurement/Root/Utilities.cxx:22
InDetDD::SolidStateDetectorElementBase::surface
Trk::Surface & surface()
Element Surface.
Identifier::get_compact
value_type get_compact() const
Get the compact id.
xAOD::PixelCluster_v1::setRDOlist
void setRDOlist(const std::vector< Identifier > &rdolist)
Sets the list of identifiers of the channels building the cluster.
Definition: PixelCluster_v1.cxx:32
PixelChargeCalibCondData::CalibrationStrategy::RD53
@ RD53
xAOD::PixelCluster_v1::setChargelist
void setChargelist(const std::vector< float > &charges)
Sets the list of charges of the channels building the cluster.
xAOD::PixelCluster_v1::setIsSplit
void setIsSplit(bool isSplit)
Sets if the cluster is split or not.
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
xAOD::PixelCluster_v1::setWidthInEta
void setWidthInEta(float widthInEta)
Sets the width of the cluster in eta (y) direction.
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
ActsTrk::PixelClusteringTool::m_useWeightedPos
Gaudi::Property< bool > m_useWeightedPos
Definition: PixelClusteringTool.h:73
xAOD::PixelCluster_v1::setTotalToT
void setTotalToT(int totalToT)
Sets the total ToT.
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
InDetDD::SolidStateDetectorElementBase::identifyHash
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
ActsTrk::PixelClusteringTool::m_addCorners
Gaudi::Property< bool > m_addCorners
Definition: PixelClusteringTool.h:72
InDetDD::PixelReadoutTechnology::RD53
@ RD53
xAOD::PixelCluster_v1::setSplitProbabilities
void setSplitProbabilities(float prob1, float prob2)
Sets the splitting probabilities for the cluster.
InDetDD::SiLocalPosition
Definition: SiLocalPosition.h:31
ActsTrk::PixelClusteringTool::m_chargeDataKey
SG::ReadCondHandleKey< PixelChargeCalibCondData > m_chargeDataKey
Definition: PixelClusteringTool.h:69
ActsTrk::PixelClusteringTool::PixelClusteringTool
PixelClusteringTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: PixelClusteringTool.cxx:53
xAOD::UncalibratedMeasurement_v1::setIdentifier
void setIdentifier(const DetectorIdentType measId)
Sets the full Identifier of the measurement.
InDetDD::SiDetectorElement::cellIdFromIdentifier
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
Definition: SiDetectorElement.cxx:120
ActsTrk::PixelClusteringTool::m_pixelReadout
ServiceHandle< InDetDD::IPixelReadoutManager > m_pixelReadout
Definition: PixelClusteringTool.h:63
InDetDD::PixelModuleDesign::widthFromColumnRange
double widthFromColumnRange(const int colMin, const int colMax) const
Method to calculate eta width from a column range.
Definition: PixelModuleDesign.cxx:155
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
PixelClusterAuxContainer.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ActsTrk::PixelClusteringTool::initialize
virtual StatusCode initialize() override
Definition: PixelClusteringTool.cxx:40
ActsTrk::PixelClusteringTool::Cell
InDet::UnpackedPixelRDO Cell
Definition: PixelClusteringTool.h:26
PixelChargeCalibCondData
Definition: PixelChargeCalibCondData.h:24
InDetDD::PixelModuleDesign::numberOfCircuits
int numberOfCircuits() const
Total number of circuits:
Definition: PixelModuleDesign.h:315
PixelClusterContainer.h
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
InDetDD::PixelModuleDesign::localPositionOfCell
virtual SiLocalPosition localPositionOfCell(const SiCellId &cellId) const
readout or diode id -> position.
Definition: PixelModuleDesign.cxx:108
xAOD::PixelCluster_v1::setToTlist
void setToTlist(const std::vector< int > &tots)
Sets the list of ToT of the channels building the cluster.
test_pyathena.parent
parent
Definition: test_pyathena.py:15
PixelCluster.h
PixelID::eta_index
int eta_index(const Identifier &id) const
Definition: PixelID.h:664
PixelChargeCalibCondData::getCalibrationStrategy
CalibrationStrategy getCalibrationStrategy(unsigned int moduleHash) const
Definition: PixelChargeCalibCondData.cxx:254
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
PixelChargeCalibCondData::CalibrationStrategy
CalibrationStrategy
Definition: PixelChargeCalibCondData.h:34
python.SystemOfUnits.micrometer
int micrometer
Definition: SystemOfUnits.py:71
xAOD::PixelCluster_v1::setLVL1A
void setLVL1A(int lvl1a)
Sets the LVL1 accept.
xAOD::xAODInDetMeasurement::Utilities::computeTotalCharge
float computeTotalCharge(const SG::AuxElement &cluster)
Definition: Event/xAOD/xAODInDetMeasurement/Root/Utilities.cxx:9
ActsTrk::PixelClusteringTool::clusterize
virtual StatusCode clusterize(const InDetRawDataCollection< PixelRDORawData > &RDOs, const PixelID &pixelID, const EventContext &ctx, xAOD::PixelClusterContainer &container) const override
Definition: PixelClusteringTool.cxx:238
Utilities.h
ActsTrk::PixelClusteringTool::Cluster
Definition: PixelClusteringTool.h:29
xAOD::PixelCluster_v1::globalPosition
ConstVectorMap< 3 > globalPosition() const
Returns the global position of the pixel cluster.
Definition: PixelCluster_v1.cxx:15
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
charge
double charge(const T &p)
Definition: AtlasPID.h:931
xAOD::PixelCluster_v1::setOmegas
void setOmegas(float omegax, float omegay)
Sets omegax and omegay, i.e.
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
InDetDD::PixelModuleDesign::getReadoutTechnology
PixelReadoutTechnology getReadoutTechnology() const
Definition: PixelModuleDesign.h:386
query_example.col
col
Definition: query_example.py:7
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
InDetDD::SiCellId
Definition: SiCellId.h:29
xAOD::PixelCluster_v1
Definition: PixelCluster_v1.h:17
xAOD::UncalibratedMeasurement_v1::setMeasurement
void setMeasurement(const DetectorIDHashType idHash, MeasVector< N > locPos, MeasMatrix< N > locCov)
Sets IdentifierHash, local position and local covariance of the measurement.
ActsTrk::PixelClusteringTool::ClusterCollection
std::vector< Cluster > ClusterCollection
Definition: PixelClusteringTool.h:35
InDet::UnpackedPixelRDO
Definition: PixelRDOTool.h:31
xAOD::PixelCluster_v1::setChannelsInPhiEta
void setChannelsInPhiEta(int channelsInPhi, int channelsInEta)
Sets the dimensions of the cluster in numbers of channels in phi (x) and eta (y) directions.
Definition: PixelCluster_v1.cxx:55
xAOD::phiWidth
phiWidth
Definition: RingSetConf_v1.cxx:612
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
ActsTrk::PixelClusteringTool::m_pixelRDOTool
ToolHandle< InDet::PixelRDOTool > m_pixelRDOTool
Definition: PixelClusteringTool.h:66
InDet::SiWidth
Definition: SiWidth.h:25
InDet::SiWidth::colRow
const Amg::Vector2D & colRow() const
Definition: SiWidth.h:115
PixelChargeCalibCondData::getCharge
float getCharge(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float ToT) const
Definition: PixelChargeCalibCondData.cxx:223
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MuonDetectorBuilderTool.cxx:55
InDet::SiWidth::phiR
double phiR() const
Definition: SiWidth.h:126
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
PixelID
Definition: PixelID.h:67
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
InDet::SiWidth::z
double z() const
Definition: SiWidth.h:131
InDetDD::SolidStateDetectorElementBase::identify
virtual Identifier identify() const override final
identifier of this detector element (inline)
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
SG::ReadCondHandle::cptr
const_pointer_type cptr()
Definition: ReadCondHandle.h:67
Identifier
Definition: IdentifierFieldParser.cxx:14