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 StatusCode makeClusters (const EventContext &ctx, typename IPixelClusteringTool::ClusterCollection &clusters, const InDetDD::SiDetectorElement &element, 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, xAOD::PixelCluster &container) 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 63 of file PixelClusteringTool.cxx.

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

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 242 of file PixelClusteringTool.cxx.

248{
249 IdentifierHash idHash = RDOs.identifyHash();
250 collection.emplace_back();
251 if ( not pixelDetElStatus.isGood(idHash) ) {
252 // the module being flagged as bad is not a failure
253 // An empty cluster collection needs to be added because the assumption
254 // is that there is one element per element RawDataCollection.
255 return StatusCode::SUCCESS;
256 }
257
258 // Retrieve the cells from the detector element
259 CellCollection cells = unpackRDOs(RDOs, pixelDetElStatus, element);
260
261 Acts::Ccl::createClusters<CellCollection, ClusterCollection, 2>
262 (data, cells, collection.back(), Acts::Ccl::DefaultConnect<Cell, 2>(m_addCorners));
263
264 return StatusCode::SUCCESS;
265}
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 42 of file PixelClusteringTool.cxx.

43{
44 ATH_MSG_DEBUG("Initializing " << name() << " ...");
45
50
52
53 ATH_CHECK(m_chargeDataKey.initialize(not m_chargeDataKey.empty()));
54
55 ATH_MSG_INFO(" Charge Data Key:" << m_chargeDataKey);
56
57 ATH_CHECK( detStore()->retrieve(m_pixelID, "PixelID") );
58
59 ATH_MSG_DEBUG(name() << " successfully initialized");
60 return StatusCode::SUCCESS;
61}
#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
retrieve(aClass, aKey=None)
Definition PyKernel.py:110

◆ isGanged()

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

Definition at line 365 of file PixelClusteringTool.cxx.

367{
368 // If the pixel is ganged, returns a new identifier for it
369 InDetDD::SiCellId cellID = element.cellIdFromIdentifier( rdoID );
370 if ( element.numberOfConnectedCells( cellID ) > 1 ) {
371 InDetDD::SiCellId gangedCellID = element.connectedCell( cellID, 1 );
372 return element.identifierFromCellId( gangedCellID );
373 }
374 return std::nullopt;
375}
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,
xAOD::PixelCluster & container ) const
private

Definition at line 69 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 xaodcluster.setMeasurement<2>(moduleHash, localPosition, localCovariance);
225 xaodcluster.setIdentifier( cluster.ids.front() );
226 xaodcluster.setRDOlist(std::move(cluster.ids));
227 xaodcluster.globalPosition() = globalPos.cast<float>();
228 xaodcluster.setTotalToT( xAOD::xAODInDetMeasurement::Utilities::computeTotalToT(cluster.tots) );
229 xaodcluster.setToTlist(std::move(cluster.tots));
230 xaodcluster.setTotalCharge( xAOD::xAODInDetMeasurement::Utilities::computeTotalCharge(chargeList) );
231 xaodcluster.setChargelist(std::move(chargeList));
232 xaodcluster.setLVL1A(cluster.lvl1min);
233 xaodcluster.setChannelsInPhiEta(rowWidth,colWidth);
234 xaodcluster.setWidthInEta(static_cast<float>(etaWidth));
235 xaodcluster.setIsSplit(false);
236 xaodcluster.setSplitProbabilities(0.0, 0.0);
237
238 return StatusCode::SUCCESS;
239}
#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
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,
typename ClusterContainer::iterator itrContainer ) const
overridevirtual

Definition at line 269 of file PixelClusteringTool.cxx.

273{
274 // We'd need a smarter move here!!!
275
276 // Retrieve the calibration data
277 const PixelChargeCalibCondData *calibData = nullptr;
278 if (not m_chargeDataKey.empty()) {
279 SG::ReadCondHandle<PixelChargeCalibCondData> calibDataHandle = SG::makeHandle( m_chargeDataKey, ctx );
280 calibData = calibDataHandle.cptr();
281
282 if (!calibData) {
283 ATH_MSG_ERROR("PixelChargeCalibCondData requested but couldn't be retrieved from " << m_chargeDataKey.key());
284 return StatusCode::FAILURE;
285 }
286 }
287
288 // Get the element design
289 const InDetDD::PixelModuleDesign& design =
290 static_cast<const InDetDD::PixelModuleDesign&>(element.design());
291
292 // Get the calibration strategy for this module.
293 // Default to RD53 if the calibData is not available. That is fine because it won't be used anyway
294 auto calibrationStrategy = calibData ? calibData->getCalibrationStrategy(element.identifyHash()) : PixelChargeCalibCondData::CalibrationStrategy::RD53;
295
296 double lorentz_shift = m_pixelLorentzAngleTool->getLorentzShift(element.identifyHash(), ctx);
297
298 for (typename IPixelClusteringTool::Cluster& cl : clusters) {
299 xAOD::PixelCluster* xaodCluster = *itrContainer;
301 &element,
302 design,
303 calibData,
304 calibrationStrategy,
305 lorentz_shift,
306 *xaodCluster));
307 ++itrContainer;
308 }
309
310 return StatusCode::SUCCESS;
311}
StatusCode makeCluster(PixelClusteringTool::Cluster &cluster, const InDetDD::SiDetectorElement *element, const InDetDD::PixelModuleDesign &design, const PixelChargeCalibCondData *calibData, const PixelChargeCalibCondData::CalibrationStrategy calibStrategy, double lorentz_shift, xAOD::PixelCluster &container) 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())
PixelCluster_v1 PixelCluster
Define the version of the pixel cluster class.

◆ unpackRDOs()

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

Definition at line 314 of file PixelClusteringTool.cxx.

317{
318 // Get the element design
319 const InDetDD::PixelModuleDesign& design =
320 static_cast<const InDetDD::PixelModuleDesign&>(element.design());
321 CellCollection cells;
322 cells.reserve(300);
323
324 const IdentifierHash& idHash = RDOs.identifyHash();
325 for (const auto *const rdo : RDOs) {
326 const Identifier& rdoID = rdo->identify();
327 std::array<InDetDD::PixelDiodeTree::CellIndexType,2> diode_idx
329 m_pixelID->eta_index(rdoID));
330 InDetDD::PixelDiodeTree::DiodeProxy si_param ( design.diodeProxyFromIdx(diode_idx));
331 std::uint32_t fe = design.getFE(si_param);
332
333 // check if good RDO
334 // the pixel RDO tool here says always good if m_useModuleMap is false
335 if (not pixelDetElStatus.isChipGood(idHash, fe)) {
336 continue;
337 }
338
339 const int lvl1 = rdo->getLVL1A();
340 const int tot = rdo->getToT();
341
342 cells.emplace_back(m_pixelID->phi_index(rdoID),
343 m_pixelID->eta_index(rdoID),
344 tot,
345 lvl1,
346 rdoID.get_compact());
347
348 if ( m_checkGanged ) {
349 std::optional<Identifier> gangedID = isGanged(rdoID, element);
350 if (gangedID.has_value()) {
351 cells.emplace_back(m_pixelID->phi_index(*gangedID),
352 m_pixelID->eta_index(*gangedID),
353 tot,
354 lvl1,
355 gangedID->get_compact());
356 }
357 }
358
359 }
360
361 return cells;
362}
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 71 of file PixelClusteringTool.h.

71{this, "AddCorners", true};

◆ m_broadErrors

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

Definition at line 73 of file PixelClusteringTool.h.

73{this, "UseBroadErrors", false};

◆ m_chargeDataKey

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

Definition at line 68 of file PixelClusteringTool.h.

68 {this, "PixelChargeCalibCondData", "",
69 "Pixel charge calibration data"};

◆ m_checkGanged

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

Definition at line 74 of file PixelClusteringTool.h.

74{this, "CheckGanged", false};

◆ m_isITk

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

Definition at line 75 of file PixelClusteringTool.h.

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

◆ m_pixelID

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

Definition at line 76 of file PixelClusteringTool.h.

76{nullptr};

◆ m_pixelLorentzAngleTool

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

Definition at line 66 of file PixelClusteringTool.h.

66{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 72 of file PixelClusteringTool.h.

72{this, "UseWeightedPosition", false};

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