ATLAS Offline Software
Public Member Functions | Private Attributes | List of all members
xAODClusterMaker Class Reference

Creates xAOD pixel and strip cluster containers from FPGA input. More...

#include <xAODClusterMaker.h>

Inheritance diagram for xAODClusterMaker:
Collaboration diagram for xAODClusterMaker:

Public Member Functions

StatusCode initialize () override
 Initialise the tool. More...
 
StatusCode makeStripClusterContainer (const EFTrackingTransient::StripClusterAuxInput &scAux, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
 Make the strip cluster container. More...
 
StatusCode makeStripClusterContainer (const uint64_t *stripClusters, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
 Make the strip cluster container. More...
 
StatusCode makePixelClusterContainer (const EFTrackingTransient::PixelClusterAuxInput &pxAux, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
 Make the pixel cluster container. More...
 
StatusCode makePixelClusterContainer (const uint64_t *pixelClusters, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
 Make the pixel cluster container. More...
 

Private Attributes

SG::WriteHandleKey< xAOD::PixelClusterContainerm_pixelClustersKey
 Key for the pixel clusters container to be created. More...
 
SG::WriteHandleKey< xAOD::StripClusterContainerm_stripClustersKey
 Key for the strip clusters container to be created. More...
 
Gaudi::Property< bool > m_doBulkCopy {this, "DoBulkCopy", true, "Do bulk copy"}
 Do bulk copy method. More...
 
ServiceHandle< IChronoStatSvc > m_chronoSvc {this, "ChronoStatSvc", "ChronoStatSvc"}
 

Detailed Description

Creates xAOD pixel and strip cluster containers from FPGA input.

Definition at line 34 of file xAODClusterMaker.h.

Member Function Documentation

◆ initialize()

StatusCode xAODClusterMaker::initialize ( )
override

Initialise the tool.

Definition at line 24 of file xAODClusterMaker.cxx.

24  {
25  ATH_MSG_INFO("Initialising xAODClusterMaker tool");
26 
27  // Initialise the write handles
28  ATH_CHECK(m_pixelClustersKey.initialize());
29  ATH_CHECK(m_stripClustersKey.initialize());
30 
31  // Initialise the chrono service
32  ATH_CHECK(m_chronoSvc.retrieve());
33 
34  return StatusCode::SUCCESS;
35 }

◆ makePixelClusterContainer() [1/2]

StatusCode xAODClusterMaker::makePixelClusterContainer ( const EFTrackingTransient::PixelClusterAuxInput pxAux,
const EFTrackingTransient::Metadata metadata,
const EventContext &  ctx 
) const

Make the pixel cluster container.

Parameters
pxAuxInput pixel cluster data
metadataInput metadata
ctx
Returns
StatusCode

Definition at line 460 of file xAODClusterMaker.cxx.

463  {
464  ATH_MSG_DEBUG("Making xAOD::PixelClusterContainer");
465 
466 
468 
469  if (!m_doBulkCopy) {
470  // --------------------------------------------------------------------
471  // proceed with the element-wise method
472  // --------------------------------------------------------------------
473  ATH_MSG_DEBUG("You are running the element-wise container creation method.");
474  Athena::Chrono chrono("ElementWiseMethod", m_chronoSvc.get());
475 
476  ATH_CHECK(pixelClustersHandle.record(
477  std::make_unique<xAOD::PixelClusterContainer>(),
478  std::make_unique<xAOD::PixelClusterAuxContainer>()));
479 
480  ATH_CHECK(pixelClustersHandle.isValid());
481  ATH_MSG_DEBUG("Container '" << m_pixelClustersKey << "' initialised");
482 
483  int rdoIndexCounter = 0;
484 
485  for (unsigned int i = 0; i < metadata->numOfPixelClusters; i++) {
486  // Push back numClusters of PixelCluster
487  auto pixelCl = pixelClustersHandle->push_back(
488  std::make_unique<xAOD::PixelCluster>());
489 
490  Eigen::Matrix<float, 2, 1> localPosition(
491  pxAux.localPosition[i * 2], pxAux.localPosition[i * 2 + 1]);
492  Eigen::Matrix<float, 2, 2> localCovariance;
493  localCovariance.setZero();
494  localCovariance(0, 0) = pxAux.localCovariance[i * 2];
495  localCovariance(1, 1) = pxAux.localCovariance[i * 2 + 1];
496  Eigen::Matrix<float, 3, 1> globalPosition(
497  pxAux.globalPosition[i * 3], pxAux.globalPosition[i * 3 + 1],
498  pxAux.globalPosition[i * 3 + 2]);
499 
500  std::vector<Identifier> RDOs;
501  RDOs.reserve(metadata->pcRdoIndex[i]);
502  // Cover RDO
503  for (unsigned int j = 0; j < metadata->pcRdoIndex[i]; ++j) {
504  RDOs.push_back(Identifier(pxAux.rdoList[rdoIndexCounter + j]));
505  }
506 
507  rdoIndexCounter += metadata->pcRdoIndex[i];
508 
509  pixelCl->setMeasurement<2>(pxAux.idHash[i], localPosition,
510  localCovariance);
511  pixelCl->setIdentifier(pxAux.id[i]);
512  pixelCl->setRDOlist(RDOs);
513  pixelCl->globalPosition() = globalPosition;
514  pixelCl->setTotalToT(pxAux.totalToT[i]);
515  pixelCl->setChannelsInPhiEta(pxAux.channelsInPhi[i],
516  pxAux.channelsInEta[i]);
517  pixelCl->setWidthInEta(pxAux.widthInEta[i]);
518  }
519 
520  return StatusCode::SUCCESS;
521  }
522 
523  // --------------------------------------------------------------------
524  // proceed with the bulk copy method
525  // --------------------------------------------------------------------
526 
527  ATH_MSG_DEBUG("You are running the bulk copy container creation method.");
528  Athena::Chrono chrono("BulkCopyMethod", m_chronoSvc.get());
529 
530  // --------------------------
531  // Create the container and aux. container
532  // --------------------------
533  auto pixelCl = std::make_unique<xAOD::PixelClusterContainer>();
534  auto pixelClAux = std::make_unique<xAOD::PixelClusterAuxContainer>();
535  pixelCl->setStore(pixelClAux.get());
536 
537  // Pre-allocate memory for all clusters in the AuxContainer
538  // and reserve the same space in the container.
539  const size_t nClusters = metadata->numOfPixelClusters;
540  pixelClAux->resize(nClusters);
541  pixelCl->reserve(nClusters);
542 
543  // Now, push back the PixelCluster objects
544  // and create them all at once.
545  // Note, that no data is set yet,
546  // we will do that in the next step.
547  for (size_t i = 0; i < nClusters; ++i) {
548  pixelCl->push_back(std::make_unique<xAOD::PixelCluster>());
549  }
550 
551  // --------------------------
552  // Prepare local buffers for each of the
553  // fixed-size attributes.
554  // --------------------------
555  std::vector<long unsigned int> identifierBuffer(nClusters);
556  std::vector<unsigned int> idHashBuffer(nClusters);
557  std::vector<std::array<float, 3>> gpBuffer(nClusters);
558  std::vector<float> localPosX(nClusters);
559  std::vector<float> localPosY(nClusters);
560  std::vector<float> localCovXX(nClusters);
561  std::vector<float> localCovYY(nClusters);
562  std::vector<int> totalToTBuffer(nClusters);
563  std::vector<float> widthInEtaBuffer(nClusters);
564  std::vector<int> channelsInPhiBuffer(nClusters);
565  std::vector<int> channelsInEtaBuffer(nClusters);
566 
567  for (size_t i = 0; i < nClusters; ++i) {
568 
569  // Fill the identifierBuffer
570  identifierBuffer[i] = pxAux.id[i];
571 
572  // Fill the idHashBuffer
573  idHashBuffer[i] = pxAux.idHash[i];
574 
575  // Fill the globalPositionBuffers
576  gpBuffer[i] = {
577  pxAux.globalPosition[3 * i],
578  pxAux.globalPosition[3 * i + 1],
579  pxAux.globalPosition[3 * i + 2],
580  };
581 
582  // Fill the localPositionBuffers
583  localPosX[i] = pxAux.localPosition[2 * i];
584  localPosY[i] = pxAux.localPosition[2 * i + 1];
585 
586  // Fill the localCovBuffer[i]
587  localCovXX[i] = pxAux.localCovariance[2 * i];
588  localCovYY[i] = pxAux.localCovariance[2 * i + 1];
589 
590  // Fill the totalToTBuffer
591  totalToTBuffer[i] = pxAux.totalToT[i];
592 
593  // Fill the widthInEtaBuffer
594  widthInEtaBuffer[i] = pxAux.widthInEta[i];
595 
596  // Fill the channelsInPhiEtaBuffer
597  channelsInPhiBuffer[i] = pxAux.channelsInPhi[i];
598  channelsInEtaBuffer[i] = pxAux.channelsInEta[i];
599  }
600 
601  // --------------------------
602  // Now, use SG::Accessors to do a bulk copy into
603  // the container memory.
604  // --------------------------
605 
606  // FIXED-SIZE ATTRIBUTES
607  static const SG::Accessor<long unsigned int> idAcc("identifier");
608  static const SG::Accessor<unsigned int> idHashAcc("idHash");
609  static const SG::Accessor<float> localPosXAcc("localPositionX");
610  static const SG::Accessor<float> localPosYAcc("localPositionY");
611  static const SG::Accessor<float> localCovXXAcc("localCovarianceXX");
612  static const SG::Accessor<float> localCovYYAcc("localCovarianceYY");
613  static const SG::Accessor<int> totAcc("totalToT");
614  static const SG::Accessor<float> widthEtaAcc("widthInEta");
615  static const SG::Accessor<int> channelsInPhiAcc("channelsInPhi");
616  static const SG::Accessor<int> channelsInEtaAcc("channelsInEta");
617 
618  // VARIABLE-LENGTH ATTRIBUTES
619  static const SG::Accessor<std::array<float, 3>> globalPosAcc(
620  "globalPosition");
621 
622  // Get spans into the container
623  auto idSpan = idAcc.getDataSpan(*pixelCl);
624  auto idHashSpan = idHashAcc.getDataSpan(*pixelCl);
625  auto locPosXSpan = localPosXAcc.getDataSpan(*pixelCl);
626  auto locPosYSpan = localPosYAcc.getDataSpan(*pixelCl);
627  auto locCovXXSpan = localCovXXAcc.getDataSpan(*pixelCl);
628  auto locCovYYSpan = localCovYYAcc.getDataSpan(*pixelCl);
629  auto totSpan = totAcc.getDataSpan(*pixelCl);
630  auto wEtaSpan = widthEtaAcc.getDataSpan(*pixelCl);
631  auto gpSpan = globalPosAcc.getDataSpan(*pixelCl);
632  auto channelsInPhiSpan = channelsInPhiAcc.getDataSpan(*pixelCl);
633  auto channelsInEtaSpan = channelsInEtaAcc.getDataSpan(*pixelCl);
634 
635  // Bulk copy the fixed-size attributes
636  CxxUtils::copy_bounded(identifierBuffer, idSpan);
637  CxxUtils::copy_bounded(idHashBuffer, idHashSpan);
638  CxxUtils::copy_bounded(localPosX, locPosXSpan);
639  CxxUtils::copy_bounded(localPosY, locPosYSpan);
640  CxxUtils::copy_bounded(localCovXX, locCovXXSpan);
641  CxxUtils::copy_bounded(localCovYY, locCovYYSpan);
642  CxxUtils::copy_bounded(totalToTBuffer, totSpan);
643  CxxUtils::copy_bounded(widthInEtaBuffer, wEtaSpan);
644  CxxUtils::copy_bounded(gpBuffer, gpSpan);
645  CxxUtils::copy_bounded(channelsInPhiBuffer, channelsInPhiSpan);
646  CxxUtils::copy_bounded(channelsInEtaBuffer, channelsInEtaSpan);
647 
648  // --------------------------
649  // Copy the variable-length data.
650  // We need to loop over the number of
651  // clusters to get access to each
652  // element.
653  // --------------------------
654  static const SG::Accessor<std::vector<unsigned long long>> rdoListAcc(
655  "rdoList");
656  auto rdoSpan = rdoListAcc.getDataSpan(*pixelCl);
657 
658  int rdoIndexCounter = 0;
659  // loop over the clusters
660  for (size_t i = 0; i < nClusters; ++i) {
661  size_t nRDOs = metadata->pcRdoIndex[i];
662 
663  // direct ref to destination vector
664  std::vector<unsigned long long> &rdosForThisCluster = rdoSpan[i];
665 
666  // pre-size the vector
667  rdosForThisCluster.resize(nRDOs);
668 
669  // direct element access
670  for (size_t j = 0; j < nRDOs; ++j) {
671  rdosForThisCluster[j] = pxAux.rdoList[rdoIndexCounter + j];
672  }
673  rdoIndexCounter += nRDOs;
674  }
675  // --------------------------
676  // Record the container + aux container into StoreGate,
677  // but now we do it AFTER filling the container!
678  // --------------------------
679 
680  ATH_CHECK(pixelClustersHandle.record(std::move(pixelCl), std::move(pixelClAux)));
681 
682  ATH_MSG_DEBUG("Bulk copy for fixed-size variables done.");
683  return StatusCode::SUCCESS;
684  }

◆ makePixelClusterContainer() [2/2]

StatusCode xAODClusterMaker::makePixelClusterContainer ( const uint64_t *  pixelClusters,
const EFTrackingTransient::Metadata metadata,
const EventContext &  ctx 
) const

Make the pixel cluster container.

Parameters
pixelClustersraw input from the EDM output
metadataInput metadata
ctx
Returns
StatusCode

Definition at line 253 of file xAODClusterMaker.cxx.

256  {
257  ATH_MSG_DEBUG("Making xAOD::PixelClusterContainer");
258 
259 
261 
262  if (!m_doBulkCopy) {
263  // --------------------------------------------------------------------
264  // proceed with the element-wise method
265  // --------------------------------------------------------------------
266  ATH_CHECK(pixelClustersHandle.record(std::make_unique<xAOD::PixelClusterContainer>(),std::make_unique<xAOD::PixelClusterAuxContainer>()));
267 
268  ATH_CHECK(pixelClustersHandle.isValid());
269 
270  for (unsigned int i = 0; i < metadata->numOfPixelClusters; i++)
271  {
272  // Push back numClusters of StripCluster
273  auto pixelCl = pixelClustersHandle->push_back(std::make_unique<xAOD::PixelCluster>());
274 
275  int row = 0; // idhash
276  long unsigned int idHash = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
277  row = 1; // id
278  unsigned long long id = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
279 
280  std::vector<Identifier> RDOs;
281  row = 2; // rdo w1
282  unsigned long long rdo = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
283  if (rdo) RDOs.push_back(Identifier(rdo));
284 
285  row = 3; // rdo w2
286  rdo = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
287  if (rdo) RDOs.push_back(Identifier(rdo));
288 
289  row = 4; // rdo w3
290  rdo = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
291  if (rdo) RDOs.push_back(Identifier(rdo));
292 
293  row = 5; // rdo w4
294  rdo = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
295  if (rdo) RDOs.push_back(Identifier(rdo));
296 
297  Eigen::Matrix<float, 2, 1> localPosition;
298  Eigen::Matrix<float, 2, 2> localCovariance;
299  localCovariance.setZero();
300  row = 6; // local x
301  localPosition(0 , 0) = std::bit_cast<double>(pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
302 
303  row = 7; // local y
304  localPosition(1 , 1) = std::bit_cast<double>(pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
305 
306  row = 8; // local covariance xx
307  localCovariance(0, 0) = std::bit_cast<double>(pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
308 
309  row = 9; // local covariance yy
310  localCovariance(1, 1) = std::bit_cast<double>(pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
311 
312  row = 10; // global x
313  float globalX = std::bit_cast<double>(pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
314 
315  row = 11; // global y
316  float globalY = std::bit_cast<double>(pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
317 
318  row = 12; // global
319  float globalZ = std::bit_cast<double>(pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
320 
321  row = 13; // channels in phi
322  int channelsInPhi = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
323 
324  row = 14; // channels in eta
325  int channelsInEta = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
326 
327  row = 15; // width in eta
328  double widthInEta = std::bit_cast<double>(pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
329 
330  row = 18; // total ToT
331  int totalToT = pixelClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
332 
333  Eigen::Matrix<float, 3, 1> globalPosition(globalX, globalY, globalZ);
334 
335  pixelCl->setMeasurement<2>(idHash, localPosition,localCovariance);
336  pixelCl->setIdentifier(id);
337  pixelCl->setRDOlist(RDOs);
338  pixelCl->globalPosition() = globalPosition;
339  pixelCl->setTotalToT(totalToT);
340  pixelCl->setChannelsInPhiEta(channelsInPhi, channelsInEta);
341  pixelCl->setWidthInEta(widthInEta);
342  }
343  return StatusCode::SUCCESS;
344  }
345 
346  ATH_MSG_DEBUG("Doing bulk copy (optimized)");
347  // --------------------------
348  // Create the container and aux. container
349  // --------------------------
350  const size_t nClusters = metadata->numOfPixelClusters;
351  auto pixelCl = std::make_unique<xAOD::PixelClusterContainer>();
352  pixelCl->reserve(nClusters);
353  {
354  Athena::Chrono chrono("Pixel object creating", m_chronoSvc.get());
355  for (std::size_t i = 0; i < nClusters; ++i) {
356  pixelCl->push_back(std::make_unique<xAOD::PixelCluster>());
357  }
358  }
359 
360  auto pixelClAux = std::make_unique<xAOD::PixelClusterAuxContainer>();
361  pixelClAux->resize(pixelCl->size());
362  pixelCl->setStore(pixelClAux.get());
363 
364 
365  // --------------------------
366  // Access fixed-size attributes directly
367  // --------------------------
369  const size_t offset = 8;
370  const auto* base = pixelClusters;
371 
372  // Direct column pointers
373  const auto* idHashPtr = base + 0 * N + offset;
374  const auto* identifierPtr = base + 1 * N + offset;
375  const uint64_t* rdoPtrs[4] = {
376  base + 2 * N + offset, base + 3 * N + offset,
377  base + 4 * N + offset, base + 5 * N + offset
378  };
379  const auto* localXPtr = base + 6 * N + offset;
380  const auto* localYPtr = base + 7 * N + offset;
381  const auto* covXXPtr = base + 8 * N + offset;
382  const auto* covYYPtr = base + 9 * N + offset;
383  const auto* gpXPtr = base + 10 * N + offset;
384  const auto* gpYPtr = base + 11 * N + offset;
385  const auto* gpZPtr = base + 12 * N + offset;
386  const auto* channelsPhiPtr = base + 13 * N + offset;
387  const auto* channelsEtaPtr = base + 14 * N + offset;
388  const auto* widthEtaPtr = base + 15 * N + offset;
389  const auto* totalToTPtr = base + 18 * N + offset;
390 
391  // --------------------------
392  // Precompute spans into aux data store
393  // --------------------------
394  static const SG::Accessor<unsigned int> idHashAcc("identifierHash");
395  static const SG::Accessor<unsigned long> idAcc("identifier");
396  static const SG::Accessor<std::array<float, 3>> gpAcc("globalPosition");
397  static const SG::Accessor<std::array<float, 2>> locPosAcc("localPositionDim2");
398  static const SG::Accessor<std::array<float, 4>> locCovAcc("localCovarianceDim2");
399  static const SG::Accessor<int> totalToTAcc("totalToT");
400  static const SG::Accessor<int> channelsPhiAcc("channelsInPhi");
401  static const SG::Accessor<int> channelsEtaAcc("channelsInEta");
402  static const SG::Accessor<float> widthEtaAcc("widthInEta");
403  static const SG::Accessor<std::vector<unsigned long long>> rdoListAcc("rdoList");
404 
405  auto idSpan = idAcc.getDataSpan(*pixelCl);
406  auto idHashSpan = idHashAcc.getDataSpan(*pixelCl);
407  auto gpSpan = gpAcc.getDataSpan(*pixelCl);
408  auto locPosSpan = locPosAcc.getDataSpan(*pixelCl);
409  auto locCovSpan = locCovAcc.getDataSpan(*pixelCl);
410  auto totalToTSpan = totalToTAcc.getDataSpan(*pixelCl);
411  auto channelsPhiSpan = channelsPhiAcc.getDataSpan(*pixelCl);
412  auto channelsEtaSpan = channelsEtaAcc.getDataSpan(*pixelCl);
413  auto widthEtaSpan = widthEtaAcc.getDataSpan(*pixelCl);
414  auto rdoSpan = rdoListAcc.getDataSpan(*pixelCl);
415 
416  // --------------------------
417  // Vectorized bulk assignments
418  // --------------------------
419  {
420  Athena::Chrono chrono("Pixel assignments", m_chronoSvc.get());
421  for (size_t i = 0; i < nClusters; ++i) {
422  idHashSpan[i] = static_cast<unsigned int>(idHashPtr[i]);
423  idSpan[i] = static_cast<unsigned long>(identifierPtr[i]);
424 
425  // reinterpret_cast instead of bit_cast for double→float conversion
426  locPosSpan[i][0] = static_cast<float>(std::bit_cast<double>(localXPtr[i]));
427  locPosSpan[i][1] = static_cast<float>(std::bit_cast<double>(localYPtr[i]));
428  locCovSpan[i][0] = static_cast<float>(std::bit_cast<double>(covXXPtr[i]));
429  locCovSpan[i][3] = static_cast<float>(std::bit_cast<double>(covYYPtr[i]));
430 
431  gpSpan[i][0] = static_cast<float>(std::bit_cast<double>(gpXPtr[i]));
432  gpSpan[i][1] = static_cast<float>(std::bit_cast<double>(gpYPtr[i]));
433  gpSpan[i][2] = static_cast<float>(std::bit_cast<double>(gpZPtr[i]));
434 
435  channelsPhiSpan[i] = static_cast<int>(channelsPhiPtr[i]);
436  channelsEtaSpan[i] = static_cast<int>(channelsEtaPtr[i]);
437  widthEtaSpan[i] = static_cast<float>(std::bit_cast<double>(widthEtaPtr[i]));
438  totalToTSpan[i] = static_cast<int>(totalToTPtr[i]);
439 
440  // Inline RDO copy (avoid heap reallocations)
441  auto& rdoList = rdoSpan[i];
442  rdoList.reserve(4);
443  for (int r = 0; r < 4; ++r) {
444  if (rdoPtrs[r][i]) rdoList.emplace_back(rdoPtrs[r][i]);
445  }
446  }
447  }
448 
449  {
450  Athena::Chrono chrono("Pixel Copy", m_chronoSvc.get());
451  ATH_CHECK(pixelClustersHandle.record(std::move(pixelCl), std::move(pixelClAux)));
452  }
453 
454 
455  return StatusCode::SUCCESS;
456 }

◆ makeStripClusterContainer() [1/2]

StatusCode xAODClusterMaker::makeStripClusterContainer ( const EFTrackingTransient::StripClusterAuxInput scAux,
const EFTrackingTransient::Metadata metadata,
const EventContext &  ctx 
) const

Make the strip cluster container.

Parameters
scAuxInput strip cluster data
metadataInput metadata
ctx
Returns
StatusCode

Definition at line 202 of file xAODClusterMaker.cxx.

205  {
206  ATH_MSG_DEBUG("Making xAOD::StripClusterContainer");
207 
209  m_stripClustersKey , ctx};
210 
211  ATH_CHECK(stripClustersHandle.record(
212  std::make_unique<xAOD::StripClusterContainer>(),
213  std::make_unique<xAOD::StripClusterAuxContainer>()));
214 
215  int rdoIndexCounter = 0;
216 
217  for (unsigned int i = 0; i < metadata->numOfStripClusters; i++) {
218  // Push back numClusters of StripCluster
219  auto stripCl =
220  stripClustersHandle->push_back(std::make_unique<xAOD::StripCluster>());
221 
222  // Build Matrix
223  Eigen::Matrix<float, 1, 1> localPosition;
224  Eigen::Matrix<float, 1, 1> localCovariance;
225 
226  localPosition(0, 0) = scAux.localPosition.at(i);
227  localCovariance(0, 0) = scAux.localCovariance.at(i);
228 
229  Eigen::Matrix<float, 3, 1> globalPosition(
230  scAux.globalPosition.at(i * 3), scAux.globalPosition.at(i * 3 + 1),
231  scAux.globalPosition.at(i * 3 + 2));
232 
233  std::vector<Identifier> RDOs;
234  RDOs.reserve(metadata->scRdoIndex[i]);
235  // Cover RDO
236  for (unsigned int j = 0; j < metadata->scRdoIndex[i]; ++j) {
237  RDOs.push_back(Identifier(scAux.rdoList.at(rdoIndexCounter + j)));
238  }
239 
240  rdoIndexCounter += metadata->scRdoIndex[i];
241 
242  stripCl->setMeasurement<1>(scAux.idHash.at(i), localPosition,
243  localCovariance);
244  stripCl->setIdentifier(scAux.id.at(i));
245  stripCl->setRDOlist(RDOs);
246  stripCl->globalPosition() = globalPosition;
247  stripCl->setChannelsInPhi(scAux.channelsInPhi.at(i));
248  }
249  return StatusCode::SUCCESS;
250 }

◆ makeStripClusterContainer() [2/2]

StatusCode xAODClusterMaker::makeStripClusterContainer ( const uint64_t *  stripClusters,
const EFTrackingTransient::Metadata metadata,
const EventContext &  ctx 
) const

Make the strip cluster container.

Parameters
stripClustersraw input from the EDM output
metadataInput metadata
ctx
Returns
StatusCode

Definition at line 37 of file xAODClusterMaker.cxx.

40  {
41  ATH_MSG_DEBUG("Making xAOD::StripClusterContainer");
42 
44 
45  if (!m_doBulkCopy) {
46  ATH_CHECK(stripClustersHandle.record(std::make_unique<xAOD::StripClusterContainer>(), std::make_unique<xAOD::StripClusterAuxContainer>()));
47 
48 
49  for (unsigned int i = 0; i < metadata->numOfStripClusters; i++)
50  {
51  // Push back numClusters of StripCluster
52  auto stripCl = stripClustersHandle->push_back(std::make_unique<xAOD::StripCluster>());
53 
54  // Build Matrix
55  Eigen::Matrix<float, 1, 1> localPosition;
56  Eigen::Matrix<float, 1, 1> localCovariance;
57 
58  int row = 0; // idhash
59  long unsigned int idHash = stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
60  row = 1; // id
61  unsigned long long id = stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
62 
63  std::vector<Identifier> RDOs;
64  row = 2; // rdo w1
65  unsigned long long rdo = stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
66  if (rdo) RDOs.push_back(Identifier(rdo));
67 
68  row = 3; // rdo w2
69  rdo = stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
70  if (rdo) RDOs.push_back(Identifier(rdo));
71 
72  row = 4; // rdo w3
73  rdo = stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
74  if (rdo) RDOs.push_back(Identifier(rdo));
75 
76  row = 5; // rdo w4
77  rdo = stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
78  if (rdo) RDOs.push_back(Identifier(rdo));
79  row = 6; // local x
80  localPosition(0, 0) = std::bit_cast<double>(stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
81  row = 8; // local covariance xx
82  localCovariance(0, 0) = std::bit_cast<double>(stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
83  row = 9; // global x
84  double globalX = std::bit_cast<double>(stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
85  row = 10; // global y
86  double globalY = std::bit_cast<double>(stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
87  row = 11; // global z
88  double globalZ = std::bit_cast<double>(stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8]);
89  row = 12; // channels in phi
90  auto channelsinPhi = stripClusters[row * EFTrackingTransient::MAX_NUM_CLUSTERS + i + 8];
91 
92 
93  Eigen::Matrix<float, 3, 1> globalPosition(globalX, globalY, globalZ);
94  stripCl->setMeasurement<1>(idHash, localPosition, localCovariance);
95 
96  stripCl->setIdentifier(id);
97  stripCl->setRDOlist(RDOs);
98  stripCl->globalPosition() = globalPosition;
99  stripCl->setChannelsInPhi(channelsinPhi);
100  }
101 
102  return StatusCode::SUCCESS;
103  }
104 
105  ATH_MSG_DEBUG("Doing Strip bulk copy (optimized)");
106  // --------------------------
107  // Create the container and aux. container
108  // --------------------------
109  const size_t nClusters = metadata->numOfStripClusters;
110  auto stripCl = std::make_unique<xAOD::StripClusterContainer>();
111  stripCl->reserve(nClusters);
112  {
113  Athena::Chrono chrono("Strip object creating", m_chronoSvc.get());
114  for (std::size_t i = 0; i < nClusters; ++i) {
115  stripCl->push_back(std::make_unique<xAOD::StripCluster>());
116  }
117  }
118 
119  auto stripClAux = std::make_unique<xAOD::StripClusterAuxContainer>();
120  stripClAux->resize(stripCl->size());
121  stripCl->setStore(stripClAux.get());
122 
123 
124  // --------------------------
125  // Access fixed-size attributes directly
126  // --------------------------
128  const size_t offset = 8;
129  const auto* base = stripClusters;
130 
131  // Direct column pointers
132  const auto* idHashPtr = base + 0 * N + offset;
133  const auto* identifierPtr = base + 1 * N + offset;
134  const uint64_t* rdoPtrs[4] = {
135  base + 2 * N + offset, base + 3 * N + offset,
136  base + 4 * N + offset, base + 5 * N + offset
137  };
138  const auto* localPosXPtr = base + 6 * N + offset;
139  const auto* localCovXXPtr = base + 8 * N + offset;
140  const auto* gpXPtr = base + 9 * N + offset;
141  const auto* gpYPtr = base + 10 * N + offset;
142  const auto* gpZPtr = base + 11 * N + offset;
143  const auto* channelsPhiPtr = base + 12 * N + offset;
144 
145  // --------------------------
146  // Precompute spans into aux data store
147  // --------------------------
148  static const SG::Accessor<unsigned int> idHashAcc("identifierHash");
149  static const SG::Accessor<unsigned long> idAcc("identifier");
150  static const SG::Accessor<std::array<float, 1>> locPosXAcc("localPositionDim1");
151  static const SG::Accessor<std::array<float, 1>> locCovXXAcc("localCovarianceDim1");
152  static const SG::Accessor<std::array<float, 3>> gpAcc("globalPosition");
153  static const SG::Accessor<int> channelsPhiAcc("channelsInPhi");
154  static const SG::Accessor<std::vector<unsigned long long>> rdoListAcc("rdoList");
155 
156  auto idSpan = idAcc.getDataSpan(*stripCl);
157  auto idHashSpan = idHashAcc.getDataSpan(*stripCl);
158  auto locPosXSpan = locPosXAcc.getDataSpan(*stripCl);
159  auto locCovXXSpan = locCovXXAcc.getDataSpan(*stripCl);
160  auto gpSpan = gpAcc.getDataSpan(*stripCl);
161  auto channelsPhiSpan = channelsPhiAcc.getDataSpan(*stripCl);
162  auto rdoSpan = rdoListAcc.getDataSpan(*stripCl);
163 
164  // --------------------------
165  // Vectorized bulk assignments
166  // --------------------------
167  {
168  Athena::Chrono chrono("Strip assignments", m_chronoSvc.get());
169  for (size_t i = 0; i < nClusters; ++i) {
170  idHashSpan[i] = static_cast<unsigned int>(idHashPtr[i]);
171  idSpan[i] = static_cast<unsigned long>(identifierPtr[i]);
172 
173  // double (bit pattern in u64) -> float, via bit_cast
174  locPosXSpan[i][0] = static_cast<float>(std::bit_cast<double>(localPosXPtr[i]));
175  locCovXXSpan[i][0] = static_cast<float>(std::bit_cast<double>(localCovXXPtr[i]));
176 
177  gpSpan[i][0] = static_cast<float>(std::bit_cast<double>(gpXPtr[i]));
178  gpSpan[i][1] = static_cast<float>(std::bit_cast<double>(gpYPtr[i]));
179  gpSpan[i][2] = static_cast<float>(std::bit_cast<double>(gpZPtr[i]));
180 
181  channelsPhiSpan[i] = static_cast<int>(channelsPhiPtr[i]);
182 
183  // Inline RDO copy (avoid heap reallocations)
184  auto& rdoList = rdoSpan[i];
185  rdoList.reserve(4);
186  for (int r = 0; r < 4; ++r) {
187  if (rdoPtrs[r][i]) rdoList.emplace_back(rdoPtrs[r][i]);
188  }
189  }
190  }
191 
192  {
193  Athena::Chrono chrono("Strip Copy", m_chronoSvc.get());
194  ATH_CHECK(stripClustersHandle.record(std::move(stripCl), std::move(stripClAux)));
195  }
196 
197  return StatusCode::SUCCESS;
198  }

Member Data Documentation

◆ m_chronoSvc

ServiceHandle<IChronoStatSvc> xAODClusterMaker::m_chronoSvc {this, "ChronoStatSvc", "ChronoStatSvc"}
private

Definition at line 106 of file xAODClusterMaker.h.

◆ m_doBulkCopy

Gaudi::Property<bool> xAODClusterMaker::m_doBulkCopy {this, "DoBulkCopy", true, "Do bulk copy"}
private

Do bulk copy method.

Definition at line 104 of file xAODClusterMaker.h.

◆ m_pixelClustersKey

SG::WriteHandleKey<xAOD::PixelClusterContainer> xAODClusterMaker::m_pixelClustersKey
private
Initial value:
{
this, "PixelClusterContainerKey", "FPGAPixelClusters",
"Key for output pixel cluster container"}

Key for the pixel clusters container to be created.

Definition at line 95 of file xAODClusterMaker.h.

◆ m_stripClustersKey

SG::WriteHandleKey<xAOD::StripClusterContainer> xAODClusterMaker::m_stripClustersKey
private
Initial value:
{
this, "StripClusterContainerKey", "FPGAStripClusters",
"Key for output strip cluster container"}

Key for the strip clusters container to be created.

Definition at line 100 of file xAODClusterMaker.h.


The documentation for this class was generated from the following files:
base
std::string base
Definition: hcg.cxx:78
beamspotman.r
def r
Definition: beamspotman.py:672
EFTrackingTransient::PixelClusterAuxInput::localPosition
std::vector< float > localPosition
Definition: EFTrackingTransient.h:234
xAODClusterMaker::m_pixelClustersKey
SG::WriteHandleKey< xAOD::PixelClusterContainer > m_pixelClustersKey
Key for the pixel clusters container to be created.
Definition: xAODClusterMaker.h:95
EFTrackingTransient::PixelClusterAuxInput::channelsInEta
std::vector< int > channelsInEta
Definition: EFTrackingTransient.h:239
xAODClusterMaker::m_doBulkCopy
Gaudi::Property< bool > m_doBulkCopy
Do bulk copy method.
Definition: xAODClusterMaker.h:104
EFTrackingTransient::StripClusterAuxInput::globalPosition
std::vector< float > globalPosition
Definition: EFTrackingTransient.h:221
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
EFTrackingTransient::MAX_NUM_CLUSTERS
constexpr unsigned int MAX_NUM_CLUSTERS
Definition: EFTrackingTransient.h:27
EFTrackingTransient::StripClusterAuxInput::localCovariance
std::vector< float > localCovariance
Definition: EFTrackingTransient.h:218
TRT::Hit::globalZ
@ globalZ
Definition: HitInfo.h:39
keylayer_zslicemap.row
row
Definition: keylayer_zslicemap.py:155
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
EFTrackingTransient::StripClusterAuxInput::rdoList
std::vector< unsigned long long > rdoList
Definition: EFTrackingTransient.h:222
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
xAODClusterMaker::m_stripClustersKey
SG::WriteHandleKey< xAOD::StripClusterContainer > m_stripClustersKey
Key for the strip clusters container to be created.
Definition: xAODClusterMaker.h:100
Athena::Chrono
Exception-safe IChronoSvc caller.
Definition: Chrono.h:50
EFTrackingTransient::PixelClusterAuxInput::rdoList
std::vector< unsigned long long > rdoList
Definition: EFTrackingTransient.h:237
lumiFormat.i
int i
Definition: lumiFormat.py:85
EFTrackingTransient::PixelClusterAuxInput::localCovariance
std::vector< float > localCovariance
Definition: EFTrackingTransient.h:235
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
EFTrackingTransient::StripClusterAuxInput::idHash
std::vector< unsigned int > idHash
Definition: EFTrackingTransient.h:219
CxxUtils::copy_bounded
OutputIterator copy_bounded(InputIterator begi, InputIterator endi, OutputIterator bego, OutputIterator endo)
Copy a range with bounds restriction.
Definition: copy_bounded.h:79
EFTrackingTransient::PixelClusterAuxInput::totalToT
std::vector< int > totalToT
Definition: EFTrackingTransient.h:242
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
EFTrackingTransient::PixelClusterAuxInput::idHash
std::vector< unsigned int > idHash
Definition: EFTrackingTransient.h:233
EFTrackingTransient::StripClusterAuxInput::localPosition
std::vector< float > localPosition
Definition: EFTrackingTransient.h:217
EFTrackingTransient::PixelClusterAuxInput::channelsInPhi
std::vector< int > channelsInPhi
Definition: EFTrackingTransient.h:238
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
EFTrackingTransient::PixelClusterAuxInput::id
std::vector< long unsigned int > id
Definition: EFTrackingTransient.h:232
EFTrackingTransient::PixelClusterAuxInput::widthInEta
std::vector< float > widthInEta
Definition: EFTrackingTransient.h:240
EFTrackingTransient::PixelClusterAuxInput::globalPosition
std::vector< float > globalPosition
Definition: EFTrackingTransient.h:236
EFTrackingTransient::StripClusterAuxInput::id
std::vector< long unsigned int > id
Definition: EFTrackingTransient.h:220
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
EFTrackingTransient::StripClusterAuxInput::channelsInPhi
std::vector< int > channelsInPhi
Definition: EFTrackingTransient.h:223
xAODClusterMaker::m_chronoSvc
ServiceHandle< IChronoStatSvc > m_chronoSvc
Definition: xAODClusterMaker.h:106
Identifier
Definition: IdentifierFieldParser.cxx:14