ATLAS Offline Software
Loading...
Searching...
No Matches
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.
StatusCode makeStripClusterContainer (const EFTrackingTransient::StripClusterAuxInput &scAux, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
 Make the strip cluster container.
StatusCode makeStripClusterContainer (const uint32_t *stripClusters, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
 Make the strip cluster container.
StatusCode makePixelClusterContainer (const EFTrackingTransient::PixelClusterAuxInput &pxAux, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
 Make the pixel cluster container.
StatusCode makePixelClusterContainer (const uint32_t *pixelClusters, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
 Make the pixel cluster container.

Private Attributes

SG::WriteHandleKey< xAOD::PixelClusterContainerm_pixelClustersKey
 Key for the pixel clusters container to be created.
SG::WriteHandleKey< xAOD::StripClusterContainerm_stripClustersKey
 Key for the strip clusters container to be created.
Gaudi::Property< bool > m_doBulkCopy {this, "DoBulkCopy", true, "Do bulk copy"}
 Do bulk copy method.
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 45 of file xAODClusterMaker.cxx.

45 {
46 ATH_MSG_INFO("Initialising xAODClusterMaker tool");
47
48 // Initialise the write handles
49 ATH_CHECK(m_pixelClustersKey.initialize());
50 ATH_CHECK(m_stripClustersKey.initialize());
51
52 // Initialise the chrono service
53 ATH_CHECK(m_chronoSvc.retrieve());
54
55 return StatusCode::SUCCESS;
56}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
SG::WriteHandleKey< xAOD::StripClusterContainer > m_stripClustersKey
Key for the strip clusters container to be created.
SG::WriteHandleKey< xAOD::PixelClusterContainer > m_pixelClustersKey
Key for the pixel clusters container to be created.
ServiceHandle< IChronoStatSvc > m_chronoSvc

◆ 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 515 of file xAODClusterMaker.cxx.

518 {
519 ATH_MSG_DEBUG("Making xAOD::PixelClusterContainer");
520
521
522 SG::WriteHandle<xAOD::PixelClusterContainer> pixelClustersHandle{m_pixelClustersKey, ctx};
523
524 if (!m_doBulkCopy) {
525 // --------------------------------------------------------------------
526 // proceed with the element-wise method
527 // --------------------------------------------------------------------
528 ATH_MSG_DEBUG("You are running the element-wise container creation method.");
529 if constexpr (enableBenchmark) Athena::Chrono chrono("ElementWiseMethod", m_chronoSvc.get());
530
531 ATH_CHECK(pixelClustersHandle.record(
532 std::make_unique<xAOD::PixelClusterContainer>(),
533 std::make_unique<xAOD::PixelClusterAuxContainer>()));
534
535 ATH_CHECK(pixelClustersHandle.isValid());
536 ATH_MSG_DEBUG("Container '" << m_pixelClustersKey << "' initialised");
537
538 int rdoIndexCounter = 0;
539
540 for (unsigned int i = 0; i < metadata->numOfPixelClusters; i++) {
541 // Push back numClusters of PixelCluster
542 auto pixelCl = pixelClustersHandle->push_back(
543 std::make_unique<xAOD::PixelCluster>());
544
545 Eigen::Matrix<float, 2, 1> localPosition(
546 pxAux.localPosition[i * 2], pxAux.localPosition[i * 2 + 1]);
547 Eigen::Matrix<float, 2, 2> localCovariance;
548 localCovariance.setZero();
549 localCovariance(0, 0) = pxAux.localCovariance[i * 2];
550 localCovariance(1, 1) = pxAux.localCovariance[i * 2 + 1];
551 Eigen::Matrix<float, 3, 1> globalPosition(
552 pxAux.globalPosition[i * 3], pxAux.globalPosition[i * 3 + 1],
553 pxAux.globalPosition[i * 3 + 2]);
554
555 std::vector<Identifier> RDOs;
556 RDOs.reserve(metadata->pcRdoIndex[i]);
557 // Cover RDO
558 for (unsigned int j = 0; j < metadata->pcRdoIndex[i]; ++j) {
559 RDOs.push_back(Identifier(pxAux.rdoList[rdoIndexCounter + j]));
560 }
561
562 rdoIndexCounter += metadata->pcRdoIndex[i];
563
564 pixelCl->setMeasurement<2>(pxAux.idHash[i], localPosition,
565 localCovariance);
566 pixelCl->setIdentifier(pxAux.id[i]);
567 pixelCl->setRDOlist(RDOs);
568 pixelCl->globalPosition() = globalPosition;
569 pixelCl->setTotalToT(pxAux.totalToT[i]);
570 pixelCl->setChannelsInPhiEta(pxAux.channelsInPhi[i],
571 pxAux.channelsInEta[i]);
572 pixelCl->setWidthInEta(pxAux.widthInEta[i]);
573 }
574
575 return StatusCode::SUCCESS;
576 }
577
578 // --------------------------------------------------------------------
579 // proceed with the bulk copy method
580 // --------------------------------------------------------------------
581
582 ATH_MSG_DEBUG("You are running the bulk copy container creation method.");
583 if constexpr (enableBenchmark) Athena::Chrono chrono("BulkCopyMethod", m_chronoSvc.get());
584
585 // --------------------------
586 // Create the container and aux. container
587 // --------------------------
588 auto pixelCl = std::make_unique<xAOD::PixelClusterContainer>();
589 auto pixelClAux = std::make_unique<xAOD::PixelClusterAuxContainer>();
590 pixelCl->setStore(pixelClAux.get());
591
592 // Pre-allocate memory for all clusters in the AuxContainer
593 // and reserve the same space in the container.
594 const size_t nClusters = metadata->numOfPixelClusters;
595 pixelClAux->resize(nClusters);
596 pixelCl->reserve(nClusters);
597
598 // Now, push back the PixelCluster objects
599 // and create them all at once.
600 // Note, that no data is set yet,
601 // we will do that in the next step.
602 for (size_t i = 0; i < nClusters; ++i) {
603 pixelCl->push_back(std::make_unique<xAOD::PixelCluster>());
604 }
605
606 // --------------------------
607 // Prepare local buffers for each of the
608 // fixed-size attributes.
609 // --------------------------
610
611 std::vector<long unsigned int> identifierBuffer(nClusters);
612 std::vector<unsigned int> idHashBuffer(nClusters);
613 std::vector<std::array<float, 3>> gpBuffer(nClusters);
614 std::vector<float> localPosX(nClusters);
615 std::vector<float> localPosY(nClusters);
616 std::vector<float> localCovXX(nClusters);
617 std::vector<float> localCovYY(nClusters);
618 std::vector<int> totalToTBuffer(nClusters);
619 std::vector<float> widthInEtaBuffer(nClusters);
620 std::vector<int> channelsInPhiBuffer(nClusters);
621 std::vector<int> channelsInEtaBuffer(nClusters);
622
623 for (size_t i = 0; i < nClusters; ++i) {
624
625 // Fill the identifierBuffer
626 identifierBuffer[i] = pxAux.id[i];
627
628 // Fill the idHashBuffer
629 idHashBuffer[i] = pxAux.idHash[i];
630
631 // Fill the globalPositionBuffers
632 gpBuffer[i] = {
633 pxAux.globalPosition[3 * i],
634 pxAux.globalPosition[3 * i + 1],
635 pxAux.globalPosition[3 * i + 2],
636 };
637
638 // Fill the localPositionBuffers
639 localPosX[i] = pxAux.localPosition[2 * i];
640 localPosY[i] = pxAux.localPosition[2 * i + 1];
641
642 // Fill the localCovBuffer[i]
643 localCovXX[i] = pxAux.localCovariance[2 * i];
644 localCovYY[i] = pxAux.localCovariance[2 * i + 1];
645
646 // Fill the totalToTBuffer
647 totalToTBuffer[i] = pxAux.totalToT[i];
648
649 // Fill the widthInEtaBuffer
650 widthInEtaBuffer[i] = pxAux.widthInEta[i];
651
652 // Fill the channelsInPhiEtaBuffer
653 channelsInPhiBuffer[i] = pxAux.channelsInPhi[i];
654 channelsInEtaBuffer[i] = pxAux.channelsInEta[i];
655 }
656
657 // --------------------------
658 // Now, use SG::Accessors to do a bulk copy into
659 // the container memory.
660 // --------------------------
661
662 // FIXED-SIZE ATTRIBUTES
663 static const SG::Accessor<long unsigned int> idAcc("identifier");
664 static const SG::Accessor<unsigned int> idHashAcc("idHash");
665 static const SG::Accessor<float> localPosXAcc("localPositionX");
666 static const SG::Accessor<float> localPosYAcc("localPositionY");
667 static const SG::Accessor<float> localCovXXAcc("localCovarianceXX");
668 static const SG::Accessor<float> localCovYYAcc("localCovarianceYY");
669 static const SG::Accessor<int> totAcc("totalToT");
670 static const SG::Accessor<float> widthEtaAcc("widthInEta");
671 static const SG::Accessor<int> channelsInPhiAcc("channelsInPhi");
672 static const SG::Accessor<int> channelsInEtaAcc("channelsInEta");
673
674 // VARIABLE-LENGTH ATTRIBUTES
675 static const SG::Accessor<std::array<float, 3>> globalPosAcc(
676 "globalPosition");
677
678 // Get spans into the container
679 auto idSpan = idAcc.getDataSpan(*pixelCl);
680 auto idHashSpan = idHashAcc.getDataSpan(*pixelCl);
681 auto locPosXSpan = localPosXAcc.getDataSpan(*pixelCl);
682 auto locPosYSpan = localPosYAcc.getDataSpan(*pixelCl);
683 auto locCovXXSpan = localCovXXAcc.getDataSpan(*pixelCl);
684 auto locCovYYSpan = localCovYYAcc.getDataSpan(*pixelCl);
685 auto totSpan = totAcc.getDataSpan(*pixelCl);
686 auto wEtaSpan = widthEtaAcc.getDataSpan(*pixelCl);
687 auto gpSpan = globalPosAcc.getDataSpan(*pixelCl);
688 auto channelsInPhiSpan = channelsInPhiAcc.getDataSpan(*pixelCl);
689 auto channelsInEtaSpan = channelsInEtaAcc.getDataSpan(*pixelCl);
690
691 // Bulk copy the fixed-size attributes
692 CxxUtils::copy_bounded(identifierBuffer, idSpan);
693 CxxUtils::copy_bounded(idHashBuffer, idHashSpan);
694 CxxUtils::copy_bounded(localPosX, locPosXSpan);
695 CxxUtils::copy_bounded(localPosY, locPosYSpan);
696 CxxUtils::copy_bounded(localCovXX, locCovXXSpan);
697 CxxUtils::copy_bounded(localCovYY, locCovYYSpan);
698 CxxUtils::copy_bounded(totalToTBuffer, totSpan);
699 CxxUtils::copy_bounded(widthInEtaBuffer, wEtaSpan);
700 CxxUtils::copy_bounded(gpBuffer, gpSpan);
701 CxxUtils::copy_bounded(channelsInPhiBuffer, channelsInPhiSpan);
702 CxxUtils::copy_bounded(channelsInEtaBuffer, channelsInEtaSpan);
703
704 // --------------------------
705 // Copy the variable-length data.
706 // We need to loop over the number of
707 // clusters to get access to each
708 // element.
709 // --------------------------
710 static const SG::Accessor<std::vector<unsigned long long>> rdoListAcc(
711 "rdoList");
712 auto rdoSpan = rdoListAcc.getDataSpan(*pixelCl);
713
714 int rdoIndexCounter = 0;
715 // loop over the clusters
716 for (size_t i = 0; i < nClusters; ++i) {
717 size_t nRDOs = metadata->pcRdoIndex[i];
718
719 // direct ref to destination vector
720 std::vector<unsigned long long> &rdosForThisCluster = rdoSpan[i];
721
722 // pre-size the vector
723 rdosForThisCluster.resize(nRDOs);
724
725 // direct element access
726 for (size_t j = 0; j < nRDOs; ++j) {
727 rdosForThisCluster[j] = pxAux.rdoList[rdoIndexCounter + j];
728 }
729 rdoIndexCounter += nRDOs;
730 }
731 // --------------------------
732 // Record the container + aux container into StoreGate,
733 // but now we do it AFTER filling the container!
734 // --------------------------
735
736 ATH_CHECK(pixelClustersHandle.record(std::move(pixelCl), std::move(pixelClAux)));
737
738 ATH_MSG_DEBUG("Bulk copy for fixed-size variables done.");
739 return StatusCode::SUCCESS;
740}
#define ATH_MSG_DEBUG(x)
static const SG::AuxElement::Accessor< std::vector< Identifier::value_type > > rdoListAcc("rdoList")
static const SG::AuxElement::Accessor< std::array< float, 3 > > globalPosAcc("globalPosition")
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Gaudi::Property< bool > m_doBulkCopy
Do bulk copy method.
OutputIterator copy_bounded(InputIterator begi, InputIterator endi, OutputIterator bego, OutputIterator endo)
Copy a range with bounds restriction.
std::vector< unsigned long long > rdoList
constexpr bool enableBenchmark

◆ makePixelClusterContainer() [2/2]

StatusCode xAODClusterMaker::makePixelClusterContainer ( const uint32_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 282 of file xAODClusterMaker.cxx.

285 {
286 ATH_MSG_DEBUG("Making xAOD::PixelClusterContainer");
287
288
289 SG::WriteHandle<xAOD::PixelClusterContainer> pixelClustersHandle{m_pixelClustersKey, ctx};
290
291 if (!m_doBulkCopy) {
292 // --------------------------------------------------------------------
293 // proceed with the element-wise method
294 // --------------------------------------------------------------------
295 ATH_CHECK(pixelClustersHandle.record(std::make_unique<xAOD::PixelClusterContainer>(),std::make_unique<xAOD::PixelClusterAuxContainer>()));
296
297 ATH_CHECK(pixelClustersHandle.isValid());
298
299 for (unsigned int i = 0; i < metadata->numOfPixelClusters; i++)
300 {
301 // Push back numClusters of StripCluster
302 auto pixelCl = pixelClustersHandle->push_back(std::make_unique<xAOD::PixelCluster>());
303
304 int row = 0; // idhash
305 unsigned int idHash = pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16];
306 row = 1; // id
307 unsigned long long id = to64 (pixelClusters + row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i*2 + 16);
308
309 std::vector<Identifier> RDOs;
310 row = 3; // rdo w1
311 unsigned long long rdo = to64 (pixelClusters + row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i*2 + 16);
312 if (rdo) RDOs.push_back(Identifier(rdo));
313
314 row = 5; // rdo w2
315 rdo = to64 (pixelClusters + row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i*2 + 16);
316 if (rdo) RDOs.push_back(Identifier(rdo));
317
318 row = 7; // rdo w3
319 rdo = to64 (pixelClusters + row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i*2 + 16);
320 if (rdo) RDOs.push_back(Identifier(rdo));
321
322 row = 9; // rdo w4
323 rdo = to64 (pixelClusters + row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i*2 + 16);
324 if (rdo) RDOs.push_back(Identifier(rdo));
325
326 Eigen::Matrix<float, 2, 1> localPosition;
327 Eigen::Matrix<float, 2, 2> localCovariance;
328 localCovariance.setZero();
329 row = 11; // local x
330 localPosition(0 , 0) = std::bit_cast<float>(pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16]);
331
332 row = 12; // local y
333 localPosition(1 , 1) = std::bit_cast<float>(pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16]);
334
335 row = 13; // local covariance xx
336 localCovariance(0, 0) = std::bit_cast<float>(pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16]);
337
338 row = 14; // local covariance yy
339 localCovariance(1, 1) = std::bit_cast<float>(pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16]);
340
341 row = 15; // global x
342 float globalX = std::bit_cast<float>(pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16]);
343
344 row = 16; // global y
345 float globalY = std::bit_cast<float>(pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16]);
346
347 row = 17; // global
348 float globalZ = std::bit_cast<float>(pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16]);
349
350 row = 18; // channels in phi
351 int channelsInPhi = pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16];
352
353 row = 19; // channels in eta
354 int channelsInEta = pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16];
355
356 row = 20; // width in eta
357 double widthInEta = std::bit_cast<float>(pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16]);
358
359 row = 21; // total ToT
360 int totalToT = pixelClusters[row * EFTrackingTransient::MAX_PIXEL_CLUSTERS + i + 16];
361
362 Eigen::Matrix<float, 3, 1> globalPosition(globalX, globalY, globalZ);
363
364 pixelCl->setMeasurement<2>(idHash, localPosition,localCovariance);
365 pixelCl->setIdentifier(id);
366 pixelCl->setRDOlist(RDOs);
367 pixelCl->globalPosition() = globalPosition;
368 pixelCl->setTotalToT(totalToT);
369 pixelCl->setChannelsInPhiEta(channelsInPhi, channelsInEta);
370 pixelCl->setWidthInEta(widthInEta);
371 }
372 return StatusCode::SUCCESS;
373 }
374
375 ATH_MSG_DEBUG("Doing bulk copy (optimized)");
376 // --------------------------
377 // Create the container and aux. container
378 // --------------------------
379 const size_t nClusters = metadata->numOfPixelClusters;
380 DataPool<xAOD::PixelCluster> pixelPool{ctx};
381 pixelPool.reserve(nClusters);
382 auto pixelCl = std::make_unique<xAOD::PixelClusterContainer>(SG::VIEW_ELEMENTS, SG::ALWAYS_TRACK_INDICES);
383 {
384 if constexpr (enableBenchmark) Athena::Chrono chrono("Pixel object creating", m_chronoSvc.get());
385 pixelCl->push_new(nClusters, [&pixelPool]() { return pixelPool.nextElementPtr(); });
386 }
387 auto pixelClAux = std::make_unique<xAOD::PixelClusterAuxContainer>();
388 pixelClAux->resize(nClusters);
389 pixelCl->setStore(pixelClAux.get());
390
391 // --------------------------
392 // Access fixed-size attributes directly (rows/offsets as in !m_doBulkCopy)
393 // --------------------------
395 const size_t offset = 16;
396
397 // Treat the raw column-major buffer as 32-bit words; 64-bit values span two words.
398 const uint32_t* base = pixelClusters;
399
400 auto load_u64 = [&](size_t row, size_t idx) -> uint64_t {
401 const uint32_t* p32 = base + row * N + offset + 2 * idx;
402 return *reinterpret_cast<const uint64_t*>(p32);
403 };
404 auto load_f32 = [&](size_t row, size_t idx) -> float {
405 return std::bit_cast<float>(*(base + row * N + offset + idx));
406 };
407 auto load_u32 = [&](size_t row, size_t idx) -> uint32_t {
408 return *(base + row * N + offset + idx);
409 };
410
411 // Row layout (must match the element-wise path)
412 constexpr size_t ROW_idHash = 0;
413 constexpr size_t ROW_identifier = 1; // u64
414 constexpr size_t ROW_rdo_w1 = 3; // u64
415 constexpr size_t ROW_rdo_w2 = 5; // u64
416 constexpr size_t ROW_rdo_w3 = 7; // u64
417 constexpr size_t ROW_rdo_w4 = 9; // u64
418 constexpr size_t ROW_localX = 11; // f32
419 constexpr size_t ROW_localY = 12; // f32
420 constexpr size_t ROW_covXX = 13; // f32
421 constexpr size_t ROW_covYY = 14; // f32
422 constexpr size_t ROW_gpX = 15; // f32
423 constexpr size_t ROW_gpY = 16; // f32
424 constexpr size_t ROW_gpZ = 17; // f32
425 constexpr size_t ROW_channelsPhi = 18; // i32
426 constexpr size_t ROW_channelsEta = 19; // i32
427 constexpr size_t ROW_widthEta = 20; // f32
428 constexpr size_t ROW_totalToT = 21; // i32
429
430 // --------------------------
431 // Precompute spans into aux data store (types aligned with !m_doBulkCopy behavior)
432 // --------------------------
433 if (nClusters > 0) {
434 static const SG::Accessor<unsigned int> idHashAcc("identifierHash");
435 static const SG::Accessor<unsigned long> idAcc("identifier");
436 static const SG::Accessor<std::array<float, 3>> gpAcc("globalPosition");
437 static const SG::Accessor<std::array<float, 2>> locPosAcc("localPositionDim2");
438 static const SG::Accessor<std::array<float, 4>> locCovAcc("localCovarianceDim2");
439 static const SG::Accessor<int> totalToTAcc("totalToT");
440 static const SG::Accessor<int> channelsPhiAcc("channelsInPhi");
441 static const SG::Accessor<int> channelsEtaAcc("channelsInEta");
442 static const SG::Accessor<float> widthEtaAcc("widthInEta");
443 static const SG::Accessor<std::vector<unsigned long long>> rdoListAcc("rdoList");
444
445
446 auto idHashSpan = idHashAcc.getDataSpan(*pixelCl);
447 auto idSpan = idAcc.getDataSpan(*pixelCl);
448 auto gpSpan = gpAcc.getDataSpan(*pixelCl);
449 auto locPosSpan = locPosAcc.getDataSpan(*pixelCl);
450 auto locCovSpan = locCovAcc.getDataSpan(*pixelCl);
451 auto totalToTSpan = totalToTAcc.getDataSpan(*pixelCl);
452 auto channelsPhiSpan = channelsPhiAcc.getDataSpan(*pixelCl);
453 auto channelsEtaSpan = channelsEtaAcc.getDataSpan(*pixelCl);
454 auto widthEtaSpan = widthEtaAcc.getDataSpan(*pixelCl);
455 auto rdoSpan = rdoListAcc.getDataSpan(*pixelCl);
456
457 // --------------------------
458 // Vectorized bulk assignments
459 // --------------------------
460 {
461 if constexpr (enableBenchmark) Athena::Chrono chrono("Pixel assignments", m_chronoSvc.get());
462 for (size_t i = 0; i < nClusters; ++i) {
463 // Basic ids
464 idHashSpan[i] = static_cast<unsigned int>(load_u32(ROW_idHash, i));
465 idSpan[i] = static_cast<unsigned long long>(load_u64(ROW_identifier, i));
466
467 // Local position (2x1)
468 locPosSpan[i][0] = load_f32(ROW_localX, i);
469 locPosSpan[i][1] = load_f32(ROW_localY, i);
470
471 // Local covariance (2x2) flattened as [xx, xy, yx, yy]
472 locCovSpan[i][0] = load_f32(ROW_covXX, i);
473 locCovSpan[i][3] = load_f32(ROW_covYY, i);
474
475 // Global position
476 gpSpan[i][0] = load_f32(ROW_gpX, i);
477 gpSpan[i][1] = load_f32(ROW_gpY, i);
478 gpSpan[i][2] = load_f32(ROW_gpZ, i);
479
480 // Discrete/int attrs
481 channelsPhiSpan[i] = static_cast<int>(load_u32(ROW_channelsPhi, i));
482 channelsEtaSpan[i] = static_cast<int>(load_u32(ROW_channelsEta, i));
483 widthEtaSpan[i] = load_f32(ROW_widthEta, i);
484 totalToTSpan[i] = static_cast<int>(load_u32(ROW_totalToT, i));
485
486 // RDOs (up to 4)
487 auto& rdoList = rdoSpan[i];
488 rdoList.reserve(4);
489 uint64_t r1 = load_u64(ROW_rdo_w1, i);
490 uint64_t r2 = load_u64(ROW_rdo_w2, i);
491 uint64_t r3 = load_u64(ROW_rdo_w3, i);
492 uint64_t r4 = load_u64(ROW_rdo_w4, i);
493 if (r1) rdoList.emplace_back(r1);
494 if (r2) rdoList.emplace_back(r2);
495 if (r3) rdoList.emplace_back(r3);
496 if (r4) rdoList.emplace_back(r4);
497 }
498 }
499 }
500
501 {
502 if constexpr (enableBenchmark) Athena::Chrono chrono("Pixel Copy", m_chronoSvc.get());
503 ATH_CHECK(pixelClustersHandle.record(std::move(pixelCl), std::move(pixelClAux)));
504 }
505
506 return StatusCode::SUCCESS;
507
508
509
510 return StatusCode::SUCCESS;
511}
void reserve(unsigned int size)
Set the desired capacity.
pointer nextElementPtr()
obtain the next available element in pool by pointer pool is resized if its limit has been reached On...
std::string base
Definition hcg.cxx:81
constexpr uint32_t MAX_PIXEL_CLUSTERS
row
Appending html table to final .html summary file.
@ ALWAYS_TRACK_INDICES
Always track indices, regardless of the setting of the ownership policy.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
@ globalZ
Definition HitInfo.h:39
setEventNumber uint32_t

◆ 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 231 of file xAODClusterMaker.cxx.

234 {
235 ATH_MSG_DEBUG("Making xAOD::StripClusterContainer");
236
237 SG::WriteHandle<xAOD::StripClusterContainer> stripClustersHandle{
238 m_stripClustersKey , ctx};
239
240 ATH_CHECK(stripClustersHandle.record(
241 std::make_unique<xAOD::StripClusterContainer>(),
242 std::make_unique<xAOD::StripClusterAuxContainer>()));
243
244 int rdoIndexCounter = 0;
245
246 for (unsigned int i = 0; i < metadata->numOfStripClusters; i++) {
247 // Push back numClusters of StripCluster
248 auto stripCl =
249 stripClustersHandle->push_back(std::make_unique<xAOD::StripCluster>());
250
251 // Build Matrix
252 Eigen::Matrix<float, 1, 1> localPosition;
253 Eigen::Matrix<float, 1, 1> localCovariance;
254
255 localPosition(0, 0) = scAux.localPosition.at(i);
256 localCovariance(0, 0) = scAux.localCovariance.at(i);
257
258 Eigen::Matrix<float, 3, 1> globalPosition(
259 scAux.globalPosition.at(i * 3), scAux.globalPosition.at(i * 3 + 1),
260 scAux.globalPosition.at(i * 3 + 2));
261
262 std::vector<Identifier> RDOs;
263 RDOs.reserve(metadata->scRdoIndex[i]);
264 // Cover RDO
265 for (unsigned int j = 0; j < metadata->scRdoIndex[i]; ++j) {
266 RDOs.push_back(Identifier(scAux.rdoList.at(rdoIndexCounter + j)));
267 }
268
269 rdoIndexCounter += metadata->scRdoIndex[i];
270
271 stripCl->setMeasurement<1>(scAux.idHash.at(i), localPosition,
272 localCovariance);
273 stripCl->setIdentifier(scAux.id.at(i));
274 stripCl->setRDOlist(RDOs);
275 stripCl->globalPosition() = globalPosition;
276 stripCl->setChannelsInPhi(scAux.channelsInPhi.at(i));
277 }
278 return StatusCode::SUCCESS;
279}
std::vector< unsigned long long > rdoList

◆ makeStripClusterContainer() [2/2]

StatusCode xAODClusterMaker::makeStripClusterContainer ( const uint32_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 58 of file xAODClusterMaker.cxx.

61 {
62 ATH_MSG_DEBUG("Making xAOD::StripClusterContainer");
63
64 SG::WriteHandle<xAOD::StripClusterContainer> stripClustersHandle{m_stripClustersKey, ctx};
65
66 if (!m_doBulkCopy) {
67 ATH_CHECK(stripClustersHandle.record(std::make_unique<xAOD::StripClusterContainer>(), std::make_unique<xAOD::StripClusterAuxContainer>()));
68
69
70 for (unsigned int i = 0; i < metadata->numOfStripClusters; i++)
71 {
72 // Push back numClusters of StripCluster
73 auto stripCl = stripClustersHandle->push_back(std::make_unique<xAOD::StripCluster>());
74
75 // Build Matrix
76 Eigen::Matrix<float, 1, 1> localPosition;
77 Eigen::Matrix<float, 1, 1> localCovariance;
78 int row = 0; // idhash
79 unsigned int idHash = stripClusters[row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i + 16];
80 row = 1; // id
81 uint64_t id = to64 (stripClusters + row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i*2 + 16);
82
83 std::vector<Identifier> RDOs;
84 row = 3; // rdo w1
85 unsigned long long rdo = to64 (stripClusters + row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i*2 + 16);
86 if (rdo) RDOs.push_back(Identifier(rdo));
87
88 row = 5; // rdo w2
89 rdo = to64 (stripClusters + row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i*2 + 16);
90 if (rdo) RDOs.push_back(Identifier(rdo));
91
92 row = 7; // local x
93 localPosition(0, 0) = std::bit_cast<float>(stripClusters[row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i + 16]);
94 row = 8; // local covariance xx
95 localCovariance(0, 0) = std::bit_cast<float>(stripClusters[row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i + 16]);
96 row = 9; // global x
97 float globalX = std::bit_cast<float>(stripClusters[row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i + 16]);
98 row = 10; // global y
99 float globalY = std::bit_cast<float>(stripClusters[row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i + 16]);
100 row = 11; // global z
101 float globalZ = std::bit_cast<float>(stripClusters[row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i + 16]);
102 row = 12; // channels in phi
103 auto channelsinPhi = stripClusters[row * EFTrackingTransient::MAX_STRIP_CLUSTERS + i + 16];
104
105
106 Eigen::Matrix<float, 3, 1> globalPosition(globalX, globalY, globalZ);
107 stripCl->setMeasurement<1>(idHash, localPosition, localCovariance);
108
109 stripCl->setIdentifier(id);
110 stripCl->setRDOlist(RDOs);
111 stripCl->globalPosition() = globalPosition;
112 stripCl->setChannelsInPhi(channelsinPhi);
113 }
114
115 return StatusCode::SUCCESS;
116 }
117
118 ATH_MSG_DEBUG("Doing Strip bulk copy (optimized)");
119 // --------------------------
120 // Create the container and aux. container
121 // --------------------------
122 const size_t nClusters = metadata->numOfStripClusters;
123 DataPool<xAOD::StripCluster> stripPool{ctx};
124 stripPool.reserve(nClusters);
125 auto stripCl = std::make_unique<xAOD::StripClusterContainer>(SG::VIEW_ELEMENTS, SG::ALWAYS_TRACK_INDICES);
126 {
127 if constexpr (enableBenchmark) Athena::Chrono chrono("Strip object creating", m_chronoSvc.get());
128 stripCl->push_new(nClusters, [&stripPool]() { return stripPool.nextElementPtr(); });
129 }
130 auto stripClAux = std::make_unique<xAOD::StripClusterAuxContainer>();
131 stripClAux->resize(nClusters);
132 stripCl->setStore(stripClAux.get());
133 // --------------------------
134 // Access fixed-size attributes directly (rows/offsets consistent with !m_doBulkCopy)
135 // --------------------------
137 const size_t offset = 16;
138
139 // Treat the raw column-major buffer as 32-bit words; 64-bit values span two words.
140 const uint32_t* base = stripClusters;
141
142 auto load_u64 = [&](size_t row, size_t idx) -> uint64_t {
143 const uint32_t* p32 = base + row * N + offset + 2 * idx;
144 return *reinterpret_cast<const uint64_t*>(p32);
145 };
146 auto load_f32 = [&](size_t row, size_t idx) -> float {
147 return std::bit_cast<float>(*(base + row * N + offset + idx));
148 };
149 auto load_u32 = [&](size_t row, size_t idx) -> uint32_t {
150 return *(base + row * N + offset + idx);
151 };
152
153 // Column rows (as in !m_doBulkCopy)
154 constexpr size_t ROW_idHash = 0;
155 constexpr size_t ROW_identifier = 1; // 64-bit (two u32 words)
156 // (row 2 unused for Strip; keep aligned with transient layout)
157 constexpr size_t ROW_rdo_w1 = 3; // 64-bit (two u32 words)
158 constexpr size_t ROW_rdo_w2 = 5; // 64-bit (two u32 words)
159 constexpr size_t ROW_localPosX = 7; // float (from u32)
160 constexpr size_t ROW_localCovXX = 8; // float (from u32)
161 constexpr size_t ROW_gpX = 9; // float (from u32)
162 constexpr size_t ROW_gpY = 10; // float (from u32)
163 constexpr size_t ROW_gpZ = 11; // float (from u32)
164 constexpr size_t ROW_channelsPhi = 12; // int (from u32)
165
166 // --------------------------
167 // Precompute spans into aux data store (types match the non-bulk path)
168 // --------------------------
169 if (nClusters > 0) {
170 static const SG::Accessor<unsigned int> idHashAcc("identifierHash");
171 static const SG::Accessor<unsigned long> idAcc("identifier");
172 static const SG::Accessor<std::array<float, 1>> locPosXAcc("localPositionDim1");
173 static const SG::Accessor<std::array<float, 1>> locCovXXAcc("localCovarianceDim1");
174 static const SG::Accessor<std::array<float, 3>> gpAcc("globalPosition");
175 static const SG::Accessor<int> channelsPhiAcc("channelsInPhi");
176 static const SG::Accessor<std::vector<unsigned long long>> rdoListAcc("rdoList");
177
178 auto idHashSpan = idHashAcc.getDataSpan(*stripCl);
179 auto idSpan = idAcc.getDataSpan(*stripCl);
180 auto locPosXSpan = locPosXAcc.getDataSpan(*stripCl);
181 auto locCovXXSpan = locCovXXAcc.getDataSpan(*stripCl);
182 auto gpSpan = gpAcc.getDataSpan(*stripCl);
183 auto channelsPhiSpan = channelsPhiAcc.getDataSpan(*stripCl);
184 auto rdoSpan = rdoListAcc.getDataSpan(*stripCl);
185
186 // --------------------------
187 // Vectorized bulk assignments
188 // --------------------------
189 {
190 if constexpr (enableBenchmark) Athena::Chrono chrono("Strip assignments", m_chronoSvc.get());
191 for (size_t i = 0; i < nClusters; ++i) {
192 // idHash: 32-bit value
193 idHashSpan[i] = static_cast<unsigned int>(load_u32(ROW_idHash, i));
194
195 // identifier: 64-bit (two words)
196 idSpan[i] = static_cast<unsigned long long>(load_u64(ROW_identifier, i));
197
198 // local position / covariance (Dim1)
199 locPosXSpan[i][0] = load_f32(ROW_localPosX, i);
200 locCovXXSpan[i][0] = load_f32(ROW_localCovXX, i);
201
202 // global position (x,y,z)
203 gpSpan[i][0] = load_f32(ROW_gpX, i);
204 gpSpan[i][1] = load_f32(ROW_gpY, i);
205 gpSpan[i][2] = load_f32(ROW_gpZ, i);
206
207 // channels in phi
208 channelsPhiSpan[i] = static_cast<int>(load_u32(ROW_channelsPhi, i));
209
210 // RDO list: up to 2 entries (Identifier)
211 auto& rdoList = rdoSpan[i];
212 rdoList.reserve(2);
213 uint64_t rdo1 = load_u64(ROW_rdo_w1, i);
214 uint64_t rdo2 = load_u64(ROW_rdo_w2, i);
215 if (rdo1) rdoList.emplace_back(rdo1);
216 if (rdo2) rdoList.emplace_back(rdo2);
217 }
218 }
219 }
220
221 {
222 if constexpr (enableBenchmark) Athena::Chrono chrono("Strip Copy", m_chronoSvc.get());
223 ATH_CHECK(stripClustersHandle.record(std::move(stripCl), std::move(stripClAux)));
224 }
225
226 return StatusCode::SUCCESS;
227}
constexpr uint32_t MAX_STRIP_CLUSTERS

Member Data Documentation

◆ m_chronoSvc

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

Definition at line 106 of file xAODClusterMaker.h.

106{this, "ChronoStatSvc", "ChronoStatSvc"};

◆ 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.

104{this, "DoBulkCopy", true, "Do bulk copy"};

◆ 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.

95 {
96 this, "PixelClusterContainerKey", "FPGAPixelClusters",
97 "Key for output pixel cluster container"};

◆ 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.

100 {
101 this, "StripClusterContainerKey", "FPGAStripClusters",
102 "Key for output strip cluster container"};

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