ATLAS Offline Software
Loading...
Searching...
No Matches
ActsTrk::PixelClusteringTool Class Reference

#include <PixelClusteringTool.h>

Inheritance diagram for ActsTrk::PixelClusteringTool:
Collaboration diagram for ActsTrk::PixelClusteringTool:

Public Member Functions

 PixelClusteringTool (const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode clusterize (const EventContext &ctx, const RawDataCollection &RDOs, const InDet::SiDetectorElementStatus &pixelDetElStatus, const InDetDD::SiDetectorElement &element, Acts::Ccl::ClusteringData &data, std::vector< ClusterCollection > &collection) const override
virtual std::any makeVars (SG::AuxVectorData &cont) const override
virtual StatusCode makeClusters (const EventContext &ctx, typename IPixelClusteringTool::ClusterCollection &clusters, const InDetDD::SiDetectorElement &element, size_t icluster, std::any &vars, typename ClusterContainer::iterator itrContainer) const override
virtual StatusCode initialize () override

Private Member Functions

StatusCode makeCluster (PixelClusteringTool::Cluster &cluster, const InDetDD::SiDetectorElement *element, const InDetDD::PixelModuleDesign &design, const PixelChargeCalibCondData *calibData, const PixelChargeCalibCondData::CalibrationStrategy calibStrategy, double lorentz_shift, size_t icluster, xAOD::PixelCluster::ClusterVars &clusterVars) const
IPixelClusteringTool::CellCollection unpackRDOs (const RawDataCollection &RDOs, const InDet::SiDetectorElementStatus &stripDetElStatus, const InDetDD::SiDetectorElement &element) const

Static Private Member Functions

static std::optional< IdentifierisGanged (const Identifier &rdoID, const InDetDD::SiDetectorElement &element)

Private Attributes

ToolHandle< ISiLorentzAngleToolm_pixelLorentzAngleTool {this, "PixelLorentzAngleTool", "", "Tool to retreive Lorentz angle of Pixel"}
SG::ReadCondHandleKey< PixelChargeCalibCondDatam_chargeDataKey
Gaudi::Property< bool > m_addCorners {this, "AddCorners", true}
Gaudi::Property< bool > m_useWeightedPos {this, "UseWeightedPosition", false}
Gaudi::Property< bool > m_broadErrors {this, "UseBroadErrors", false}
Gaudi::Property< bool > m_checkGanged {this, "CheckGanged", false}
Gaudi::Property< bool > m_isITk {this, "isITk", true, "True if running in ITk"}
const PixelIDm_pixelID {nullptr}

Detailed Description

Definition at line 21 of file PixelClusteringTool.h.

Constructor & Destructor Documentation

◆ PixelClusteringTool()

ActsTrk::PixelClusteringTool::PixelClusteringTool ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 62 of file PixelClusteringTool.cxx.

64 : base_class(type,name,parent)
65{}

Member Function Documentation

◆ clusterize()

StatusCode ActsTrk::PixelClusteringTool::clusterize ( const EventContext & ctx,
const RawDataCollection & RDOs,
const InDet::SiDetectorElementStatus & pixelDetElStatus,
const InDetDD::SiDetectorElement & element,
Acts::Ccl::ClusteringData & data,
std::vector< ClusterCollection > & collection ) const
overridevirtual

Definition at line 240 of file PixelClusteringTool.cxx.

246{
247 IdentifierHash idHash = RDOs.identifyHash();
248 collection.emplace_back();
249 if ( not pixelDetElStatus.isGood(idHash) ) {
250 // the module being flagged as bad is not a failure
251 // An empty cluster collection needs to be added because the assumption
252 // is that there is one element per element RawDataCollection.
253 return StatusCode::SUCCESS;
254 }
255
256 // Retrieve the cells from the detector element
257 CellCollection cells = unpackRDOs(RDOs, pixelDetElStatus, element);
258
259 Acts::Ccl::createClusters<CellCollection, ClusterCollection, 2>
260 (data, cells, collection.back(), Acts::Ccl::DefaultConnect<Cell, 2>(m_addCorners));
261
262 return StatusCode::SUCCESS;
263}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
IPixelClusteringTool::CellCollection unpackRDOs(const RawDataCollection &RDOs, const InDet::SiDetectorElementStatus &stripDetElStatus, const InDetDD::SiDetectorElement &element) const
Gaudi::Property< bool > m_addCorners
bool isGood(IdentifierHash hash) const

◆ initialize()

StatusCode ActsTrk::PixelClusteringTool::initialize ( )
overridevirtual

Definition at line 41 of file PixelClusteringTool.cxx.

42{
43 ATH_MSG_DEBUG("Initializing " << name() << " ...");
44
49
51
52 ATH_CHECK(m_chargeDataKey.initialize(not m_chargeDataKey.empty()));
53
54 ATH_MSG_INFO(" Charge Data Key:" << m_chargeDataKey);
55
56 ATH_CHECK( detStore()->retrieve(m_pixelID, "PixelID") );
57
58 ATH_MSG_DEBUG(name() << " successfully initialized");
59 return StatusCode::SUCCESS;
60}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
Gaudi::Property< bool > m_broadErrors
SG::ReadCondHandleKey< PixelChargeCalibCondData > m_chargeDataKey
Gaudi::Property< bool > m_checkGanged
ToolHandle< ISiLorentzAngleTool > m_pixelLorentzAngleTool
Gaudi::Property< bool > m_useWeightedPos

◆ isGanged()

std::optional< Identifier > ActsTrk::PixelClusteringTool::isGanged ( const Identifier & rdoID,
const InDetDD::SiDetectorElement & element )
inlinestaticprivate

Definition at line 371 of file PixelClusteringTool.cxx.

373{
374 // If the pixel is ganged, returns a new identifier for it
375 InDetDD::SiCellId cellID = element.cellIdFromIdentifier( rdoID );
376 if ( element.numberOfConnectedCells( cellID ) > 1 ) {
377 InDetDD::SiCellId gangedCellID = element.connectedCell( cellID, 1 );
378 return element.identifierFromCellId( gangedCellID );
379 }
380 return std::nullopt;
381}
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
virtual Identifier identifierFromCellId(const SiCellId &cellId) const override final
Identifier <-> SiCellId (ie strip number or pixel eta_index,phi_index) Identifier from SiCellId (ie s...
SiCellId connectedCell(const SiCellId cellId, int number) const
Get the cell ids sharing the readout for this cell.
int numberOfConnectedCells(const SiCellId cellId) const
Test if readout cell has more than one diode associated with it.

◆ makeCluster()

StatusCode ActsTrk::PixelClusteringTool::makeCluster ( PixelClusteringTool::Cluster & cluster,
const InDetDD::SiDetectorElement * element,
const InDetDD::PixelModuleDesign & design,
const PixelChargeCalibCondData * calibData,
const PixelChargeCalibCondData::CalibrationStrategy calibStrategy,
double lorentz_shift,
size_t icluster,
xAOD::PixelCluster::ClusterVars & clusterVars ) const
private

Definition at line 68 of file PixelClusteringTool.cxx.

76{
77
78 Amg::Vector2D pos_acc(0,0);
79 int tot_acc = 0;
80
81 std::vector<float> chargeList;
82 if (calibData) chargeList.reserve(cluster.ids.size());
83
84 InDetDD::PixelDiodeTree::CellIndexType rowmax = std::numeric_limits<InDetDD::PixelDiodeTree::CellIndexType>::min();
85 InDetDD::PixelDiodeTree::CellIndexType colmax = std::numeric_limits<InDetDD::PixelDiodeTree::CellIndexType>::min();
86 InDetDD::PixelDiodeTree::CellIndexType rowmin = std::numeric_limits<InDetDD::PixelDiodeTree::CellIndexType>::max();
87 InDetDD::PixelDiodeTree::CellIndexType colmin = std::numeric_limits<InDetDD::PixelDiodeTree::CellIndexType>::max();
88 InDetDD::PixelDiodeTree::DiodeProxyWithPosition colmin_diode{};
89 InDetDD::PixelDiodeTree::DiodeProxyWithPosition colmax_diode{};
90 InDetDD::PixelDiodeTree::DiodeProxyWithPosition rowmin_diode{};
91 InDetDD::PixelDiodeTree::DiodeProxyWithPosition rowmax_diode{};
92
93 // We temporary comment this since it is not used
94 // bool hasGanged = false;
95
96 IdentifierHash moduleHash = element->identifyHash();
97
98 for (size_t i = 0; i < cluster.ids.size(); i++) {
99
100 //Construct the identifier class
101 Identifier id = Identifier(cluster.ids[i]);
102
103 // We temporary comment this since it is not used
104 // TODO: Check how the ganged info is used in legacy
105 // if (multiChip) {
106 // hasGanged = hasGanged ||
107 // m_pixelRDOTool->isGanged(id, element).has_value();
108 // }
109
110 int tot = cluster.tots.at(i);
111 float charge = tot;
112
113 std::array<InDetDD::PixelDiodeTree::CellIndexType,2> diode_idx
115 m_pixelID->eta_index(id));
116 InDetDD::PixelDiodeTree::DiodeProxyWithPosition si_param ( design.diodeProxyFromIdxCachePosition(diode_idx));
117
118 if (calibData) {
119 // Retrieving the calibration only depends on FE and not per cell (can be further optimized)
120 // Single FE modules could have an optimized getCharge function where the calib constants are cached
121 std::uint32_t feValue = design.getFE(si_param);
122 auto diode_type = design.getDiodeType(si_param);
123 if (m_isITk){
125 ATH_MSG_ERROR("Chip type is not recognized!");
126 return StatusCode::FAILURE;
127 }
128
129 charge = calibData->getCharge(diode_type,
130 calibStrategy,
131 moduleHash,
132 feValue,
133 tot);
134 chargeList.push_back(charge);
135 } else {
136 charge = calibData->getCharge(diode_type,
137 moduleHash,
138 feValue,
139 tot);
140
141 // These numbers are taken from the Cluster Maker Tool
142 if (design.getReadoutTechnology() != InDetDD::PixelReadoutTechnology::RD53 && (moduleHash < 12 or moduleHash > 2035)) {
143 charge = tot/8.0*(8000.0-1200.0)+1200.0;
144 }
145 chargeList.push_back(charge);
146 }
147 }
148
149 const InDetDD::PixelDiodeTree::CellIndexType &row = diode_idx[0];
150 const InDetDD::PixelDiodeTree::CellIndexType &col = diode_idx[1];
151 if (row>rowmax) {
152 rowmax=row;
153 rowmax_diode = si_param;
154 }
155 if (row<rowmin) {
156 rowmin=row;
157 rowmin_diode = si_param;
158 }
159 if (col>colmax) {
160 colmax=col;
161 colmax_diode = si_param;
162 }
163 if (col<colmin) {
164 colmin=col;
165 colmin_diode = si_param;
166 }
167
168 // We compute the digital position as a sum of all RDO positions
169 // all with the same weight of 1
170 // We do not compute a charge-weighted center of gravity here (by default) since
171 // we observe it to be worse than the digital position
172 // ToT-weighted center of gravity must not be used
173 if (m_useWeightedPos) {
174 pos_acc += charge * si_param.position();
175 tot_acc += charge;
176 } else {
177 pos_acc += si_param.position();
178 tot_acc += 1;
179 }
180
181 }
182
183 if (tot_acc > 0)
184 pos_acc /= tot_acc;
185
186
187 const int colWidth = colmax - colmin + 1;
188 const int rowWidth = rowmax - rowmin + 1;
189
190 double etaWidth = colmax_diode.xEtaMax() - colmin_diode.xEtaMin(); // design.widthFromColumnRange(colmin, colmax);
191 double phiWidth = rowmax_diode.xPhiMax() - rowmin_diode.xPhiMin(); // design.widthFromColumnRange(colmin, colmax);
192
193 // ask for Lorentz correction, get global position
194 const Amg::Vector2D localPos = pos_acc;
195 Amg::Vector2D locpos(localPos[Trk::locX]+lorentz_shift, localPos[Trk::locY]);
196 // find global position of element
197 const Amg::Transform3D& T = element->surface().transform();
198 double Ax[3] = {T(0,0),T(1,0),T(2,0)};
199 double Ay[3] = {T(0,1),T(1,1),T(2,1)};
200 double R [3] = {T(0,3),T(1,3),T(2,3)};
201
202 const Amg::Vector2D& M = locpos;
203 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]);
204
205 // Compute error matrix
206 float width0, width1;
207 if (m_broadErrors) {
208 // Use cluster width
209 width0 = phiWidth;
210 width1 = etaWidth;
211 } else {
212 // Use average pixel width
213 width0 = phiWidth / rowWidth;
214 width1 = etaWidth / colWidth;
215 }
216
217 // Actually create the cluster (i.e. fill the values)
218
219 Eigen::Matrix<float,2,1> localPosition(locpos.x(), locpos.y());
220 Eigen::Matrix<float,2,2> localCovariance = Eigen::Matrix<float,2,2>::Zero();
221 localCovariance(0, 0) = width0 * width0 / 12.0f;
222 localCovariance(1, 1) = width1 * width1 / 12.0f;
223
224 clusterVars.identifierHash[icluster] = moduleHash;
225 xAOD::VectorMap<2>(clusterVars.localPositionDim2[icluster].data()) = localPosition;
226 xAOD::MatrixMap<2>(clusterVars.localCovarianceDim2[icluster].data()) = localCovariance;
227 clusterVars.identifier[icluster] = cluster.ids.front();
228 clusterVars.rdoList[icluster] = std::move(cluster.ids);
229 xAOD::VectorMap<3>(clusterVars.globalPosition[icluster].data()) = globalPos.cast<float>();
230 clusterVars.totList[icluster] = std::move(cluster.tots);
231 clusterVars.lvl1a[icluster] = cluster.lvl1min;
232 clusterVars.channelsInPhi[icluster] = rowWidth;
233 clusterVars.channelsInEta[icluster] = colWidth;
234 clusterVars.widthInEta[icluster] = etaWidth;
235
236 return StatusCode::SUCCESS;
237}
#define ATH_MSG_ERROR(x)
double charge(const T &p)
Definition AtlasPID.h:997
Gaudi::Property< bool > m_isITk
static constexpr std::array< PixelDiodeTree::CellIndexType, 2 > makeCellIndex(T local_x_idx, T local_y_idx)
Create a 2D cell index from the indices in local-x (phi, row) and local-y (eta, column) direction.
PixelDiodeTree::DiodeProxyWithPosition diodeProxyFromIdxCachePosition(const std::array< PixelDiodeTree::IndexType, 2 > &idx) const
PixelReadoutTechnology getReadoutTechnology() const
static InDetDD::PixelDiodeType getDiodeType(const PixelDiodeTree::DiodeProxy &diode_proxy)
static unsigned int getFE(const PixelDiodeTree::DiodeProxy &diode_proxy)
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
Trk::Surface & surface()
Element Surface.
float getCharge(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float ToT) const
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
double R(const INavigable4Momentum *p1, const double v_eta, const double v_phi)
row
Appending html table to final .html summary file.
unsigned long long T
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
Eigen::Map< MeasVector< N > > VectorMap
Eigen::Map< MeasMatrix< N > > MatrixMap
double xPhiMax() const
for backward compatibility, return the position of the lower edge of the diode in local-y(phi,...
double xEtaMin() const
for backward compatibility, return the position of the lower edge of the diode in local-y(eta,...
double xPhiMin() const
for backward compatibility, return the position of the lower edge of the diode in local-x(phi,...
double xEtaMax() const
for backward compatibility, return the position of the upper edge of the diode in local-y(eta,...

◆ makeClusters()

StatusCode ActsTrk::PixelClusteringTool::makeClusters ( const EventContext & ctx,
typename IPixelClusteringTool::ClusterCollection & clusters,
const InDetDD::SiDetectorElement & element,
size_t icluster,
std::any & vars,
typename ClusterContainer::iterator itrContainer ) const
overridevirtual

Definition at line 273 of file PixelClusteringTool.cxx.

279{
280 // Retrieve the calibration data
281 const PixelChargeCalibCondData *calibData = nullptr;
282 if (not m_chargeDataKey.empty()) {
283 SG::ReadCondHandle<PixelChargeCalibCondData> calibDataHandle = SG::makeHandle( m_chargeDataKey, ctx );
284 calibData = calibDataHandle.cptr();
285
286 if (!calibData) {
287 ATH_MSG_ERROR("PixelChargeCalibCondData requested but couldn't be retrieved from " << m_chargeDataKey.key());
288 return StatusCode::FAILURE;
289 }
290 }
291
292 // Get the element design
293 const InDetDD::PixelModuleDesign& design =
294 static_cast<const InDetDD::PixelModuleDesign&>(element.design());
295
296 // Get the calibration strategy for this module.
297 // Default to RD53 if the calibData is not available. That is fine because it won't be used anyway
298 auto calibrationStrategy = calibData ? calibData->getCalibrationStrategy(element.identifyHash()) : PixelChargeCalibCondData::CalibrationStrategy::RD53;
299
300 double lorentz_shift = m_pixelLorentzAngleTool->getLorentzShift(element.identifyHash(), ctx);
301
302 auto* clusterVars = std::any_cast<xAOD::PixelCluster::ClusterVars> (&vars);
303 if (!clusterVars) throw std::bad_any_cast();
304
305 for (typename IPixelClusteringTool::Cluster& cl : clusters) {
307 &element,
308 design,
309 calibData,
310 calibrationStrategy,
311 lorentz_shift,
312 icluster++,
313 *clusterVars));
314 }
315
316 return StatusCode::SUCCESS;
317}
StatusCode makeCluster(PixelClusteringTool::Cluster &cluster, const InDetDD::SiDetectorElement *element, const InDetDD::PixelModuleDesign &design, const PixelChargeCalibCondData *calibData, const PixelChargeCalibCondData::CalibrationStrategy calibStrategy, double lorentz_shift, size_t icluster, xAOD::PixelCluster::ClusterVars &clusterVars) const
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
CalibrationStrategy getCalibrationStrategy(unsigned int moduleHash) const
const_pointer_type cptr()
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())

◆ makeVars()

std::any ActsTrk::PixelClusteringTool::makeVars ( SG::AuxVectorData & cont) const
overridevirtual

Definition at line 266 of file PixelClusteringTool.cxx.

267{
268 return std::any (xAOD::PixelCluster::ClusterVars (cont));
269}

◆ unpackRDOs()

IPixelClusteringTool::CellCollection ActsTrk::PixelClusteringTool::unpackRDOs ( const RawDataCollection & RDOs,
const InDet::SiDetectorElementStatus & stripDetElStatus,
const InDetDD::SiDetectorElement & element ) const
private

Definition at line 320 of file PixelClusteringTool.cxx.

323{
324 // Get the element design
325 const InDetDD::PixelModuleDesign& design =
326 static_cast<const InDetDD::PixelModuleDesign&>(element.design());
327 CellCollection cells;
328 cells.reserve(300);
329
330 const IdentifierHash& idHash = RDOs.identifyHash();
331 for (const auto *const rdo : RDOs) {
332 const Identifier& rdoID = rdo->identify();
333 std::array<InDetDD::PixelDiodeTree::CellIndexType,2> diode_idx
335 m_pixelID->eta_index(rdoID));
336 InDetDD::PixelDiodeTree::DiodeProxy si_param ( design.diodeProxyFromIdx(diode_idx));
337 std::uint32_t fe = design.getFE(si_param);
338
339 // check if good RDO
340 // the pixel RDO tool here says always good if m_useModuleMap is false
341 if (not pixelDetElStatus.isChipGood(idHash, fe)) {
342 continue;
343 }
344
345 const int lvl1 = rdo->getLVL1A();
346 const int tot = rdo->getToT();
347
348 cells.emplace_back(m_pixelID->phi_index(rdoID),
349 m_pixelID->eta_index(rdoID),
350 tot,
351 lvl1,
352 rdoID.get_compact());
353
354 if ( m_checkGanged ) {
355 std::optional<Identifier> gangedID = isGanged(rdoID, element);
356 if (gangedID.has_value()) {
357 cells.emplace_back(m_pixelID->phi_index(*gangedID),
358 m_pixelID->eta_index(*gangedID),
359 tot,
360 lvl1,
361 gangedID->get_compact());
362 }
363 }
364
365 }
366
367 return cells;
368}
static std::optional< Identifier > isGanged(const Identifier &rdoID, const InDetDD::SiDetectorElement &element)
value_type get_compact() const
Get the compact id.
PixelDiodeTree::DiodeProxy diodeProxyFromIdx(const std::array< PixelDiodeTree::IndexType, 2 > &idx) const

Member Data Documentation

◆ m_addCorners

Gaudi::Property<bool> ActsTrk::PixelClusteringTool::m_addCorners {this, "AddCorners", true}
private

Definition at line 76 of file PixelClusteringTool.h.

76{this, "AddCorners", true};

◆ m_broadErrors

Gaudi::Property<bool> ActsTrk::PixelClusteringTool::m_broadErrors {this, "UseBroadErrors", false}
private

Definition at line 78 of file PixelClusteringTool.h.

78{this, "UseBroadErrors", false};

◆ m_chargeDataKey

SG::ReadCondHandleKey<PixelChargeCalibCondData> ActsTrk::PixelClusteringTool::m_chargeDataKey
private
Initial value:
{this, "PixelChargeCalibCondData", "",
"Pixel charge calibration data"}

Definition at line 73 of file PixelClusteringTool.h.

73 {this, "PixelChargeCalibCondData", "",
74 "Pixel charge calibration data"};

◆ m_checkGanged

Gaudi::Property<bool> ActsTrk::PixelClusteringTool::m_checkGanged {this, "CheckGanged", false}
private

Definition at line 79 of file PixelClusteringTool.h.

79{this, "CheckGanged", false};

◆ m_isITk

Gaudi::Property<bool> ActsTrk::PixelClusteringTool::m_isITk {this, "isITk", true, "True if running in ITk"}
private

Definition at line 80 of file PixelClusteringTool.h.

80{this, "isITk", true, "True if running in ITk"};

◆ m_pixelID

const PixelID* ActsTrk::PixelClusteringTool::m_pixelID {nullptr}
private

Definition at line 81 of file PixelClusteringTool.h.

81{nullptr};

◆ m_pixelLorentzAngleTool

ToolHandle< ISiLorentzAngleTool > ActsTrk::PixelClusteringTool::m_pixelLorentzAngleTool {this, "PixelLorentzAngleTool", "", "Tool to retreive Lorentz angle of Pixel"}
private

Definition at line 71 of file PixelClusteringTool.h.

71{this, "PixelLorentzAngleTool", "", "Tool to retreive Lorentz angle of Pixel"};

◆ m_useWeightedPos

Gaudi::Property<bool> ActsTrk::PixelClusteringTool::m_useWeightedPos {this, "UseWeightedPosition", false}
private

Definition at line 77 of file PixelClusteringTool.h.

77{this, "UseWeightedPosition", false};

The documentation for this class was generated from the following files: