From 1afce7983a873a43c80415fb57527323611d8df0 Mon Sep 17 00:00:00 2001 From: Christian Ariel Asch Burgos Date: Wed, 3 Jul 2024 05:08:15 +0200 Subject: [PATCH 01/92] Added code to dump RichPDInfo Added condition derivation for PDInfo Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/40752293 Modified the way the RichSmartIDs are printed, added methods to support this initial RichPD.cuh file Initial RichPDInfo.cuh file Started working on the make pixels algorithm Added code to dump RichPDInfo Added condition derivation for PDInfo Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/40752293 Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/41141633 Fixed CUDA compilation errors Added Rich side enum to RichDefinitions initial porting of RichMakePixels (work in progress). removed pixel padding functors (this was only relevant in SIMD) quick ci test config fix ci test config retry ci test ns unit is 1 progress into SmartIDs helper RichPDPanel progress set Pixel count to smartIDs count Added RichSmartIDs.cuh, replaced "emplace back" vector functionalities with array indexing and started using "DEVICE_INPUT" data structures initial bug fixes, still missing NAMESPACE problems Assignment of DetectorType types in RichSmartIDs Remove extra qualification Allen::RichSmartIDs:: from member functions Single Pixel global position getters in SmartIDs helper individual globalPositions for pixels Constructor PDPanel added detection point to RichPDPanel.cuh PD arrays Update file RichDefinitions.cuh Update file RichDefinitions.cuh Creation of get_pd Update file RichDefinitions.cuh Update file RichSmartIDs.cuh Update file RichSmartIDs.cuh Update file RichSmartIDs.cuh Update file RichSmartIDs.cuh Update file RichPDPanel.cuh Update file RichPDPanel.cuh Compilation errors fixes and getPD fix fixed pixel count getter by passing it from the previous decoding sequence as dev_rich_total_number_of_hits_t host to dev memory examples for meeting question Update 2 files - /device/rich/decoding/src/RichSmartIDs.cu - /device/rich/decoding/include/RichSmartIDs.cuh Bug fixes Added row and col setters Added pdIsSet Added identifier for PDPanel DumpRichPDPanel add dumper identifiers, cmake routes, and so on Update file DumpRichPDPanel.cpp globalToPdPanel start with global to PD Panel using 3d transforms Added Transform3D savePix functor indexing Fixed RichPixel constructor Added future reminders Added dePD function to PDPanel Added time related constants for RichSmartID Fixed effective area Fixed effective area in MakePixels passing index param to savePix functor Fixed operator() parameters Started fixing operator params, TODO: create smartIDsHelper inside operator after receiving RichPDPanels from dump Build smartIDsHelper at MakePixels operator() Removed pdInfo from RichSmartIDs Panel array ay MakePixels bug fix: pointer to ISV locator instead of copy Added code to copy number of hits from host to device Fixel transform3D definition Added operator() to DumpRichPDPanel getter for the dumped pdpanel in the makePixels alg. We still need to make it so that the Panels are perceived as an array of 4 panel objects. Add initial Allen RichX class initial RichX dumper, the idea here is to Dump the RichX objects which have PDPanel arrays Other Dumper requirements: Note in the main dumper we might have to add to the namespace Rich::Detector::Allen instead of just Allen added details namespace Started with Rich1 Dump, Not sure if the Geometric information from Rich1Path is complete or if we need to add more paths, but this is easily doable with the paths located at DeRichLocations in LHCb Rich1 dumper details fix Rich1Geometry identifiers refocus dumper on LHCb::Detector instead of DeRich Changed way of casting panels Fix type mismatch in DumpRich1Geometry by adding const qualifier to det parameter Removed DumpRichPDPanel call add cmake dependencies, linking Gaudi libraries Changed detector path at DumpRich1 Changed from RichGeoCond to DefaultConditionKey With the dumper working, we start trying to reconstruct the RICH1 object from our Allen algorithm bug fixes Bug fixes Starting to write sequence Typo Typo Typo RICH decoding updates and bug fixes TestAllenRichMakePixels Removed anything related to PDInfo, PDPanel, or RichX, as we now dump the whole Rich1 fix parentheses Fix compilation crash in +detdesc platforms and some minor warnings Small fix Changed attribute order and type namespace change in constants reference to Allen Rich1 class add rich::detector:: namespace to Allen::Rich1 Revert "add rich::detector:: namespace to Allen::Rich1" This reverts commit c45abf0992398c8dc01039c1d188979e36b62030. fixed geometry dump. ft Isaac Fixed m_panelID type warning Minor changes in the debugging process with Isaac. Lots of prints in this commit to be removed later Changed PD pointers to automatic objects copy constructor in PD reordered class attributes and changed types to perfectly match dumped classes Started correcting sequence Added necessary verifications to check that SmartIDs match a Photon detector which is not null. additionally fixed warnings, removed debug prints: TODO: parallelize loops, verify correctness in results, tidy up code, fit array size to actual hit size and not an overly large number (currently used to avoid dynamic memory allocation) The Parallel Update: Created Global kernel and device function to create pixels in parallel. events by blocks and smartID->pix by threads, TODO: operator(). Done with Ipalmame The Parallel Update part II, coded algorithms operator, reformatted block dim property, cleaned code. with Ipalmame sent smartID offsets from decoding to pixel sequence Debugged parallelization of the sequence and achieved complete run, with Josef comment cleanup Running on GPUs. made __constant__ arrays to be accesible from __device__ functions, made SmartIDsHelper HostToDevice Copy, added __host__ __device__ to RichPD functions. With Isaac fix some warnings fixed merge Add TestAllenRichMakePixels to CMakeLists.txt Trying to copy pixels from device to host Fixing test that compares pixels, work in progress, with Josef Cleaned debug prints and fixed test Created rich 2 geometry dumper Update DumpRich2Geometry.cpp Finished adding Rich2 to allen Fixing bugs trying to send rich type as sequence param Testing change rich number from argument to property diff make_pixels for rich1 and rich2 Tests run. still not passing Fixed transform3D. Test now runs with both RICHs. w/ Josef Removed unnecessary debug prints updated Allen property declarations some RichSmartID attribute handling fixes, and Moore test event indexing fix. X coordinate wrong in Allen pixels, the rest is perf. with Ipalmame matched datatypes in SmartIDs with HLT2, changed ToStrings of PDs and Panels Debug prints Test pixels started to match, using m_modNumOffset instead of panelLocalModuleNum, ft. Josef Iterate over RecSIMDSummaryPixels. Test finally passes, except for the padding pix (to be confirmed that these can be ignored) ft Isaac fixed ignoring Padding pixels test cleanup now testing all attributes as well, ft Isaac Code cleanup part 1 Code cleanup part 2 Restore test_config.yaml remove unused class PDInfo remove references to unused PDInfo class and removed more prints from test Add copyright where missing --- Dumpers/BinaryDumpers/CMakeLists.txt | 8 +- .../include/Dumpers/Identifiers.h | 14 + .../BinaryDumpers/src/DumpRich1Geometry.cpp | 90 ++++ .../BinaryDumpers/src/DumpRich2Geometry.cpp | 90 ++++ Rec/Allen/CMakeLists.txt | 1 + Rec/Allen/python/Allen/config.py | 14 +- Rec/Allen/src/TestAllenRichMakePixels.cpp | 169 +++++++ configuration/python/AllenConf/HLT1.py | 2 +- .../python/AllenConf/hlt1_reconstruction.py | 13 +- .../python/AllenConf/rich_make_pixels.py | 34 ++ .../python/AllenConf/rich_reconstruction.py | 18 +- configuration/python/AllenSequences/rich.py | 30 +- device/rich/decoding/include/Rich1.cuh | 36 ++ device/rich/decoding/include/Rich2.cuh | 36 ++ device/rich/decoding/include/RichDecoding.cuh | 2 +- .../rich/decoding/include/RichDefinitions.cuh | 457 +++++++++++++----- .../rich/decoding/include/RichMakePixels.cuh | 40 ++ device/rich/decoding/include/RichPD.cuh | 112 +++++ device/rich/decoding/include/RichPDPanel.cuh | 110 +++++ device/rich/decoding/include/RichPixels.cuh | 122 +++++ device/rich/decoding/include/RichSmartIDs.cuh | 84 ++++ device/rich/decoding/src/RichDecoding.cu | 4 +- device/rich/decoding/src/RichMakePixels.cu | 148 ++++++ device/rich/decoding/src/RichSmartIDs.cu | 45 ++ integration/non_event_data/src/Updater.cpp | 4 +- main/src/RegisterConsumers.cpp | 19 + out.txt | 0 stream/sequence/include/Constants.cuh | 11 +- 28 files changed, 1582 insertions(+), 131 deletions(-) create mode 100644 Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp create mode 100644 Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp create mode 100644 Rec/Allen/src/TestAllenRichMakePixels.cpp create mode 100644 configuration/python/AllenConf/rich_make_pixels.py create mode 100644 device/rich/decoding/include/Rich1.cuh create mode 100644 device/rich/decoding/include/Rich2.cuh create mode 100644 device/rich/decoding/include/RichMakePixels.cuh create mode 100644 device/rich/decoding/include/RichPD.cuh create mode 100644 device/rich/decoding/include/RichPDPanel.cuh create mode 100644 device/rich/decoding/include/RichPixels.cuh create mode 100644 device/rich/decoding/include/RichSmartIDs.cuh create mode 100644 device/rich/decoding/src/RichMakePixels.cu create mode 100644 device/rich/decoding/src/RichSmartIDs.cu create mode 100644 out.txt diff --git a/Dumpers/BinaryDumpers/CMakeLists.txt b/Dumpers/BinaryDumpers/CMakeLists.txt index f9cfc428b34..344435a9cc5 100644 --- a/Dumpers/BinaryDumpers/CMakeLists.txt +++ b/Dumpers/BinaryDumpers/CMakeLists.txt @@ -34,7 +34,8 @@ gaudi_add_library(BinaryDumpers LHCb::RecEvent LHCb::RichFutureDAQLib LHCb::RichFutureKernel - ) + LHCb::RichDetectorsLib + LHCb::RichDetLib) gaudi_add_module(BinaryDumpersModule SOURCES @@ -59,6 +60,8 @@ gaudi_add_module(BinaryDumpersModule src/DumpVPGeometry.cpp src/DumpRichCableMapping.cpp src/DumpRichPDMDBMapping.cpp + src/DumpRich1Geometry.cpp + src/DumpRich2Geometry.cpp src/PVDumper.cpp src/ProvideConstants.cpp src/TestMuonTable.cpp @@ -79,7 +82,8 @@ gaudi_add_module(BinaryDumpersModule LHCb::CaloDetLib LHCb::FTDetLib LHCb::MuonDAQLib - Rec::PrKernel + LHCb::RichDetLib + Rec::PrKernel yaml-cpp::yaml-cpp BinaryDumpers) diff --git a/Dumpers/BinaryDumpers/include/Dumpers/Identifiers.h b/Dumpers/BinaryDumpers/include/Dumpers/Identifiers.h index 352bca5456d..767a1a82a2e 100644 --- a/Dumpers/BinaryDumpers/include/Dumpers/Identifiers.h +++ b/Dumpers/BinaryDumpers/include/Dumpers/Identifiers.h @@ -122,5 +122,19 @@ namespace Allen { inline static std::string const id = "RichCableMapping"; }; + /** @class Rich1 + * Identifier for the RICH 1 objects for Allen + */ + struct Rich1Geometry : Identifier { + inline static std::string const id = "Rich1Geometry"; + }; + + /** @class Rich2 + * Identifier for the RICH 2 objects for Allen + */ + struct Rich2Geometry : Identifier { + inline static std::string const id = "Rich2Geometry"; + }; + } // namespace NonEventData } // namespace Allen diff --git a/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp b/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp new file mode 100644 index 00000000000..848e12d2245 --- /dev/null +++ b/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp @@ -0,0 +1,90 @@ +/*****************************************************************************\ + * (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "LICENSE". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ + +// Gaudi Array properties ( must be first ...) +#include "GaudiKernel/StdArrayAsProperty.h" + +// Rich Kernel +#include "RichFutureKernel/RichAlgBase.h" +#include "Kernel/RichDetectorType.h" + +// Gaudi Functional +#include "LHCbAlgs/Transformer.h" + +// Rich Utils +#include "RichFutureUtils/RichDecodedData.h" +#include "RichUtils/RichException.h" +#include "RichUtils/RichHashMap.h" +#include "RichUtils/RichMap.h" +#include "RichUtils/RichSmartIDSorter.h" + +// LHCb +#include +#include + +// Dumper +#include "Dumper.h" +#include + +namespace { +#ifdef USE_DD4HEP + inline const std::string RichGeoCond = DeRichLocations::Rich1Path; +#else + inline const std::string RichGeoCond = DeRichLocations::OldRich1; +#endif + + struct Rich1Geometry_t { + Rich1Geometry_t() = default; + Rich1Geometry_t(std::vector& data, const Rich::Detector::Rich1& rich_1) { + Rich::Detector::Allen::Rich1 allenRich1 {rich_1}; + DumpUtils::Writer output {}; + output.write(allenRich1); + data = output.buffer(); + } + }; +} // namespace + +/** + * @brief Dump RICH detector object information. + */ + +class DumpRich1Geometry final +: public Allen::Dumpers::Dumper> +{ + public: + DumpRich1Geometry(const std::string& name, ISvcLocator* svcLoc); + void operator()(const Rich1Geometry_t& RichGeo) const override; + StatusCode initialize() override; + + private: + std::vector m_data; +}; + +DECLARE_COMPONENT(DumpRich1Geometry) + + DumpRich1Geometry::DumpRich1Geometry(const std::string& name, ISvcLocator* svcLoc) : + Dumper(name, svcLoc, {KeyValue {"Rich1GeometryLocation", location(name, "rich1Geometry")}}) +{} + +StatusCode DumpRich1Geometry::initialize() +{ + return Dumper::initialize().andThen([&, this] { + register_producer(Allen::NonEventData::Rich1Geometry::id, "rich_1_geometry", m_data); + Rich::Detector::Rich1::addConditionDerivation(this); + addConditionDerivation({Rich::Detector::Rich1::DefaultConditionKey},inputLocation(), [&](const Rich::Detector::Rich1& det) { + auto Rich1Geo = Rich1Geometry_t {m_data, det}; + dump(); + return Rich1Geo; + }); + }); +} + +void DumpRich1Geometry::operator()(const Rich1Geometry_t&) const {} diff --git a/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp b/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp new file mode 100644 index 00000000000..901fa308be9 --- /dev/null +++ b/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp @@ -0,0 +1,90 @@ +/*****************************************************************************\ + * (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "LICENSE". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ + +// Gaudi Array properties ( must be first ...) +#include "GaudiKernel/StdArrayAsProperty.h" + +// Rich Kernel +#include "RichFutureKernel/RichAlgBase.h" +#include "Kernel/RichDetectorType.h" + +// Gaudi Functional +#include "LHCbAlgs/Transformer.h" + +// Rich Utils +#include "RichFutureUtils/RichDecodedData.h" +#include "RichUtils/RichException.h" +#include "RichUtils/RichHashMap.h" +#include "RichUtils/RichMap.h" +#include "RichUtils/RichSmartIDSorter.h" + +// LHCb +#include +#include + +// Dumper +#include "Dumper.h" +#include + +namespace { +#ifdef USE_DD4HEP + inline const std::string RichGeoCond = DeRichLocations::Rich2Path; +#else + inline const std::string RichGeoCond = DeRichLocations::OldRich2; +#endif + + struct Rich2Geometry_t { + Rich2Geometry_t() = default; + Rich2Geometry_t(std::vector& data, const Rich::Detector::Rich2& rich_2) { + Rich::Detector::Allen::Rich2 allenRich2 {rich_2}; + DumpUtils::Writer output {}; + output.write(allenRich2); + data = output.buffer(); + } + }; +} // namespace + +/** + * @brief Dump RICH detector object information. + */ + +class DumpRich2Geometry final +: public Allen::Dumpers::Dumper> +{ + public: + DumpRich2Geometry(const std::string& name, ISvcLocator* svcLoc); + void operator()(const Rich2Geometry_t& RichGeo) const override; + StatusCode initialize() override; + + private: + std::vector m_data; +}; + +DECLARE_COMPONENT(DumpRich2Geometry) + + DumpRich2Geometry::DumpRich2Geometry(const std::string& name, ISvcLocator* svcLoc) : + Dumper(name, svcLoc, {KeyValue {"Rich2GeometryLocation", location(name, "rich2Geometry")}}) +{} + +StatusCode DumpRich2Geometry::initialize() +{ + return Dumper::initialize().andThen([&, this] { + register_producer(Allen::NonEventData::Rich2Geometry::id, "rich_2_geometry", m_data); + Rich::Detector::Rich2::addConditionDerivation(this); + addConditionDerivation({Rich::Detector::Rich2::DefaultConditionKey},inputLocation(), [&](const Rich::Detector::Rich2& det) { + auto Rich2Geo = Rich2Geometry_t {m_data, det}; + dump(); + return Rich2Geo; + }); + }); +} + +void DumpRich2Geometry::operator()(const Rich2Geometry_t&) const {} diff --git a/Rec/Allen/CMakeLists.txt b/Rec/Allen/CMakeLists.txt index 53c981529a7..8293d3c9636 100644 --- a/Rec/Allen/CMakeLists.txt +++ b/Rec/Allen/CMakeLists.txt @@ -40,6 +40,7 @@ gaudi_add_module(AllenWrapper src/CompareRecAllenVPHits.cpp src/TestVeloClusters.cpp src/TestAllenRichPixels.cpp + src/TestAllenRichMakePixels.cpp src/IOMonitor.cpp LINK AllenLib diff --git a/Rec/Allen/python/Allen/config.py b/Rec/Allen/python/Allen/config.py index 572b7ea16ea..a82af735e5c 100755 --- a/Rec/Allen/python/Allen/config.py +++ b/Rec/Allen/python/Allen/config.py @@ -21,7 +21,7 @@ from PyConf.Algorithms import ( DumpMagneticFieldPolarity, DumpVPGeometry, DumpCrossingAngles, DumpFTGeometry, DumpUTGeometry, DumpUTLookupTables, DumpMuonGeometry, DumpMuonTable, AllenODINProducer, DumpRichPDMDBMapping, - DumpRichCableMapping) + DumpRichCableMapping, DumpRich1Geometry, DumpRich2Geometry) from DDDB.CheckDD4Hep import UseDD4Hep from PyConf.reading import get_generator_BeamParameters from GaudiConf.LbExec import Options as DefaultOptions @@ -122,7 +122,11 @@ def setup_allen_non_event_data_service(allen_event_loop=False, 'Rich': [(DumpRichPDMDBMapping, 'DeviceRichPDMDBMapping', {}, 'rich_pdmdbmaps'), (DumpRichCableMapping, 'DeviceRichCableMapping', {}, - 'rich_tel40maps')] + 'rich_tel40maps'), + (DumpRich1Geometry, 'DeviceRich1Geometry', {}, + 'rich_1_geometry'), + (DumpRich2Geometry, 'DeviceRich2Geometry', {}, + 'rich_2_geometry')] } else: converter_types = { @@ -147,7 +151,11 @@ def setup_allen_non_event_data_service(allen_event_loop=False, 'Rich': [(DumpRichPDMDBMapping, 'DeviceRichPDMDBMapping', {}, 'rich_pdmdbmaps'), (DumpRichCableMapping, 'DeviceRichCableMapping', {}, - 'rich_tel40maps')] + 'rich_tel40maps'), + (DumpRich1Geometry, 'DeviceRich1Geometry', {}, + 'rich_1_geometry'), + (DumpRich2Geometry, 'DeviceRich2Geometry', {}, + 'rich_2_geometry')] } detector_names = { diff --git a/Rec/Allen/src/TestAllenRichMakePixels.cpp b/Rec/Allen/src/TestAllenRichMakePixels.cpp new file mode 100644 index 00000000000..80f2b819ca1 --- /dev/null +++ b/Rec/Allen/src/TestAllenRichMakePixels.cpp @@ -0,0 +1,169 @@ +/***************************************************************************** \ + * (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +\*****************************************************************************/ +// Gaudi +#include "GaudiAlg/Consumer.h" + +// Rec +#include "RichFutureRecEvent/RichRecSIMDPixels.h" + +// Allen +#include "RichMakePixels.cuh" +#include "RichPixels.cuh" + +class TestAllenRichMakePixels final : public Gaudi::Functional::Consumer&, + const std::vector&, + const Rich::Future::Rec::SIMDPixelSummaries&)> +{ + public: + /// Standard constructor + TestAllenRichMakePixels(const std::string& name, ISvcLocator* pSvcLocator); + + /// Algorithm execution + void operator()(const std::vector&, const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&) const override; +}; + +DECLARE_COMPONENT(TestAllenRichMakePixels) + +TestAllenRichMakePixels::TestAllenRichMakePixels(const std::string& name, ISvcLocator* pSvcLocator) : + Consumer( + name, + pSvcLocator, + {KeyValue {"rich1_pixels", ""}, KeyValue {"rich2_pixels", ""}, KeyValue {"SIMDPixelSummaries", ""}}) +{} + + +// When reading this code, keep in mind that recPixelSummaries contain multiple pixels, while allenRichPixels contain individual pixels +void TestAllenRichMakePixels::operator()( + const std::vector& allenRich1Pixels, + const std::vector& allenRich2Pixels, + const Rich::Future::Rec::SIMDPixelSummaries& recPixelSummaries + ) const +{ + int allen_in_rec = 0; + int allen_not_in_rec = 0; + int rec_in_allen = 0; + int rec_not_in_allen = 0; + int allen_null = 0; + auto rich1_pixels = allenRich1Pixels; + auto rich2_pixels = allenRich2Pixels; + + // Concatenate Allen Pixel vectors + std::vector allenPixels; + allenPixels.reserve(allenRich1Pixels.size() + allenRich2Pixels.size()); + allenPixels.insert(allenPixels.end(), rich1_pixels.begin(), rich1_pixels.end()); + allenPixels.insert(allenPixels.end(), rich2_pixels.begin(), rich2_pixels.end()); + + // functor to check if allen pixels exist in HLT2 + auto allenPixelExistsInRec = [&](const Allen::RichPixel& allenPixel) -> bool { + // iterate over all pixel summaries + for(const auto &recPixelSummary : recPixelSummaries) { + // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. + for(size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { + // ensure HLT2 pixel validity + if (recPixelSummary.validMask()[i]){ + // check for match + if( + (allenPixel.gloPos()[0] == recPixelSummary.gloPos().X()[i]) && + (allenPixel.gloPos()[1] == recPixelSummary.gloPos().Y()[i]) && + (allenPixel.gloPos()[2] == recPixelSummary.gloPos().Z()[i]) && + (allenPixel.locPos()[0] == recPixelSummary.locPos().X()[i]) && + (allenPixel.locPos()[1] == recPixelSummary.locPos().Y()[i]) && + (allenPixel.locPos()[2] == recPixelSummary.locPos().Z()[i]) && + (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && + (allenPixel.effArea() == recPixelSummary.effArea()[i]) && + ((int)allenPixel.rich() == (int)recPixelSummary.rich()) && + ((int)allenPixel.side() == (int)recPixelSummary.side()) && + (allenPixel.timeWindow() == recPixelSummary.timeWindow()[i]) && + (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i]) + ) { + return true; + } + } else { + return true; // ignore invalid pix, assume correctness + }// invalid pix + } // didn't find pix match + } // covered all + return false; + }; + + + // functor to check if HLT2 pixels exist in Allen + auto recPixelExistsInAllen = [&](const Rich::Future::Rec::SIMDPixel& recPixelSummary) -> bool { + bool found_all_pixels = true; + bool found_current_pixel = true; + + // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. + for(size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { + // case: HLT2 pixels in case they are not found in Allen + if (!found_current_pixel) { + rec_not_in_allen++; + error() << "Rec pixel does not exist in Allen" << endmsg; + std::cout << "Rec pixel: " << recPixelSummary.gloPos().X()[i-1] << ',' << recPixelSummary.gloPos().Y()[i-1] << ',' << recPixelSummary.gloPos().Z()[i-1] << ',' + << recPixelSummary.locPos().X()[i-1] << ',' << recPixelSummary.locPos().Y()[i-1] << ',' << recPixelSummary.locPos().Z()[i-1] << ',' + << recPixelSummary.smartID()[i-1].key() << ',' << recPixelSummary.effArea()[i-1] << ',' << (int)(recPixelSummary.rich()) << ',' + << (int)(recPixelSummary.side()) << ',' << recPixelSummary.validMask()[i-1] << ',' << recPixelSummary.timeWindow()[i-1] << ',' << recPixelSummary.isInnerRegion()[i-1] << '\n'; +} + found_current_pixel = false; + + // ensure HLT2 pixel validity + if (recPixelSummary.validMask()[i]){ + // iterate over Allen pixels + for(const auto &allenPixel : allenPixels) { + // check for match + if( + (allenPixel.gloPos()[0] == recPixelSummary.gloPos().X()[i]) && + (allenPixel.gloPos()[1] == recPixelSummary.gloPos().Y()[i]) && + (allenPixel.gloPos()[2] == recPixelSummary.gloPos().Z()[i]) && + (allenPixel.locPos()[0] == recPixelSummary.locPos().X()[i]) && + (allenPixel.locPos()[1] == recPixelSummary.locPos().Y()[i]) && + (allenPixel.locPos()[2] == recPixelSummary.locPos().Z()[i]) && + (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && + (allenPixel.effArea() == recPixelSummary.effArea()[i]) && + ((int)allenPixel.rich() == (int)recPixelSummary.rich()) && + ((int)allenPixel.side() == (int)recPixelSummary.side()) && + (allenPixel.timeWindow() == recPixelSummary.timeWindow()[i]) && + (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i]) + ) { + found_current_pixel = true; + rec_in_allen++; + continue; + } // found a match + } // iterate over Allen pixels + } else { + found_current_pixel = true; //assume correctedness on invalid pix to ignore it. + } // valid pix + found_all_pixels = found_all_pixels && found_current_pixel; + } + return found_all_pixels; + }; + + // call allen in hlt2 functor + for (auto &allenPixel : allenPixels) { + if(!allenPixel.isNull()) { + if (!allenPixelExistsInRec(allenPixel)) { + error() << "Allen pixel does not exist in Rec" << endmsg; + std::cout << allenPixel.toString() << std::endl; + allen_not_in_rec++; + }else{ + allen_in_rec++; + } + }else{ + allen_null++; + } + } + + // call hlt2 in allen functor + for (auto &recPixelSummary : recPixelSummaries) { + recPixelExistsInAllen(recPixelSummary); + } + + // print final stats + /* std::cout << "allen_in_rec " << allen_in_rec << std::endl; + std::cout << "allen_not_in_rec " << allen_not_in_rec << std::endl; + std::cout << "allen_null " << allen_null << std::endl; + std::cout << "rec_in_allen " << rec_in_allen << std::endl; + std::cout << "rec_not_in_allen " << rec_not_in_allen << std::endl; + **/ +} diff --git a/configuration/python/AllenConf/HLT1.py b/configuration/python/AllenConf/HLT1.py index 92f56b1177d..3c6fec37ef0 100644 --- a/configuration/python/AllenConf/HLT1.py +++ b/configuration/python/AllenConf/HLT1.py @@ -1583,7 +1583,7 @@ def setup_hlt1_node(enablePhysics=True, hlt1_node = CompositeNode( "AllenWithRich", [ hlt1_node, - reconstructed_objects["decoded_rich"]["dev_smart_ids"].producer + reconstructed_objects["decoded_rich1"]["dev_smart_ids"].producer ], NodeLogic.NONLAZY_AND, force_order=True) diff --git a/configuration/python/AllenConf/hlt1_reconstruction.py b/configuration/python/AllenConf/hlt1_reconstruction.py index 4facbc4411a..468882b45de 100644 --- a/configuration/python/AllenConf/hlt1_reconstruction.py +++ b/configuration/python/AllenConf/hlt1_reconstruction.py @@ -498,8 +498,17 @@ def hlt1_reconstruction(algorithm_name='', if with_rich: from AllenConf.rich_reconstruction import decode_rich - output.update({"decoded_rich": decode_rich()}) - + from AllenConf.rich_make_pixels import make_pixels + decoded_rich1 = decode_rich(rich=1) + decoded_rich2 = decode_rich(rich=2) + output.update( + { + "decoded_rich1": decoded_rich1, + "decoded_rich2": decoded_rich2, + "rich1_pixels": make_pixels(decoded_rich1,rich=1), + "rich2_pixels": make_pixels(decoded_rich2,rich=2) + }) + if with_AC_split: velo_tracks_A_side, velo_tracks_C_side = make_velo_tracks_ACsplit( decoded_velo) diff --git a/configuration/python/AllenConf/rich_make_pixels.py b/configuration/python/AllenConf/rich_make_pixels.py new file mode 100644 index 00000000000..c42fc3484d9 --- /dev/null +++ b/configuration/python/AllenConf/rich_make_pixels.py @@ -0,0 +1,34 @@ +############################################################################### +# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the Apache License # +# version 2 (Apache-2.0), copied verbatim in the file "LICENSE". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from AllenCore.algorithms import (data_provider_t, rich_make_pixels_t) +from AllenConf.utils import initialize_number_of_events +from AllenConf.rich_reconstruction import (RICH_1, RICH_2, VALID_RICHS, decode_rich) +from AllenCore.generator import make_algorithm + +def make_pixels(decoded_rich=None, rich=RICH_1): + if rich not in VALID_RICHS: + raise ValueError(f"rich must be one of {VALID_RICHS}") + if decoded_rich is None: + decoded_rich = decode_rich(rich) + number_of_hits = decoded_rich["host_rich_total_number_of_hits"] + smart_ids = decoded_rich["dev_smart_ids"] + hit_offsets = decoded_rich["dev_rich_hit_offsets"] + + rich_pixels = make_algorithm( + rich_make_pixels_t, + name=f"rich{rich}_make_pixels", + host_rich_total_number_of_hits_t=number_of_hits, + dev_smart_ids_t=smart_ids, + dev_rich_hit_offsets_t=hit_offsets, + current_rich=rich) + return { + "dev_rich_pixels": rich_pixels.dev_rich_pixels_t + } diff --git a/configuration/python/AllenConf/rich_reconstruction.py b/configuration/python/AllenConf/rich_reconstruction.py index 3452cd084b4..9d2bdadacb8 100644 --- a/configuration/python/AllenConf/rich_reconstruction.py +++ b/configuration/python/AllenConf/rich_reconstruction.py @@ -12,10 +12,14 @@ from AllenCore.algorithms import (data_provider_t, rich_decoding_t) from AllenConf.utils import initialize_number_of_events from AllenCore.generator import make_algorithm +RICH_1 = 1 +RICH_2 = 2 -def decode_rich(rich=1): - if rich not in (1, 2): - raise ValueError("rich must be 1 or 2") +VALID_RICHS = [RICH_1, RICH_2] + +def decode_rich(rich=RICH_1): + if rich not in VALID_RICHS: + raise ValueError(f"rich must be one of {VALID_RICHS}") number_of_events = initialize_number_of_events() @@ -30,10 +34,10 @@ def decode_rich(rich=1): dev_rich_raw_input_t=rich_banks.dev_raw_banks_t, dev_rich_raw_input_offsets_t=rich_banks.dev_raw_offsets_t, dev_rich_raw_input_sizes_t=rich_banks.dev_raw_sizes_t, - dev_rich_raw_input_types_t=rich_banks.dev_raw_types_t, - block_dim_x=128) - + dev_rich_raw_input_types_t=rich_banks.dev_raw_types_t) + return { "dev_smart_ids": rich_decoding.dev_smart_ids_t, - "dev_rich_hit_offsets": rich_decoding.dev_rich_hit_offsets_t + "dev_rich_hit_offsets": rich_decoding.dev_rich_hit_offsets_t, + "host_rich_total_number_of_hits": rich_decoding.host_rich_total_number_of_hits_t } diff --git a/configuration/python/AllenSequences/rich.py b/configuration/python/AllenSequences/rich.py index 3592c2f89f8..759597e45b1 100644 --- a/configuration/python/AllenSequences/rich.py +++ b/configuration/python/AllenSequences/rich.py @@ -9,12 +9,36 @@ # or submit itself to any jurisdiction. # ############################################################################### from AllenConf.rich_reconstruction import decode_rich +from AllenConf.rich_make_pixels import make_pixels from AllenCore.generator import generate from PyConf.control_flow import NodeLogic, CompositeNode -rich_decoding = CompositeNode( - "RichDecoding", [decode_rich()["dev_smart_ids"].producer], +decoded_rich1 = decode_rich(rich=1) +decoded_rich2 = decode_rich(rich=2) + +rich1_decoding = CompositeNode( + "Rich1Decoding", [decoded_rich1["dev_smart_ids"].producer], + NodeLogic.NONLAZY_AND, + force_order=False) + +rich2_decoding = CompositeNode( + "Rich2Decoding", [decoded_rich2["dev_smart_ids"].producer], + NodeLogic.NONLAZY_AND, + force_order=False) + +rich1_make_pixels = CompositeNode( + "Rich1MakePixels", [make_pixels(decoded_rich1, rich=1)["dev_rich_pixels"].producer], + NodeLogic.NONLAZY_AND, + force_order=True) + +rich2_make_pixels = CompositeNode( + "Rich2MakePixels", [make_pixels(decoded_rich2, rich=2)["dev_rich_pixels"].producer], + NodeLogic.NONLAZY_AND, + force_order=True) + +rich_node = CompositeNode( + "RichNode", [rich1_decoding, rich1_make_pixels, rich2_decoding, rich2_make_pixels], NodeLogic.NONLAZY_AND, force_order=True) -generate(rich_decoding) +generate(rich_node) diff --git a/device/rich/decoding/include/Rich1.cuh b/device/rich/decoding/include/Rich1.cuh new file mode 100644 index 00000000000..d706868a2e6 --- /dev/null +++ b/device/rich/decoding/include/Rich1.cuh @@ -0,0 +1,36 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include + +namespace Allen { + class Rich1 { + public: + __host__ __device__ Rich1(); + + __host__ __device__ Rich1(const int8_t m_type, const std::array m_panels) + : m_panels(m_panels), m_type(m_type) { } + + __host__ __device__ inline auto rich() { return m_type; } + + /// Access PD Panels + __host__ __device__ inline auto& pdPanels() { return m_panels; } + + /// Access PD Panel for a given side + __host__ __device__ inline auto pdPanel( const Rich::Future::DAQ::Side panel ) noexcept { + return &( pdPanels()[panel] ); + } + + private: + std::array m_panels; + int8_t m_type; + }; +} // namespace Allen diff --git a/device/rich/decoding/include/Rich2.cuh b/device/rich/decoding/include/Rich2.cuh new file mode 100644 index 00000000000..f0ded49a516 --- /dev/null +++ b/device/rich/decoding/include/Rich2.cuh @@ -0,0 +1,36 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include + +namespace Allen { + class Rich2 { + public: + __host__ __device__ Rich2(); + + __host__ __device__ Rich2(const int8_t m_type, const std::array m_panels) + : m_panels(m_panels), m_type(m_type) { } + + __host__ __device__ inline auto rich() { return m_type; } + + /// Access PD Panels + __host__ __device__ inline auto& pdPanels() { return m_panels; } + + /// Access PD Panel for a given side + __host__ __device__ inline auto pdPanel( const Rich::Future::DAQ::Side panel ) noexcept { + return &( pdPanels()[panel] ); + } + + private: + std::array m_panels; + int8_t m_type; + }; +} // namespace Allen diff --git a/device/rich/decoding/include/RichDecoding.cuh b/device/rich/decoding/include/RichDecoding.cuh index 715330c90ce..d5da38ba481 100644 --- a/device/rich/decoding/include/RichDecoding.cuh +++ b/device/rich/decoding/include/RichDecoding.cuh @@ -37,6 +37,6 @@ namespace rich_decoding { const Allen::Context&) const; private: - Allen::Property m_block_dim_x {this, "block_dim_x", 64, "block dimension x"}; + Allen::Property m_block_dim {this, "block_dim", {64,1,1}, "block dimensions"}; }; } // namespace rich_decoding diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 5cb8359fe65..31675525f78 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -1,159 +1,400 @@ /*****************************************************************************\ -* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the Apache License * -* version 2 (Apache-2.0), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ #pragma once #include #include +#include #include "BackendCommon.h" namespace Allen { + using FP = float; + using Point = std::array; + using DataType = std::uint32_t; + using Transform3D = std::array; + using KeyType = std::uint64_t; + using BitPackType = KeyType; + using ADCTimeType = std::uint16_t; + + __host__ __device__ inline Point transform3DTimesPoint(Transform3D fM, Point point) { + return Point{ + fM[0]*point[0] + fM[1]*point[1] + fM[2]*point[2] + fM[3], + fM[4]*point[0] + fM[5]*point[1] + fM[6]*point[2] + fM[7], + fM[8]*point[0] + fM[9]*point[1] + fM[10]*point[2] + fM[11] + }; + } + class RichSmartID { - uint64_t m_key; + KeyType m_key; + + public: + + // Set the RICH PD pixel row identifier + __host__ __device__ constexpr void setPixelRow( const DataType row ) + { + setData( row, ShiftPixelRow, MaskPixelRow, MaskPixelRowIsSet ); + } + + // Set the RICH PD pixel column identifier + __host__ __device__ constexpr void setPixelCol( const DataType col ) + { + setData( col, ShiftPixelCol, MaskPixelCol, MaskPixelColIsSet ); + } public: - RichSmartID() = default; + __host__ __device__ RichSmartID() = default; - __host__ __device__ RichSmartID(uint64_t key) : m_key(key) {} + __host__ __device__ RichSmartID(KeyType key) : m_key(key) {} // Number of bits for each data field in the word - static constexpr const unsigned BitsPixelCol = 3; ///< Number of bits for MaPMT pixel column - static constexpr const unsigned BitsPixelRow = 3; ///< Number of bits for MaPMT pixel row - static constexpr const unsigned BitsPDNumInMod = 4; ///< Number of bits for MaPMT 'number in module' - static constexpr const unsigned BitsPDMod = 9; ///< Number of bits for MaPMT module - static constexpr const unsigned BitsPanel = 1; ///< Number of bits for MaPMT panel - static constexpr const unsigned BitsRich = 1; ///< Number of bits for RICH detector - static constexpr const unsigned BitsPixelSubRowIsSet = 1; - static constexpr const unsigned BitsPixelColIsSet = 1; - static constexpr const unsigned BitsPixelRowIsSet = 1; - static constexpr const unsigned BitsPDIsSet = 1; - static constexpr const unsigned BitsPanelIsSet = 1; - static constexpr const unsigned BitsRichIsSet = 1; - static constexpr const unsigned BitsLargePixel = 1; + static constexpr const BitPackType BitsPixelCol = 3; //< Number of bits for MaPMT pixel column + static constexpr const BitPackType BitsPixelRow = 3; //< Number of bits for MaPMT pixel row + static constexpr const BitPackType BitsPDNumInMod = 4; //< Number of bits for MaPMT 'number in module' + static constexpr const BitPackType BitsPDMod = 9; //< Number of bits for MaPMT module + static constexpr const BitPackType BitsPanel = 1; //< Number of bits for MaPMT panel + static constexpr const BitPackType BitsRich = 1; //< Number of bits for RICH detector + static constexpr const BitPackType BitsPixelSubRowIsSet = 1; + static constexpr const BitPackType BitsPixelColIsSet = 1; + static constexpr const BitPackType BitsPixelRowIsSet = 1; + static constexpr const BitPackType BitsPDIsSet = 1; + static constexpr const BitPackType BitsPanelIsSet = 1; + static constexpr const BitPackType BitsRichIsSet = 1; + static constexpr const BitPackType BitsLargePixel = 1; // The shifts - static constexpr const unsigned ShiftPixelCol = 0; - static constexpr const unsigned ShiftPixelRow = ShiftPixelCol + BitsPixelCol; - static constexpr const unsigned ShiftPDNumInMod = ShiftPixelRow + BitsPixelRow; - static constexpr const unsigned ShiftPDMod = ShiftPDNumInMod + BitsPDNumInMod; - static constexpr const unsigned ShiftPanel = ShiftPDMod + BitsPDMod; - static constexpr const unsigned ShiftRich = ShiftPanel + BitsPanel; - static constexpr const unsigned ShiftPixelSubRowIsSet = ShiftRich + BitsRich; - static constexpr const unsigned ShiftPixelColIsSet = ShiftPixelSubRowIsSet + BitsPixelSubRowIsSet; - static constexpr const unsigned ShiftPixelRowIsSet = ShiftPixelColIsSet + BitsPixelColIsSet; - static constexpr const unsigned ShiftPDIsSet = ShiftPixelRowIsSet + BitsPixelRowIsSet; - static constexpr const unsigned ShiftPanelIsSet = ShiftPDIsSet + BitsPDIsSet; - static constexpr const unsigned ShiftRichIsSet = ShiftPanelIsSet + BitsPanelIsSet; - static constexpr const unsigned ShiftLargePixel = ShiftRichIsSet + BitsRichIsSet; + static constexpr const BitPackType ShiftPixelCol = 0; + static constexpr const BitPackType ShiftPixelRow = ShiftPixelCol + BitsPixelCol; + static constexpr const BitPackType ShiftPDNumInMod = ShiftPixelRow + BitsPixelRow; + static constexpr const BitPackType ShiftPDMod = ShiftPDNumInMod + BitsPDNumInMod; + static constexpr const BitPackType ShiftPanel = ShiftPDMod + BitsPDMod; + static constexpr const BitPackType ShiftRich = ShiftPanel + BitsPanel; + static constexpr const BitPackType ShiftPixelSubRowIsSet = ShiftRich + BitsRich; + static constexpr const BitPackType ShiftPixelColIsSet = ShiftPixelSubRowIsSet + BitsPixelSubRowIsSet; + static constexpr const BitPackType ShiftPixelRowIsSet = ShiftPixelColIsSet + BitsPixelColIsSet; + static constexpr const BitPackType ShiftPDIsSet = ShiftPixelRowIsSet + BitsPixelRowIsSet; + static constexpr const BitPackType ShiftPanelIsSet = ShiftPDIsSet + BitsPDIsSet; + static constexpr const BitPackType ShiftRichIsSet = ShiftPanelIsSet + BitsPanelIsSet; + static constexpr const BitPackType ShiftLargePixel = ShiftRichIsSet + BitsRichIsSet; // The masks - static constexpr const unsigned MaskPixelCol = (unsigned) ((1 << BitsPixelCol) - 1) << ShiftPixelCol; - static constexpr const unsigned MaskPixelRow = (unsigned) ((1 << BitsPixelRow) - 1) << ShiftPixelRow; - static constexpr const unsigned MaskPDNumInMod = (unsigned) ((1 << BitsPDNumInMod) - 1) << ShiftPDNumInMod; - static constexpr const unsigned MaskPDMod = (unsigned) ((1 << BitsPDMod) - 1) << ShiftPDMod; - static constexpr const unsigned MaskPanel = (unsigned) ((1 << BitsPanel) - 1) << ShiftPanel; - static constexpr const unsigned MaskRich = (unsigned) ((1 << BitsRich) - 1) << ShiftRich; - static constexpr const unsigned MaskPixelSubRowIsSet = (unsigned) ((1 << BitsPixelSubRowIsSet) - 1) - << ShiftPixelSubRowIsSet; - static constexpr const unsigned MaskPixelColIsSet = (unsigned) ((1 << BitsPixelColIsSet) - 1) << ShiftPixelColIsSet; - static constexpr const unsigned MaskPixelRowIsSet = (unsigned) ((1 << BitsPixelRowIsSet) - 1) << ShiftPixelRowIsSet; - static constexpr const unsigned MaskPDIsSet = (unsigned) ((1 << BitsPDIsSet) - 1) << ShiftPDIsSet; - static constexpr const unsigned MaskPanelIsSet = (unsigned) ((1 << BitsPanelIsSet) - 1) << ShiftPanelIsSet; - static constexpr const unsigned MaskRichIsSet = (unsigned) ((1 << BitsRichIsSet) - 1) << ShiftRichIsSet; - static constexpr const unsigned MaskLargePixel = (unsigned) ((1 << BitsLargePixel) - 1) << ShiftLargePixel; - - // Max Values - static constexpr const unsigned MaxPixelCol = (unsigned) (1 << BitsPixelCol) - 1; - static constexpr const unsigned MaxPixelRow = (unsigned) (1 << BitsPixelRow) - 1; - static constexpr const unsigned MaxPDNumInMod = (unsigned) (1 << BitsPDNumInMod) - 1; - static constexpr const unsigned MaxPDMod = (unsigned) (1 << BitsPDMod) - 1; - static constexpr const unsigned MaxPanel = (unsigned) (1 << BitsPanel) - 1; - static constexpr const unsigned MaxRich = (unsigned) (1 << BitsRich) - 1; - - __host__ __device__ constexpr inline void - setData(const unsigned value, const unsigned shift, const unsigned mask) noexcept + static constexpr const BitPackType MaskPixelCol = + ( BitPackType )( ( BitPackType{1} << BitsPixelCol ) - BitPackType{1} ) << ShiftPixelCol; + static constexpr const BitPackType MaskPixelRow = + ( BitPackType )( ( BitPackType{1} << BitsPixelRow ) - BitPackType{1} ) << ShiftPixelRow; + static constexpr const BitPackType MaskPDNumInMod = + ( BitPackType )( ( BitPackType{1} << BitsPDNumInMod ) - BitPackType{1} ) << ShiftPDNumInMod; + static constexpr const BitPackType MaskPDMod = + ( BitPackType )( ( BitPackType{1} << BitsPDMod ) - BitPackType{1} ) << ShiftPDMod; + static constexpr const BitPackType MaskPanel = + ( BitPackType )( ( BitPackType{1} << BitsPanel ) - BitPackType{1} ) << ShiftPanel; + static constexpr const BitPackType MaskRich = + ( BitPackType )( ( BitPackType{1} << BitsRich ) - BitPackType{1} ) << ShiftRich; + static constexpr const BitPackType MaskPixelSubRowIsSet = + ( BitPackType )( ( BitPackType{1} << BitsPixelSubRowIsSet ) - BitPackType{1} ) << ShiftPixelSubRowIsSet; + static constexpr const BitPackType MaskPixelColIsSet = + ( BitPackType )( ( BitPackType{1} << BitsPixelColIsSet ) - BitPackType{1} ) << ShiftPixelColIsSet; + static constexpr const BitPackType MaskPixelRowIsSet = + ( BitPackType )( ( BitPackType{1} << BitsPixelRowIsSet ) - BitPackType{1} ) << ShiftPixelRowIsSet; + static constexpr const BitPackType MaskPDIsSet = + ( BitPackType )( ( BitPackType{1} << BitsPDIsSet ) - BitPackType{1} ) << ShiftPDIsSet; + static constexpr const BitPackType MaskPanelIsSet = + ( BitPackType )( ( BitPackType{1} << BitsPanelIsSet ) - BitPackType{1} ) << ShiftPanelIsSet; + static constexpr const BitPackType MaskRichIsSet = + ( BitPackType )( ( BitPackType{1} << BitsRichIsSet ) - BitPackType{1} ) << ShiftRichIsSet; + static constexpr const BitPackType MaskLargePixel = + ( BitPackType )( ( BitPackType{1} << BitsLargePixel ) - BitPackType{1} ) << ShiftLargePixel; + + // Max values + static constexpr const DataType MaxPixelCol = ( DataType )( BitPackType{1} << BitsPixelCol ) - DataType{1}; + static constexpr const DataType MaxPixelRow = ( DataType )( BitPackType{1} << BitsPixelRow ) - DataType{1}; + static constexpr const DataType MaxPDNumInMod = ( DataType )( BitPackType{1} << BitsPDNumInMod ) - DataType{1}; + static constexpr const DataType MaxPDMod = ( DataType )( BitPackType{1} << BitsPDMod ) - DataType{1}; + static constexpr const DataType MaxPanel = ( DataType )( BitPackType{1} << BitsPanel ) - DataType{1}; + static constexpr const DataType MaxRich = ( DataType )( BitPackType{1} << BitsRich ) - DataType{1}; + + // Number of bits for the channel identification (i.e. excluding any time info) + // Currently use the lowest 32 bits for this. + static constexpr const BitPackType NChannelBits = 32; + + __host__ __device__ constexpr inline void setData( + const DataType value, + const BitPackType shift, + const BitPackType mask) noexcept { - m_key = ((static_cast(value) << shift) & mask) | (m_key & ~mask); + m_key = ((BitPackType{value} << shift) & mask) | (m_key & ~mask); } __host__ __device__ constexpr inline void setData( - const unsigned value, // - const unsigned shift, // - const unsigned mask, // - const unsigned okMask) noexcept + const DataType value, + const BitPackType shift, + const BitPackType mask, + const BitPackType okMask) noexcept { - m_key = ((static_cast(value) << shift) & mask) | (m_key & ~mask) | okMask; + m_key = ((BitPackType{value} << shift) & mask) | (m_key & ~mask) | okMask; } - __host__ __device__ constexpr inline uint64_t getData(const unsigned shift, const unsigned mask) const noexcept + __host__ __device__ constexpr inline BitPackType getData( + const BitPackType shift, + const BitPackType mask) const noexcept { return (m_key & mask) >> shift; } - __host__ __device__ constexpr inline auto key() const noexcept { return m_key; } + __host__ __device__ constexpr inline BitPackType key() const noexcept { return m_key; } __host__ __device__ constexpr inline bool operator==(const RichSmartID& other) const noexcept { return m_key == other.key(); } - /// ostream operator - __host__ friend std::ostream& operator<<(std::ostream& str, const RichSmartID& id) { return str << id.key(); } + __host__ __device__ constexpr inline auto isLargePMT() const noexcept + { + return 0 != getData(ShiftLargePixel, MaskLargePixel); + } + + __host__ __device__ constexpr inline auto rich() const noexcept { return getData(ShiftRich, MaskRich); } + + __host__ __device__ constexpr inline auto panel() const noexcept { return getData(ShiftPanel, MaskPanel); } + + __host__ __device__ constexpr inline DataType pdMod() const noexcept { return getData(ShiftPDMod, MaskPDMod); } + + __host__ __device__ constexpr inline DataType pdNumInMod() const noexcept + { + return getData(ShiftPDNumInMod, MaskPDNumInMod); + } + + __host__ __device__ constexpr inline DataType panelLocalModuleNum() const noexcept + { + return pdMod() - PanelModuleOffsets()[rich()][panel()]; + } + + __host__ __device__ constexpr inline DataType columnLocalModuleNum() const noexcept + { + return panelLocalModuleNum() % ModulesPerColumn; + } + + __host__ __device__ constexpr inline DataType numPMTsPerEC() const noexcept + { + return isLargePMT() ? HTypePMTsPerEC : RTypePMTsPerEC; + } + + __host__ __device__ constexpr inline DataType elementaryCell() const noexcept { return pdNumInMod() / numPMTsPerEC(); } + + __host__ __device__ constexpr inline DataType pdNumInEC() const noexcept { return pdNumInMod() % numPMTsPerEC(); } + + __host__ __device__ constexpr inline auto pixelColIsSet() const noexcept + { + return 0 != getData(ShiftPixelColIsSet, MaskPixelColIsSet); + } + + __host__ __device__ constexpr inline auto pixelRowIsSet() const noexcept + { + return 0 != getData(ShiftPixelRowIsSet, MaskPixelRowIsSet); + } + + [[nodiscard]] __host__ __device__ constexpr bool pdIsSet() const noexcept { + return 0 != ((key() & MaskPDIsSet ) >> ShiftPDIsSet); + } + + __host__ __device__ constexpr inline DataType pixelCol() const noexcept { return getData(ShiftPixelCol, MaskPixelCol); } + + __host__ __device__ constexpr inline DataType pixelRow() const noexcept { return getData(ShiftPixelRow, MaskPixelRow); } + + __host__ __device__ constexpr inline DataType anodeIndex() const noexcept + { + return pixelRow() * PixelsPerCol + PixelsPerRow - 1 - pixelCol(); + } + + __host__ __device__ constexpr inline bool adcTimeIsSet() const noexcept { + return (0 != (key() & MaPMT::MaskADCTimeIsSet) >> MaPMT::ShiftADCTimeIsSet); + } + + __host__ __device__ constexpr ADCTimeType adcTime() const { + return ((key() & MaPMT::MaskADCTime) >> MaPMT::ShiftADCTime); + } + + __host__ __device__ constexpr auto time() const noexcept { + return (MaPMT::MinTime + (adcTime() * MaPMT::ScaleADCToTime)); + } + + // ostream operator + __host__ friend std::ostream& operator<<(std::ostream& str, const RichSmartID& id) + { + const auto rich = id.rich(); + const auto panel = id.panel(); + str << "{ "; + str << "PMT"; + str << (id.isLargePMT() ? ":h " : ":r "); + str << (rich == 0 ? "Rich1 " : "Rich2 "); + if (rich == 0) { + str << (panel == 0 ? "Top " : "Bot "); + } + else { + str << (panel == 0 ? "L-A " : "R-C "); + } + str << "PD[Mod,NInMod]: "; + str << std::setfill('0') << std::setw(3) << id.pdMod() << ','; + str << std::setfill('0') << std::setw(2) << id.pdNumInMod() << ' '; + str << "Mod[Col,NInCol] "; + str << std::setfill('0') << std::setw(2) << id.panelLocalModuleNum() << ','; + str << std::setfill('0') << std::setw(2) << id.columnLocalModuleNum() << ' '; + str << " PD[EC,NInEC]: "; + str << id.elementaryCell() << ','; + str << id.pdNumInEC() << ' '; + + const auto pixColSet = id.pixelColIsSet(); + const auto pixRowSet = id.pixelRowIsSet(); + if (pixColSet || pixRowSet) { + if (pixColSet && pixRowSet) { + str << "Pix[Col,Row]: " << std::setfill('0') << std::setw(1) << id.pixelCol() << "," << id.pixelRow(); + } + else { + const auto fSPix = 2; + if (pixColSet) { + str << std::setfill('0') << std::setw(fSPix) << " pixCol" << id.pixelCol(); + } + if (pixRowSet) { + str << std::setfill('0') << std::setw(fSPix) << " pixRow" << id.pixelRow(); + } + } + // Include PMT derived info + if (pixColSet && pixRowSet) { + str << " Anode:" << std::setfill('0') << std::setw(2) << id.anodeIndex(); + } + } + str << " }\n"; + return str; + } + + public: + // Number of PMT pixels per row + static constexpr const DataType PixelsPerRow = 8; + // Number of PMT pixels per column + static constexpr const DataType PixelsPerCol = 8; + // Total number of PMT pixels + static constexpr const DataType TotalPixels = PixelsPerRow * PixelsPerCol; + // Number PMTs per EC for R type PMTs + static constexpr const DataType RTypePMTsPerEC = 4; + // Number PMTs per EC for H type PMTs + static constexpr const DataType HTypePMTsPerEC = 1; + // Number of ECs per module + static constexpr const DataType ECsPerModule = 4; + // Number of modules per column + static constexpr const DataType ModulesPerColumn = 6; + // Number of module columns per panel, in each RICH + static constexpr const std::array ModuleColumnsPerPanel = { + {11, 14} + }; + // Maximum number of module columns in any panel, RICH1 or RICH2 + static constexpr const DataType MaxModuleColumnsAnyPanel = std::max(ModuleColumnsPerPanel[0], ModuleColumnsPerPanel[1]); + // Number of modules per panel, in each RICH + static constexpr const std::array ModulesPerPanel{ + {(ModulesPerColumn * ModuleColumnsPerPanel[0]), (ModulesPerColumn * ModuleColumnsPerPanel[1])} + }; + + __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() { + return { + std::array{0, ModulesPerPanel[0]}, + std::array{2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]} + }; + } + + class MaPMT { + public: + static constexpr const DataType MaxPDsPerModule = 16; + static constexpr const DataType MaxModulesPerPanel = 92; + + // Bits for time field. + static constexpr const BitPackType BitsADCTime = 16; + static constexpr const BitPackType BitsADCTimeIsSet = 1; + static constexpr const BitPackType ShiftADCTime = NChannelBits; + static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; + static constexpr const BitPackType MaskADCTime = + ( BitPackType )( ( BitPackType{1} << BitsADCTime ) - BitPackType{1} ) << ShiftADCTime; + static constexpr const BitPackType MaskADCTimeIsSet = + ( BitPackType )( ( BitPackType{1} << BitsADCTimeIsSet ) - BitPackType{1} ) << ShiftADCTimeIsSet; + + // Max ADC time that can be stored + static constexpr const ADCTimeType MaxADCTime = ( ADCTimeType )( BitPackType{1} << BitsADCTime ) - ADCTimeType{1}; + + // Parameters for conversion between float and ADC time values + static constexpr const double MinTime = -50.0; // In nanoseconds + static constexpr const double MaxTime = 150.0; // In nanoseconds + static constexpr const double ScaleTimeToADC = MaxADCTime / ( MaxTime - MinTime ); + static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; + }; }; // namespace RichSmartID } // namespace Allen namespace Rich::Future::DAQ { enum DetectorType : std::int8_t { - InvalidDetector = -1, ///< Unspecified Detector - Rich1 = 0, ///< RICH1 detector - Rich2 = 1, ///< RICH2 detector - Rich = 1 ///< Single RICH detector + InvalidDetector = -1, //< Unspecified Detector + Rich1 = 0, //< RICH1 detector + Rich2 = 1, //< RICH2 detector + Rich = 1 //< Single RICH detector + }; + + // Detector side enum + enum Side : std::int8_t { + InvalidSide = -1, //< Invalid side + // RICH1 + top = 0, //< Upper panel in RICH1 + bottom = 1, //< Lower panel in RICH1 + // RICH2 + left = 0, //< Left panel in RICH2 + right = 1, //< Right panel in RICH2 + aside = 0, //< A-Side panel in RICH2 + cside = 1, //< C-Side panel in RICH2 + // Generic + firstSide = 0, //< Upper panel in RICH1 or Left panel in RICH2 + secondSide = 1 //< Lower panel in RICH1 or Right panel in RICH2 }; class PackedFrameSizes final { - public: - /// Packed type - using IntType = std::uint8_t; - - private: - // Bits for each Size - static const IntType Bits0 = 4; - static const IntType Bits1 = 4; - // shifts - static const IntType Shift0 = 0; - static const IntType Shift1 = Shift0 + Bits0; - // masks - static const IntType Mask0 = (IntType)((1 << Bits0) - 1) << Shift0; - static const IntType Mask1 = (IntType)((1 << Bits1) - 1) << Shift1; - // max values - static const IntType Max0 = (1 << Bits0) - 1; - static const IntType Max1 = (1 << Bits1) - 1; + public: + // Packed type + using IntType = std::uint8_t; - public: - /// Contructor from a single word - __host__ __device__ explicit PackedFrameSizes(const IntType d) : m_data(d) {} + private: + // Bits for each Size + static const IntType Bits0 = 4; + static const IntType Bits1 = 4; + // shifts + static const IntType Shift0 = 0; + static const IntType Shift1 = Shift0 + Bits0; + // masks + static const IntType Mask0 = (IntType)((1 << Bits0) - 1) << Shift0; + static const IntType Mask1 = (IntType)((1 << Bits1) - 1) << Shift1; + // max values + static const IntType Max0 = (1 << Bits0) - 1; + static const IntType Max1 = (1 << Bits1) - 1; + + public: + // Contructor from a single word + __host__ __device__ explicit PackedFrameSizes(const IntType d) : m_data(d) {} - /// Get the overall data - __host__ __device__ inline IntType data() const noexcept { return m_data; } + // Get the overall data + __host__ __device__ inline IntType data() const noexcept { return m_data; } - /// Get first size word - __host__ __device__ inline IntType size0() const noexcept { return ((data() & Mask0) >> Shift0); } + // Get first size word + __host__ __device__ inline IntType size0() const noexcept { return ((data() & Mask0) >> Shift0); } - /// Get second size word - __host__ __device__ inline IntType size1() const noexcept { return ((data() & Mask1) >> Shift1); } + // Get second size word + __host__ __device__ inline IntType size1() const noexcept { return ((data() & Mask1) >> Shift1); } - /// Get the total size - __host__ __device__ inline auto totalSize() const noexcept { return size0() + size1(); } + // Get the total size + __host__ __device__ inline auto totalSize() const noexcept { return size0() + size1(); } - private: - /// The data word - IntType m_data {0}; + private: + // The data word + IntType m_data {0}; }; } // namespace Rich::Future::DAQ diff --git a/device/rich/decoding/include/RichMakePixels.cuh b/device/rich/decoding/include/RichMakePixels.cuh new file mode 100644 index 00000000000..b6bdebcfb48 --- /dev/null +++ b/device/rich/decoding/include/RichMakePixels.cuh @@ -0,0 +1,40 @@ +/*****************************************************************************\ + * (c) Copyright 2018-2020 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "LICENSE". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once + +#include "AlgorithmTypes.cuh" +#include +#include +#include +namespace rich_make_pixels { + struct Parameters { + HOST_INPUT(host_rich_total_number_of_hits_t, unsigned) host_rich_total_number_of_hits; + MASK_INPUT(dev_event_list_t) dev_event_list; + DEVICE_INPUT(dev_smart_ids_t, Allen::RichSmartID) dev_smart_ids; + DEVICE_INPUT(dev_rich_hit_offsets_t, unsigned) dev_rich_hit_offsets; + DEVICE_OUTPUT(dev_rich_hits_t, char) dev_rich_hits; + DEVICE_OUTPUT(dev_rich_pixels_t, Allen::RichPixel) dev_rich_pixels; + }; + + struct rich_make_pixels_t : public DeviceAlgorithm, Parameters { + void set_arguments_size(ArgumentReferences, const RuntimeOptions&, const Constants&) const; + + void operator()( + const ArgumentReferences&, + const RuntimeOptions&, + const Constants&, + const Allen::Context&) const; + + private: + Allen::Property m_block_dim {this, "block_dim", {64,1,1}, "block dimensions"}; + Allen::Property m_current_rich {this, "current_rich", 1, "current rich"}; + }; +} // namespace rich_make_pixels diff --git a/device/rich/decoding/include/RichPD.cuh b/device/rich/decoding/include/RichPD.cuh new file mode 100644 index 00000000000..c2c6f5cb9d2 --- /dev/null +++ b/device/rich/decoding/include/RichPD.cuh @@ -0,0 +1,112 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ + +#pragma once + +#include +#include + +namespace Rich::Detector::Allen { + class PD final { + using FP = ::Allen::FP; + using Point = ::Allen::Point; + + public: + /// Default constructor + __host__ __device__ PD() = default; + /// Copy assignment operator + __host__ __device__ PD& operator=(const PD&) = default; + /// Copy Constructor + __host__ __device__ PD( const PD& pd ) + : m_locToGloM( pd.m_locToGloM ) + , m_zeroInPanelFrame(pd.m_zeroInPanelFrame) + , m_pdSmartID( pd.m_pdSmartID ) + , m_effPixelArea( pd.m_effPixelArea ) + , m_numPixels( pd.m_numPixels ) + , m_localZcoord( pd.m_localZcoord) + , m_NumPixColFrac( pd.m_NumPixColFrac ) + , m_NumPixRowFrac( pd.m_NumPixRowFrac ) + , m_EffectivePixelXSize( pd.m_EffectivePixelXSize ) + , m_EffectivePixelYSize( pd.m_EffectivePixelYSize ) + , m_isHType( pd.m_isHType ) + , m_isNull( pd.m_isNull ){ + } + + __host__ __device__ inline auto pdSmartID() const { return m_pdSmartID; } + + __host__ __device__ inline auto detectionPoint(const ::Allen::RichSmartID id) const noexcept + { + const auto fPixCol = id.pixelCol(); + const auto fPixRow = id.pixelRow(); + const auto xh = (fPixCol - m_NumPixColFrac) * m_EffectivePixelXSize; + const auto yh = (fPixRow - m_NumPixRowFrac) * m_EffectivePixelYSize; + return ::Allen::transform3DTimesPoint(localToGlobal(), Point{xh, yh, m_localZcoord}); + } + + __host__ __device__ inline float get_EffectivePixelXSize() const noexcept {return m_EffectivePixelXSize;} + __host__ __device__ inline float get_EffectivePixelYSize() const noexcept {return m_EffectivePixelYSize;} + __host__ __device__ inline float get_localZcoord() const noexcept {return m_localZcoord;} + __host__ __device__ inline float get_NumPixRowFrac() const { return m_NumPixRowFrac; } + + /// Effective pixel area + __host__ __device__ inline auto effectivePixelArea() const noexcept { return m_effPixelArea; } + + __host__ __device__ inline float get_NumPixColFrac() const noexcept {return m_NumPixColFrac;} + + /// Access the local to global transform + __host__ __device__ inline const std::array& localToGlobal() const noexcept { return m_locToGloM; } + + std::string toString() const { + std::ostringstream oss; + oss << "PD { " + << "m_locToGloM: " + << m_locToGloM[0] << " " << m_locToGloM[1] << " " << m_locToGloM[2] << " " + << m_locToGloM[3] << " " << m_locToGloM[4] << " " << m_locToGloM[5] << " " + << m_locToGloM[6] << " " << m_locToGloM[7] << " " << m_locToGloM[8] << " " + << m_locToGloM[9] << " " << m_locToGloM[10] << " " << m_locToGloM[11] << " " << ", " + << "m_zeroInPanelFrame: " << m_zeroInPanelFrame[0] << m_zeroInPanelFrame[1] << m_zeroInPanelFrame[2] << ", " + << "effPixelArea: " << m_effPixelArea << ", " + << "numPixels: " << m_numPixels << ", " + << "localZcoord: " << m_localZcoord << ", " + << "NumPixColFrac: " << m_NumPixColFrac << ", " + << "NumPixRowFrac: " << m_NumPixRowFrac << ", " + << "EffectivePixelXSize: " << m_EffectivePixelXSize << ", " + << "EffectivePixelYSize: " << m_EffectivePixelYSize << ", " + << "pdSmartID: " << m_pdSmartID << ", " + << "isHType: " << (m_isHType ? "true" : "false") + << "isNull: " << (m_isNull ? "true" : "false") + << " }"; + return oss.str(); + } + + __host__ __device__ bool getIsNull() const { + return m_isNull; + } + + __host__ __device__ void setIsNull(bool value){ + m_isNull = value; + } + + private: + std::array m_locToGloM; + std::array m_zeroInPanelFrame; + std::uint64_t m_pdSmartID; + float m_effPixelArea {0.f}; + float m_numPixels {0.f}; + float m_localZcoord {0.f}; + float m_NumPixColFrac {0.f}; + float m_NumPixRowFrac {0.f}; + float m_EffectivePixelXSize {0.f}; + float m_EffectivePixelYSize {0.f}; + bool m_isHType {false}; + bool m_isNull {false}; + }; +} // namespace Rich::Detector::Allen diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh new file mode 100644 index 00000000000..44560cdfaeb --- /dev/null +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -0,0 +1,110 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include +#include +#include + +namespace Allen { + class PDPanel final { + public: + PDPanel() { } + + using PDsArray = std::array; + using ModuleArray = std::array; + + PDPanel( + Rich::Future::DAQ::DetectorType rich, + Rich::Future::DAQ::Side side, + std::array gloToPDPanelM, + ModuleArray PDs + ) : m_PDs(std::move(PDs)), + m_gloToPDPanelM(gloToPDPanelM), + m_panelID({rich, side, 0}), + m_rich(rich), + m_side(side) { } + + PDPanel(const PDPanel& other) + : m_gloToPDPanelM(other.m_gloToPDPanelM), + m_panelID(other.m_panelID), + m_rich(other.m_rich), + m_side(other.m_side) { + for (size_t i = 0; i < other.m_PDs.size(); ++i) { + for (size_t j = 0; j < other.m_PDs[i].size(); ++j) { + if (!(other.m_PDs[i][j].getIsNull())) { + m_PDs[i][j] = Rich::Detector::Allen::PD(other.m_PDs[i][j]); + } else { + m_PDs[i][j] = Rich::Detector::Allen::PD(); + m_PDs[i][j].setIsNull(true); + } + } + } + } + + /// Access the RICH detector type + __host__ __device__ inline auto rich() const noexcept { return m_rich; } + + /// Access the PD panel side + __host__ __device__ inline auto side() const noexcept { return m_side; } + + __host__ __device__ auto dePD(const RichSmartID smartID) const { + const Rich::Detector::Allen::PD* dePD = nullptr; + if (smartID.pdIsSet()) { + const auto localModNum = smartID.pdMod() - m_modNumOffset; + if (localModNum < pdModules().size()) { + const auto& mod = pdModules()[localModNum]; + if (smartID.pdNumInMod() < mod.size()) { + const auto& pd = mod[smartID.pdNumInMod()]; + dePD = &pd; + } + } + } + return dePD; + } + + /// Compute the detection point for a given RichSmartID + __host__ __device__ inline auto detectionPoint( const RichSmartID id ) const noexcept { + const auto pd = dePD( id ); + return ( pd ? pd->detectionPoint( id ) : Allen::Point{0,0,0} ); + } + + /// Access the global to local transform + __host__ __device__ inline const auto& globalToPDPanel() const noexcept { return m_gloToPDPanelM; } + + /// Access all owned PD Modules + __host__ __device__ const ModuleArray& pdModules() const noexcept { return m_PDs; } + + std::string toString() const { + std::stringstream ss; + for (size_t i = 0; i < m_PDs.size(); ++i) { + ss << "RICH " << (int)m_rich << ", Side " << (int)m_side << ", Module No. " << i << ", PDs: "; + for (size_t j = 0; j < m_PDs[i].size(); ++j) { + if (!(m_PDs[i][j].getIsNull())) { + auto pd = m_PDs[i][j]; + ss << pd.toString() << '\n'; + } else { + ss << " 0\n"; + } + } + ss << "\n"; + } + return ss.str(); + } + + private: + ModuleArray m_PDs; + std::array m_gloToPDPanelM; // 3D Transform + uint32_t m_modNumOffset; + std::array m_panelID; + Rich::Future::DAQ::DetectorType m_rich; + Rich::Future::DAQ::Side m_side; + }; +} diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh new file mode 100644 index 00000000000..119f31e9223 --- /dev/null +++ b/device/rich/decoding/include/RichPixels.cuh @@ -0,0 +1,122 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include + +namespace Allen { + class RichPixel { + + public: + + // Default + __host__ __device__ RichPixel() : + gPos({0.0f, 0.0f, 0.0f}), + lPos({0.0f, 0.0f, 0.0f}), + m_smartID(), + m_effArea(0.0f), + m_rich(0), + m_side(0), + m_mask(0), + m_timeWindow(0.0f), + m_isInnerRegion(true), + m_isNull(true) {} + + // 3D + __host__ __device__ RichPixel( + const Point& gPos, + const Point& lPos, + const Allen::RichSmartID& smartID, + double effArea, + uint8_t rich, + uint8_t side, + uint8_t mask): + gPos(gPos), lPos(lPos), + m_smartID(smartID), + m_effArea(effArea), + m_rich(rich), + m_side(side), + m_mask(mask), + m_isNull(false) { + m_isInnerRegion = !smartID.isLargePMT(); + } + + // 4D + __host__ __device__ RichPixel( + const Point& gPos, + const Point& lPos, + const Allen::RichSmartID& smartID, + double effArea, + uint8_t rich, + uint8_t side, + uint8_t mask, + float timeWindow): + gPos(gPos), + lPos(lPos), + m_smartID(smartID), + m_effArea(effArea), + m_rich(rich), + m_side(side), + m_mask(mask), + m_timeWindow(timeWindow), + m_isNull(false) { + m_isInnerRegion = !smartID.isLargePMT(); + } + + __host__ __device__ inline void overrideRegions(const bool isInnerRegion ) noexcept { m_isInnerRegion = isInnerRegion; } + + __host__ __device__ inline auto rich() const { return m_rich; } + + __host__ __device__ inline auto side() const { return m_side; } + + __host__ __device__ inline Allen::RichSmartID smartID() const { return m_smartID; } + + __host__ __device__ inline auto gloPos() const { return gPos; } + + __host__ __device__ inline auto locPos() const { return lPos; } + + __host__ __device__ inline auto effArea() const { return m_effArea; } + + __host__ __device__ inline auto mask() const { return m_mask; } + + __host__ __device__ inline auto timeWindow() const { return m_timeWindow; } + + __host__ __device__ inline auto isInnerRegion() const { return m_isInnerRegion; } + + __host__ __device__ inline auto isNull() const { return m_isNull; } + + std::string toString() { + std::stringstream ss; + if (m_smartID.key() == 0) return "SmartID key is 0"; + ss << m_smartID.key() << ',' + << gPos[0] << ',' << gPos[1] << ',' << gPos[2] << ',' + << lPos[0] << ',' << lPos[1] << ',' << lPos[2] << ',' + << m_effArea << ',' + << (int)m_rich << ',' << (int)m_side << ',' + << (int)m_mask << ',' + << m_timeWindow << ',' + << m_isInnerRegion << ',' + << m_isNull << '\n'; + return ss.str(); + } + + private: + Point gPos; + Point lPos; + Allen::RichSmartID m_smartID; + double m_effArea; + uint8_t m_rich; + uint8_t m_side; + uint8_t m_mask; + float m_timeWindow; + bool m_isInnerRegion; + bool m_isNull; + }; +} // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDs.cuh b/device/rich/decoding/include/RichSmartIDs.cuh new file mode 100644 index 00000000000..00a06524e7b --- /dev/null +++ b/device/rich/decoding/include/RichSmartIDs.cuh @@ -0,0 +1,84 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include +#include +#include +#include + +#define PANEL_COUNT 2 + +namespace Allen { + class RichSmartIDs { + public: + /// Constructor from RICH detector elements + RichSmartIDs( + const Allen::PDPanel& pdPanel1, + const Allen::PDPanel& pdPanel2) + : m_pdPanels{&pdPanel1, &pdPanel2} { } + + RichSmartIDs(const std::array m_pdPanels) + : m_pdPanels{m_pdPanels} { } + + __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Allen::PDPanel* { + using DetectorType = Rich::Future::DAQ::DetectorType; + using Side = Rich::Future::DAQ::Side; + + // Determine the rich type + DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; + // Determine the side + Side side; + if (rich == DetectorType::Rich1) { + // For Rich1, 0 = top, 1 = bottom + side = (smartID.panel() == 0) ? Side::top : Side::bottom; + } else { + // For Rich2, 0 = left, 1 = right + side = (smartID.panel() == 0) ? Side::left : Side::right; + } + + for (size_t i = 0; i < m_pdPanels.size(); i++) { + const Allen::PDPanel* pdPanel = m_pdPanels[i]; + if (pdPanel->rich() == rich && pdPanel->side() == side) { + return pdPanel; + } + } + return nullptr; + } + + __host__ __device__ inline auto panel( + const Rich::Future::DAQ::DetectorType rtype, + const Rich::Future::DAQ::Side side ) const -> const Allen::PDPanel* { + for (size_t i = 0;i < m_pdPanels.size(); i++) { + const Allen::PDPanel* pdPanel = m_pdPanels[i]; + if (pdPanel->rich() == rtype && pdPanel->side() == side) { + return pdPanel; + } + } + return nullptr; + } + + // Converts an PD RichSmartID identification into a position in global LHCb coordinates. + __host__ __device__ Point pdPosition( const Allen::RichSmartID pdid ) const; + + // Converts a position in global coordinates to the corresponding RichSmartID + __host__ __device__ bool smartID( const Point& globalPoint, Allen::RichSmartID& smartid ) const; + + // Converts a position in global coordinates to the local coordinate system. + __host__ __device__ Point globalToPDPanel( const Point& globalPoint ) const; + + // Get the position for a given SmartID. + __host__ __device__ inline auto _globalPosition( const Allen::RichSmartID id ) const { + return panel(id)->detectionPoint(id); + } + private: + const std::array m_pdPanels; + }; +} diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index ec1761452a5..b49cbf19dfd 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -440,7 +440,7 @@ void rich_decoding::rich_decoding_t::operator()( Allen::memset_async(arguments, 0, context); global_function( runtime_options.mep_layout ? rich_calculate_number_of_hits : rich_calculate_number_of_hits)( - dim3(size(arguments)), dim3(m_block_dim_x), context)( + dim3(size(arguments)), m_block_dim, context)( arguments, std::get<0>(runtime_options.event_interval), cable_mapping, pdmdb_mapping); PrefixSum::prefix_sum(*this, arguments, context); @@ -452,7 +452,7 @@ void rich_decoding::rich_decoding_t::operator()( resize(arguments, first(arguments)); global_function(runtime_options.mep_layout ? rich_decoding_kernel : rich_decoding_kernel)( - dim3(size(arguments)), dim3(m_block_dim_x), context)( + dim3(size(arguments)), m_block_dim, context)( arguments, std::get<0>(runtime_options.event_interval), cable_mapping, diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu new file mode 100644 index 00000000000..047539b3b63 --- /dev/null +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -0,0 +1,148 @@ +/*****************************************************************************\ + * (c) Copyright 2018-2020 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "LICENSE". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +INSTANTIATE_ALGORITHM(rich_make_pixels::rich_make_pixels_t); + +/// Enabled 4D reconstruction +__constant__ std::array m_enable4D{false, false}; + +/// Average expected hit time for signal in each RICH in ns +__constant__ std::array m_avHitTime{13.03, 52.94}; + +/// Course (pixel) Time window for each RICH in ns +__constant__ std::array m_timeWindow{3.0, 3.0}; + +/// Enable the override of inner and out regions +__constant__ std::array m_overrideRegions{false, false}; + +/// Size in X defining the inner pixels for each RICH +__constant__ std::array m_innerPixX{250.0, 99999.9}; + +/// Size in Y defining the inner pixels for each RICH +__constant__ std::array m_innerPixY{300.0, 300.0}; + +/// Time resolution for inner regions in ns +__constant__ std::array m_innerTimeWindow{0.15, 0.15}; + +/// Time resolution for outer regions in ns +__constant__ std::array m_outerTimeWindow{0.3, 0.3}; + +__device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, const Allen::RichSmartID& smartID) +{ + float effArea; // Effective area + uint8_t mask = 0; // Selection mask + bool innerRegion = 1; // Inner/outer region + + const auto rich = smartID.rich(); + const auto side = smartID.panel(); + + // Functor to save a Rich pixel + auto savePix = [&]() { + const auto gPos = smartIDsHelper->_globalPosition(smartID); + const auto lPos = smartIDsHelper->globalToPDPanel(gPos); + const auto isInner = ( m_overrideRegions[rich] ? + ( abs( lPos[0] ) < float( m_innerPixX[rich] ) && + abs( lPos[1] ) < float( m_innerPixY[rich] ) ) + : innerRegion ); + + Allen::RichPixel pixel; + + // 4D specific properties + float timeWindow = 999999; + if ( m_enable4D[rich] ) { + timeWindow = isInner ? float( m_innerTimeWindow[rich] ) : float( m_outerTimeWindow[rich] ); + } + pixel = Allen::RichPixel(gPos, lPos, smartID, effArea, rich, side, mask, timeWindow); + if ( m_overrideRegions[rich] ) { pixel.overrideRegions( isInner ); } + return pixel; + }; + + bool smartIDSelected = true; + if ( m_enable4D[rich] ) { + if ( smartID.adcTimeIsSet() ) { + const auto hitT = smartID.time(); + if ( fabs( hitT - m_avHitTime[rich] ) > m_timeWindow[rich] ) { + smartIDSelected = false; + } + } + } + + if ( smartIDSelected ) { + if ((smartIDsHelper->panel(smartID)->dePD(smartID))){ + if (!(smartIDsHelper->panel(smartID)->dePD(smartID)->getIsNull())){ + effArea = smartIDsHelper->panel(smartID)->dePD(smartID)->effectivePixelArea(); + innerRegion = !smartID.isLargePMT(); + return savePix(); + } + } + } + return Allen::RichPixel(); +} + +__global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Allen::RichSmartIDs* smartIDsHelper) +{ + const auto eventNumber = parameters.dev_event_list[blockIdx.x]; + auto eventSmartIDCount = parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; + for (unsigned smartID = threadIdx.x; smartID < eventSmartIDCount; smartID += blockDim.x) { + parameters.dev_rich_pixels[smartID] = make_pixel(smartIDsHelper, parameters.dev_smart_ids[smartID]); + } +} + +void rich_make_pixels::rich_make_pixels_t::set_arguments_size( + ArgumentReferences arguments, + const RuntimeOptions&, + const Constants&) const +{ + set_size(arguments, size(arguments)); +} + +void rich_make_pixels::rich_make_pixels_t::operator()( + const ArgumentReferences& arguments, + const RuntimeOptions&, + const Constants& constants, + const Allen::Context& context) const +{ + // Create RICH objects from dump + Allen::Rich1* rich1; + Allen::Rich2* rich2; + const auto richValue = m_current_rich; + if (richValue == 1) + rich1 = reinterpret_cast(constants.dev_rich_1_geometry); + else + rich2 = reinterpret_cast(constants.dev_rich_2_geometry); + + // Send panels from RICH to SmartIDsHelper + std::array panels; + for (size_t i = 0; i < 2; i++) { + if (richValue == 1) + panels[i] = &(rich1->pdPanels()[i]); + else + panels[i] = &(rich2->pdPanels()[i]); + } + + Allen::RichSmartIDs smartIDsHelper = Allen::RichSmartIDs(panels); + Allen::RichSmartIDs* dev_smartIDsHelper; + Allen::malloc((void**)&dev_smartIDsHelper, sizeof(Allen::RichSmartIDs)); + Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDs), Allen::memcpyHostToDevice); + + global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim,context)( + arguments, dev_smartIDsHelper + ); + Allen::free(dev_smartIDsHelper); +} diff --git a/device/rich/decoding/src/RichSmartIDs.cu b/device/rich/decoding/src/RichSmartIDs.cu new file mode 100644 index 00000000000..2bda3dc9a2d --- /dev/null +++ b/device/rich/decoding/src/RichSmartIDs.cu @@ -0,0 +1,45 @@ +/*****************************************************************************\ +* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the Apache License * +* version 2 (Apache-2.0), copied verbatim in the file "COPYING". * +* * +* In applying this licence, CERN does not waive the privileges and immunities * +* granted to it by virtue of its status as an Intergovernmental Organization * +* or submit itself to any jurisdiction. * +\*****************************************************************************/ + +#include +#include + +using Point = Allen::Point; + +Point Allen::RichSmartIDs::pdPosition( const Allen::RichSmartID pdid ) const { + // Create temporary RichSmartIDs for two corners of the PD wafer + Allen::RichSmartID id1( pdid ), id0( pdid ); + id0.setPixelRow( 1 ); + id0.setPixelCol( 1 ); + id1.setPixelRow( 6 ); + id1.setPixelCol( 6 ); + // Get position of each of these pixels + const auto a = _globalPosition( id0 ); + const auto b = _globalPosition( id1 ); + // Return average position (i.e. PD centre) + return Point{0.5f * ( a[0] + b[0] ), // + 0.5f * ( a[1] + b[1] ), // + 0.5f * ( a[2] + b[2] )}; +} + +// Converts a point from the global frame to the detector panel frame +Point Allen::RichSmartIDs::globalToPDPanel( const Point& globalPoint ) const { + return ( globalPoint[2] < 8000.f ? + // RICH1 + ( globalPoint[1] > 0.f ? + Allen::transform3DTimesPoint(panel( Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::top )->globalToPDPanel(), globalPoint) + : Allen::transform3DTimesPoint(panel( Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::bottom )->globalToPDPanel(), globalPoint) ) + : + // RICH2 + ( globalPoint[0] > 0.f ? + Allen::transform3DTimesPoint(panel( Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::left )->globalToPDPanel(), globalPoint) + : Allen::transform3DTimesPoint(panel( Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::right )->globalToPDPanel(), globalPoint )) ); +} diff --git a/integration/non_event_data/src/Updater.cpp b/integration/non_event_data/src/Updater.cpp index c63b72d4c6b..7c37280f129 100644 --- a/integration/non_event_data/src/Updater.cpp +++ b/integration/non_event_data/src/Updater.cpp @@ -65,7 +65,9 @@ namespace Allen { tuple {NonEventData::MuonGeometry {}, std::string("muon_geometry.bin")}, tuple {NonEventData::MuonLookupTables {}, std::string("muon_tables.bin")}, tuple {NonEventData::RichPDMDBMapping {}, std::string("rich_pdmdbmaps.bin")}, - tuple {NonEventData::RichCableMapping {}, std::string("rich_tel40maps.bin")}}; + tuple {NonEventData::RichCableMapping {}, std::string("rich_tel40maps.bin")}, + tuple {NonEventData::Rich1Geometry {}, std::string("rich_1_geometry.bin")}, + tuple {NonEventData::Rich2Geometry {}, std::string("rich_2_geometry.bin")}}; for_each(producers, [this, &geometry_producer](const auto& p) { using id_t = typename std::remove_reference_t(p))>; diff --git a/main/src/RegisterConsumers.cpp b/main/src/RegisterConsumers.cpp index 4eeee89dfd6..c9a8c496094 100644 --- a/main/src/RegisterConsumers.cpp +++ b/main/src/RegisterConsumers.cpp @@ -89,6 +89,19 @@ void register_consumers( constants.host_rich_cable_mapping, constants.dev_rich_cable_mapping); }, BankTypes::Rich1), + std::make_tuple( + Allen::NonEventData::RichPDMDBMapping {}, + [&constants]() { + return std::make_unique( + constants.host_rich_pdmdb_mapping, constants.dev_rich_pdmdb_mapping); + }, + BankTypes::Rich1), + std::make_tuple( + Allen::NonEventData::Rich1Geometry {}, + [&constants]() { + return std::make_unique(constants.host_rich_1_geometry, constants.dev_rich_1_geometry); + }, + BankTypes::Rich1), std::make_tuple( Allen::NonEventData::RichPDMDBMapping {}, [&constants]() { @@ -102,6 +115,12 @@ void register_consumers( return std::make_unique( constants.host_rich_cable_mapping, constants.dev_rich_cable_mapping); }, + BankTypes::Rich2), + std::make_tuple( + Allen::NonEventData::Rich2Geometry {}, + [&constants]() { + return std::make_unique(constants.host_rich_2_geometry, constants.dev_rich_2_geometry); + }, BankTypes::Rich2)); const auto unconditional_consumers = std::make_tuple( diff --git a/out.txt b/out.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/stream/sequence/include/Constants.cuh b/stream/sequence/include/Constants.cuh index df9da96e337..75cf748b7ce 100644 --- a/stream/sequence/include/Constants.cuh +++ b/stream/sequence/include/Constants.cuh @@ -46,7 +46,11 @@ namespace TrackMatchingConsts { namespace Rich::Future::DAQ::Allen { class PDMDBDecodeMapping; class Tel40CableMapping; -} // namespace Rich::Future::DAQ::Allen +} +namespace Allen { + class Rich1; + class Rich2; +} namespace UT::Constants { struct UTLayerGeometry; @@ -154,8 +158,13 @@ struct Constants { // Rich std::vector host_rich_pdmdb_mapping; std::vector host_rich_cable_mapping; + std::vector host_rich_1_geometry; + std::vector host_rich_2_geometry; + char* dev_rich_pdmdb_mapping; char* dev_rich_cable_mapping; + char* dev_rich_1_geometry; + char* dev_rich_2_geometry; /** * @brief Reserves and initializes constants. -- GitLab From eb2c2bfbb18a5afa5248bf83139fa34933774e23 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Wed, 26 Mar 2025 18:31:30 +0100 Subject: [PATCH 02/92] fix formatting --- .../BinaryDumpers/src/DumpRich1Geometry.cpp | 45 +-- .../BinaryDumpers/src/DumpRich2Geometry.cpp | 45 +-- Rec/Allen/src/TestAllenRichMakePixels.cpp | 201 +++++------ configuration/python/AllenConf/HLT1.py | 4 +- .../python/AllenConf/hlt1_reconstruction.py | 15 +- .../python/AllenConf/rich_make_pixels.py | 10 +- .../python/AllenConf/rich_reconstruction.py | 12 +- configuration/python/AllenSequences/rich.py | 9 +- device/rich/decoding/include/Rich1.cuh | 30 +- device/rich/decoding/include/Rich2.cuh | 30 +- device/rich/decoding/include/RichDecoding.cuh | 2 +- .../rich/decoding/include/RichDefinitions.cuh | 322 +++++++++--------- .../rich/decoding/include/RichMakePixels.cuh | 14 +- device/rich/decoding/include/RichPD.cuh | 84 ++--- device/rich/decoding/include/RichPDPanel.cuh | 193 +++++------ device/rich/decoding/include/RichPixels.cuh | 189 +++++----- device/rich/decoding/include/RichSmartIDs.cuh | 135 ++++---- device/rich/decoding/src/RichMakePixels.cu | 75 ++-- device/rich/decoding/src/RichSmartIDs.cu | 74 ++-- main/src/RegisterConsumers.cpp | 6 +- stream/sequence/include/Constants.cuh | 4 +- 21 files changed, 753 insertions(+), 746 deletions(-) diff --git a/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp b/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp index 848e12d2245..7b90d437aab 100644 --- a/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp +++ b/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp @@ -34,7 +34,7 @@ #include "Dumper.h" #include -namespace { +namespace { #ifdef USE_DD4HEP inline const std::string RichGeoCond = DeRichLocations::Rich1Path; #else @@ -43,48 +43,51 @@ namespace { struct Rich1Geometry_t { Rich1Geometry_t() = default; - Rich1Geometry_t(std::vector& data, const Rich::Detector::Rich1& rich_1) { + Rich1Geometry_t(std::vector& data, const Rich::Detector::Rich1& rich_1) + { Rich::Detector::Allen::Rich1 allenRich1 {rich_1}; DumpUtils::Writer output {}; output.write(allenRich1); data = output.buffer(); } - }; + }; } // namespace /** * @brief Dump RICH detector object information. */ -class DumpRich1Geometry final -: public Allen::Dumpers::Dumper> -{ - public: - DumpRich1Geometry(const std::string& name, ISvcLocator* svcLoc); - void operator()(const Rich1Geometry_t& RichGeo) const override; - StatusCode initialize() override; +class DumpRich1Geometry final + : public Allen::Dumpers::Dumper> { +public: + DumpRich1Geometry(const std::string& name, ISvcLocator* svcLoc); + void operator()(const Rich1Geometry_t& RichGeo) const override; + StatusCode initialize() override; - private: - std::vector m_data; +private: + std::vector m_data; }; DECLARE_COMPONENT(DumpRich1Geometry) - DumpRich1Geometry::DumpRich1Geometry(const std::string& name, ISvcLocator* svcLoc) : - Dumper(name, svcLoc, {KeyValue {"Rich1GeometryLocation", location(name, "rich1Geometry")}}) +DumpRich1Geometry::DumpRich1Geometry(const std::string& name, ISvcLocator* svcLoc) : + Dumper(name, svcLoc, {KeyValue {"Rich1GeometryLocation", location(name, "rich1Geometry")}}) {} StatusCode DumpRich1Geometry::initialize() { return Dumper::initialize().andThen([&, this] { - register_producer(Allen::NonEventData::Rich1Geometry::id, "rich_1_geometry", m_data); - Rich::Detector::Rich1::addConditionDerivation(this); - addConditionDerivation({Rich::Detector::Rich1::DefaultConditionKey},inputLocation(), [&](const Rich::Detector::Rich1& det) { - auto Rich1Geo = Rich1Geometry_t {m_data, det}; - dump(); - return Rich1Geo; - }); + register_producer(Allen::NonEventData::Rich1Geometry::id, "rich_1_geometry", m_data); + Rich::Detector::Rich1::addConditionDerivation(this); + addConditionDerivation( + {Rich::Detector::Rich1::DefaultConditionKey}, + inputLocation(), + [&](const Rich::Detector::Rich1& det) { + auto Rich1Geo = Rich1Geometry_t {m_data, det}; + dump(); + return Rich1Geo; }); + }); } void DumpRich1Geometry::operator()(const Rich1Geometry_t&) const {} diff --git a/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp b/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp index 901fa308be9..c76b0c6888e 100644 --- a/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp +++ b/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp @@ -34,7 +34,7 @@ #include "Dumper.h" #include -namespace { +namespace { #ifdef USE_DD4HEP inline const std::string RichGeoCond = DeRichLocations::Rich2Path; #else @@ -43,48 +43,51 @@ namespace { struct Rich2Geometry_t { Rich2Geometry_t() = default; - Rich2Geometry_t(std::vector& data, const Rich::Detector::Rich2& rich_2) { + Rich2Geometry_t(std::vector& data, const Rich::Detector::Rich2& rich_2) + { Rich::Detector::Allen::Rich2 allenRich2 {rich_2}; DumpUtils::Writer output {}; output.write(allenRich2); data = output.buffer(); } - }; + }; } // namespace /** * @brief Dump RICH detector object information. */ -class DumpRich2Geometry final -: public Allen::Dumpers::Dumper> -{ - public: - DumpRich2Geometry(const std::string& name, ISvcLocator* svcLoc); - void operator()(const Rich2Geometry_t& RichGeo) const override; - StatusCode initialize() override; +class DumpRich2Geometry final + : public Allen::Dumpers::Dumper> { +public: + DumpRich2Geometry(const std::string& name, ISvcLocator* svcLoc); + void operator()(const Rich2Geometry_t& RichGeo) const override; + StatusCode initialize() override; - private: - std::vector m_data; +private: + std::vector m_data; }; DECLARE_COMPONENT(DumpRich2Geometry) - DumpRich2Geometry::DumpRich2Geometry(const std::string& name, ISvcLocator* svcLoc) : - Dumper(name, svcLoc, {KeyValue {"Rich2GeometryLocation", location(name, "rich2Geometry")}}) +DumpRich2Geometry::DumpRich2Geometry(const std::string& name, ISvcLocator* svcLoc) : + Dumper(name, svcLoc, {KeyValue {"Rich2GeometryLocation", location(name, "rich2Geometry")}}) {} StatusCode DumpRich2Geometry::initialize() { return Dumper::initialize().andThen([&, this] { - register_producer(Allen::NonEventData::Rich2Geometry::id, "rich_2_geometry", m_data); - Rich::Detector::Rich2::addConditionDerivation(this); - addConditionDerivation({Rich::Detector::Rich2::DefaultConditionKey},inputLocation(), [&](const Rich::Detector::Rich2& det) { - auto Rich2Geo = Rich2Geometry_t {m_data, det}; - dump(); - return Rich2Geo; - }); + register_producer(Allen::NonEventData::Rich2Geometry::id, "rich_2_geometry", m_data); + Rich::Detector::Rich2::addConditionDerivation(this); + addConditionDerivation( + {Rich::Detector::Rich2::DefaultConditionKey}, + inputLocation(), + [&](const Rich::Detector::Rich2& det) { + auto Rich2Geo = Rich2Geometry_t {m_data, det}; + dump(); + return Rich2Geo; }); + }); } void DumpRich2Geometry::operator()(const Rich2Geometry_t&) const {} diff --git a/Rec/Allen/src/TestAllenRichMakePixels.cpp b/Rec/Allen/src/TestAllenRichMakePixels.cpp index 80f2b819ca1..1a85ff978e1 100644 --- a/Rec/Allen/src/TestAllenRichMakePixels.cpp +++ b/Rec/Allen/src/TestAllenRichMakePixels.cpp @@ -12,16 +12,18 @@ #include "RichPixels.cuh" class TestAllenRichMakePixels final : public Gaudi::Functional::Consumer&, - const std::vector&, - const Rich::Future::Rec::SIMDPixelSummaries&)> -{ - public: - /// Standard constructor - TestAllenRichMakePixels(const std::string& name, ISvcLocator* pSvcLocator); - - /// Algorithm execution - void operator()(const std::vector&, const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&) const override; + const std::vector&, + const std::vector&, + const Rich::Future::Rec::SIMDPixelSummaries&)> { +public: + /// Standard constructor + TestAllenRichMakePixels(const std::string& name, ISvcLocator* pSvcLocator); + + /// Algorithm execution + void operator()( + const std::vector&, + const std::vector&, + const Rich::Future::Rec::SIMDPixelSummaries&) const override; }; DECLARE_COMPONENT(TestAllenRichMakePixels) @@ -33,38 +35,37 @@ TestAllenRichMakePixels::TestAllenRichMakePixels(const std::string& name, ISvcLo {KeyValue {"rich1_pixels", ""}, KeyValue {"rich2_pixels", ""}, KeyValue {"SIMDPixelSummaries", ""}}) {} - -// When reading this code, keep in mind that recPixelSummaries contain multiple pixels, while allenRichPixels contain individual pixels +// When reading this code, keep in mind that recPixelSummaries contain multiple pixels, while allenRichPixels contain +// individual pixels void TestAllenRichMakePixels::operator()( const std::vector& allenRich1Pixels, const std::vector& allenRich2Pixels, - const Rich::Future::Rec::SIMDPixelSummaries& recPixelSummaries - ) const + const Rich::Future::Rec::SIMDPixelSummaries& recPixelSummaries) const { - int allen_in_rec = 0; + int allen_in_rec = 0; int allen_not_in_rec = 0; - int rec_in_allen = 0; + int rec_in_allen = 0; int rec_not_in_allen = 0; - int allen_null = 0; + int allen_null = 0; auto rich1_pixels = allenRich1Pixels; auto rich2_pixels = allenRich2Pixels; - + // Concatenate Allen Pixel vectors std::vector allenPixels; allenPixels.reserve(allenRich1Pixels.size() + allenRich2Pixels.size()); allenPixels.insert(allenPixels.end(), rich1_pixels.begin(), rich1_pixels.end()); allenPixels.insert(allenPixels.end(), rich2_pixels.begin(), rich2_pixels.end()); - - // functor to check if allen pixels exist in HLT2 + + // functor to check if allen pixels exist in HLT2 auto allenPixelExistsInRec = [&](const Allen::RichPixel& allenPixel) -> bool { - // iterate over all pixel summaries - for(const auto &recPixelSummary : recPixelSummaries) { + // iterate over all pixel summaries + for (const auto& recPixelSummary : recPixelSummaries) { // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. - for(size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { + for (size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { // ensure HLT2 pixel validity - if (recPixelSummary.validMask()[i]){ - // check for match - if( + if (recPixelSummary.validMask()[i]) { + // check for match + if ( (allenPixel.gloPos()[0] == recPixelSummary.gloPos().X()[i]) && (allenPixel.gloPos()[1] == recPixelSummary.gloPos().Y()[i]) && (allenPixel.gloPos()[2] == recPixelSummary.gloPos().Z()[i]) && @@ -73,92 +74,96 @@ void TestAllenRichMakePixels::operator()( (allenPixel.locPos()[2] == recPixelSummary.locPos().Z()[i]) && (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && (allenPixel.effArea() == recPixelSummary.effArea()[i]) && - ((int)allenPixel.rich() == (int)recPixelSummary.rich()) && - ((int)allenPixel.side() == (int)recPixelSummary.side()) && + ((int) allenPixel.rich() == (int) recPixelSummary.rich()) && + ((int) allenPixel.side() == (int) recPixelSummary.side()) && (allenPixel.timeWindow() == recPixelSummary.timeWindow()[i]) && - (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i]) - ) { + (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i])) { return true; } - } else { - return true; // ignore invalid pix, assume correctness - }// invalid pix - } // didn't find pix match - } // covered all + } + else { + return true; // ignore invalid pix, assume correctness + } // invalid pix + } // didn't find pix match + } // covered all return false; }; - - // functor to check if HLT2 pixels exist in Allen - auto recPixelExistsInAllen = [&](const Rich::Future::Rec::SIMDPixel& recPixelSummary) -> bool { - bool found_all_pixels = true; - bool found_current_pixel = true; + // functor to check if HLT2 pixels exist in Allen + auto recPixelExistsInAllen = [&](const Rich::Future::Rec::SIMDPixel& recPixelSummary) -> bool { + bool found_all_pixels = true; + bool found_current_pixel = true; - // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. - for(size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { - // case: HLT2 pixels in case they are not found in Allen - if (!found_current_pixel) { - rec_not_in_allen++; - error() << "Rec pixel does not exist in Allen" << endmsg; - std::cout << "Rec pixel: " << recPixelSummary.gloPos().X()[i-1] << ',' << recPixelSummary.gloPos().Y()[i-1] << ',' << recPixelSummary.gloPos().Z()[i-1] << ',' - << recPixelSummary.locPos().X()[i-1] << ',' << recPixelSummary.locPos().Y()[i-1] << ',' << recPixelSummary.locPos().Z()[i-1] << ',' - << recPixelSummary.smartID()[i-1].key() << ',' << recPixelSummary.effArea()[i-1] << ',' << (int)(recPixelSummary.rich()) << ',' - << (int)(recPixelSummary.side()) << ',' << recPixelSummary.validMask()[i-1] << ',' << recPixelSummary.timeWindow()[i-1] << ',' << recPixelSummary.isInnerRegion()[i-1] << '\n'; -} - found_current_pixel = false; - - // ensure HLT2 pixel validity - if (recPixelSummary.validMask()[i]){ - // iterate over Allen pixels - for(const auto &allenPixel : allenPixels) { - // check for match - if( - (allenPixel.gloPos()[0] == recPixelSummary.gloPos().X()[i]) && - (allenPixel.gloPos()[1] == recPixelSummary.gloPos().Y()[i]) && - (allenPixel.gloPos()[2] == recPixelSummary.gloPos().Z()[i]) && - (allenPixel.locPos()[0] == recPixelSummary.locPos().X()[i]) && - (allenPixel.locPos()[1] == recPixelSummary.locPos().Y()[i]) && - (allenPixel.locPos()[2] == recPixelSummary.locPos().Z()[i]) && - (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && - (allenPixel.effArea() == recPixelSummary.effArea()[i]) && - ((int)allenPixel.rich() == (int)recPixelSummary.rich()) && - ((int)allenPixel.side() == (int)recPixelSummary.side()) && - (allenPixel.timeWindow() == recPixelSummary.timeWindow()[i]) && - (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i]) - ) { - found_current_pixel = true; - rec_in_allen++; - continue; - } // found a match - } // iterate over Allen pixels - } else { - found_current_pixel = true; //assume correctedness on invalid pix to ignore it. - } // valid pix - found_all_pixels = found_all_pixels && found_current_pixel; + // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. + for (size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { + // case: HLT2 pixels in case they are not found in Allen + if (!found_current_pixel) { + rec_not_in_allen++; + error() << "Rec pixel does not exist in Allen" << endmsg; + std::cout << "Rec pixel: " << recPixelSummary.gloPos().X()[i - 1] << ',' << recPixelSummary.gloPos().Y()[i - 1] + << ',' << recPixelSummary.gloPos().Z()[i - 1] << ',' << recPixelSummary.locPos().X()[i - 1] << ',' + << recPixelSummary.locPos().Y()[i - 1] << ',' << recPixelSummary.locPos().Z()[i - 1] << ',' + << recPixelSummary.smartID()[i - 1].key() << ',' << recPixelSummary.effArea()[i - 1] << ',' + << (int) (recPixelSummary.rich()) << ',' << (int) (recPixelSummary.side()) << ',' + << recPixelSummary.validMask()[i - 1] << ',' << recPixelSummary.timeWindow()[i - 1] << ',' + << recPixelSummary.isInnerRegion()[i - 1] << '\n'; + } + found_current_pixel = false; + + // ensure HLT2 pixel validity + if (recPixelSummary.validMask()[i]) { + // iterate over Allen pixels + for (const auto& allenPixel : allenPixels) { + // check for match + if ( + (allenPixel.gloPos()[0] == recPixelSummary.gloPos().X()[i]) && + (allenPixel.gloPos()[1] == recPixelSummary.gloPos().Y()[i]) && + (allenPixel.gloPos()[2] == recPixelSummary.gloPos().Z()[i]) && + (allenPixel.locPos()[0] == recPixelSummary.locPos().X()[i]) && + (allenPixel.locPos()[1] == recPixelSummary.locPos().Y()[i]) && + (allenPixel.locPos()[2] == recPixelSummary.locPos().Z()[i]) && + (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && + (allenPixel.effArea() == recPixelSummary.effArea()[i]) && + ((int) allenPixel.rich() == (int) recPixelSummary.rich()) && + ((int) allenPixel.side() == (int) recPixelSummary.side()) && + (allenPixel.timeWindow() == recPixelSummary.timeWindow()[i]) && + (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i])) { + found_current_pixel = true; + rec_in_allen++; + continue; + } // found a match + } // iterate over Allen pixels + } + else { + found_current_pixel = true; // assume correctedness on invalid pix to ignore it. + } // valid pix + found_all_pixels = found_all_pixels && found_current_pixel; } return found_all_pixels; }; - - // call allen in hlt2 functor - for (auto &allenPixel : allenPixels) { - if(!allenPixel.isNull()) { - if (!allenPixelExistsInRec(allenPixel)) { - error() << "Allen pixel does not exist in Rec" << endmsg; - std::cout << allenPixel.toString() << std::endl; - allen_not_in_rec++; - }else{ - allen_in_rec++; - } - }else{ - allen_null++; - } + + // call allen in hlt2 functor + for (auto& allenPixel : allenPixels) { + if (!allenPixel.isNull()) { + if (!allenPixelExistsInRec(allenPixel)) { + error() << "Allen pixel does not exist in Rec" << endmsg; + std::cout << allenPixel.toString() << std::endl; + allen_not_in_rec++; + } + else { + allen_in_rec++; + } + } + else { + allen_null++; + } } - // call hlt2 in allen functor - for (auto &recPixelSummary : recPixelSummaries) { + // call hlt2 in allen functor + for (auto& recPixelSummary : recPixelSummaries) { recPixelExistsInAllen(recPixelSummary); } - + // print final stats /* std::cout << "allen_in_rec " << allen_in_rec << std::endl; std::cout << "allen_not_in_rec " << allen_not_in_rec << std::endl; diff --git a/configuration/python/AllenConf/HLT1.py b/configuration/python/AllenConf/HLT1.py index 3c6fec37ef0..932d1289dd5 100644 --- a/configuration/python/AllenConf/HLT1.py +++ b/configuration/python/AllenConf/HLT1.py @@ -1582,8 +1582,8 @@ def setup_hlt1_node(enablePhysics=True, if with_rich: hlt1_node = CompositeNode( "AllenWithRich", [ - hlt1_node, - reconstructed_objects["decoded_rich1"]["dev_smart_ids"].producer + hlt1_node, reconstructed_objects["decoded_rich1"] + ["dev_smart_ids"].producer ], NodeLogic.NONLAZY_AND, force_order=True) diff --git a/configuration/python/AllenConf/hlt1_reconstruction.py b/configuration/python/AllenConf/hlt1_reconstruction.py index 468882b45de..592fdb76d10 100644 --- a/configuration/python/AllenConf/hlt1_reconstruction.py +++ b/configuration/python/AllenConf/hlt1_reconstruction.py @@ -501,14 +501,13 @@ def hlt1_reconstruction(algorithm_name='', from AllenConf.rich_make_pixels import make_pixels decoded_rich1 = decode_rich(rich=1) decoded_rich2 = decode_rich(rich=2) - output.update( - { - "decoded_rich1": decoded_rich1, - "decoded_rich2": decoded_rich2, - "rich1_pixels": make_pixels(decoded_rich1,rich=1), - "rich2_pixels": make_pixels(decoded_rich2,rich=2) - }) - + output.update({ + "decoded_rich1": decoded_rich1, + "decoded_rich2": decoded_rich2, + "rich1_pixels": make_pixels(decoded_rich1, rich=1), + "rich2_pixels": make_pixels(decoded_rich2, rich=2) + }) + if with_AC_split: velo_tracks_A_side, velo_tracks_C_side = make_velo_tracks_ACsplit( decoded_velo) diff --git a/configuration/python/AllenConf/rich_make_pixels.py b/configuration/python/AllenConf/rich_make_pixels.py index c42fc3484d9..a5ad57396f0 100644 --- a/configuration/python/AllenConf/rich_make_pixels.py +++ b/configuration/python/AllenConf/rich_make_pixels.py @@ -10,12 +10,14 @@ ############################################################################### from AllenCore.algorithms import (data_provider_t, rich_make_pixels_t) from AllenConf.utils import initialize_number_of_events -from AllenConf.rich_reconstruction import (RICH_1, RICH_2, VALID_RICHS, decode_rich) +from AllenConf.rich_reconstruction import (RICH_1, RICH_2, VALID_RICHS, + decode_rich) from AllenCore.generator import make_algorithm + def make_pixels(decoded_rich=None, rich=RICH_1): if rich not in VALID_RICHS: - raise ValueError(f"rich must be one of {VALID_RICHS}") + raise ValueError(f"rich must be one of {VALID_RICHS}") if decoded_rich is None: decoded_rich = decode_rich(rich) number_of_hits = decoded_rich["host_rich_total_number_of_hits"] @@ -29,6 +31,4 @@ def make_pixels(decoded_rich=None, rich=RICH_1): dev_smart_ids_t=smart_ids, dev_rich_hit_offsets_t=hit_offsets, current_rich=rich) - return { - "dev_rich_pixels": rich_pixels.dev_rich_pixels_t - } + return {"dev_rich_pixels": rich_pixels.dev_rich_pixels_t} diff --git a/configuration/python/AllenConf/rich_reconstruction.py b/configuration/python/AllenConf/rich_reconstruction.py index 9d2bdadacb8..4ba18f16764 100644 --- a/configuration/python/AllenConf/rich_reconstruction.py +++ b/configuration/python/AllenConf/rich_reconstruction.py @@ -17,6 +17,7 @@ RICH_2 = 2 VALID_RICHS = [RICH_1, RICH_2] + def decode_rich(rich=RICH_1): if rich not in VALID_RICHS: raise ValueError(f"rich must be one of {VALID_RICHS}") @@ -35,9 +36,12 @@ def decode_rich(rich=RICH_1): dev_rich_raw_input_offsets_t=rich_banks.dev_raw_offsets_t, dev_rich_raw_input_sizes_t=rich_banks.dev_raw_sizes_t, dev_rich_raw_input_types_t=rich_banks.dev_raw_types_t) - + return { - "dev_smart_ids": rich_decoding.dev_smart_ids_t, - "dev_rich_hit_offsets": rich_decoding.dev_rich_hit_offsets_t, - "host_rich_total_number_of_hits": rich_decoding.host_rich_total_number_of_hits_t + "dev_smart_ids": + rich_decoding.dev_smart_ids_t, + "dev_rich_hit_offsets": + rich_decoding.dev_rich_hit_offsets_t, + "host_rich_total_number_of_hits": + rich_decoding.host_rich_total_number_of_hits_t } diff --git a/configuration/python/AllenSequences/rich.py b/configuration/python/AllenSequences/rich.py index 759597e45b1..22abb82a33b 100644 --- a/configuration/python/AllenSequences/rich.py +++ b/configuration/python/AllenSequences/rich.py @@ -27,17 +27,20 @@ rich2_decoding = CompositeNode( force_order=False) rich1_make_pixels = CompositeNode( - "Rich1MakePixels", [make_pixels(decoded_rich1, rich=1)["dev_rich_pixels"].producer], + "Rich1MakePixels", + [make_pixels(decoded_rich1, rich=1)["dev_rich_pixels"].producer], NodeLogic.NONLAZY_AND, force_order=True) rich2_make_pixels = CompositeNode( - "Rich2MakePixels", [make_pixels(decoded_rich2, rich=2)["dev_rich_pixels"].producer], + "Rich2MakePixels", + [make_pixels(decoded_rich2, rich=2)["dev_rich_pixels"].producer], NodeLogic.NONLAZY_AND, force_order=True) rich_node = CompositeNode( - "RichNode", [rich1_decoding, rich1_make_pixels, rich2_decoding, rich2_make_pixels], + "RichNode", + [rich1_decoding, rich1_make_pixels, rich2_decoding, rich2_make_pixels], NodeLogic.NONLAZY_AND, force_order=True) diff --git a/device/rich/decoding/include/Rich1.cuh b/device/rich/decoding/include/Rich1.cuh index d706868a2e6..4b7981238d3 100644 --- a/device/rich/decoding/include/Rich1.cuh +++ b/device/rich/decoding/include/Rich1.cuh @@ -13,24 +13,26 @@ namespace Allen { class Rich1 { - public: - __host__ __device__ Rich1(); + public: + __host__ __device__ Rich1(); - __host__ __device__ Rich1(const int8_t m_type, const std::array m_panels) - : m_panels(m_panels), m_type(m_type) { } + __host__ __device__ Rich1(const int8_t m_type, const std::array m_panels) : + m_panels(m_panels), m_type(m_type) + {} - __host__ __device__ inline auto rich() { return m_type; } + __host__ __device__ inline auto rich() { return m_type; } - /// Access PD Panels - __host__ __device__ inline auto& pdPanels() { return m_panels; } + /// Access PD Panels + __host__ __device__ inline auto& pdPanels() { return m_panels; } - /// Access PD Panel for a given side - __host__ __device__ inline auto pdPanel( const Rich::Future::DAQ::Side panel ) noexcept { - return &( pdPanels()[panel] ); - } + /// Access PD Panel for a given side + __host__ __device__ inline auto pdPanel(const Rich::Future::DAQ::Side panel) noexcept + { + return &(pdPanels()[panel]); + } - private: - std::array m_panels; - int8_t m_type; + private: + std::array m_panels; + int8_t m_type; }; } // namespace Allen diff --git a/device/rich/decoding/include/Rich2.cuh b/device/rich/decoding/include/Rich2.cuh index f0ded49a516..efdfd485944 100644 --- a/device/rich/decoding/include/Rich2.cuh +++ b/device/rich/decoding/include/Rich2.cuh @@ -13,24 +13,26 @@ namespace Allen { class Rich2 { - public: - __host__ __device__ Rich2(); + public: + __host__ __device__ Rich2(); - __host__ __device__ Rich2(const int8_t m_type, const std::array m_panels) - : m_panels(m_panels), m_type(m_type) { } + __host__ __device__ Rich2(const int8_t m_type, const std::array m_panels) : + m_panels(m_panels), m_type(m_type) + {} - __host__ __device__ inline auto rich() { return m_type; } + __host__ __device__ inline auto rich() { return m_type; } - /// Access PD Panels - __host__ __device__ inline auto& pdPanels() { return m_panels; } + /// Access PD Panels + __host__ __device__ inline auto& pdPanels() { return m_panels; } - /// Access PD Panel for a given side - __host__ __device__ inline auto pdPanel( const Rich::Future::DAQ::Side panel ) noexcept { - return &( pdPanels()[panel] ); - } + /// Access PD Panel for a given side + __host__ __device__ inline auto pdPanel(const Rich::Future::DAQ::Side panel) noexcept + { + return &(pdPanels()[panel]); + } - private: - std::array m_panels; - int8_t m_type; + private: + std::array m_panels; + int8_t m_type; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichDecoding.cuh b/device/rich/decoding/include/RichDecoding.cuh index d5da38ba481..ce74c591ed7 100644 --- a/device/rich/decoding/include/RichDecoding.cuh +++ b/device/rich/decoding/include/RichDecoding.cuh @@ -37,6 +37,6 @@ namespace rich_decoding { const Allen::Context&) const; private: - Allen::Property m_block_dim {this, "block_dim", {64,1,1}, "block dimensions"}; + Allen::Property m_block_dim {this, "block_dim", {64, 1, 1}, "block dimensions"}; }; } // namespace rich_decoding diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 31675525f78..5f16f361914 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -24,29 +24,27 @@ namespace Allen { using BitPackType = KeyType; using ADCTimeType = std::uint16_t; - __host__ __device__ inline Point transform3DTimesPoint(Transform3D fM, Point point) { - return Point{ - fM[0]*point[0] + fM[1]*point[1] + fM[2]*point[2] + fM[3], - fM[4]*point[0] + fM[5]*point[1] + fM[6]*point[2] + fM[7], - fM[8]*point[0] + fM[9]*point[1] + fM[10]*point[2] + fM[11] - }; - } + __host__ __device__ inline Point transform3DTimesPoint(Transform3D fM, Point point) + { + return Point {fM[0] * point[0] + fM[1] * point[1] + fM[2] * point[2] + fM[3], + fM[4] * point[0] + fM[5] * point[1] + fM[6] * point[2] + fM[7], + fM[8] * point[0] + fM[9] * point[1] + fM[10] * point[2] + fM[11]}; + } class RichSmartID { KeyType m_key; - public: - + public: // Set the RICH PD pixel row identifier - __host__ __device__ constexpr void setPixelRow( const DataType row ) + __host__ __device__ constexpr void setPixelRow(const DataType row) { - setData( row, ShiftPixelRow, MaskPixelRow, MaskPixelRowIsSet ); + setData(row, ShiftPixelRow, MaskPixelRow, MaskPixelRowIsSet); } // Set the RICH PD pixel column identifier - __host__ __device__ constexpr void setPixelCol( const DataType col ) + __host__ __device__ constexpr void setPixelCol(const DataType col) { - setData( col, ShiftPixelCol, MaskPixelCol, MaskPixelColIsSet ); + setData(col, ShiftPixelCol, MaskPixelCol, MaskPixelColIsSet); } public: @@ -55,95 +53,89 @@ namespace Allen { __host__ __device__ RichSmartID(KeyType key) : m_key(key) {} // Number of bits for each data field in the word - static constexpr const BitPackType BitsPixelCol = 3; //< Number of bits for MaPMT pixel column - static constexpr const BitPackType BitsPixelRow = 3; //< Number of bits for MaPMT pixel row - static constexpr const BitPackType BitsPDNumInMod = 4; //< Number of bits for MaPMT 'number in module' - static constexpr const BitPackType BitsPDMod = 9; //< Number of bits for MaPMT module - static constexpr const BitPackType BitsPanel = 1; //< Number of bits for MaPMT panel - static constexpr const BitPackType BitsRich = 1; //< Number of bits for RICH detector + static constexpr const BitPackType BitsPixelCol = 3; //< Number of bits for MaPMT pixel column + static constexpr const BitPackType BitsPixelRow = 3; //< Number of bits for MaPMT pixel row + static constexpr const BitPackType BitsPDNumInMod = 4; //< Number of bits for MaPMT 'number in module' + static constexpr const BitPackType BitsPDMod = 9; //< Number of bits for MaPMT module + static constexpr const BitPackType BitsPanel = 1; //< Number of bits for MaPMT panel + static constexpr const BitPackType BitsRich = 1; //< Number of bits for RICH detector static constexpr const BitPackType BitsPixelSubRowIsSet = 1; - static constexpr const BitPackType BitsPixelColIsSet = 1; - static constexpr const BitPackType BitsPixelRowIsSet = 1; - static constexpr const BitPackType BitsPDIsSet = 1; - static constexpr const BitPackType BitsPanelIsSet = 1; - static constexpr const BitPackType BitsRichIsSet = 1; - static constexpr const BitPackType BitsLargePixel = 1; + static constexpr const BitPackType BitsPixelColIsSet = 1; + static constexpr const BitPackType BitsPixelRowIsSet = 1; + static constexpr const BitPackType BitsPDIsSet = 1; + static constexpr const BitPackType BitsPanelIsSet = 1; + static constexpr const BitPackType BitsRichIsSet = 1; + static constexpr const BitPackType BitsLargePixel = 1; // The shifts - static constexpr const BitPackType ShiftPixelCol = 0; - static constexpr const BitPackType ShiftPixelRow = ShiftPixelCol + BitsPixelCol; - static constexpr const BitPackType ShiftPDNumInMod = ShiftPixelRow + BitsPixelRow; - static constexpr const BitPackType ShiftPDMod = ShiftPDNumInMod + BitsPDNumInMod; - static constexpr const BitPackType ShiftPanel = ShiftPDMod + BitsPDMod; - static constexpr const BitPackType ShiftRich = ShiftPanel + BitsPanel; - static constexpr const BitPackType ShiftPixelSubRowIsSet = ShiftRich + BitsRich; - static constexpr const BitPackType ShiftPixelColIsSet = ShiftPixelSubRowIsSet + BitsPixelSubRowIsSet; - static constexpr const BitPackType ShiftPixelRowIsSet = ShiftPixelColIsSet + BitsPixelColIsSet; - static constexpr const BitPackType ShiftPDIsSet = ShiftPixelRowIsSet + BitsPixelRowIsSet; - static constexpr const BitPackType ShiftPanelIsSet = ShiftPDIsSet + BitsPDIsSet; - static constexpr const BitPackType ShiftRichIsSet = ShiftPanelIsSet + BitsPanelIsSet; - static constexpr const BitPackType ShiftLargePixel = ShiftRichIsSet + BitsRichIsSet; + static constexpr const BitPackType ShiftPixelCol = 0; + static constexpr const BitPackType ShiftPixelRow = ShiftPixelCol + BitsPixelCol; + static constexpr const BitPackType ShiftPDNumInMod = ShiftPixelRow + BitsPixelRow; + static constexpr const BitPackType ShiftPDMod = ShiftPDNumInMod + BitsPDNumInMod; + static constexpr const BitPackType ShiftPanel = ShiftPDMod + BitsPDMod; + static constexpr const BitPackType ShiftRich = ShiftPanel + BitsPanel; + static constexpr const BitPackType ShiftPixelSubRowIsSet = ShiftRich + BitsRich; + static constexpr const BitPackType ShiftPixelColIsSet = ShiftPixelSubRowIsSet + BitsPixelSubRowIsSet; + static constexpr const BitPackType ShiftPixelRowIsSet = ShiftPixelColIsSet + BitsPixelColIsSet; + static constexpr const BitPackType ShiftPDIsSet = ShiftPixelRowIsSet + BitsPixelRowIsSet; + static constexpr const BitPackType ShiftPanelIsSet = ShiftPDIsSet + BitsPDIsSet; + static constexpr const BitPackType ShiftRichIsSet = ShiftPanelIsSet + BitsPanelIsSet; + static constexpr const BitPackType ShiftLargePixel = ShiftRichIsSet + BitsRichIsSet; // The masks - static constexpr const BitPackType MaskPixelCol = - ( BitPackType )( ( BitPackType{1} << BitsPixelCol ) - BitPackType{1} ) << ShiftPixelCol; - static constexpr const BitPackType MaskPixelRow = - ( BitPackType )( ( BitPackType{1} << BitsPixelRow ) - BitPackType{1} ) << ShiftPixelRow; + static constexpr const BitPackType MaskPixelCol = (BitPackType)((BitPackType {1} << BitsPixelCol) - BitPackType {1}) + << ShiftPixelCol; + static constexpr const BitPackType MaskPixelRow = (BitPackType)((BitPackType {1} << BitsPixelRow) - BitPackType {1}) + << ShiftPixelRow; static constexpr const BitPackType MaskPDNumInMod = - ( BitPackType )( ( BitPackType{1} << BitsPDNumInMod ) - BitPackType{1} ) << ShiftPDNumInMod; - static constexpr const BitPackType MaskPDMod = - ( BitPackType )( ( BitPackType{1} << BitsPDMod ) - BitPackType{1} ) << ShiftPDMod; - static constexpr const BitPackType MaskPanel = - ( BitPackType )( ( BitPackType{1} << BitsPanel ) - BitPackType{1} ) << ShiftPanel; - static constexpr const BitPackType MaskRich = - ( BitPackType )( ( BitPackType{1} << BitsRich ) - BitPackType{1} ) << ShiftRich; + (BitPackType)((BitPackType {1} << BitsPDNumInMod) - BitPackType {1}) << ShiftPDNumInMod; + static constexpr const BitPackType MaskPDMod = (BitPackType)((BitPackType {1} << BitsPDMod) - BitPackType {1}) + << ShiftPDMod; + static constexpr const BitPackType MaskPanel = (BitPackType)((BitPackType {1} << BitsPanel) - BitPackType {1}) + << ShiftPanel; + static constexpr const BitPackType MaskRich = (BitPackType)((BitPackType {1} << BitsRich) - BitPackType {1}) + << ShiftRich; static constexpr const BitPackType MaskPixelSubRowIsSet = - ( BitPackType )( ( BitPackType{1} << BitsPixelSubRowIsSet ) - BitPackType{1} ) << ShiftPixelSubRowIsSet; + (BitPackType)((BitPackType {1} << BitsPixelSubRowIsSet) - BitPackType {1}) << ShiftPixelSubRowIsSet; static constexpr const BitPackType MaskPixelColIsSet = - ( BitPackType )( ( BitPackType{1} << BitsPixelColIsSet ) - BitPackType{1} ) << ShiftPixelColIsSet; + (BitPackType)((BitPackType {1} << BitsPixelColIsSet) - BitPackType {1}) << ShiftPixelColIsSet; static constexpr const BitPackType MaskPixelRowIsSet = - ( BitPackType )( ( BitPackType{1} << BitsPixelRowIsSet ) - BitPackType{1} ) << ShiftPixelRowIsSet; - static constexpr const BitPackType MaskPDIsSet = - ( BitPackType )( ( BitPackType{1} << BitsPDIsSet ) - BitPackType{1} ) << ShiftPDIsSet; + (BitPackType)((BitPackType {1} << BitsPixelRowIsSet) - BitPackType {1}) << ShiftPixelRowIsSet; + static constexpr const BitPackType MaskPDIsSet = (BitPackType)((BitPackType {1} << BitsPDIsSet) - BitPackType {1}) + << ShiftPDIsSet; static constexpr const BitPackType MaskPanelIsSet = - ( BitPackType )( ( BitPackType{1} << BitsPanelIsSet ) - BitPackType{1} ) << ShiftPanelIsSet; + (BitPackType)((BitPackType {1} << BitsPanelIsSet) - BitPackType {1}) << ShiftPanelIsSet; static constexpr const BitPackType MaskRichIsSet = - ( BitPackType )( ( BitPackType{1} << BitsRichIsSet ) - BitPackType{1} ) << ShiftRichIsSet; + (BitPackType)((BitPackType {1} << BitsRichIsSet) - BitPackType {1}) << ShiftRichIsSet; static constexpr const BitPackType MaskLargePixel = - ( BitPackType )( ( BitPackType{1} << BitsLargePixel ) - BitPackType{1} ) << ShiftLargePixel; + (BitPackType)((BitPackType {1} << BitsLargePixel) - BitPackType {1}) << ShiftLargePixel; // Max values - static constexpr const DataType MaxPixelCol = ( DataType )( BitPackType{1} << BitsPixelCol ) - DataType{1}; - static constexpr const DataType MaxPixelRow = ( DataType )( BitPackType{1} << BitsPixelRow ) - DataType{1}; - static constexpr const DataType MaxPDNumInMod = ( DataType )( BitPackType{1} << BitsPDNumInMod ) - DataType{1}; - static constexpr const DataType MaxPDMod = ( DataType )( BitPackType{1} << BitsPDMod ) - DataType{1}; - static constexpr const DataType MaxPanel = ( DataType )( BitPackType{1} << BitsPanel ) - DataType{1}; - static constexpr const DataType MaxRich = ( DataType )( BitPackType{1} << BitsRich ) - DataType{1}; + static constexpr const DataType MaxPixelCol = (DataType)(BitPackType {1} << BitsPixelCol) - DataType {1}; + static constexpr const DataType MaxPixelRow = (DataType)(BitPackType {1} << BitsPixelRow) - DataType {1}; + static constexpr const DataType MaxPDNumInMod = (DataType)(BitPackType {1} << BitsPDNumInMod) - DataType {1}; + static constexpr const DataType MaxPDMod = (DataType)(BitPackType {1} << BitsPDMod) - DataType {1}; + static constexpr const DataType MaxPanel = (DataType)(BitPackType {1} << BitsPanel) - DataType {1}; + static constexpr const DataType MaxRich = (DataType)(BitPackType {1} << BitsRich) - DataType {1}; // Number of bits for the channel identification (i.e. excluding any time info) // Currently use the lowest 32 bits for this. static constexpr const BitPackType NChannelBits = 32; - __host__ __device__ constexpr inline void setData( - const DataType value, - const BitPackType shift, - const BitPackType mask) noexcept + __host__ __device__ constexpr inline void + setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept { - m_key = ((BitPackType{value} << shift) & mask) | (m_key & ~mask); + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); } - __host__ __device__ constexpr inline void setData( - const DataType value, - const BitPackType shift, - const BitPackType mask, - const BitPackType okMask) noexcept + __host__ __device__ constexpr inline void + setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept { - m_key = ((BitPackType{value} << shift) & mask) | (m_key & ~mask) | okMask; + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; } - __host__ __device__ constexpr inline BitPackType getData( - const BitPackType shift, - const BitPackType mask) const noexcept + __host__ __device__ constexpr inline BitPackType getData(const BitPackType shift, const BitPackType mask) const + noexcept { return (m_key & mask) >> shift; } @@ -186,7 +178,10 @@ namespace Allen { return isLargePMT() ? HTypePMTsPerEC : RTypePMTsPerEC; } - __host__ __device__ constexpr inline DataType elementaryCell() const noexcept { return pdNumInMod() / numPMTsPerEC(); } + __host__ __device__ constexpr inline DataType elementaryCell() const noexcept + { + return pdNumInMod() / numPMTsPerEC(); + } __host__ __device__ constexpr inline DataType pdNumInEC() const noexcept { return pdNumInMod() % numPMTsPerEC(); } @@ -200,29 +195,39 @@ namespace Allen { return 0 != getData(ShiftPixelRowIsSet, MaskPixelRowIsSet); } - [[nodiscard]] __host__ __device__ constexpr bool pdIsSet() const noexcept { - return 0 != ((key() & MaskPDIsSet ) >> ShiftPDIsSet); + [[nodiscard]] __host__ __device__ constexpr bool pdIsSet() const noexcept + { + return 0 != ((key() & MaskPDIsSet) >> ShiftPDIsSet); } - __host__ __device__ constexpr inline DataType pixelCol() const noexcept { return getData(ShiftPixelCol, MaskPixelCol); } + __host__ __device__ constexpr inline DataType pixelCol() const noexcept + { + return getData(ShiftPixelCol, MaskPixelCol); + } - __host__ __device__ constexpr inline DataType pixelRow() const noexcept { return getData(ShiftPixelRow, MaskPixelRow); } + __host__ __device__ constexpr inline DataType pixelRow() const noexcept + { + return getData(ShiftPixelRow, MaskPixelRow); + } __host__ __device__ constexpr inline DataType anodeIndex() const noexcept { return pixelRow() * PixelsPerCol + PixelsPerRow - 1 - pixelCol(); } - __host__ __device__ constexpr inline bool adcTimeIsSet() const noexcept { + __host__ __device__ constexpr inline bool adcTimeIsSet() const noexcept + { return (0 != (key() & MaPMT::MaskADCTimeIsSet) >> MaPMT::ShiftADCTimeIsSet); } - __host__ __device__ constexpr ADCTimeType adcTime() const { + __host__ __device__ constexpr ADCTimeType adcTime() const + { return ((key() & MaPMT::MaskADCTime) >> MaPMT::ShiftADCTime); } - __host__ __device__ constexpr auto time() const noexcept { - return (MaPMT::MinTime + (adcTime() * MaPMT::ScaleADCToTime)); + __host__ __device__ constexpr auto time() const noexcept + { + return (MaPMT::MinTime + (adcTime() * MaPMT::ScaleADCToTime)); } // ostream operator @@ -274,7 +279,7 @@ namespace Allen { return str; } - public: + public: // Number of PMT pixels per row static constexpr const DataType PixelsPerRow = 8; // Number of PMT pixels per column @@ -290,46 +295,43 @@ namespace Allen { // Number of modules per column static constexpr const DataType ModulesPerColumn = 6; // Number of module columns per panel, in each RICH - static constexpr const std::array ModuleColumnsPerPanel = { - {11, 14} - }; + static constexpr const std::array ModuleColumnsPerPanel = {{11, 14}}; // Maximum number of module columns in any panel, RICH1 or RICH2 - static constexpr const DataType MaxModuleColumnsAnyPanel = std::max(ModuleColumnsPerPanel[0], ModuleColumnsPerPanel[1]); + static constexpr const DataType MaxModuleColumnsAnyPanel = + std::max(ModuleColumnsPerPanel[0], ModuleColumnsPerPanel[1]); // Number of modules per panel, in each RICH - static constexpr const std::array ModulesPerPanel{ - {(ModulesPerColumn * ModuleColumnsPerPanel[0]), (ModulesPerColumn * ModuleColumnsPerPanel[1])} - }; + static constexpr const std::array ModulesPerPanel { + {(ModulesPerColumn * ModuleColumnsPerPanel[0]), (ModulesPerColumn * ModuleColumnsPerPanel[1])}}; - __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() { - return { - std::array{0, ModulesPerPanel[0]}, - std::array{2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]} - }; + __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() + { + return {std::array {0, ModulesPerPanel[0]}, + std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; } class MaPMT { - public: - static constexpr const DataType MaxPDsPerModule = 16; - static constexpr const DataType MaxModulesPerPanel = 92; - - // Bits for time field. - static constexpr const BitPackType BitsADCTime = 16; - static constexpr const BitPackType BitsADCTimeIsSet = 1; - static constexpr const BitPackType ShiftADCTime = NChannelBits; - static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; - static constexpr const BitPackType MaskADCTime = - ( BitPackType )( ( BitPackType{1} << BitsADCTime ) - BitPackType{1} ) << ShiftADCTime; - static constexpr const BitPackType MaskADCTimeIsSet = - ( BitPackType )( ( BitPackType{1} << BitsADCTimeIsSet ) - BitPackType{1} ) << ShiftADCTimeIsSet; - - // Max ADC time that can be stored - static constexpr const ADCTimeType MaxADCTime = ( ADCTimeType )( BitPackType{1} << BitsADCTime ) - ADCTimeType{1}; - - // Parameters for conversion between float and ADC time values - static constexpr const double MinTime = -50.0; // In nanoseconds - static constexpr const double MaxTime = 150.0; // In nanoseconds - static constexpr const double ScaleTimeToADC = MaxADCTime / ( MaxTime - MinTime ); - static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; + public: + static constexpr const DataType MaxPDsPerModule = 16; + static constexpr const DataType MaxModulesPerPanel = 92; + + // Bits for time field. + static constexpr const BitPackType BitsADCTime = 16; + static constexpr const BitPackType BitsADCTimeIsSet = 1; + static constexpr const BitPackType ShiftADCTime = NChannelBits; + static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; + static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) + << ShiftADCTime; + static constexpr const BitPackType MaskADCTimeIsSet = + (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; + + // Max ADC time that can be stored + static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType {1}; + + // Parameters for conversion between float and ADC time values + static constexpr const double MinTime = -50.0; // In nanoseconds + static constexpr const double MaxTime = 150.0; // In nanoseconds + static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); + static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; }; }; // namespace RichSmartID } // namespace Allen @@ -346,55 +348,55 @@ namespace Rich::Future::DAQ { enum Side : std::int8_t { InvalidSide = -1, //< Invalid side // RICH1 - top = 0, //< Upper panel in RICH1 - bottom = 1, //< Lower panel in RICH1 + top = 0, //< Upper panel in RICH1 + bottom = 1, //< Lower panel in RICH1 // RICH2 - left = 0, //< Left panel in RICH2 - right = 1, //< Right panel in RICH2 - aside = 0, //< A-Side panel in RICH2 - cside = 1, //< C-Side panel in RICH2 + left = 0, //< Left panel in RICH2 + right = 1, //< Right panel in RICH2 + aside = 0, //< A-Side panel in RICH2 + cside = 1, //< C-Side panel in RICH2 // Generic - firstSide = 0, //< Upper panel in RICH1 or Left panel in RICH2 - secondSide = 1 //< Lower panel in RICH1 or Right panel in RICH2 + firstSide = 0, //< Upper panel in RICH1 or Left panel in RICH2 + secondSide = 1 //< Lower panel in RICH1 or Right panel in RICH2 }; class PackedFrameSizes final { - public: - // Packed type - using IntType = std::uint8_t; - - private: - // Bits for each Size - static const IntType Bits0 = 4; - static const IntType Bits1 = 4; - // shifts - static const IntType Shift0 = 0; - static const IntType Shift1 = Shift0 + Bits0; - // masks - static const IntType Mask0 = (IntType)((1 << Bits0) - 1) << Shift0; - static const IntType Mask1 = (IntType)((1 << Bits1) - 1) << Shift1; - // max values - static const IntType Max0 = (1 << Bits0) - 1; - static const IntType Max1 = (1 << Bits1) - 1; + public: + // Packed type + using IntType = std::uint8_t; + + private: + // Bits for each Size + static const IntType Bits0 = 4; + static const IntType Bits1 = 4; + // shifts + static const IntType Shift0 = 0; + static const IntType Shift1 = Shift0 + Bits0; + // masks + static const IntType Mask0 = (IntType)((1 << Bits0) - 1) << Shift0; + static const IntType Mask1 = (IntType)((1 << Bits1) - 1) << Shift1; + // max values + static const IntType Max0 = (1 << Bits0) - 1; + static const IntType Max1 = (1 << Bits1) - 1; - public: - // Contructor from a single word - __host__ __device__ explicit PackedFrameSizes(const IntType d) : m_data(d) {} + public: + // Contructor from a single word + __host__ __device__ explicit PackedFrameSizes(const IntType d) : m_data(d) {} - // Get the overall data - __host__ __device__ inline IntType data() const noexcept { return m_data; } + // Get the overall data + __host__ __device__ inline IntType data() const noexcept { return m_data; } - // Get first size word - __host__ __device__ inline IntType size0() const noexcept { return ((data() & Mask0) >> Shift0); } + // Get first size word + __host__ __device__ inline IntType size0() const noexcept { return ((data() & Mask0) >> Shift0); } - // Get second size word - __host__ __device__ inline IntType size1() const noexcept { return ((data() & Mask1) >> Shift1); } + // Get second size word + __host__ __device__ inline IntType size1() const noexcept { return ((data() & Mask1) >> Shift1); } - // Get the total size - __host__ __device__ inline auto totalSize() const noexcept { return size0() + size1(); } + // Get the total size + __host__ __device__ inline auto totalSize() const noexcept { return size0() + size1(); } - private: - // The data word - IntType m_data {0}; + private: + // The data word + IntType m_data {0}; }; } // namespace Rich::Future::DAQ diff --git a/device/rich/decoding/include/RichMakePixels.cuh b/device/rich/decoding/include/RichMakePixels.cuh index b6bdebcfb48..2ca91462822 100644 --- a/device/rich/decoding/include/RichMakePixels.cuh +++ b/device/rich/decoding/include/RichMakePixels.cuh @@ -20,7 +20,7 @@ namespace rich_make_pixels { MASK_INPUT(dev_event_list_t) dev_event_list; DEVICE_INPUT(dev_smart_ids_t, Allen::RichSmartID) dev_smart_ids; DEVICE_INPUT(dev_rich_hit_offsets_t, unsigned) dev_rich_hit_offsets; - DEVICE_OUTPUT(dev_rich_hits_t, char) dev_rich_hits; + DEVICE_OUTPUT(dev_rich_hits_t, char) dev_rich_hits; DEVICE_OUTPUT(dev_rich_pixels_t, Allen::RichPixel) dev_rich_pixels; }; @@ -28,13 +28,13 @@ namespace rich_make_pixels { void set_arguments_size(ArgumentReferences, const RuntimeOptions&, const Constants&) const; void operator()( - const ArgumentReferences&, - const RuntimeOptions&, - const Constants&, - const Allen::Context&) const; + const ArgumentReferences&, + const RuntimeOptions&, + const Constants&, + const Allen::Context&) const; - private: - Allen::Property m_block_dim {this, "block_dim", {64,1,1}, "block dimensions"}; + private: + Allen::Property m_block_dim {this, "block_dim", {64, 1, 1}, "block dimensions"}; Allen::Property m_current_rich {this, "current_rich", 1, "current rich"}; }; } // namespace rich_make_pixels diff --git a/device/rich/decoding/include/RichPD.cuh b/device/rich/decoding/include/RichPD.cuh index c2c6f5cb9d2..89d6cba9d68 100644 --- a/device/rich/decoding/include/RichPD.cuh +++ b/device/rich/decoding/include/RichPD.cuh @@ -16,29 +16,22 @@ namespace Rich::Detector::Allen { class PD final { - using FP = ::Allen::FP; + using FP = ::Allen::FP; using Point = ::Allen::Point; - public: + public: /// Default constructor __host__ __device__ PD() = default; /// Copy assignment operator - __host__ __device__ PD& operator=(const PD&) = default; + __host__ __device__ PD& operator=(const PD&) = default; /// Copy Constructor - __host__ __device__ PD( const PD& pd ) - : m_locToGloM( pd.m_locToGloM ) - , m_zeroInPanelFrame(pd.m_zeroInPanelFrame) - , m_pdSmartID( pd.m_pdSmartID ) - , m_effPixelArea( pd.m_effPixelArea ) - , m_numPixels( pd.m_numPixels ) - , m_localZcoord( pd.m_localZcoord) - , m_NumPixColFrac( pd.m_NumPixColFrac ) - , m_NumPixRowFrac( pd.m_NumPixRowFrac ) - , m_EffectivePixelXSize( pd.m_EffectivePixelXSize ) - , m_EffectivePixelYSize( pd.m_EffectivePixelYSize ) - , m_isHType( pd.m_isHType ) - , m_isNull( pd.m_isNull ){ - } + __host__ __device__ PD(const PD& pd) : + m_locToGloM(pd.m_locToGloM), m_zeroInPanelFrame(pd.m_zeroInPanelFrame), m_pdSmartID(pd.m_pdSmartID), + m_effPixelArea(pd.m_effPixelArea), m_numPixels(pd.m_numPixels), m_localZcoord(pd.m_localZcoord), + m_NumPixColFrac(pd.m_NumPixColFrac), m_NumPixRowFrac(pd.m_NumPixRowFrac), + m_EffectivePixelXSize(pd.m_EffectivePixelXSize), m_EffectivePixelYSize(pd.m_EffectivePixelYSize), + m_isHType(pd.m_isHType), m_isNull(pd.m_isNull) + {} __host__ __device__ inline auto pdSmartID() const { return m_pdSmartID; } @@ -48,54 +41,49 @@ namespace Rich::Detector::Allen { const auto fPixRow = id.pixelRow(); const auto xh = (fPixCol - m_NumPixColFrac) * m_EffectivePixelXSize; const auto yh = (fPixRow - m_NumPixRowFrac) * m_EffectivePixelYSize; - return ::Allen::transform3DTimesPoint(localToGlobal(), Point{xh, yh, m_localZcoord}); + return ::Allen::transform3DTimesPoint(localToGlobal(), Point {xh, yh, m_localZcoord}); } - __host__ __device__ inline float get_EffectivePixelXSize() const noexcept {return m_EffectivePixelXSize;} - __host__ __device__ inline float get_EffectivePixelYSize() const noexcept {return m_EffectivePixelYSize;} - __host__ __device__ inline float get_localZcoord() const noexcept {return m_localZcoord;} + __host__ __device__ inline float get_EffectivePixelXSize() const noexcept { return m_EffectivePixelXSize; } + __host__ __device__ inline float get_EffectivePixelYSize() const noexcept { return m_EffectivePixelYSize; } + __host__ __device__ inline float get_localZcoord() const noexcept { return m_localZcoord; } __host__ __device__ inline float get_NumPixRowFrac() const { return m_NumPixRowFrac; } /// Effective pixel area __host__ __device__ inline auto effectivePixelArea() const noexcept { return m_effPixelArea; } - __host__ __device__ inline float get_NumPixColFrac() const noexcept {return m_NumPixColFrac;} + __host__ __device__ inline float get_NumPixColFrac() const noexcept { return m_NumPixColFrac; } /// Access the local to global transform - __host__ __device__ inline const std::array& localToGlobal() const noexcept { return m_locToGloM; } + __host__ __device__ inline const std::array& localToGlobal() const noexcept { return m_locToGloM; } - std::string toString() const { + std::string toString() const + { std::ostringstream oss; oss << "PD { " - << "m_locToGloM: " - << m_locToGloM[0] << " " << m_locToGloM[1] << " " << m_locToGloM[2] << " " - << m_locToGloM[3] << " " << m_locToGloM[4] << " " << m_locToGloM[5] << " " - << m_locToGloM[6] << " " << m_locToGloM[7] << " " << m_locToGloM[8] << " " - << m_locToGloM[9] << " " << m_locToGloM[10] << " " << m_locToGloM[11] << " " << ", " - << "m_zeroInPanelFrame: " << m_zeroInPanelFrame[0] << m_zeroInPanelFrame[1] << m_zeroInPanelFrame[2] << ", " - << "effPixelArea: " << m_effPixelArea << ", " - << "numPixels: " << m_numPixels << ", " - << "localZcoord: " << m_localZcoord << ", " - << "NumPixColFrac: " << m_NumPixColFrac << ", " - << "NumPixRowFrac: " << m_NumPixRowFrac << ", " - << "EffectivePixelXSize: " << m_EffectivePixelXSize << ", " - << "EffectivePixelYSize: " << m_EffectivePixelYSize << ", " - << "pdSmartID: " << m_pdSmartID << ", " - << "isHType: " << (m_isHType ? "true" : "false") - << "isNull: " << (m_isNull ? "true" : "false") - << " }"; + << "m_locToGloM: " << m_locToGloM[0] << " " << m_locToGloM[1] << " " << m_locToGloM[2] << " " + << m_locToGloM[3] << " " << m_locToGloM[4] << " " << m_locToGloM[5] << " " << m_locToGloM[6] << " " + << m_locToGloM[7] << " " << m_locToGloM[8] << " " << m_locToGloM[9] << " " << m_locToGloM[10] << " " + << m_locToGloM[11] << " " + << ", " + << "m_zeroInPanelFrame: " << m_zeroInPanelFrame[0] << m_zeroInPanelFrame[1] << m_zeroInPanelFrame[2] << ", " + << "effPixelArea: " << m_effPixelArea << ", " + << "numPixels: " << m_numPixels << ", " + << "localZcoord: " << m_localZcoord << ", " + << "NumPixColFrac: " << m_NumPixColFrac << ", " + << "NumPixRowFrac: " << m_NumPixRowFrac << ", " + << "EffectivePixelXSize: " << m_EffectivePixelXSize << ", " + << "EffectivePixelYSize: " << m_EffectivePixelYSize << ", " + << "pdSmartID: " << m_pdSmartID << ", " + << "isHType: " << (m_isHType ? "true" : "false") << "isNull: " << (m_isNull ? "true" : "false") << " }"; return oss.str(); } - __host__ __device__ bool getIsNull() const { - return m_isNull; - } + __host__ __device__ bool getIsNull() const { return m_isNull; } - __host__ __device__ void setIsNull(bool value){ - m_isNull = value; - } + __host__ __device__ void setIsNull(bool value) { m_isNull = value; } - private: + private: std::array m_locToGloM; std::array m_zeroInPanelFrame; std::uint64_t m_pdSmartID; diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index 44560cdfaeb..7b0ef8031bd 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -12,99 +12,100 @@ #include #include #include - -namespace Allen { - class PDPanel final { - public: - PDPanel() { } - - using PDsArray = std::array; - using ModuleArray = std::array; - - PDPanel( - Rich::Future::DAQ::DetectorType rich, - Rich::Future::DAQ::Side side, - std::array gloToPDPanelM, - ModuleArray PDs - ) : m_PDs(std::move(PDs)), - m_gloToPDPanelM(gloToPDPanelM), - m_panelID({rich, side, 0}), - m_rich(rich), - m_side(side) { } - - PDPanel(const PDPanel& other) - : m_gloToPDPanelM(other.m_gloToPDPanelM), - m_panelID(other.m_panelID), - m_rich(other.m_rich), - m_side(other.m_side) { - for (size_t i = 0; i < other.m_PDs.size(); ++i) { - for (size_t j = 0; j < other.m_PDs[i].size(); ++j) { - if (!(other.m_PDs[i][j].getIsNull())) { - m_PDs[i][j] = Rich::Detector::Allen::PD(other.m_PDs[i][j]); - } else { - m_PDs[i][j] = Rich::Detector::Allen::PD(); - m_PDs[i][j].setIsNull(true); - } - } - } - } - - /// Access the RICH detector type - __host__ __device__ inline auto rich() const noexcept { return m_rich; } - - /// Access the PD panel side - __host__ __device__ inline auto side() const noexcept { return m_side; } - - __host__ __device__ auto dePD(const RichSmartID smartID) const { - const Rich::Detector::Allen::PD* dePD = nullptr; - if (smartID.pdIsSet()) { - const auto localModNum = smartID.pdMod() - m_modNumOffset; - if (localModNum < pdModules().size()) { - const auto& mod = pdModules()[localModNum]; - if (smartID.pdNumInMod() < mod.size()) { - const auto& pd = mod[smartID.pdNumInMod()]; - dePD = &pd; - } - } - } - return dePD; - } - - /// Compute the detection point for a given RichSmartID - __host__ __device__ inline auto detectionPoint( const RichSmartID id ) const noexcept { - const auto pd = dePD( id ); - return ( pd ? pd->detectionPoint( id ) : Allen::Point{0,0,0} ); - } - - /// Access the global to local transform - __host__ __device__ inline const auto& globalToPDPanel() const noexcept { return m_gloToPDPanelM; } - - /// Access all owned PD Modules - __host__ __device__ const ModuleArray& pdModules() const noexcept { return m_PDs; } - - std::string toString() const { - std::stringstream ss; - for (size_t i = 0; i < m_PDs.size(); ++i) { - ss << "RICH " << (int)m_rich << ", Side " << (int)m_side << ", Module No. " << i << ", PDs: "; - for (size_t j = 0; j < m_PDs[i].size(); ++j) { - if (!(m_PDs[i][j].getIsNull())) { - auto pd = m_PDs[i][j]; - ss << pd.toString() << '\n'; - } else { - ss << " 0\n"; - } - } - ss << "\n"; - } - return ss.str(); - } - - private: - ModuleArray m_PDs; - std::array m_gloToPDPanelM; // 3D Transform - uint32_t m_modNumOffset; - std::array m_panelID; - Rich::Future::DAQ::DetectorType m_rich; - Rich::Future::DAQ::Side m_side; - }; -} + +namespace Allen { + class PDPanel final { + public: + PDPanel() {} + + using PDsArray = std::array; + using ModuleArray = std::array; + + PDPanel( + Rich::Future::DAQ::DetectorType rich, + Rich::Future::DAQ::Side side, + std::array gloToPDPanelM, + ModuleArray PDs) : + m_PDs(std::move(PDs)), + m_gloToPDPanelM(gloToPDPanelM), m_panelID({rich, side, 0}), m_rich(rich), m_side(side) + {} + + PDPanel(const PDPanel& other) : + m_gloToPDPanelM(other.m_gloToPDPanelM), m_panelID(other.m_panelID), m_rich(other.m_rich), m_side(other.m_side) + { + for (size_t i = 0; i < other.m_PDs.size(); ++i) { + for (size_t j = 0; j < other.m_PDs[i].size(); ++j) { + if (!(other.m_PDs[i][j].getIsNull())) { + m_PDs[i][j] = Rich::Detector::Allen::PD(other.m_PDs[i][j]); + } + else { + m_PDs[i][j] = Rich::Detector::Allen::PD(); + m_PDs[i][j].setIsNull(true); + } + } + } + } + + /// Access the RICH detector type + __host__ __device__ inline auto rich() const noexcept { return m_rich; } + + /// Access the PD panel side + __host__ __device__ inline auto side() const noexcept { return m_side; } + + __host__ __device__ auto dePD(const RichSmartID smartID) const + { + const Rich::Detector::Allen::PD* dePD = nullptr; + if (smartID.pdIsSet()) { + const auto localModNum = smartID.pdMod() - m_modNumOffset; + if (localModNum < pdModules().size()) { + const auto& mod = pdModules()[localModNum]; + if (smartID.pdNumInMod() < mod.size()) { + const auto& pd = mod[smartID.pdNumInMod()]; + dePD = &pd; + } + } + } + return dePD; + } + + /// Compute the detection point for a given RichSmartID + __host__ __device__ inline auto detectionPoint(const RichSmartID id) const noexcept + { + const auto pd = dePD(id); + return (pd ? pd->detectionPoint(id) : Allen::Point {0, 0, 0}); + } + + /// Access the global to local transform + __host__ __device__ inline const auto& globalToPDPanel() const noexcept { return m_gloToPDPanelM; } + + /// Access all owned PD Modules + __host__ __device__ const ModuleArray& pdModules() const noexcept { return m_PDs; } + + std::string toString() const + { + std::stringstream ss; + for (size_t i = 0; i < m_PDs.size(); ++i) { + ss << "RICH " << (int) m_rich << ", Side " << (int) m_side << ", Module No. " << i << ", PDs: "; + for (size_t j = 0; j < m_PDs[i].size(); ++j) { + if (!(m_PDs[i][j].getIsNull())) { + auto pd = m_PDs[i][j]; + ss << pd.toString() << '\n'; + } + else { + ss << " 0\n"; + } + } + ss << "\n"; + } + return ss.str(); + } + + private: + ModuleArray m_PDs; + std::array m_gloToPDPanelM; // 3D Transform + uint32_t m_modNumOffset; + std::array m_panelID; + Rich::Future::DAQ::DetectorType m_rich; + Rich::Future::DAQ::Side m_side; + }; +} // namespace Allen diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index 119f31e9223..94813d8903f 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -14,109 +14,90 @@ namespace Allen { class RichPixel { - public: - - // Default - __host__ __device__ RichPixel() : - gPos({0.0f, 0.0f, 0.0f}), - lPos({0.0f, 0.0f, 0.0f}), - m_smartID(), - m_effArea(0.0f), - m_rich(0), - m_side(0), - m_mask(0), - m_timeWindow(0.0f), - m_isInnerRegion(true), - m_isNull(true) {} - - // 3D - __host__ __device__ RichPixel( - const Point& gPos, - const Point& lPos, - const Allen::RichSmartID& smartID, - double effArea, - uint8_t rich, - uint8_t side, - uint8_t mask): - gPos(gPos), lPos(lPos), - m_smartID(smartID), - m_effArea(effArea), - m_rich(rich), - m_side(side), - m_mask(mask), - m_isNull(false) { - m_isInnerRegion = !smartID.isLargePMT(); - } - - // 4D - __host__ __device__ RichPixel( - const Point& gPos, - const Point& lPos, - const Allen::RichSmartID& smartID, - double effArea, - uint8_t rich, - uint8_t side, - uint8_t mask, - float timeWindow): - gPos(gPos), - lPos(lPos), - m_smartID(smartID), - m_effArea(effArea), - m_rich(rich), - m_side(side), - m_mask(mask), - m_timeWindow(timeWindow), - m_isNull(false) { - m_isInnerRegion = !smartID.isLargePMT(); - } - - __host__ __device__ inline void overrideRegions(const bool isInnerRegion ) noexcept { m_isInnerRegion = isInnerRegion; } - - __host__ __device__ inline auto rich() const { return m_rich; } - - __host__ __device__ inline auto side() const { return m_side; } - - __host__ __device__ inline Allen::RichSmartID smartID() const { return m_smartID; } - - __host__ __device__ inline auto gloPos() const { return gPos; } - - __host__ __device__ inline auto locPos() const { return lPos; } - - __host__ __device__ inline auto effArea() const { return m_effArea; } - - __host__ __device__ inline auto mask() const { return m_mask; } - - __host__ __device__ inline auto timeWindow() const { return m_timeWindow; } - - __host__ __device__ inline auto isInnerRegion() const { return m_isInnerRegion; } - - __host__ __device__ inline auto isNull() const { return m_isNull; } - - std::string toString() { - std::stringstream ss; - if (m_smartID.key() == 0) return "SmartID key is 0"; - ss << m_smartID.key() << ',' - << gPos[0] << ',' << gPos[1] << ',' << gPos[2] << ',' - << lPos[0] << ',' << lPos[1] << ',' << lPos[2] << ',' - << m_effArea << ',' - << (int)m_rich << ',' << (int)m_side << ',' - << (int)m_mask << ',' - << m_timeWindow << ',' - << m_isInnerRegion << ',' - << m_isNull << '\n'; - return ss.str(); - } - - private: - Point gPos; - Point lPos; - Allen::RichSmartID m_smartID; - double m_effArea; - uint8_t m_rich; - uint8_t m_side; - uint8_t m_mask; - float m_timeWindow; - bool m_isInnerRegion; - bool m_isNull; + public: + // Default + __host__ __device__ RichPixel() : + gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID(), m_effArea(0.0f), m_rich(0), m_side(0), m_mask(0), + m_timeWindow(0.0f), m_isInnerRegion(true), m_isNull(true) + {} + + // 3D + __host__ __device__ RichPixel( + const Point& gPos, + const Point& lPos, + const Allen::RichSmartID& smartID, + double effArea, + uint8_t rich, + uint8_t side, + uint8_t mask) : + gPos(gPos), + lPos(lPos), m_smartID(smartID), m_effArea(effArea), m_rich(rich), m_side(side), m_mask(mask), m_isNull(false) + { + m_isInnerRegion = !smartID.isLargePMT(); + } + + // 4D + __host__ __device__ RichPixel( + const Point& gPos, + const Point& lPos, + const Allen::RichSmartID& smartID, + double effArea, + uint8_t rich, + uint8_t side, + uint8_t mask, + float timeWindow) : + gPos(gPos), + lPos(lPos), m_smartID(smartID), m_effArea(effArea), m_rich(rich), m_side(side), m_mask(mask), + m_timeWindow(timeWindow), m_isNull(false) + { + m_isInnerRegion = !smartID.isLargePMT(); + } + + __host__ __device__ inline void overrideRegions(const bool isInnerRegion) noexcept + { + m_isInnerRegion = isInnerRegion; + } + + __host__ __device__ inline auto rich() const { return m_rich; } + + __host__ __device__ inline auto side() const { return m_side; } + + __host__ __device__ inline Allen::RichSmartID smartID() const { return m_smartID; } + + __host__ __device__ inline auto gloPos() const { return gPos; } + + __host__ __device__ inline auto locPos() const { return lPos; } + + __host__ __device__ inline auto effArea() const { return m_effArea; } + + __host__ __device__ inline auto mask() const { return m_mask; } + + __host__ __device__ inline auto timeWindow() const { return m_timeWindow; } + + __host__ __device__ inline auto isInnerRegion() const { return m_isInnerRegion; } + + __host__ __device__ inline auto isNull() const { return m_isNull; } + + std::string toString() + { + std::stringstream ss; + if (m_smartID.key() == 0) return "SmartID key is 0"; + ss << m_smartID.key() << ',' << gPos[0] << ',' << gPos[1] << ',' << gPos[2] << ',' << lPos[0] << ',' << lPos[1] + << ',' << lPos[2] << ',' << m_effArea << ',' << (int) m_rich << ',' << (int) m_side << ',' << (int) m_mask + << ',' << m_timeWindow << ',' << m_isInnerRegion << ',' << m_isNull << '\n'; + return ss.str(); + } + + private: + Point gPos; + Point lPos; + Allen::RichSmartID m_smartID; + double m_effArea; + uint8_t m_rich; + uint8_t m_side; + uint8_t m_mask; + float m_timeWindow; + bool m_isInnerRegion; + bool m_isNull; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDs.cuh b/device/rich/decoding/include/RichSmartIDs.cuh index 00a06524e7b..1935ea968b3 100644 --- a/device/rich/decoding/include/RichSmartIDs.cuh +++ b/device/rich/decoding/include/RichSmartIDs.cuh @@ -15,70 +15,71 @@ #include #define PANEL_COUNT 2 - -namespace Allen { - class RichSmartIDs { - public: - /// Constructor from RICH detector elements - RichSmartIDs( - const Allen::PDPanel& pdPanel1, - const Allen::PDPanel& pdPanel2) - : m_pdPanels{&pdPanel1, &pdPanel2} { } - - RichSmartIDs(const std::array m_pdPanels) - : m_pdPanels{m_pdPanels} { } - - __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Allen::PDPanel* { - using DetectorType = Rich::Future::DAQ::DetectorType; - using Side = Rich::Future::DAQ::Side; - - // Determine the rich type - DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; - // Determine the side - Side side; - if (rich == DetectorType::Rich1) { - // For Rich1, 0 = top, 1 = bottom - side = (smartID.panel() == 0) ? Side::top : Side::bottom; - } else { - // For Rich2, 0 = left, 1 = right - side = (smartID.panel() == 0) ? Side::left : Side::right; - } - - for (size_t i = 0; i < m_pdPanels.size(); i++) { - const Allen::PDPanel* pdPanel = m_pdPanels[i]; - if (pdPanel->rich() == rich && pdPanel->side() == side) { - return pdPanel; - } - } - return nullptr; - } - - __host__ __device__ inline auto panel( - const Rich::Future::DAQ::DetectorType rtype, - const Rich::Future::DAQ::Side side ) const -> const Allen::PDPanel* { - for (size_t i = 0;i < m_pdPanels.size(); i++) { - const Allen::PDPanel* pdPanel = m_pdPanels[i]; - if (pdPanel->rich() == rtype && pdPanel->side() == side) { - return pdPanel; - } - } - return nullptr; - } - - // Converts an PD RichSmartID identification into a position in global LHCb coordinates. - __host__ __device__ Point pdPosition( const Allen::RichSmartID pdid ) const; - - // Converts a position in global coordinates to the corresponding RichSmartID - __host__ __device__ bool smartID( const Point& globalPoint, Allen::RichSmartID& smartid ) const; - - // Converts a position in global coordinates to the local coordinate system. - __host__ __device__ Point globalToPDPanel( const Point& globalPoint ) const; - - // Get the position for a given SmartID. - __host__ __device__ inline auto _globalPosition( const Allen::RichSmartID id ) const { - return panel(id)->detectionPoint(id); - } - private: - const std::array m_pdPanels; - }; -} + +namespace Allen { + class RichSmartIDs { + public: + /// Constructor from RICH detector elements + RichSmartIDs(const Allen::PDPanel& pdPanel1, const Allen::PDPanel& pdPanel2) : m_pdPanels {&pdPanel1, &pdPanel2} {} + + RichSmartIDs(const std::array m_pdPanels) : m_pdPanels {m_pdPanels} {} + + __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Allen::PDPanel* + { + using DetectorType = Rich::Future::DAQ::DetectorType; + using Side = Rich::Future::DAQ::Side; + + // Determine the rich type + DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; + // Determine the side + Side side; + if (rich == DetectorType::Rich1) { + // For Rich1, 0 = top, 1 = bottom + side = (smartID.panel() == 0) ? Side::top : Side::bottom; + } + else { + // For Rich2, 0 = left, 1 = right + side = (smartID.panel() == 0) ? Side::left : Side::right; + } + + for (size_t i = 0; i < m_pdPanels.size(); i++) { + const Allen::PDPanel* pdPanel = m_pdPanels[i]; + if (pdPanel->rich() == rich && pdPanel->side() == side) { + return pdPanel; + } + } + return nullptr; + } + + __host__ __device__ inline auto panel( + const Rich::Future::DAQ::DetectorType rtype, + const Rich::Future::DAQ::Side side) const -> const Allen::PDPanel* + { + for (size_t i = 0; i < m_pdPanels.size(); i++) { + const Allen::PDPanel* pdPanel = m_pdPanels[i]; + if (pdPanel->rich() == rtype && pdPanel->side() == side) { + return pdPanel; + } + } + return nullptr; + } + + // Converts an PD RichSmartID identification into a position in global LHCb coordinates. + __host__ __device__ Point pdPosition(const Allen::RichSmartID pdid) const; + + // Converts a position in global coordinates to the corresponding RichSmartID + __host__ __device__ bool smartID(const Point& globalPoint, Allen::RichSmartID& smartid) const; + + // Converts a position in global coordinates to the local coordinate system. + __host__ __device__ Point globalToPDPanel(const Point& globalPoint) const; + + // Get the position for a given SmartID. + __host__ __device__ inline auto _globalPosition(const Allen::RichSmartID id) const + { + return panel(id)->detectionPoint(id); + } + + private: + const std::array m_pdPanels; + }; +} // namespace Allen diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index 047539b3b63..aa5211b5f3e 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -20,31 +20,31 @@ INSTANTIATE_ALGORITHM(rich_make_pixels::rich_make_pixels_t); /// Enabled 4D reconstruction -__constant__ std::array m_enable4D{false, false}; +__constant__ std::array m_enable4D {false, false}; /// Average expected hit time for signal in each RICH in ns -__constant__ std::array m_avHitTime{13.03, 52.94}; +__constant__ std::array m_avHitTime {13.03, 52.94}; /// Course (pixel) Time window for each RICH in ns -__constant__ std::array m_timeWindow{3.0, 3.0}; +__constant__ std::array m_timeWindow {3.0, 3.0}; /// Enable the override of inner and out regions -__constant__ std::array m_overrideRegions{false, false}; +__constant__ std::array m_overrideRegions {false, false}; /// Size in X defining the inner pixels for each RICH -__constant__ std::array m_innerPixX{250.0, 99999.9}; +__constant__ std::array m_innerPixX {250.0, 99999.9}; /// Size in Y defining the inner pixels for each RICH -__constant__ std::array m_innerPixY{300.0, 300.0}; +__constant__ std::array m_innerPixY {300.0, 300.0}; /// Time resolution for inner regions in ns -__constant__ std::array m_innerTimeWindow{0.15, 0.15}; +__constant__ std::array m_innerTimeWindow {0.15, 0.15}; /// Time resolution for outer regions in ns -__constant__ std::array m_outerTimeWindow{0.3, 0.3}; +__constant__ std::array m_outerTimeWindow {0.3, 0.3}; __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, const Allen::RichSmartID& smartID) -{ +{ float effArea; // Effective area uint8_t mask = 0; // Selection mask bool innerRegion = 1; // Inner/outer region @@ -56,36 +56,37 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, cons auto savePix = [&]() { const auto gPos = smartIDsHelper->_globalPosition(smartID); const auto lPos = smartIDsHelper->globalToPDPanel(gPos); - const auto isInner = ( m_overrideRegions[rich] ? - ( abs( lPos[0] ) < float( m_innerPixX[rich] ) && - abs( lPos[1] ) < float( m_innerPixY[rich] ) ) - : innerRegion ); + const auto isInner = + (m_overrideRegions[rich] ? (abs(lPos[0]) < float(m_innerPixX[rich]) && abs(lPos[1]) < float(m_innerPixY[rich])) : + innerRegion); Allen::RichPixel pixel; // 4D specific properties float timeWindow = 999999; - if ( m_enable4D[rich] ) { - timeWindow = isInner ? float( m_innerTimeWindow[rich] ) : float( m_outerTimeWindow[rich] ); + if (m_enable4D[rich]) { + timeWindow = isInner ? float(m_innerTimeWindow[rich]) : float(m_outerTimeWindow[rich]); } pixel = Allen::RichPixel(gPos, lPos, smartID, effArea, rich, side, mask, timeWindow); - if ( m_overrideRegions[rich] ) { pixel.overrideRegions( isInner ); } + if (m_overrideRegions[rich]) { + pixel.overrideRegions(isInner); + } return pixel; }; bool smartIDSelected = true; - if ( m_enable4D[rich] ) { - if ( smartID.adcTimeIsSet() ) { + if (m_enable4D[rich]) { + if (smartID.adcTimeIsSet()) { const auto hitT = smartID.time(); - if ( fabs( hitT - m_avHitTime[rich] ) > m_timeWindow[rich] ) { + if (fabs(hitT - m_avHitTime[rich]) > m_timeWindow[rich]) { smartIDSelected = false; } } } - if ( smartIDSelected ) { - if ((smartIDsHelper->panel(smartID)->dePD(smartID))){ - if (!(smartIDsHelper->panel(smartID)->dePD(smartID)->getIsNull())){ + if (smartIDSelected) { + if ((smartIDsHelper->panel(smartID)->dePD(smartID))) { + if (!(smartIDsHelper->panel(smartID)->dePD(smartID)->getIsNull())) { effArea = smartIDsHelper->panel(smartID)->dePD(smartID)->effectivePixelArea(); innerRegion = !smartID.isLargePMT(); return savePix(); @@ -98,25 +99,26 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, cons __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Allen::RichSmartIDs* smartIDsHelper) { const auto eventNumber = parameters.dev_event_list[blockIdx.x]; - auto eventSmartIDCount = parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; + auto eventSmartIDCount = + parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; for (unsigned smartID = threadIdx.x; smartID < eventSmartIDCount; smartID += blockDim.x) { parameters.dev_rich_pixels[smartID] = make_pixel(smartIDsHelper, parameters.dev_smart_ids[smartID]); } } void rich_make_pixels::rich_make_pixels_t::set_arguments_size( - ArgumentReferences arguments, - const RuntimeOptions&, - const Constants&) const + ArgumentReferences arguments, + const RuntimeOptions&, + const Constants&) const { set_size(arguments, size(arguments)); } void rich_make_pixels::rich_make_pixels_t::operator()( - const ArgumentReferences& arguments, - const RuntimeOptions&, - const Constants& constants, - const Allen::Context& context) const + const ArgumentReferences& arguments, + const RuntimeOptions&, + const Constants& constants, + const Allen::Context& context) const { // Create RICH objects from dump Allen::Rich1* rich1; @@ -126,23 +128,22 @@ void rich_make_pixels::rich_make_pixels_t::operator()( rich1 = reinterpret_cast(constants.dev_rich_1_geometry); else rich2 = reinterpret_cast(constants.dev_rich_2_geometry); - + // Send panels from RICH to SmartIDsHelper - std::array panels; + std::array panels; for (size_t i = 0; i < 2; i++) { if (richValue == 1) panels[i] = &(rich1->pdPanels()[i]); else - panels[i] = &(rich2->pdPanels()[i]); + panels[i] = &(rich2->pdPanels()[i]); } Allen::RichSmartIDs smartIDsHelper = Allen::RichSmartIDs(panels); Allen::RichSmartIDs* dev_smartIDsHelper; - Allen::malloc((void**)&dev_smartIDsHelper, sizeof(Allen::RichSmartIDs)); + Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDs)); Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDs), Allen::memcpyHostToDevice); - global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim,context)( - arguments, dev_smartIDsHelper - ); + global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( + arguments, dev_smartIDsHelper); Allen::free(dev_smartIDsHelper); } diff --git a/device/rich/decoding/src/RichSmartIDs.cu b/device/rich/decoding/src/RichSmartIDs.cu index 2bda3dc9a2d..d65b3206d65 100644 --- a/device/rich/decoding/src/RichSmartIDs.cu +++ b/device/rich/decoding/src/RichSmartIDs.cu @@ -11,35 +11,45 @@ #include #include - -using Point = Allen::Point; - -Point Allen::RichSmartIDs::pdPosition( const Allen::RichSmartID pdid ) const { - // Create temporary RichSmartIDs for two corners of the PD wafer - Allen::RichSmartID id1( pdid ), id0( pdid ); - id0.setPixelRow( 1 ); - id0.setPixelCol( 1 ); - id1.setPixelRow( 6 ); - id1.setPixelCol( 6 ); - // Get position of each of these pixels - const auto a = _globalPosition( id0 ); - const auto b = _globalPosition( id1 ); - // Return average position (i.e. PD centre) - return Point{0.5f * ( a[0] + b[0] ), // - 0.5f * ( a[1] + b[1] ), // - 0.5f * ( a[2] + b[2] )}; -} - -// Converts a point from the global frame to the detector panel frame -Point Allen::RichSmartIDs::globalToPDPanel( const Point& globalPoint ) const { - return ( globalPoint[2] < 8000.f ? - // RICH1 - ( globalPoint[1] > 0.f ? - Allen::transform3DTimesPoint(panel( Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::top )->globalToPDPanel(), globalPoint) - : Allen::transform3DTimesPoint(panel( Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::bottom )->globalToPDPanel(), globalPoint) ) - : - // RICH2 - ( globalPoint[0] > 0.f ? - Allen::transform3DTimesPoint(panel( Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::left )->globalToPDPanel(), globalPoint) - : Allen::transform3DTimesPoint(panel( Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::right )->globalToPDPanel(), globalPoint )) ); -} + +using Point = Allen::Point; + +Point Allen::RichSmartIDs::pdPosition(const Allen::RichSmartID pdid) const +{ + // Create temporary RichSmartIDs for two corners of the PD wafer + Allen::RichSmartID id1(pdid), id0(pdid); + id0.setPixelRow(1); + id0.setPixelCol(1); + id1.setPixelRow(6); + id1.setPixelCol(6); + // Get position of each of these pixels + const auto a = _globalPosition(id0); + const auto b = _globalPosition(id1); + // Return average position (i.e. PD centre) + return Point {0.5f * (a[0] + b[0]), // + 0.5f * (a[1] + b[1]), // + 0.5f * (a[2] + b[2])}; +} + +// Converts a point from the global frame to the detector panel frame +Point Allen::RichSmartIDs::globalToPDPanel(const Point& globalPoint) const +{ + return ( + globalPoint[2] < 8000.f ? + // RICH1 + (globalPoint[1] > 0.f ? + Allen::transform3DTimesPoint( + panel(Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::top)->globalToPDPanel(), + globalPoint) : + Allen::transform3DTimesPoint( + panel(Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::bottom)->globalToPDPanel(), + globalPoint)) : + // RICH2 + (globalPoint[0] > 0.f ? + Allen::transform3DTimesPoint( + panel(Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::left)->globalToPDPanel(), + globalPoint) : + Allen::transform3DTimesPoint( + panel(Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::right)->globalToPDPanel(), + globalPoint))); +} diff --git a/main/src/RegisterConsumers.cpp b/main/src/RegisterConsumers.cpp index c9a8c496094..b600f3aa945 100644 --- a/main/src/RegisterConsumers.cpp +++ b/main/src/RegisterConsumers.cpp @@ -99,7 +99,8 @@ void register_consumers( std::make_tuple( Allen::NonEventData::Rich1Geometry {}, [&constants]() { - return std::make_unique(constants.host_rich_1_geometry, constants.dev_rich_1_geometry); + return std::make_unique( + constants.host_rich_1_geometry, constants.dev_rich_1_geometry); }, BankTypes::Rich1), std::make_tuple( @@ -119,7 +120,8 @@ void register_consumers( std::make_tuple( Allen::NonEventData::Rich2Geometry {}, [&constants]() { - return std::make_unique(constants.host_rich_2_geometry, constants.dev_rich_2_geometry); + return std::make_unique( + constants.host_rich_2_geometry, constants.dev_rich_2_geometry); }, BankTypes::Rich2)); diff --git a/stream/sequence/include/Constants.cuh b/stream/sequence/include/Constants.cuh index 75cf748b7ce..9e748818906 100644 --- a/stream/sequence/include/Constants.cuh +++ b/stream/sequence/include/Constants.cuh @@ -46,11 +46,11 @@ namespace TrackMatchingConsts { namespace Rich::Future::DAQ::Allen { class PDMDBDecodeMapping; class Tel40CableMapping; -} +} // namespace Rich::Future::DAQ::Allen namespace Allen { class Rich1; class Rich2; -} +} // namespace Allen namespace UT::Constants { struct UTLayerGeometry; -- GitLab From a03e71bde1582ed303cc5e87818ea53c181ea92c Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Wed, 26 Mar 2025 17:31:56 +0000 Subject: [PATCH 03/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/53353377 --- device/rich/decoding/include/RichPDPanel.cuh | 28 +++++++-------- device/rich/decoding/include/RichSmartIDs.cuh | 34 +++++++++---------- device/rich/decoding/src/RichSmartIDs.cu | 26 +++++++------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index 7b0ef8031bd..671d79b7dd9 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -1,17 +1,17 @@ -/*****************************************************************************\ - * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * - * * - * This software is distributed under the terms of the Apache License * - * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * - * * - * In applying this licence, CERN does not waive the privileges and immunities * - * granted to it by virtue of its status as an Intergovernmental Organization * - * or submit itself to any jurisdiction. * - \*****************************************************************************/ -#pragma once -#include -#include -#include +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include +#include +#include namespace Allen { class PDPanel final { diff --git a/device/rich/decoding/include/RichSmartIDs.cuh b/device/rich/decoding/include/RichSmartIDs.cuh index 1935ea968b3..dcda7d72018 100644 --- a/device/rich/decoding/include/RichSmartIDs.cuh +++ b/device/rich/decoding/include/RichSmartIDs.cuh @@ -1,20 +1,20 @@ -/*****************************************************************************\ - * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * - * * - * This software is distributed under the terms of the Apache License * - * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * - * * - * In applying this licence, CERN does not waive the privileges and immunities * - * granted to it by virtue of its status as an Intergovernmental Organization * - * or submit itself to any jurisdiction. * - \*****************************************************************************/ -#pragma once -#include -#include -#include -#include - -#define PANEL_COUNT 2 +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include +#include +#include +#include + +#define PANEL_COUNT 2 namespace Allen { class RichSmartIDs { diff --git a/device/rich/decoding/src/RichSmartIDs.cu b/device/rich/decoding/src/RichSmartIDs.cu index d65b3206d65..41f1e0f0c3e 100644 --- a/device/rich/decoding/src/RichSmartIDs.cu +++ b/device/rich/decoding/src/RichSmartIDs.cu @@ -1,16 +1,16 @@ -/*****************************************************************************\ -* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the Apache License * -* version 2 (Apache-2.0), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ - -#include -#include +/*****************************************************************************\ +* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the Apache License * +* version 2 (Apache-2.0), copied verbatim in the file "COPYING". * +* * +* In applying this licence, CERN does not waive the privileges and immunities * +* granted to it by virtue of its status as an Intergovernmental Organization * +* or submit itself to any jurisdiction. * +\*****************************************************************************/ + +#include +#include using Point = Allen::Point; -- GitLab From 4e530bea3dd0ce1143f7a146bd8d9a8851172569 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 28 Mar 2025 04:30:35 +0100 Subject: [PATCH 04/92] moved constants to richDefinitions, added Gaudi counters to tests and renamed them for uniformity --- Rec/Allen/CMakeLists.txt | 4 +- ...xels.cpp => CompareRecAllenRichPixels.cpp} | 51 +++-- ...ls.cpp => CompareRecAllenRichSmartIDs.cpp} | 10 +- .../rich/decoding/include/RichDefinitions.cuh | 177 ++++++++++-------- device/rich/decoding/src/RichMakePixels.cu | 57 ++---- out.txt | 0 6 files changed, 149 insertions(+), 150 deletions(-) rename Rec/Allen/src/{TestAllenRichMakePixels.cpp => CompareRecAllenRichPixels.cpp} (84%) rename Rec/Allen/src/{TestAllenRichPixels.cpp => CompareRecAllenRichSmartIDs.cpp} (91%) delete mode 100644 out.txt diff --git a/Rec/Allen/CMakeLists.txt b/Rec/Allen/CMakeLists.txt index 8293d3c9636..1abe385c8be 100644 --- a/Rec/Allen/CMakeLists.txt +++ b/Rec/Allen/CMakeLists.txt @@ -39,8 +39,8 @@ gaudi_add_module(AllenWrapper src/CompareRecAllenFTClusters.cpp src/CompareRecAllenVPHits.cpp src/TestVeloClusters.cpp - src/TestAllenRichPixels.cpp - src/TestAllenRichMakePixels.cpp + src/CompareRecAllenRichSmartIDs.cpp + src/CompareRecAllenRichPixels.cpp src/IOMonitor.cpp LINK AllenLib diff --git a/Rec/Allen/src/TestAllenRichMakePixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp similarity index 84% rename from Rec/Allen/src/TestAllenRichMakePixels.cpp rename to Rec/Allen/src/CompareRecAllenRichPixels.cpp index 1a85ff978e1..d98804c907a 100644 --- a/Rec/Allen/src/TestAllenRichMakePixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -3,6 +3,7 @@ \*****************************************************************************/ // Gaudi #include "GaudiAlg/Consumer.h" +#include "Gaudi/Accumulators.h" // Rec #include "RichFutureRecEvent/RichRecSIMDPixels.h" @@ -11,24 +12,32 @@ #include "RichMakePixels.cuh" #include "RichPixels.cuh" -class TestAllenRichMakePixels final : public Gaudi::Functional::Consumer&, const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&)> { + public: /// Standard constructor - TestAllenRichMakePixels(const std::string& name, ISvcLocator* pSvcLocator); + CompareRecAllenRichPixels(const std::string& name, ISvcLocator* pSvcLocator); /// Algorithm execution void operator()( const std::vector&, const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&) const override; +private: + + mutable Gaudi::Accumulators::Counter<> m_allen_in_rec {this, "Allen Pixels found in Rec"}; + mutable Gaudi::Accumulators::Counter<> m_allen_not_in_rec {this, "Allen Pixels not found in Rec"}; + mutable Gaudi::Accumulators::Counter<> m_rec_in_allen {this, "Rec Pixels found in Allen"}; + mutable Gaudi::Accumulators::Counter<> m_rec_not_in_allen {this, "Rec Pixels found in Allen"}; + mutable Gaudi::Accumulators::Counter<> m_allen_null {this, "Null Allen Pixels"}; }; -DECLARE_COMPONENT(TestAllenRichMakePixels) +DECLARE_COMPONENT(CompareRecAllenRichPixels) -TestAllenRichMakePixels::TestAllenRichMakePixels(const std::string& name, ISvcLocator* pSvcLocator) : +CompareRecAllenRichPixels::CompareRecAllenRichPixels(const std::string& name, ISvcLocator* pSvcLocator) : Consumer( name, pSvcLocator, @@ -37,24 +46,16 @@ TestAllenRichMakePixels::TestAllenRichMakePixels(const std::string& name, ISvcLo // When reading this code, keep in mind that recPixelSummaries contain multiple pixels, while allenRichPixels contain // individual pixels -void TestAllenRichMakePixels::operator()( +void CompareRecAllenRichPixels::operator()( const std::vector& allenRich1Pixels, const std::vector& allenRich2Pixels, const Rich::Future::Rec::SIMDPixelSummaries& recPixelSummaries) const { - int allen_in_rec = 0; - int allen_not_in_rec = 0; - int rec_in_allen = 0; - int rec_not_in_allen = 0; - int allen_null = 0; - auto rich1_pixels = allenRich1Pixels; - auto rich2_pixels = allenRich2Pixels; - - // Concatenate Allen Pixel vectors + // Concatenate Allen Pixel vectors std::vector allenPixels; allenPixels.reserve(allenRich1Pixels.size() + allenRich2Pixels.size()); - allenPixels.insert(allenPixels.end(), rich1_pixels.begin(), rich1_pixels.end()); - allenPixels.insert(allenPixels.end(), rich2_pixels.begin(), rich2_pixels.end()); + allenPixels.insert(allenPixels.end(), allenRich1Pixels.begin(), allenRich1Pixels.end()); + allenPixels.insert(allenPixels.end(), allenRich2Pixels.begin(), allenRich2Pixels.end()); // functor to check if allen pixels exist in HLT2 auto allenPixelExistsInRec = [&](const Allen::RichPixel& allenPixel) -> bool { @@ -98,7 +99,7 @@ void TestAllenRichMakePixels::operator()( for (size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { // case: HLT2 pixels in case they are not found in Allen if (!found_current_pixel) { - rec_not_in_allen++; + ++m_rec_not_in_allen; error() << "Rec pixel does not exist in Allen" << endmsg; std::cout << "Rec pixel: " << recPixelSummary.gloPos().X()[i - 1] << ',' << recPixelSummary.gloPos().Y()[i - 1] << ',' << recPixelSummary.gloPos().Z()[i - 1] << ',' << recPixelSummary.locPos().X()[i - 1] << ',' @@ -129,7 +130,7 @@ void TestAllenRichMakePixels::operator()( (allenPixel.timeWindow() == recPixelSummary.timeWindow()[i]) && (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i])) { found_current_pixel = true; - rec_in_allen++; + ++m_rec_in_allen; continue; } // found a match } // iterate over Allen pixels @@ -148,14 +149,14 @@ void TestAllenRichMakePixels::operator()( if (!allenPixelExistsInRec(allenPixel)) { error() << "Allen pixel does not exist in Rec" << endmsg; std::cout << allenPixel.toString() << std::endl; - allen_not_in_rec++; + ++m_allen_not_in_rec; } else { - allen_in_rec++; + ++m_allen_in_rec; } } else { - allen_null++; + ++m_allen_null; } } @@ -163,12 +164,4 @@ void TestAllenRichMakePixels::operator()( for (auto& recPixelSummary : recPixelSummaries) { recPixelExistsInAllen(recPixelSummary); } - - // print final stats - /* std::cout << "allen_in_rec " << allen_in_rec << std::endl; - std::cout << "allen_not_in_rec " << allen_not_in_rec << std::endl; - std::cout << "allen_null " << allen_null << std::endl; - std::cout << "rec_in_allen " << rec_in_allen << std::endl; - std::cout << "rec_not_in_allen " << rec_not_in_allen << std::endl; - **/ } diff --git a/Rec/Allen/src/TestAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp similarity index 91% rename from Rec/Allen/src/TestAllenRichPixels.cpp rename to Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp index 98d6f414c23..9a45ccab8c6 100644 --- a/Rec/Allen/src/TestAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp @@ -19,14 +19,14 @@ #include "RichDecoding.cuh" #include "RichPDMDBDecodeMapping.cuh" -class TestAllenRichPixels final : public Gaudi::Functional::Consumer&, const std::vector&, const Rich::Future::DAQ::DecodedData&)> { public: /// Standard constructor - TestAllenRichPixels(const std::string& name, ISvcLocator* pSvcLocator); + CompareRecAllenRichSmartIDs(const std::string& name, ISvcLocator* pSvcLocator); /// Algorithm execution void operator()( @@ -35,9 +35,9 @@ public: const Rich::Future::DAQ::DecodedData&) const override; }; -DECLARE_COMPONENT(TestAllenRichPixels) +DECLARE_COMPONENT(CompareRecAllenRichSmartIDs) -TestAllenRichPixels::TestAllenRichPixels(const std::string& name, ISvcLocator* pSvcLocator) : +CompareRecAllenRichSmartIDs::CompareRecAllenRichSmartIDs(const std::string& name, ISvcLocator* pSvcLocator) : Consumer( name, pSvcLocator, @@ -46,7 +46,7 @@ TestAllenRichPixels::TestAllenRichPixels(const std::string& name, ISvcLocator* p KeyValue {"RichDecodedData", Rich::Future::DAQ::DecodedDataLocation::Default}}) {} -void TestAllenRichPixels::operator()( +void CompareRecAllenRichSmartIDs::operator()( const std::vector& allen_rich1_smart_ids, const std::vector& allen_rich2_smart_ids, const Rich::Future::DAQ::DecodedData& rec_rich_pixels) const diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 5f16f361914..43a49ad52c3 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -24,17 +24,44 @@ namespace Allen { using BitPackType = KeyType; using ADCTimeType = std::uint16_t; + //// Constants related to pixel reconstruction + /// Enabled 4D reconstruction + [[maybe_unused]] __constant__ static std::array m_enable4D = {false, false}; + + /// Average expected hit time for signal in each RICH in ns + [[maybe_unused]] __constant__ static std::array m_avHitTime = {13.03, 52.94}; + + /// Course (pixel) Time window for each RICH in ns + [[maybe_unused]] __constant__ static std::array m_timeWindow = {3.0, 3.0}; + + /// Enable the override of inner and out regions + [[maybe_unused]] __constant__ static std::array m_overrideRegions = {false, false}; + + /// Size in X defining the inner pixels for each RICH + [[maybe_unused]] __constant__ static std::array m_innerPixX = {250.0, 99999.9}; + + /// Size in Y defining the inner pixels for each RICH + [[maybe_unused]] __constant__ static std::array m_innerPixY = {300.0, 300.0}; + + /// Time resolution for inner regions in ns + [[maybe_unused]] __constant__ static std::array m_innerTimeWindow = {0.15, 0.15}; + + /// Time resolution for outer regions in ns + [[maybe_unused]] __constant__ static std::array m_outerTimeWindow = {0.3, 0.3}; + + /// Matrix-point transform3D, adapted from ROOT::Math __host__ __device__ inline Point transform3DTimesPoint(Transform3D fM, Point point) { return Point {fM[0] * point[0] + fM[1] * point[1] + fM[2] * point[2] + fM[3], - fM[4] * point[0] + fM[5] * point[1] + fM[6] * point[2] + fM[7], - fM[8] * point[0] + fM[9] * point[1] + fM[10] * point[2] + fM[11]}; + fM[4] * point[0] + fM[5] * point[1] + fM[6] * point[2] + fM[7], + fM[8] * point[0] + fM[9] * point[1] + fM[10] * point[2] + fM[11]}; } + /// RICH SmartIDs class class RichSmartID { KeyType m_key; - public: + public: // Set the RICH PD pixel row identifier __host__ __device__ constexpr void setPixelRow(const DataType row) { @@ -84,17 +111,17 @@ namespace Allen { // The masks static constexpr const BitPackType MaskPixelCol = (BitPackType)((BitPackType {1} << BitsPixelCol) - BitPackType {1}) - << ShiftPixelCol; + << ShiftPixelCol; static constexpr const BitPackType MaskPixelRow = (BitPackType)((BitPackType {1} << BitsPixelRow) - BitPackType {1}) - << ShiftPixelRow; + << ShiftPixelRow; static constexpr const BitPackType MaskPDNumInMod = (BitPackType)((BitPackType {1} << BitsPDNumInMod) - BitPackType {1}) << ShiftPDNumInMod; static constexpr const BitPackType MaskPDMod = (BitPackType)((BitPackType {1} << BitsPDMod) - BitPackType {1}) - << ShiftPDMod; + << ShiftPDMod; static constexpr const BitPackType MaskPanel = (BitPackType)((BitPackType {1} << BitsPanel) - BitPackType {1}) - << ShiftPanel; + << ShiftPanel; static constexpr const BitPackType MaskRich = (BitPackType)((BitPackType {1} << BitsRich) - BitPackType {1}) - << ShiftRich; + << ShiftRich; static constexpr const BitPackType MaskPixelSubRowIsSet = (BitPackType)((BitPackType {1} << BitsPixelSubRowIsSet) - BitPackType {1}) << ShiftPixelSubRowIsSet; static constexpr const BitPackType MaskPixelColIsSet = @@ -102,7 +129,7 @@ namespace Allen { static constexpr const BitPackType MaskPixelRowIsSet = (BitPackType)((BitPackType {1} << BitsPixelRowIsSet) - BitPackType {1}) << ShiftPixelRowIsSet; static constexpr const BitPackType MaskPDIsSet = (BitPackType)((BitPackType {1} << BitsPDIsSet) - BitPackType {1}) - << ShiftPDIsSet; + << ShiftPDIsSet; static constexpr const BitPackType MaskPanelIsSet = (BitPackType)((BitPackType {1} << BitsPanelIsSet) - BitPackType {1}) << ShiftPanelIsSet; static constexpr const BitPackType MaskRichIsSet = @@ -123,22 +150,22 @@ namespace Allen { static constexpr const BitPackType NChannelBits = 32; __host__ __device__ constexpr inline void - setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept - { - m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); - } + setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept + { + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); + } __host__ __device__ constexpr inline void - setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept - { - m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; - } + setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept + { + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; + } __host__ __device__ constexpr inline BitPackType getData(const BitPackType shift, const BitPackType mask) const noexcept - { - return (m_key & mask) >> shift; - } + { + return (m_key & mask) >> shift; + } __host__ __device__ constexpr inline BitPackType key() const noexcept { return m_key; } @@ -279,7 +306,7 @@ namespace Allen { return str; } - public: + public: // Number of PMT pixels per row static constexpr const DataType PixelsPerRow = 8; // Number of PMT pixels per column @@ -306,32 +333,32 @@ namespace Allen { __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() { return {std::array {0, ModulesPerPanel[0]}, - std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; + std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; } class MaPMT { - public: - static constexpr const DataType MaxPDsPerModule = 16; - static constexpr const DataType MaxModulesPerPanel = 92; - - // Bits for time field. - static constexpr const BitPackType BitsADCTime = 16; - static constexpr const BitPackType BitsADCTimeIsSet = 1; - static constexpr const BitPackType ShiftADCTime = NChannelBits; - static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; - static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) - << ShiftADCTime; - static constexpr const BitPackType MaskADCTimeIsSet = - (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; - - // Max ADC time that can be stored - static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType {1}; - - // Parameters for conversion between float and ADC time values - static constexpr const double MinTime = -50.0; // In nanoseconds - static constexpr const double MaxTime = 150.0; // In nanoseconds - static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); - static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; + public: + static constexpr const DataType MaxPDsPerModule = 16; + static constexpr const DataType MaxModulesPerPanel = 92; + + // Bits for time field. + static constexpr const BitPackType BitsADCTime = 16; + static constexpr const BitPackType BitsADCTimeIsSet = 1; + static constexpr const BitPackType ShiftADCTime = NChannelBits; + static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; + static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) + << ShiftADCTime; + static constexpr const BitPackType MaskADCTimeIsSet = + (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; + + // Max ADC time that can be stored + static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType {1}; + + // Parameters for conversion between float and ADC time values + static constexpr const double MinTime = -50.0; // In nanoseconds + static constexpr const double MaxTime = 150.0; // In nanoseconds + static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); + static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; }; }; // namespace RichSmartID } // namespace Allen @@ -361,42 +388,42 @@ namespace Rich::Future::DAQ { }; class PackedFrameSizes final { - public: - // Packed type - using IntType = std::uint8_t; - - private: - // Bits for each Size - static const IntType Bits0 = 4; - static const IntType Bits1 = 4; - // shifts - static const IntType Shift0 = 0; - static const IntType Shift1 = Shift0 + Bits0; - // masks - static const IntType Mask0 = (IntType)((1 << Bits0) - 1) << Shift0; - static const IntType Mask1 = (IntType)((1 << Bits1) - 1) << Shift1; - // max values - static const IntType Max0 = (1 << Bits0) - 1; - static const IntType Max1 = (1 << Bits1) - 1; + public: + // Packed type + using IntType = std::uint8_t; + + private: + // Bits for each Size + static const IntType Bits0 = 4; + static const IntType Bits1 = 4; + // shifts + static const IntType Shift0 = 0; + static const IntType Shift1 = Shift0 + Bits0; + // masks + static const IntType Mask0 = (IntType)((1 << Bits0) - 1) << Shift0; + static const IntType Mask1 = (IntType)((1 << Bits1) - 1) << Shift1; + // max values + static const IntType Max0 = (1 << Bits0) - 1; + static const IntType Max1 = (1 << Bits1) - 1; - public: - // Contructor from a single word - __host__ __device__ explicit PackedFrameSizes(const IntType d) : m_data(d) {} + public: + // Contructor from a single word + __host__ __device__ explicit PackedFrameSizes(const IntType d) : m_data(d) {} - // Get the overall data - __host__ __device__ inline IntType data() const noexcept { return m_data; } + // Get the overall data + __host__ __device__ inline IntType data() const noexcept { return m_data; } - // Get first size word - __host__ __device__ inline IntType size0() const noexcept { return ((data() & Mask0) >> Shift0); } + // Get first size word + __host__ __device__ inline IntType size0() const noexcept { return ((data() & Mask0) >> Shift0); } - // Get second size word - __host__ __device__ inline IntType size1() const noexcept { return ((data() & Mask1) >> Shift1); } + // Get second size word + __host__ __device__ inline IntType size1() const noexcept { return ((data() & Mask1) >> Shift1); } - // Get the total size - __host__ __device__ inline auto totalSize() const noexcept { return size0() + size1(); } + // Get the total size + __host__ __device__ inline auto totalSize() const noexcept { return size0() + size1(); } - private: - // The data word - IntType m_data {0}; + private: + // The data word + IntType m_data {0}; }; } // namespace Rich::Future::DAQ diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index aa5211b5f3e..d1ff9a32e63 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -19,30 +19,7 @@ INSTANTIATE_ALGORITHM(rich_make_pixels::rich_make_pixels_t); -/// Enabled 4D reconstruction -__constant__ std::array m_enable4D {false, false}; - -/// Average expected hit time for signal in each RICH in ns -__constant__ std::array m_avHitTime {13.03, 52.94}; - -/// Course (pixel) Time window for each RICH in ns -__constant__ std::array m_timeWindow {3.0, 3.0}; - -/// Enable the override of inner and out regions -__constant__ std::array m_overrideRegions {false, false}; - -/// Size in X defining the inner pixels for each RICH -__constant__ std::array m_innerPixX {250.0, 99999.9}; - -/// Size in Y defining the inner pixels for each RICH -__constant__ std::array m_innerPixY {300.0, 300.0}; - -/// Time resolution for inner regions in ns -__constant__ std::array m_innerTimeWindow {0.15, 0.15}; - -/// Time resolution for outer regions in ns -__constant__ std::array m_outerTimeWindow {0.3, 0.3}; - +/// Create a Pixel object from a given SmartID __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, const Allen::RichSmartID& smartID) { float effArea; // Effective area @@ -57,28 +34,28 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, cons const auto gPos = smartIDsHelper->_globalPosition(smartID); const auto lPos = smartIDsHelper->globalToPDPanel(gPos); const auto isInner = - (m_overrideRegions[rich] ? (abs(lPos[0]) < float(m_innerPixX[rich]) && abs(lPos[1]) < float(m_innerPixY[rich])) : - innerRegion); + (Allen::m_overrideRegions[rich] ? (abs(lPos[0]) < float(Allen::m_innerPixX[rich]) && abs(lPos[1]) < float(Allen::m_innerPixY[rich])) : + innerRegion); Allen::RichPixel pixel; // 4D specific properties float timeWindow = 999999; - if (m_enable4D[rich]) { - timeWindow = isInner ? float(m_innerTimeWindow[rich]) : float(m_outerTimeWindow[rich]); + if (Allen::m_enable4D[rich]) { + timeWindow = isInner ? float(Allen::m_innerTimeWindow[rich]) : float(Allen::m_outerTimeWindow[rich]); } pixel = Allen::RichPixel(gPos, lPos, smartID, effArea, rich, side, mask, timeWindow); - if (m_overrideRegions[rich]) { + if (Allen::m_overrideRegions[rich]) { pixel.overrideRegions(isInner); } return pixel; }; bool smartIDSelected = true; - if (m_enable4D[rich]) { + if (Allen::m_enable4D[rich]) { if (smartID.adcTimeIsSet()) { const auto hitT = smartID.time(); - if (fabs(hitT - m_avHitTime[rich]) > m_timeWindow[rich]) { + if (fabs(hitT - Allen::m_avHitTime[rich]) > Allen::m_timeWindow[rich]) { smartIDSelected = false; } } @@ -96,6 +73,7 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, cons return Allen::RichPixel(); } +/// Kernel function to iterate over Events, SmartIDs, and create Pixels __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Allen::RichSmartIDs* smartIDsHelper) { const auto eventNumber = parameters.dev_event_list[blockIdx.x]; @@ -106,19 +84,20 @@ __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, } } +/// Function to resize Allen sequence output data structure void rich_make_pixels::rich_make_pixels_t::set_arguments_size( - ArgumentReferences arguments, - const RuntimeOptions&, - const Constants&) const + ArgumentReferences arguments, + const RuntimeOptions&, + const Constants&) const { set_size(arguments, size(arguments)); } void rich_make_pixels::rich_make_pixels_t::operator()( - const ArgumentReferences& arguments, - const RuntimeOptions&, - const Constants& constants, - const Allen::Context& context) const + const ArgumentReferences& arguments, + const RuntimeOptions&, + const Constants& constants, + const Allen::Context& context) const { // Create RICH objects from dump Allen::Rich1* rich1; @@ -144,6 +123,6 @@ void rich_make_pixels::rich_make_pixels_t::operator()( Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDs), Allen::memcpyHostToDevice); global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - arguments, dev_smartIDsHelper); + arguments, dev_smartIDsHelper); Allen::free(dev_smartIDsHelper); } diff --git a/out.txt b/out.txt deleted file mode 100644 index e69de29bb2d..00000000000 -- GitLab From 28078db17de78efea1ee135376fc8212f733f991 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 28 Mar 2025 05:24:51 +0100 Subject: [PATCH 05/92] using float3 instead of arrays of three floats to represent points --- Rec/Allen/src/CompareRecAllenRichPixels.cpp | 24 +++++++++---------- .../rich/decoding/include/RichDefinitions.cuh | 8 +++---- device/rich/decoding/include/RichPixels.cuh | 4 ++-- device/rich/decoding/src/RichMakePixels.cu | 2 +- device/rich/decoding/src/RichSmartIDs.cu | 12 +++++----- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index d98804c907a..095eebc0e71 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -67,12 +67,12 @@ void CompareRecAllenRichPixels::operator()( if (recPixelSummary.validMask()[i]) { // check for match if ( - (allenPixel.gloPos()[0] == recPixelSummary.gloPos().X()[i]) && - (allenPixel.gloPos()[1] == recPixelSummary.gloPos().Y()[i]) && - (allenPixel.gloPos()[2] == recPixelSummary.gloPos().Z()[i]) && - (allenPixel.locPos()[0] == recPixelSummary.locPos().X()[i]) && - (allenPixel.locPos()[1] == recPixelSummary.locPos().Y()[i]) && - (allenPixel.locPos()[2] == recPixelSummary.locPos().Z()[i]) && + (allenPixel.gloPos().x == recPixelSummary.gloPos().X()[i]) && + (allenPixel.gloPos().y == recPixelSummary.gloPos().Y()[i]) && + (allenPixel.gloPos().z == recPixelSummary.gloPos().Z()[i]) && + (allenPixel.locPos().x == recPixelSummary.locPos().X()[i]) && + (allenPixel.locPos().y == recPixelSummary.locPos().Y()[i]) && + (allenPixel.locPos().z == recPixelSummary.locPos().Z()[i]) && (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && (allenPixel.effArea() == recPixelSummary.effArea()[i]) && ((int) allenPixel.rich() == (int) recPixelSummary.rich()) && @@ -117,12 +117,12 @@ void CompareRecAllenRichPixels::operator()( for (const auto& allenPixel : allenPixels) { // check for match if ( - (allenPixel.gloPos()[0] == recPixelSummary.gloPos().X()[i]) && - (allenPixel.gloPos()[1] == recPixelSummary.gloPos().Y()[i]) && - (allenPixel.gloPos()[2] == recPixelSummary.gloPos().Z()[i]) && - (allenPixel.locPos()[0] == recPixelSummary.locPos().X()[i]) && - (allenPixel.locPos()[1] == recPixelSummary.locPos().Y()[i]) && - (allenPixel.locPos()[2] == recPixelSummary.locPos().Z()[i]) && + (allenPixel.gloPos().x == recPixelSummary.gloPos().X()[i]) && + (allenPixel.gloPos().y == recPixelSummary.gloPos().Y()[i]) && + (allenPixel.gloPos().z == recPixelSummary.gloPos().Z()[i]) && + (allenPixel.locPos().x == recPixelSummary.locPos().X()[i]) && + (allenPixel.locPos().y == recPixelSummary.locPos().Y()[i]) && + (allenPixel.locPos().z == recPixelSummary.locPos().Z()[i]) && (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && (allenPixel.effArea() == recPixelSummary.effArea()[i]) && ((int) allenPixel.rich() == (int) recPixelSummary.rich()) && diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 43a49ad52c3..b5fbca46fa8 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -17,7 +17,7 @@ namespace Allen { using FP = float; - using Point = std::array; + using Point = float3; using DataType = std::uint32_t; using Transform3D = std::array; using KeyType = std::uint64_t; @@ -52,9 +52,9 @@ namespace Allen { /// Matrix-point transform3D, adapted from ROOT::Math __host__ __device__ inline Point transform3DTimesPoint(Transform3D fM, Point point) { - return Point {fM[0] * point[0] + fM[1] * point[1] + fM[2] * point[2] + fM[3], - fM[4] * point[0] + fM[5] * point[1] + fM[6] * point[2] + fM[7], - fM[8] * point[0] + fM[9] * point[1] + fM[10] * point[2] + fM[11]}; + return Point {fM[0] * point.x + fM[1] * point.y + fM[2] * point.z + fM[3], + fM[4] * point.x + fM[5] * point.y + fM[6] * point.z + fM[7], + fM[8] * point.x + fM[9] * point.y + fM[10] * point.z + fM[11]}; } /// RICH SmartIDs class diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index 94813d8903f..c09e7d75d22 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -82,8 +82,8 @@ namespace Allen { { std::stringstream ss; if (m_smartID.key() == 0) return "SmartID key is 0"; - ss << m_smartID.key() << ',' << gPos[0] << ',' << gPos[1] << ',' << gPos[2] << ',' << lPos[0] << ',' << lPos[1] - << ',' << lPos[2] << ',' << m_effArea << ',' << (int) m_rich << ',' << (int) m_side << ',' << (int) m_mask + ss << m_smartID.key() << ',' << gPos.x << ',' << gPos.y << ',' << gPos.z << ',' << lPos.x << ',' << lPos.y + << ',' << lPos.z << ',' << m_effArea << ',' << (int) m_rich << ',' << (int) m_side << ',' << (int) m_mask << ',' << m_timeWindow << ',' << m_isInnerRegion << ',' << m_isNull << '\n'; return ss.str(); } diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index d1ff9a32e63..71ace3ec426 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -34,7 +34,7 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, cons const auto gPos = smartIDsHelper->_globalPosition(smartID); const auto lPos = smartIDsHelper->globalToPDPanel(gPos); const auto isInner = - (Allen::m_overrideRegions[rich] ? (abs(lPos[0]) < float(Allen::m_innerPixX[rich]) && abs(lPos[1]) < float(Allen::m_innerPixY[rich])) : + (Allen::m_overrideRegions[rich] ? (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : innerRegion); Allen::RichPixel pixel; diff --git a/device/rich/decoding/src/RichSmartIDs.cu b/device/rich/decoding/src/RichSmartIDs.cu index 41f1e0f0c3e..7abbcb165a4 100644 --- a/device/rich/decoding/src/RichSmartIDs.cu +++ b/device/rich/decoding/src/RichSmartIDs.cu @@ -26,18 +26,18 @@ Point Allen::RichSmartIDs::pdPosition(const Allen::RichSmartID pdid) const const auto a = _globalPosition(id0); const auto b = _globalPosition(id1); // Return average position (i.e. PD centre) - return Point {0.5f * (a[0] + b[0]), // - 0.5f * (a[1] + b[1]), // - 0.5f * (a[2] + b[2])}; + return Point {0.5f * (a.x + b.x), // + 0.5f * (a.y + b.y), // + 0.5f * (a.z + b.z)}; } // Converts a point from the global frame to the detector panel frame Point Allen::RichSmartIDs::globalToPDPanel(const Point& globalPoint) const { return ( - globalPoint[2] < 8000.f ? + globalPoint.z < 8000.f ? // RICH1 - (globalPoint[1] > 0.f ? + (globalPoint.y > 0.f ? Allen::transform3DTimesPoint( panel(Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::top)->globalToPDPanel(), globalPoint) : @@ -45,7 +45,7 @@ Point Allen::RichSmartIDs::globalToPDPanel(const Point& globalPoint) const panel(Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::bottom)->globalToPDPanel(), globalPoint)) : // RICH2 - (globalPoint[0] > 0.f ? + (globalPoint.x > 0.f ? Allen::transform3DTimesPoint( panel(Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::left)->globalToPDPanel(), globalPoint) : -- GitLab From 85741c8f422b88a2b6524e5d80b821e160421f06 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Fri, 28 Mar 2025 04:25:26 +0000 Subject: [PATCH 06/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/53504339 --- Rec/Allen/src/CompareRecAllenRichPixels.cpp | 10 +- Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp | 6 +- .../rich/decoding/include/RichDefinitions.cuh | 168 +++++++++--------- device/rich/decoding/include/RichPixels.cuh | 6 +- device/rich/decoding/src/RichMakePixels.cu | 21 +-- 5 files changed, 106 insertions(+), 105 deletions(-) diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index 095eebc0e71..e2d6d2db673 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -13,9 +13,9 @@ #include "RichPixels.cuh" class CompareRecAllenRichPixels final : public Gaudi::Functional::Consumer&, - const std::vector&, - const Rich::Future::Rec::SIMDPixelSummaries&)> { + const std::vector&, + const std::vector&, + const Rich::Future::Rec::SIMDPixelSummaries&)> { public: /// Standard constructor @@ -26,8 +26,8 @@ public: const std::vector&, const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&) const override; -private: +private: mutable Gaudi::Accumulators::Counter<> m_allen_in_rec {this, "Allen Pixels found in Rec"}; mutable Gaudi::Accumulators::Counter<> m_allen_not_in_rec {this, "Allen Pixels not found in Rec"}; mutable Gaudi::Accumulators::Counter<> m_rec_in_allen {this, "Rec Pixels found in Allen"}; @@ -51,7 +51,7 @@ void CompareRecAllenRichPixels::operator()( const std::vector& allenRich2Pixels, const Rich::Future::Rec::SIMDPixelSummaries& recPixelSummaries) const { - // Concatenate Allen Pixel vectors + // Concatenate Allen Pixel vectors std::vector allenPixels; allenPixels.reserve(allenRich1Pixels.size() + allenRich2Pixels.size()); allenPixels.insert(allenPixels.end(), allenRich1Pixels.begin(), allenRich1Pixels.end()); diff --git a/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp b/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp index 9a45ccab8c6..7d896d8cc67 100644 --- a/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp +++ b/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp @@ -20,9 +20,9 @@ #include "RichPDMDBDecodeMapping.cuh" class CompareRecAllenRichSmartIDs final : public Gaudi::Functional::Consumer&, - const std::vector&, - const Rich::Future::DAQ::DecodedData&)> { + const std::vector&, + const std::vector&, + const Rich::Future::DAQ::DecodedData&)> { public: /// Standard constructor diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index b5fbca46fa8..05cddc4d8b2 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -26,42 +26,42 @@ namespace Allen { //// Constants related to pixel reconstruction /// Enabled 4D reconstruction - [[maybe_unused]] __constant__ static std::array m_enable4D = {false, false}; + [[maybe_unused]] __constant__ static std::array m_enable4D = {false, false}; /// Average expected hit time for signal in each RICH in ns - [[maybe_unused]] __constant__ static std::array m_avHitTime = {13.03, 52.94}; + [[maybe_unused]] __constant__ static std::array m_avHitTime = {13.03, 52.94}; /// Course (pixel) Time window for each RICH in ns - [[maybe_unused]] __constant__ static std::array m_timeWindow = {3.0, 3.0}; + [[maybe_unused]] __constant__ static std::array m_timeWindow = {3.0, 3.0}; /// Enable the override of inner and out regions - [[maybe_unused]] __constant__ static std::array m_overrideRegions = {false, false}; + [[maybe_unused]] __constant__ static std::array m_overrideRegions = {false, false}; /// Size in X defining the inner pixels for each RICH - [[maybe_unused]] __constant__ static std::array m_innerPixX = {250.0, 99999.9}; + [[maybe_unused]] __constant__ static std::array m_innerPixX = {250.0, 99999.9}; /// Size in Y defining the inner pixels for each RICH - [[maybe_unused]] __constant__ static std::array m_innerPixY = {300.0, 300.0}; + [[maybe_unused]] __constant__ static std::array m_innerPixY = {300.0, 300.0}; /// Time resolution for inner regions in ns - [[maybe_unused]] __constant__ static std::array m_innerTimeWindow = {0.15, 0.15}; + [[maybe_unused]] __constant__ static std::array m_innerTimeWindow = {0.15, 0.15}; /// Time resolution for outer regions in ns - [[maybe_unused]] __constant__ static std::array m_outerTimeWindow = {0.3, 0.3}; + [[maybe_unused]] __constant__ static std::array m_outerTimeWindow = {0.3, 0.3}; - /// Matrix-point transform3D, adapted from ROOT::Math + /// Matrix-point transform3D, adapted from ROOT::Math __host__ __device__ inline Point transform3DTimesPoint(Transform3D fM, Point point) { return Point {fM[0] * point.x + fM[1] * point.y + fM[2] * point.z + fM[3], - fM[4] * point.x + fM[5] * point.y + fM[6] * point.z + fM[7], - fM[8] * point.x + fM[9] * point.y + fM[10] * point.z + fM[11]}; + fM[4] * point.x + fM[5] * point.y + fM[6] * point.z + fM[7], + fM[8] * point.x + fM[9] * point.y + fM[10] * point.z + fM[11]}; } /// RICH SmartIDs class class RichSmartID { KeyType m_key; - public: + public: // Set the RICH PD pixel row identifier __host__ __device__ constexpr void setPixelRow(const DataType row) { @@ -111,17 +111,17 @@ namespace Allen { // The masks static constexpr const BitPackType MaskPixelCol = (BitPackType)((BitPackType {1} << BitsPixelCol) - BitPackType {1}) - << ShiftPixelCol; + << ShiftPixelCol; static constexpr const BitPackType MaskPixelRow = (BitPackType)((BitPackType {1} << BitsPixelRow) - BitPackType {1}) - << ShiftPixelRow; + << ShiftPixelRow; static constexpr const BitPackType MaskPDNumInMod = (BitPackType)((BitPackType {1} << BitsPDNumInMod) - BitPackType {1}) << ShiftPDNumInMod; static constexpr const BitPackType MaskPDMod = (BitPackType)((BitPackType {1} << BitsPDMod) - BitPackType {1}) - << ShiftPDMod; + << ShiftPDMod; static constexpr const BitPackType MaskPanel = (BitPackType)((BitPackType {1} << BitsPanel) - BitPackType {1}) - << ShiftPanel; + << ShiftPanel; static constexpr const BitPackType MaskRich = (BitPackType)((BitPackType {1} << BitsRich) - BitPackType {1}) - << ShiftRich; + << ShiftRich; static constexpr const BitPackType MaskPixelSubRowIsSet = (BitPackType)((BitPackType {1} << BitsPixelSubRowIsSet) - BitPackType {1}) << ShiftPixelSubRowIsSet; static constexpr const BitPackType MaskPixelColIsSet = @@ -129,7 +129,7 @@ namespace Allen { static constexpr const BitPackType MaskPixelRowIsSet = (BitPackType)((BitPackType {1} << BitsPixelRowIsSet) - BitPackType {1}) << ShiftPixelRowIsSet; static constexpr const BitPackType MaskPDIsSet = (BitPackType)((BitPackType {1} << BitsPDIsSet) - BitPackType {1}) - << ShiftPDIsSet; + << ShiftPDIsSet; static constexpr const BitPackType MaskPanelIsSet = (BitPackType)((BitPackType {1} << BitsPanelIsSet) - BitPackType {1}) << ShiftPanelIsSet; static constexpr const BitPackType MaskRichIsSet = @@ -150,22 +150,22 @@ namespace Allen { static constexpr const BitPackType NChannelBits = 32; __host__ __device__ constexpr inline void - setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept - { - m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); - } + setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept + { + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); + } __host__ __device__ constexpr inline void - setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept - { - m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; - } + setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept + { + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; + } __host__ __device__ constexpr inline BitPackType getData(const BitPackType shift, const BitPackType mask) const noexcept - { - return (m_key & mask) >> shift; - } + { + return (m_key & mask) >> shift; + } __host__ __device__ constexpr inline BitPackType key() const noexcept { return m_key; } @@ -306,7 +306,7 @@ namespace Allen { return str; } - public: + public: // Number of PMT pixels per row static constexpr const DataType PixelsPerRow = 8; // Number of PMT pixels per column @@ -333,32 +333,32 @@ namespace Allen { __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() { return {std::array {0, ModulesPerPanel[0]}, - std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; + std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; } class MaPMT { - public: - static constexpr const DataType MaxPDsPerModule = 16; - static constexpr const DataType MaxModulesPerPanel = 92; - - // Bits for time field. - static constexpr const BitPackType BitsADCTime = 16; - static constexpr const BitPackType BitsADCTimeIsSet = 1; - static constexpr const BitPackType ShiftADCTime = NChannelBits; - static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; - static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) - << ShiftADCTime; - static constexpr const BitPackType MaskADCTimeIsSet = - (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; - - // Max ADC time that can be stored - static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType {1}; - - // Parameters for conversion between float and ADC time values - static constexpr const double MinTime = -50.0; // In nanoseconds - static constexpr const double MaxTime = 150.0; // In nanoseconds - static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); - static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; + public: + static constexpr const DataType MaxPDsPerModule = 16; + static constexpr const DataType MaxModulesPerPanel = 92; + + // Bits for time field. + static constexpr const BitPackType BitsADCTime = 16; + static constexpr const BitPackType BitsADCTimeIsSet = 1; + static constexpr const BitPackType ShiftADCTime = NChannelBits; + static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; + static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) + << ShiftADCTime; + static constexpr const BitPackType MaskADCTimeIsSet = + (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; + + // Max ADC time that can be stored + static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType {1}; + + // Parameters for conversion between float and ADC time values + static constexpr const double MinTime = -50.0; // In nanoseconds + static constexpr const double MaxTime = 150.0; // In nanoseconds + static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); + static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; }; }; // namespace RichSmartID } // namespace Allen @@ -388,42 +388,42 @@ namespace Rich::Future::DAQ { }; class PackedFrameSizes final { - public: - // Packed type - using IntType = std::uint8_t; - - private: - // Bits for each Size - static const IntType Bits0 = 4; - static const IntType Bits1 = 4; - // shifts - static const IntType Shift0 = 0; - static const IntType Shift1 = Shift0 + Bits0; - // masks - static const IntType Mask0 = (IntType)((1 << Bits0) - 1) << Shift0; - static const IntType Mask1 = (IntType)((1 << Bits1) - 1) << Shift1; - // max values - static const IntType Max0 = (1 << Bits0) - 1; - static const IntType Max1 = (1 << Bits1) - 1; + public: + // Packed type + using IntType = std::uint8_t; + + private: + // Bits for each Size + static const IntType Bits0 = 4; + static const IntType Bits1 = 4; + // shifts + static const IntType Shift0 = 0; + static const IntType Shift1 = Shift0 + Bits0; + // masks + static const IntType Mask0 = (IntType)((1 << Bits0) - 1) << Shift0; + static const IntType Mask1 = (IntType)((1 << Bits1) - 1) << Shift1; + // max values + static const IntType Max0 = (1 << Bits0) - 1; + static const IntType Max1 = (1 << Bits1) - 1; - public: - // Contructor from a single word - __host__ __device__ explicit PackedFrameSizes(const IntType d) : m_data(d) {} + public: + // Contructor from a single word + __host__ __device__ explicit PackedFrameSizes(const IntType d) : m_data(d) {} - // Get the overall data - __host__ __device__ inline IntType data() const noexcept { return m_data; } + // Get the overall data + __host__ __device__ inline IntType data() const noexcept { return m_data; } - // Get first size word - __host__ __device__ inline IntType size0() const noexcept { return ((data() & Mask0) >> Shift0); } + // Get first size word + __host__ __device__ inline IntType size0() const noexcept { return ((data() & Mask0) >> Shift0); } - // Get second size word - __host__ __device__ inline IntType size1() const noexcept { return ((data() & Mask1) >> Shift1); } + // Get second size word + __host__ __device__ inline IntType size1() const noexcept { return ((data() & Mask1) >> Shift1); } - // Get the total size - __host__ __device__ inline auto totalSize() const noexcept { return size0() + size1(); } + // Get the total size + __host__ __device__ inline auto totalSize() const noexcept { return size0() + size1(); } - private: - // The data word - IntType m_data {0}; + private: + // The data word + IntType m_data {0}; }; } // namespace Rich::Future::DAQ diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index c09e7d75d22..51b55bb068b 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -82,9 +82,9 @@ namespace Allen { { std::stringstream ss; if (m_smartID.key() == 0) return "SmartID key is 0"; - ss << m_smartID.key() << ',' << gPos.x << ',' << gPos.y << ',' << gPos.z << ',' << lPos.x << ',' << lPos.y - << ',' << lPos.z << ',' << m_effArea << ',' << (int) m_rich << ',' << (int) m_side << ',' << (int) m_mask - << ',' << m_timeWindow << ',' << m_isInnerRegion << ',' << m_isNull << '\n'; + ss << m_smartID.key() << ',' << gPos.x << ',' << gPos.y << ',' << gPos.z << ',' << lPos.x << ',' << lPos.y << ',' + << lPos.z << ',' << m_effArea << ',' << (int) m_rich << ',' << (int) m_side << ',' << (int) m_mask << ',' + << m_timeWindow << ',' << m_isInnerRegion << ',' << m_isNull << '\n'; return ss.str(); } diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index 71ace3ec426..b92c5c30ff9 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -34,8 +34,9 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, cons const auto gPos = smartIDsHelper->_globalPosition(smartID); const auto lPos = smartIDsHelper->globalToPDPanel(gPos); const auto isInner = - (Allen::m_overrideRegions[rich] ? (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : - innerRegion); + (Allen::m_overrideRegions[rich] ? + (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : + innerRegion); Allen::RichPixel pixel; @@ -86,18 +87,18 @@ __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, /// Function to resize Allen sequence output data structure void rich_make_pixels::rich_make_pixels_t::set_arguments_size( - ArgumentReferences arguments, - const RuntimeOptions&, - const Constants&) const + ArgumentReferences arguments, + const RuntimeOptions&, + const Constants&) const { set_size(arguments, size(arguments)); } void rich_make_pixels::rich_make_pixels_t::operator()( - const ArgumentReferences& arguments, - const RuntimeOptions&, - const Constants& constants, - const Allen::Context& context) const + const ArgumentReferences& arguments, + const RuntimeOptions&, + const Constants& constants, + const Allen::Context& context) const { // Create RICH objects from dump Allen::Rich1* rich1; @@ -123,6 +124,6 @@ void rich_make_pixels::rich_make_pixels_t::operator()( Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDs), Allen::memcpyHostToDevice); global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - arguments, dev_smartIDsHelper); + arguments, dev_smartIDsHelper); Allen::free(dev_smartIDsHelper); } -- GitLab From 4b1c12ca121519547fed5c22e04d8f9ea6c38b90 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 28 Mar 2025 19:03:11 +0100 Subject: [PATCH 07/92] fix sign change warning, added producers to throughput test --- configuration/python/AllenConf/HLT1.py | 36 ++++++++++++++++--- .../rich/decoding/include/RichDefinitions.cuh | 3 +- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/configuration/python/AllenConf/HLT1.py b/configuration/python/AllenConf/HLT1.py index 932d1289dd5..1f7f3e40601 100644 --- a/configuration/python/AllenConf/HLT1.py +++ b/configuration/python/AllenConf/HLT1.py @@ -1580,15 +1580,41 @@ def setup_hlt1_node(enablePhysics=True, """ if with_rich: + # store SmartID decoding for pixel rec + decoded_rich1 = decode_rich(rich=1) + decoded_rich2 = decode_rich(rich=2) + + # get SmartIDs + rich1_decoding = CompositeNode( + "Rich1Decoding", [decoded_rich1["dev_smart_ids"].producer], + NodeLogic.NONLAZY_AND, + force_order=False) + + rich2_decoding = CompositeNode( + "Rich2Decoding", [decoded_rich2["dev_smart_ids"].producer], + NodeLogic.NONLAZY_AND, + force_order=False) + + # get pixels + rich1_make_pixels = CompositeNode( + "Rich1MakePixels", + [make_pixels(decoded_rich1, rich=1)["dev_rich_pixels"].producer], + NodeLogic.NONLAZY_AND, + force_order=True) + + rich2_make_pixels = CompositeNode( + "Rich2MakePixels", + [make_pixels(decoded_rich2, rich=2)["dev_rich_pixels"].producer], + NodeLogic.NONLAZY_AND, + force_order=True) + hlt1_node = CompositeNode( - "AllenWithRich", [ - hlt1_node, reconstructed_objects["decoded_rich1"] - ["dev_smart_ids"].producer - ], + "AllenWithRich", + [hlt1_node, rich1_decoding, rich1_make_pixels, rich2_decoding, rich2_make_pixels], NodeLogic.NONLAZY_AND, force_order=True) - if enableRateValidator: + if enableRateValidator: hlt1_node = CompositeNode( "AllenRateValidation", [ hlt1_node, diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 05cddc4d8b2..203d7480479 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -352,7 +352,8 @@ namespace Allen { (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; // Max ADC time that can be stored - static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType {1}; + static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType{1} << BitsADCTime) - 1); + //static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType {1}; // Parameters for conversion between float and ADC time values static constexpr const double MinTime = -50.0; // In nanoseconds -- GitLab From f90320f9c52902e8262a21c889c46e8b056fbf7f Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Fri, 28 Mar 2025 18:03:48 +0000 Subject: [PATCH 08/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/53579712 --- device/rich/decoding/include/RichDefinitions.cuh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 203d7480479..2f0522ac072 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -352,8 +352,9 @@ namespace Allen { (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; // Max ADC time that can be stored - static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType{1} << BitsADCTime) - 1); - //static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType {1}; + static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType {1} << BitsADCTime) - 1); + // static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType + // {1}; // Parameters for conversion between float and ADC time values static constexpr const double MinTime = -50.0; // In nanoseconds -- GitLab From 193bdc502ae3f0347b8a5a4338dae365d63e23a9 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 28 Mar 2025 20:26:13 +0100 Subject: [PATCH 09/92] retry HLT1 seq --- configuration/python/AllenConf/HLT1.py | 39 ++++++-------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/configuration/python/AllenConf/HLT1.py b/configuration/python/AllenConf/HLT1.py index 1f7f3e40601..1a81eec7ce3 100644 --- a/configuration/python/AllenConf/HLT1.py +++ b/configuration/python/AllenConf/HLT1.py @@ -1580,41 +1580,18 @@ def setup_hlt1_node(enablePhysics=True, """ if with_rich: - # store SmartID decoding for pixel rec - decoded_rich1 = decode_rich(rich=1) - decoded_rich2 = decode_rich(rich=2) - - # get SmartIDs - rich1_decoding = CompositeNode( - "Rich1Decoding", [decoded_rich1["dev_smart_ids"].producer], - NodeLogic.NONLAZY_AND, - force_order=False) - - rich2_decoding = CompositeNode( - "Rich2Decoding", [decoded_rich2["dev_smart_ids"].producer], - NodeLogic.NONLAZY_AND, - force_order=False) - - # get pixels - rich1_make_pixels = CompositeNode( - "Rich1MakePixels", - [make_pixels(decoded_rich1, rich=1)["dev_rich_pixels"].producer], - NodeLogic.NONLAZY_AND, - force_order=True) - - rich2_make_pixels = CompositeNode( - "Rich2MakePixels", - [make_pixels(decoded_rich2, rich=2)["dev_rich_pixels"].producer], - NodeLogic.NONLAZY_AND, - force_order=True) - hlt1_node = CompositeNode( - "AllenWithRich", - [hlt1_node, rich1_decoding, rich1_make_pixels, rich2_decoding, rich2_make_pixels], + "AllenWithRich", [ + hlt1_node, + reconstructed_objects["decoded_rich1"]["dev_smart_ids"].producer, + reconstructed_objects["decoded_rich2"]["dev_smart_ids"].producer, + reconstructed_objects["rich1_pixels"]["dev_rich_pixels"].producer, + reconstructed_objects["rich2_pixels"]["dev_rich_pixels"].producer + ], NodeLogic.NONLAZY_AND, force_order=True) - if enableRateValidator: + if enableRateValidator: hlt1_node = CompositeNode( "AllenRateValidation", [ hlt1_node, -- GitLab From 6dfeb1de0eb13c6c3190080ead7b624e5fe44ba1 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Fri, 28 Mar 2025 19:26:47 +0000 Subject: [PATCH 10/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/53585140 --- configuration/python/AllenConf/HLT1.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/configuration/python/AllenConf/HLT1.py b/configuration/python/AllenConf/HLT1.py index 1a81eec7ce3..bbee8db765f 100644 --- a/configuration/python/AllenConf/HLT1.py +++ b/configuration/python/AllenConf/HLT1.py @@ -1582,11 +1582,13 @@ def setup_hlt1_node(enablePhysics=True, if with_rich: hlt1_node = CompositeNode( "AllenWithRich", [ - hlt1_node, - reconstructed_objects["decoded_rich1"]["dev_smart_ids"].producer, - reconstructed_objects["decoded_rich2"]["dev_smart_ids"].producer, - reconstructed_objects["rich1_pixels"]["dev_rich_pixels"].producer, - reconstructed_objects["rich2_pixels"]["dev_rich_pixels"].producer + hlt1_node, reconstructed_objects["decoded_rich1"] + ["dev_smart_ids"].producer, + reconstructed_objects["decoded_rich2"]["dev_smart_ids"]. + producer, reconstructed_objects["rich1_pixels"] + ["dev_rich_pixels"].producer, + reconstructed_objects["rich2_pixels"]["dev_rich_pixels"]. + producer ], NodeLogic.NONLAZY_AND, force_order=True) -- GitLab From 1de35eef6647b23763a19f49c67e0702131ebc08 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Thu, 17 Apr 2025 23:50:08 +0200 Subject: [PATCH 11/92] fix calling RICH sequence from HLT1 and hlt1_reconstruction using with_rich param --- configuration/python/AllenConf/HLT1.py | 15 +++++---------- .../python/AllenConf/hlt1_reconstruction.py | 17 ++++++++--------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/configuration/python/AllenConf/HLT1.py b/configuration/python/AllenConf/HLT1.py index bbee8db765f..46cc123595c 100644 --- a/configuration/python/AllenConf/HLT1.py +++ b/configuration/python/AllenConf/HLT1.py @@ -1581,18 +1581,13 @@ def setup_hlt1_node(enablePhysics=True, if with_rich: hlt1_node = CompositeNode( - "AllenWithRich", [ - hlt1_node, reconstructed_objects["decoded_rich1"] - ["dev_smart_ids"].producer, - reconstructed_objects["decoded_rich2"]["dev_smart_ids"]. - producer, reconstructed_objects["rich1_pixels"] - ["dev_rich_pixels"].producer, - reconstructed_objects["rich2_pixels"]["dev_rich_pixels"]. - producer + "AllenWithRich", [hlt1_node, + reconstructed_objects["rich1_pixels"]["dev_rich_pixels"].producer, + reconstructed_objects["rich2_pixels"]["dev_rich_pixels"].producer ], NodeLogic.NONLAZY_AND, - force_order=True) - + force_order=False) + if enableRateValidator: hlt1_node = CompositeNode( "AllenRateValidation", [ diff --git a/configuration/python/AllenConf/hlt1_reconstruction.py b/configuration/python/AllenConf/hlt1_reconstruction.py index 592fdb76d10..1e8e75b1bbf 100644 --- a/configuration/python/AllenConf/hlt1_reconstruction.py +++ b/configuration/python/AllenConf/hlt1_reconstruction.py @@ -32,7 +32,9 @@ from AllenConf.persistency import make_gather_selections, make_sel_report_writer from AllenConf.filters import make_gec from AllenConf.best_track_creator import best_track_creator from AllenConf.enum_types import TrackingType - +from AllenConf.secondary_vertex_reconstruction import make_kalman_long +from AllenConf.rich_reconstruction import decode_rich +from AllenConf.rich_make_pixels import make_pixels def hlt1_reconstruction(algorithm_name='', tracking_type=TrackingType.FORWARD, @@ -497,15 +499,12 @@ def hlt1_reconstruction(algorithm_name='', }) if with_rich: - from AllenConf.rich_reconstruction import decode_rich - from AllenConf.rich_make_pixels import make_pixels - decoded_rich1 = decode_rich(rich=1) - decoded_rich2 = decode_rich(rich=2) + rich1_pixels = make_pixels(rich=1) + rich2_pixels = make_pixels(rich=2) + output.update({ - "decoded_rich1": decoded_rich1, - "decoded_rich2": decoded_rich2, - "rich1_pixels": make_pixels(decoded_rich1, rich=1), - "rich2_pixels": make_pixels(decoded_rich2, rich=2) + "rich1_pixels": rich1_pixels, + "rich2_pixels": rich2_pixels }) if with_AC_split: -- GitLab From f2f6db3d1aae473e690379752778757059ac50f7 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 18 Apr 2025 05:01:43 +0200 Subject: [PATCH 12/92] combined RICH binary dumpers --- Dumpers/BinaryDumpers/CMakeLists.txt | 3 +- .../BinaryDumpers/src/DumpRich2Geometry.cpp | 93 ------------------- ...Rich1Geometry.cpp => DumpRichGeometry.cpp} | 62 ++++++++++--- Rec/Allen/python/Allen/config.py | 14 +-- 4 files changed, 53 insertions(+), 119 deletions(-) delete mode 100644 Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp rename Dumpers/BinaryDumpers/src/{DumpRich1Geometry.cpp => DumpRichGeometry.cpp} (52%) diff --git a/Dumpers/BinaryDumpers/CMakeLists.txt b/Dumpers/BinaryDumpers/CMakeLists.txt index 344435a9cc5..12f161691d0 100644 --- a/Dumpers/BinaryDumpers/CMakeLists.txt +++ b/Dumpers/BinaryDumpers/CMakeLists.txt @@ -60,8 +60,7 @@ gaudi_add_module(BinaryDumpersModule src/DumpVPGeometry.cpp src/DumpRichCableMapping.cpp src/DumpRichPDMDBMapping.cpp - src/DumpRich1Geometry.cpp - src/DumpRich2Geometry.cpp + src/DumpRichGeometry.cpp src/PVDumper.cpp src/ProvideConstants.cpp src/TestMuonTable.cpp diff --git a/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp b/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp deleted file mode 100644 index c76b0c6888e..00000000000 --- a/Dumpers/BinaryDumpers/src/DumpRich2Geometry.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/*****************************************************************************\ - * (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration * - * * - * This software is distributed under the terms of the Apache License * - * version 2 (Apache-2.0), copied verbatim in the file "LICENSE". * - * * - * In applying this licence, CERN does not waive the privileges and immunities * - * granted to it by virtue of its status as an Intergovernmental Organization * - * or submit itself to any jurisdiction. * - \*****************************************************************************/ - -// Gaudi Array properties ( must be first ...) -#include "GaudiKernel/StdArrayAsProperty.h" - -// Rich Kernel -#include "RichFutureKernel/RichAlgBase.h" -#include "Kernel/RichDetectorType.h" - -// Gaudi Functional -#include "LHCbAlgs/Transformer.h" - -// Rich Utils -#include "RichFutureUtils/RichDecodedData.h" -#include "RichUtils/RichException.h" -#include "RichUtils/RichHashMap.h" -#include "RichUtils/RichMap.h" -#include "RichUtils/RichSmartIDSorter.h" - -// LHCb -#include -#include - -// Dumper -#include "Dumper.h" -#include - -namespace { -#ifdef USE_DD4HEP - inline const std::string RichGeoCond = DeRichLocations::Rich2Path; -#else - inline const std::string RichGeoCond = DeRichLocations::OldRich2; -#endif - - struct Rich2Geometry_t { - Rich2Geometry_t() = default; - Rich2Geometry_t(std::vector& data, const Rich::Detector::Rich2& rich_2) - { - Rich::Detector::Allen::Rich2 allenRich2 {rich_2}; - DumpUtils::Writer output {}; - output.write(allenRich2); - data = output.buffer(); - } - }; -} // namespace - -/** - * @brief Dump RICH detector object information. - */ - -class DumpRich2Geometry final - : public Allen::Dumpers::Dumper> { -public: - DumpRich2Geometry(const std::string& name, ISvcLocator* svcLoc); - void operator()(const Rich2Geometry_t& RichGeo) const override; - StatusCode initialize() override; - -private: - std::vector m_data; -}; - -DECLARE_COMPONENT(DumpRich2Geometry) - -DumpRich2Geometry::DumpRich2Geometry(const std::string& name, ISvcLocator* svcLoc) : - Dumper(name, svcLoc, {KeyValue {"Rich2GeometryLocation", location(name, "rich2Geometry")}}) -{} - -StatusCode DumpRich2Geometry::initialize() -{ - return Dumper::initialize().andThen([&, this] { - register_producer(Allen::NonEventData::Rich2Geometry::id, "rich_2_geometry", m_data); - Rich::Detector::Rich2::addConditionDerivation(this); - addConditionDerivation( - {Rich::Detector::Rich2::DefaultConditionKey}, - inputLocation(), - [&](const Rich::Detector::Rich2& det) { - auto Rich2Geo = Rich2Geometry_t {m_data, det}; - dump(); - return Rich2Geo; - }); - }); -} - -void DumpRich2Geometry::operator()(const Rich2Geometry_t&) const {} diff --git a/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp b/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp similarity index 52% rename from Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp rename to Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp index 7b90d437aab..dfa41ea9297 100644 --- a/Dumpers/BinaryDumpers/src/DumpRich1Geometry.cpp +++ b/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp @@ -29,16 +29,20 @@ // LHCb #include #include +#include // Dumper #include "Dumper.h" #include namespace { +// paths unused while DefaultConditionKey works #ifdef USE_DD4HEP - inline const std::string RichGeoCond = DeRichLocations::Rich1Path; + inline const std::string Rich1GeoCond = DeRichLocations::Rich1Path; + inline const std::string Rich2GeoCond = DeRichLocations::Rich2Path; #else - inline const std::string RichGeoCond = DeRichLocations::OldRich1; + inline const std::string Rich1GeoCond = DeRichLocations::OldRich1; + inline const std::string Rich2GeoCond = DeRichLocations::OldRich2; #endif struct Rich1Geometry_t { @@ -51,43 +55,71 @@ namespace { data = output.buffer(); } }; + + struct Rich2Geometry_t { + Rich2Geometry_t() = default; + Rich2Geometry_t(std::vector& data, const Rich::Detector::Rich2& rich_2) + { + Rich::Detector::Allen::Rich2 allenRich2 {rich_2}; + DumpUtils::Writer output {}; + output.write(allenRich2); + data = output.buffer(); + } + }; } // namespace /** * @brief Dump RICH detector object information. */ - -class DumpRich1Geometry final - : public Allen::Dumpers::Dumper> { +class DumpRichGeometry final : public Allen::Dumpers::Dumper< + void(Rich1Geometry_t const&, Rich2Geometry_t const&), + LHCb::DetDesc::usesConditions> { public: - DumpRich1Geometry(const std::string& name, ISvcLocator* svcLoc); - void operator()(const Rich1Geometry_t& RichGeo) const override; + DumpRichGeometry(const std::string& name, ISvcLocator* svcLoc); + void operator()(const Rich1Geometry_t& Rich1Geo, const Rich2Geometry_t& Rich2Geo) const override; StatusCode initialize() override; private: - std::vector m_data; + std::vector m_Rich1Data; + std::vector m_Rich2Data; }; -DECLARE_COMPONENT(DumpRich1Geometry) +DECLARE_COMPONENT(DumpRichGeometry) -DumpRich1Geometry::DumpRich1Geometry(const std::string& name, ISvcLocator* svcLoc) : - Dumper(name, svcLoc, {KeyValue {"Rich1GeometryLocation", location(name, "rich1Geometry")}}) +DumpRichGeometry::DumpRichGeometry(const std::string& name, ISvcLocator* svcLoc) : + Dumper( + name, + svcLoc, + {KeyValue {"Rich1GeometryLocation", location(name, "rich1geometry")}, + KeyValue {"Rich2GeometryLocation", location(name, "rich2Geometry")}}) {} -StatusCode DumpRich1Geometry::initialize() +StatusCode DumpRichGeometry::initialize() { return Dumper::initialize().andThen([&, this] { - register_producer(Allen::NonEventData::Rich1Geometry::id, "rich_1_geometry", m_data); + register_producer(Allen::NonEventData::Rich1Geometry::id, "rich_1_geometry", m_Rich1Data); Rich::Detector::Rich1::addConditionDerivation(this); addConditionDerivation( {Rich::Detector::Rich1::DefaultConditionKey}, inputLocation(), [&](const Rich::Detector::Rich1& det) { - auto Rich1Geo = Rich1Geometry_t {m_data, det}; + Rich1Geometry_t Rich1Geo {m_Rich1Data, det}; dump(); return Rich1Geo; }); + + register_producer(Allen::NonEventData::Rich2Geometry::id, "rich_2_geometry", m_Rich2Data); + Rich::Detector::Rich2::addConditionDerivation(this); + addConditionDerivation( + {Rich::Detector::Rich2::DefaultConditionKey}, + inputLocation(), + [&](const Rich::Detector::Rich2& det) { + Rich2Geometry_t Rich2Geo {m_Rich2Data, det}; + dump(); + return Rich2Geo; + }); }); } -void DumpRich1Geometry::operator()(const Rich1Geometry_t&) const {} +void DumpRichGeometry::operator()(const Rich1Geometry_t&, const Rich2Geometry_t&) const {} + diff --git a/Rec/Allen/python/Allen/config.py b/Rec/Allen/python/Allen/config.py index a82af735e5c..fac4e7d9ffb 100755 --- a/Rec/Allen/python/Allen/config.py +++ b/Rec/Allen/python/Allen/config.py @@ -21,7 +21,7 @@ from PyConf.Algorithms import ( DumpMagneticFieldPolarity, DumpVPGeometry, DumpCrossingAngles, DumpFTGeometry, DumpUTGeometry, DumpUTLookupTables, DumpMuonGeometry, DumpMuonTable, AllenODINProducer, DumpRichPDMDBMapping, - DumpRichCableMapping, DumpRich1Geometry, DumpRich2Geometry) + DumpRichCableMapping, DumpRichGeometry) from DDDB.CheckDD4Hep import UseDD4Hep from PyConf.reading import get_generator_BeamParameters from GaudiConf.LbExec import Options as DefaultOptions @@ -123,10 +123,8 @@ def setup_allen_non_event_data_service(allen_event_loop=False, 'rich_pdmdbmaps'), (DumpRichCableMapping, 'DeviceRichCableMapping', {}, 'rich_tel40maps'), - (DumpRich1Geometry, 'DeviceRich1Geometry', {}, - 'rich_1_geometry'), - (DumpRich2Geometry, 'DeviceRich2Geometry', {}, - 'rich_2_geometry')] + (DumpRichGeometry,'DeviceRichGeometry', {}, + 'rich_geometry')] } else: converter_types = { @@ -152,10 +150,8 @@ def setup_allen_non_event_data_service(allen_event_loop=False, 'rich_pdmdbmaps'), (DumpRichCableMapping, 'DeviceRichCableMapping', {}, 'rich_tel40maps'), - (DumpRich1Geometry, 'DeviceRich1Geometry', {}, - 'rich_1_geometry'), - (DumpRich2Geometry, 'DeviceRich2Geometry', {}, - 'rich_2_geometry')] + (DumpRichGeometry,'DeviceRichGeometry', {}, + 'rich_geometry')] } detector_names = { -- GitLab From 0bcca56bee27d323be12e61510f2b95b919ec6df Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 18 Apr 2025 08:50:08 +0200 Subject: [PATCH 13/92] Address test cleanup MR comments --- Rec/Allen/src/CompareRecAllenRichPixels.cpp | 120 +++++++++----------- 1 file changed, 52 insertions(+), 68 deletions(-) diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index e2d6d2db673..4e07bcd4941 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -27,6 +27,24 @@ public: const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&) const override; + /// Compare the attributes of an Allen Pixel and a Rec Pixel + bool matchPixels(const Allen::RichPixel& allenPixel, + const Rich::Future::Rec::SIMDPixel& recPixelSummary, + size_t i) const { + return (allenPixel.gloPos().x == recPixelSummary.gloPos().X()[i] && + allenPixel.gloPos().y == recPixelSummary.gloPos().Y()[i] && + allenPixel.gloPos().z == recPixelSummary.gloPos().Z()[i] && + allenPixel.locPos().x == recPixelSummary.locPos().X()[i] && + allenPixel.locPos().y == recPixelSummary.locPos().Y()[i] && + allenPixel.locPos().z == recPixelSummary.locPos().Z()[i] && + allenPixel.smartID().key() == recPixelSummary.smartID()[i].key() && + allenPixel.effArea() == recPixelSummary.effArea()[i] && + static_cast(allenPixel.rich()) == static_cast(recPixelSummary.rich()) && + static_cast(allenPixel.side()) == static_cast(recPixelSummary.side()) && + allenPixel.timeWindow() == recPixelSummary.timeWindow()[i] && + allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i]); + } + private: mutable Gaudi::Accumulators::Counter<> m_allen_in_rec {this, "Allen Pixels found in Rec"}; mutable Gaudi::Accumulators::Counter<> m_allen_not_in_rec {this, "Allen Pixels not found in Rec"}; @@ -59,6 +77,10 @@ void CompareRecAllenRichPixels::operator()( // functor to check if allen pixels exist in HLT2 auto allenPixelExistsInRec = [&](const Allen::RichPixel& allenPixel) -> bool { + if (allenPixel.isNull()){ + ++m_allen_null; + return true; // ignore invalid allen pix, assume correctedness + } // iterate over all pixel summaries for (const auto& recPixelSummary : recPixelSummaries) { // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. @@ -66,27 +88,19 @@ void CompareRecAllenRichPixels::operator()( // ensure HLT2 pixel validity if (recPixelSummary.validMask()[i]) { // check for match - if ( - (allenPixel.gloPos().x == recPixelSummary.gloPos().X()[i]) && - (allenPixel.gloPos().y == recPixelSummary.gloPos().Y()[i]) && - (allenPixel.gloPos().z == recPixelSummary.gloPos().Z()[i]) && - (allenPixel.locPos().x == recPixelSummary.locPos().X()[i]) && - (allenPixel.locPos().y == recPixelSummary.locPos().Y()[i]) && - (allenPixel.locPos().z == recPixelSummary.locPos().Z()[i]) && - (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && - (allenPixel.effArea() == recPixelSummary.effArea()[i]) && - ((int) allenPixel.rich() == (int) recPixelSummary.rich()) && - ((int) allenPixel.side() == (int) recPixelSummary.side()) && - (allenPixel.timeWindow() == recPixelSummary.timeWindow()[i]) && - (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i])) { + if (matchPixels(allenPixel, recPixelSummary, i)) { + ++m_allen_in_rec; return true; } } else { - return true; // ignore invalid pix, assume correctness - } // invalid pix + ++m_allen_in_rec; + return true; // ignore invalid rec pix, assume correctness + } } // didn't find pix match } // covered all + ++m_allen_not_in_rec; + error() << "Found an Allen pixel that does not exist in Rec" << endmsg; return false; }; @@ -97,67 +111,37 @@ void CompareRecAllenRichPixels::operator()( // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. for (size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { + if (found_current_pixel) { + found_current_pixel = false; + + // ensure HLT2 pixel validity + if (recPixelSummary.validMask()[i]) { + // iterate over Allen pixels + for (const auto& allenPixel : allenPixels) { + // check for match + if (matchPixels(allenPixel, recPixelSummary, i)) { + found_current_pixel = true; + ++m_rec_in_allen; + continue; + } // found a match + } // iterate over Allen pixels + } else { + found_current_pixel = true; // assume correctness on invalid pix to ignore it. + } // valid pix + found_all_pixels = found_all_pixels && found_current_pixel; + // case: HLT2 pixels in case they are not found in Allen - if (!found_current_pixel) { + } else { ++m_rec_not_in_allen; - error() << "Rec pixel does not exist in Allen" << endmsg; - std::cout << "Rec pixel: " << recPixelSummary.gloPos().X()[i - 1] << ',' << recPixelSummary.gloPos().Y()[i - 1] - << ',' << recPixelSummary.gloPos().Z()[i - 1] << ',' << recPixelSummary.locPos().X()[i - 1] << ',' - << recPixelSummary.locPos().Y()[i - 1] << ',' << recPixelSummary.locPos().Z()[i - 1] << ',' - << recPixelSummary.smartID()[i - 1].key() << ',' << recPixelSummary.effArea()[i - 1] << ',' - << (int) (recPixelSummary.rich()) << ',' << (int) (recPixelSummary.side()) << ',' - << recPixelSummary.validMask()[i - 1] << ',' << recPixelSummary.timeWindow()[i - 1] << ',' - << recPixelSummary.isInnerRegion()[i - 1] << '\n'; - } - found_current_pixel = false; - - // ensure HLT2 pixel validity - if (recPixelSummary.validMask()[i]) { - // iterate over Allen pixels - for (const auto& allenPixel : allenPixels) { - // check for match - if ( - (allenPixel.gloPos().x == recPixelSummary.gloPos().X()[i]) && - (allenPixel.gloPos().y == recPixelSummary.gloPos().Y()[i]) && - (allenPixel.gloPos().z == recPixelSummary.gloPos().Z()[i]) && - (allenPixel.locPos().x == recPixelSummary.locPos().X()[i]) && - (allenPixel.locPos().y == recPixelSummary.locPos().Y()[i]) && - (allenPixel.locPos().z == recPixelSummary.locPos().Z()[i]) && - (allenPixel.smartID().key() == recPixelSummary.smartID()[i].key()) && - (allenPixel.effArea() == recPixelSummary.effArea()[i]) && - ((int) allenPixel.rich() == (int) recPixelSummary.rich()) && - ((int) allenPixel.side() == (int) recPixelSummary.side()) && - (allenPixel.timeWindow() == recPixelSummary.timeWindow()[i]) && - (allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i])) { - found_current_pixel = true; - ++m_rec_in_allen; - continue; - } // found a match - } // iterate over Allen pixels + error() << "Found a Rec pixel that does not exist in Allen" << endmsg; } - else { - found_current_pixel = true; // assume correctedness on invalid pix to ignore it. - } // valid pix - found_all_pixels = found_all_pixels && found_current_pixel; - } + } return found_all_pixels; }; // call allen in hlt2 functor for (auto& allenPixel : allenPixels) { - if (!allenPixel.isNull()) { - if (!allenPixelExistsInRec(allenPixel)) { - error() << "Allen pixel does not exist in Rec" << endmsg; - std::cout << allenPixel.toString() << std::endl; - ++m_allen_not_in_rec; - } - else { - ++m_allen_in_rec; - } - } - else { - ++m_allen_null; - } + allenPixelExistsInRec(allenPixel); } // call hlt2 in allen functor -- GitLab From 22f16d813c19adab825d2eeb21c6174172f12bc1 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 18 Apr 2025 09:12:08 +0200 Subject: [PATCH 14/92] Address comments for AllenConf and AllenSequences for rich pixels --- .../python/AllenConf/hlt1_reconstruction.py | 3 +- .../python/AllenConf/rich_make_pixels.py | 34 ------------------- .../python/AllenConf/rich_reconstruction.py | 24 ++++++++++++- configuration/python/AllenSequences/rich.py | 3 +- 4 files changed, 25 insertions(+), 39 deletions(-) delete mode 100644 configuration/python/AllenConf/rich_make_pixels.py diff --git a/configuration/python/AllenConf/hlt1_reconstruction.py b/configuration/python/AllenConf/hlt1_reconstruction.py index 1e8e75b1bbf..b94181e4184 100644 --- a/configuration/python/AllenConf/hlt1_reconstruction.py +++ b/configuration/python/AllenConf/hlt1_reconstruction.py @@ -33,8 +33,7 @@ from AllenConf.filters import make_gec from AllenConf.best_track_creator import best_track_creator from AllenConf.enum_types import TrackingType from AllenConf.secondary_vertex_reconstruction import make_kalman_long -from AllenConf.rich_reconstruction import decode_rich -from AllenConf.rich_make_pixels import make_pixels +from AllenConf.rich_reconstruction import make_pixels def hlt1_reconstruction(algorithm_name='', tracking_type=TrackingType.FORWARD, diff --git a/configuration/python/AllenConf/rich_make_pixels.py b/configuration/python/AllenConf/rich_make_pixels.py deleted file mode 100644 index a5ad57396f0..00000000000 --- a/configuration/python/AllenConf/rich_make_pixels.py +++ /dev/null @@ -1,34 +0,0 @@ -############################################################################### -# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the Apache License # -# version 2 (Apache-2.0), copied verbatim in the file "LICENSE". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -from AllenCore.algorithms import (data_provider_t, rich_make_pixels_t) -from AllenConf.utils import initialize_number_of_events -from AllenConf.rich_reconstruction import (RICH_1, RICH_2, VALID_RICHS, - decode_rich) -from AllenCore.generator import make_algorithm - - -def make_pixels(decoded_rich=None, rich=RICH_1): - if rich not in VALID_RICHS: - raise ValueError(f"rich must be one of {VALID_RICHS}") - if decoded_rich is None: - decoded_rich = decode_rich(rich) - number_of_hits = decoded_rich["host_rich_total_number_of_hits"] - smart_ids = decoded_rich["dev_smart_ids"] - hit_offsets = decoded_rich["dev_rich_hit_offsets"] - - rich_pixels = make_algorithm( - rich_make_pixels_t, - name=f"rich{rich}_make_pixels", - host_rich_total_number_of_hits_t=number_of_hits, - dev_smart_ids_t=smart_ids, - dev_rich_hit_offsets_t=hit_offsets, - current_rich=rich) - return {"dev_rich_pixels": rich_pixels.dev_rich_pixels_t} diff --git a/configuration/python/AllenConf/rich_reconstruction.py b/configuration/python/AllenConf/rich_reconstruction.py index 4ba18f16764..852588c1d4c 100644 --- a/configuration/python/AllenConf/rich_reconstruction.py +++ b/configuration/python/AllenConf/rich_reconstruction.py @@ -8,7 +8,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # # or submit itself to any jurisdiction. # ############################################################################### -from AllenCore.algorithms import (data_provider_t, rich_decoding_t) +from AllenCore.algorithms import (data_provider_t, rich_decoding_t, rich_make_pixels_t) from AllenConf.utils import initialize_number_of_events from AllenCore.generator import make_algorithm @@ -45,3 +45,25 @@ def decode_rich(rich=RICH_1): "host_rich_total_number_of_hits": rich_decoding.host_rich_total_number_of_hits_t } + + +def make_pixels(decoded_rich=None, rich=RICH_1): + if rich not in VALID_RICHS: + raise ValueError(f"rich must be one of {VALID_RICHS}") + + if decoded_rich is None: + decoded_rich = decode_rich(rich) + + number_of_hits = decoded_rich["host_rich_total_number_of_hits"] + smart_ids = decoded_rich["dev_smart_ids"] + hit_offsets = decoded_rich["dev_rich_hit_offsets"] + + rich_pixels = make_algorithm( + rich_make_pixels_t, + name=f"rich{rich}_make_pixels", + host_rich_total_number_of_hits_t=number_of_hits, + dev_smart_ids_t=smart_ids, + dev_rich_hit_offsets_t=hit_offsets, + current_rich=rich) + + return {"dev_rich_pixels": rich_pixels.dev_rich_pixels_t} diff --git a/configuration/python/AllenSequences/rich.py b/configuration/python/AllenSequences/rich.py index 22abb82a33b..8c424ea7914 100644 --- a/configuration/python/AllenSequences/rich.py +++ b/configuration/python/AllenSequences/rich.py @@ -8,8 +8,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # # or submit itself to any jurisdiction. # ############################################################################### -from AllenConf.rich_reconstruction import decode_rich -from AllenConf.rich_make_pixels import make_pixels +from AllenConf.rich_reconstruction import decode_rich, make_pixels from AllenCore.generator import generate from PyConf.control_flow import NodeLogic, CompositeNode -- GitLab From 86729b834e563185bd99c5801a1b5623031e7456 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 18 Apr 2025 19:43:14 +0200 Subject: [PATCH 15/92] combine RICH object classes --- .../decoding/include/{Rich1.cuh => Rich.cuh} | 8 ++-- device/rich/decoding/include/Rich2.cuh | 38 ------------------- device/rich/decoding/src/RichMakePixels.cu | 17 +++------ 3 files changed, 10 insertions(+), 53 deletions(-) rename device/rich/decoding/include/{Rich1.cuh => Rich.cuh} (84%) delete mode 100644 device/rich/decoding/include/Rich2.cuh diff --git a/device/rich/decoding/include/Rich1.cuh b/device/rich/decoding/include/Rich.cuh similarity index 84% rename from device/rich/decoding/include/Rich1.cuh rename to device/rich/decoding/include/Rich.cuh index 4b7981238d3..5a9f3f1186b 100644 --- a/device/rich/decoding/include/Rich1.cuh +++ b/device/rich/decoding/include/Rich.cuh @@ -12,11 +12,11 @@ #include namespace Allen { - class Rich1 { + class Rich { public: - __host__ __device__ Rich1(); + __host__ __device__ Rich(); - __host__ __device__ Rich1(const int8_t m_type, const std::array m_panels) : + __host__ __device__ Rich(const int8_t m_type, const std::array m_panels) : m_panels(m_panels), m_type(m_type) {} @@ -26,7 +26,7 @@ namespace Allen { __host__ __device__ inline auto& pdPanels() { return m_panels; } /// Access PD Panel for a given side - __host__ __device__ inline auto pdPanel(const Rich::Future::DAQ::Side panel) noexcept + __host__ __device__ inline auto pdPanel(const ::Rich::Future::DAQ::Side panel) noexcept { return &(pdPanels()[panel]); } diff --git a/device/rich/decoding/include/Rich2.cuh b/device/rich/decoding/include/Rich2.cuh deleted file mode 100644 index efdfd485944..00000000000 --- a/device/rich/decoding/include/Rich2.cuh +++ /dev/null @@ -1,38 +0,0 @@ -/*****************************************************************************\ - * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * - * * - * This software is distributed under the terms of the Apache License * - * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * - * * - * In applying this licence, CERN does not waive the privileges and immunities * - * granted to it by virtue of its status as an Intergovernmental Organization * - * or submit itself to any jurisdiction. * - \*****************************************************************************/ -#pragma once -#include - -namespace Allen { - class Rich2 { - public: - __host__ __device__ Rich2(); - - __host__ __device__ Rich2(const int8_t m_type, const std::array m_panels) : - m_panels(m_panels), m_type(m_type) - {} - - __host__ __device__ inline auto rich() { return m_type; } - - /// Access PD Panels - __host__ __device__ inline auto& pdPanels() { return m_panels; } - - /// Access PD Panel for a given side - __host__ __device__ inline auto pdPanel(const Rich::Future::DAQ::Side panel) noexcept - { - return &(pdPanels()[panel]); - } - - private: - std::array m_panels; - int8_t m_type; - }; -} // namespace Allen diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index b92c5c30ff9..bdb744e2a2c 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -11,8 +11,7 @@ #include #include -#include -#include +#include #include #include #include @@ -100,22 +99,18 @@ void rich_make_pixels::rich_make_pixels_t::operator()( const Constants& constants, const Allen::Context& context) const { - // Create RICH objects from dump - Allen::Rich1* rich1; - Allen::Rich2* rich2; + // Create RICH object from dump + Allen::Rich* rich; const auto richValue = m_current_rich; if (richValue == 1) - rich1 = reinterpret_cast(constants.dev_rich_1_geometry); + rich = reinterpret_cast(constants.dev_rich_1_geometry); else - rich2 = reinterpret_cast(constants.dev_rich_2_geometry); + rich = reinterpret_cast(constants.dev_rich_2_geometry); // Send panels from RICH to SmartIDsHelper std::array panels; for (size_t i = 0; i < 2; i++) { - if (richValue == 1) - panels[i] = &(rich1->pdPanels()[i]); - else - panels[i] = &(rich2->pdPanels()[i]); + panels[i] = &(rich->pdPanels()[i]); } Allen::RichSmartIDs smartIDsHelper = Allen::RichSmartIDs(panels); -- GitLab From 1574279518b6f0c11201c059b24ce9d80b199f74 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 18 Apr 2025 20:32:52 +0200 Subject: [PATCH 16/92] removed comments, initialized nullptrs --- device/rich/decoding/include/RichDefinitions.cuh | 5 ----- device/rich/decoding/src/RichMakePixels.cu | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 2f0522ac072..78523cadc2e 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -34,9 +34,6 @@ namespace Allen { /// Course (pixel) Time window for each RICH in ns [[maybe_unused]] __constant__ static std::array m_timeWindow = {3.0, 3.0}; - /// Enable the override of inner and out regions - [[maybe_unused]] __constant__ static std::array m_overrideRegions = {false, false}; - /// Size in X defining the inner pixels for each RICH [[maybe_unused]] __constant__ static std::array m_innerPixX = {250.0, 99999.9}; @@ -353,8 +350,6 @@ namespace Allen { // Max ADC time that can be stored static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType {1} << BitsADCTime) - 1); - // static constexpr const ADCTimeType MaxADCTime = (ADCTimeType)(BitPackType {1} << BitsADCTime) - ADCTimeType - // {1}; // Parameters for conversion between float and ADC time values static constexpr const double MinTime = -50.0; // In nanoseconds diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index bdb744e2a2c..240f88020ba 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -100,7 +100,7 @@ void rich_make_pixels::rich_make_pixels_t::operator()( const Allen::Context& context) const { // Create RICH object from dump - Allen::Rich* rich; + Allen::Rich* rich = nullptr; const auto richValue = m_current_rich; if (richValue == 1) rich = reinterpret_cast(constants.dev_rich_1_geometry); @@ -114,7 +114,7 @@ void rich_make_pixels::rich_make_pixels_t::operator()( } Allen::RichSmartIDs smartIDsHelper = Allen::RichSmartIDs(panels); - Allen::RichSmartIDs* dev_smartIDsHelper; + Allen::RichSmartIDs* dev_smartIDsHelper = nullptr; Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDs)); Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDs), Allen::memcpyHostToDevice); -- GitLab From 3128494f4e3ac375f90b715eee8573e0647ead65 Mon Sep 17 00:00:00 2001 From: ipalmame Date: Fri, 18 Apr 2025 23:08:57 +0200 Subject: [PATCH 17/92] Added default init to class members --- device/rich/decoding/include/Rich.cuh | 6 ++-- device/rich/decoding/include/RichPD.cuh | 6 ++-- device/rich/decoding/include/RichPDPanel.cuh | 15 ++++++---- device/rich/decoding/include/RichPixels.cuh | 30 +++++++++---------- device/rich/decoding/include/RichSmartIDs.cuh | 2 +- device/rich/decoding/src/RichMakePixels.cu | 4 +-- 6 files changed, 33 insertions(+), 30 deletions(-) diff --git a/device/rich/decoding/include/Rich.cuh b/device/rich/decoding/include/Rich.cuh index 5a9f3f1186b..f34158b4735 100644 --- a/device/rich/decoding/include/Rich.cuh +++ b/device/rich/decoding/include/Rich.cuh @@ -16,7 +16,7 @@ namespace Allen { public: __host__ __device__ Rich(); - __host__ __device__ Rich(const int8_t m_type, const std::array m_panels) : + __host__ __device__ Rich(const Rich::Future::DAQ::DetectorType m_type, const std::array m_panels) : m_panels(m_panels), m_type(m_type) {} @@ -32,7 +32,7 @@ namespace Allen { } private: - std::array m_panels; - int8_t m_type; + std::array m_panels{}; + Rich::Future::DAQ::DetectorType m_type{Rich::Future::DAQ::DetectorType::Rich1}; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichPD.cuh b/device/rich/decoding/include/RichPD.cuh index 89d6cba9d68..142f6ac08c0 100644 --- a/device/rich/decoding/include/RichPD.cuh +++ b/device/rich/decoding/include/RichPD.cuh @@ -84,9 +84,9 @@ namespace Rich::Detector::Allen { __host__ __device__ void setIsNull(bool value) { m_isNull = value; } private: - std::array m_locToGloM; - std::array m_zeroInPanelFrame; - std::uint64_t m_pdSmartID; + std::array m_locToGloM{}; + std::array m_zeroInPanelFrame{}; + std::uint64_t m_pdSmartID{0}; float m_effPixelArea {0.f}; float m_numPixels {0.f}; float m_localZcoord {0.f}; diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index 671d79b7dd9..93c1f7f448f 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -101,11 +101,14 @@ namespace Allen { } private: - ModuleArray m_PDs; - std::array m_gloToPDPanelM; // 3D Transform - uint32_t m_modNumOffset; - std::array m_panelID; - Rich::Future::DAQ::DetectorType m_rich; - Rich::Future::DAQ::Side m_side; + ModuleArray m_PDs{}; + std::array m_gloToPDPanelM{}; // 3D Transform + uint32_t m_modNumOffset{0}; + std::array m_panelID{ + Rich::Future::DAQ::DetectorType::InvalidDetector, + Rich::Future::DAQ::Side::InvalidSide, + -1}; + Rich::Future::DAQ::DetectorType m_rich{Rich::Future::DAQ::DetectorType::InvalidDetector}; + Rich::Future::DAQ::Side m_side{Rich::Future::DAQ::Side::InvalidSide}; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index 51b55bb068b..214078c3bcb 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -17,7 +17,7 @@ namespace Allen { public: // Default __host__ __device__ RichPixel() : - gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID(), m_effArea(0.0f), m_rich(0), m_side(0), m_mask(0), + gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID(), m_effArea(0.0f), m_rich(Rich::Future::DAQ::DetectorType::InvalidDetector), m_side(Rich::Future::DAQ::InvalidSide), m_mask(0), m_timeWindow(0.0f), m_isInnerRegion(true), m_isNull(true) {} @@ -27,8 +27,8 @@ namespace Allen { const Point& lPos, const Allen::RichSmartID& smartID, double effArea, - uint8_t rich, - uint8_t side, + Rich::Future::DAQ::DetectorType rich, + Rich::Future::DAQ::Side side, uint8_t mask) : gPos(gPos), lPos(lPos), m_smartID(smartID), m_effArea(effArea), m_rich(rich), m_side(side), m_mask(mask), m_isNull(false) @@ -42,8 +42,8 @@ namespace Allen { const Point& lPos, const Allen::RichSmartID& smartID, double effArea, - uint8_t rich, - uint8_t side, + Rich::Future::DAQ::DetectorType rich, + Rich::Future::DAQ::Side side, uint8_t mask, float timeWindow) : gPos(gPos), @@ -89,15 +89,15 @@ namespace Allen { } private: - Point gPos; - Point lPos; - Allen::RichSmartID m_smartID; - double m_effArea; - uint8_t m_rich; - uint8_t m_side; - uint8_t m_mask; - float m_timeWindow; - bool m_isInnerRegion; - bool m_isNull; + Point gPos{0.0f, 0.0f, 0.0f}; + Point lPos{0.0f, 0.0f, 0.0f}; + Allen::RichSmartID m_smartID {Allen::RichSmartID()}; + double m_effArea{0.0f}; + Rich::Future::DAQ::DetectorType m_rich{Rich::Future::DAQ::DetectorType::InvalidDetector}; + Rich::Future::DAQ::Side m_side{Rich::Future::DAQ::InvalidSide}; + uint8_t m_mask{0}; + float m_timeWindow{0.0f}; + bool m_isInnerRegion{true}; + bool m_isNull{true}; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDs.cuh b/device/rich/decoding/include/RichSmartIDs.cuh index dcda7d72018..250c2c5b9af 100644 --- a/device/rich/decoding/include/RichSmartIDs.cuh +++ b/device/rich/decoding/include/RichSmartIDs.cuh @@ -80,6 +80,6 @@ namespace Allen { } private: - const std::array m_pdPanels; + const std::array m_pdPanels{}; }; } // namespace Allen diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index 240f88020ba..114d6f8d1e8 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -25,8 +25,8 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, cons uint8_t mask = 0; // Selection mask bool innerRegion = 1; // Inner/outer region - const auto rich = smartID.rich(); - const auto side = smartID.panel(); + const auto rich = (Rich::Future::DAQ::DetectorType)smartID.rich(); + const auto side = (Rich::Future::DAQ::Side)smartID.panel(); // Functor to save a Rich pixel auto savePix = [&]() { -- GitLab From 5d3a385eef716bfa4e8068c2e250bff8724fbdc3 Mon Sep 17 00:00:00 2001 From: ipalmame Date: Sat, 19 Apr 2025 00:35:26 +0200 Subject: [PATCH 18/92] Solved merge conflicts --- device/rich/decoding/include/Rich.cuh | 4 ++-- device/rich/decoding/include/RichDefinitions.cuh | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/device/rich/decoding/include/Rich.cuh b/device/rich/decoding/include/Rich.cuh index f34158b4735..681f35d798c 100644 --- a/device/rich/decoding/include/Rich.cuh +++ b/device/rich/decoding/include/Rich.cuh @@ -16,7 +16,7 @@ namespace Allen { public: __host__ __device__ Rich(); - __host__ __device__ Rich(const Rich::Future::DAQ::DetectorType m_type, const std::array m_panels) : + __host__ __device__ Rich(const ::Rich::Future::DAQ::DetectorType m_type, const std::array m_panels) : m_panels(m_panels), m_type(m_type) {} @@ -33,6 +33,6 @@ namespace Allen { private: std::array m_panels{}; - Rich::Future::DAQ::DetectorType m_type{Rich::Future::DAQ::DetectorType::Rich1}; + ::Rich::Future::DAQ::DetectorType m_type{::Rich::Future::DAQ::DetectorType::Rich1}; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 78523cadc2e..382843ab3b7 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -34,6 +34,9 @@ namespace Allen { /// Course (pixel) Time window for each RICH in ns [[maybe_unused]] __constant__ static std::array m_timeWindow = {3.0, 3.0}; + /// Enable the override of inner and out regions + [[maybe_unused]] __constant__ static std::array m_overrideRegions = {false, false}; + /// Size in X defining the inner pixels for each RICH [[maybe_unused]] __constant__ static std::array m_innerPixX = {250.0, 99999.9}; -- GitLab From 8b05b2b1d2789cfaaf49f03c8dd4408d925de935 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Sat, 19 Apr 2025 22:49:00 +0200 Subject: [PATCH 19/92] Modularized RichSmartID class files, one bug to fix in RichPixels in Allen Standalone --- device/rich/decoding/include/Rich.cuh | 5 +- device/rich/decoding/include/RichDecoding.cuh | 2 +- .../rich/decoding/include/RichDefinitions.cuh | 341 +----------------- .../rich/decoding/include/RichMakePixels.cuh | 4 +- device/rich/decoding/include/RichPD.cuh | 1 + device/rich/decoding/include/RichPDPanel.cuh | 12 +- device/rich/decoding/include/RichPixels.cuh | 9 +- device/rich/decoding/include/RichSmartID.cuh | 324 +++++++++++++++++ .../decoding/include/RichSmartIDHelper.cuh | 85 +++++ device/rich/decoding/src/RichMakePixels.cu | 24 +- .../{RichSmartIDs.cu => RichSmartIDHelper.cu} | 8 +- 11 files changed, 464 insertions(+), 351 deletions(-) create mode 100644 device/rich/decoding/include/RichSmartID.cuh create mode 100644 device/rich/decoding/include/RichSmartIDHelper.cuh rename device/rich/decoding/src/{RichSmartIDs.cu => RichSmartIDHelper.cu} (89%) diff --git a/device/rich/decoding/include/Rich.cuh b/device/rich/decoding/include/Rich.cuh index 681f35d798c..fad5a3243a5 100644 --- a/device/rich/decoding/include/Rich.cuh +++ b/device/rich/decoding/include/Rich.cuh @@ -10,13 +10,14 @@ \*****************************************************************************/ #pragma once #include +#include -namespace Allen { +namespace Rich::Detector::Allen { class Rich { public: __host__ __device__ Rich(); - __host__ __device__ Rich(const ::Rich::Future::DAQ::DetectorType m_type, const std::array m_panels) : + __host__ __device__ Rich(const ::Rich::Future::DAQ::DetectorType m_type, const std::array< ::Rich::Detector::Allen::PDPanel, 2 > m_panels) : m_panels(m_panels), m_type(m_type) {} diff --git a/device/rich/decoding/include/RichDecoding.cuh b/device/rich/decoding/include/RichDecoding.cuh index ce74c591ed7..80e1e01df8d 100644 --- a/device/rich/decoding/include/RichDecoding.cuh +++ b/device/rich/decoding/include/RichDecoding.cuh @@ -11,7 +11,7 @@ #pragma once #include "AlgorithmTypes.cuh" -#include +#include namespace rich_decoding { struct Parameters { diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/rich/decoding/include/RichDefinitions.cuh index 382843ab3b7..6cd7cb9e0ed 100644 --- a/device/rich/decoding/include/RichDefinitions.cuh +++ b/device/rich/decoding/include/RichDefinitions.cuh @@ -12,10 +12,9 @@ #include #include -#include #include "BackendCommon.h" -namespace Allen { +namespace Rich { using FP = float; using Point = float3; using DataType = std::uint32_t; @@ -24,30 +23,32 @@ namespace Allen { using BitPackType = KeyType; using ADCTimeType = std::uint16_t; - //// Constants related to pixel reconstruction + //// Constants related to pixel reconstruction, value definition based on those in HLT2's + /// Rec/Rich/RichFutureRecPixelAlgorithms/src/RichSIMDSummaryPixels.cpp + /// Enabled 4D reconstruction - [[maybe_unused]] __constant__ static std::array m_enable4D = {false, false}; + [[maybe_unused]] __device__ constexpr bool m_enable4D[2] = {false, false}; /// Average expected hit time for signal in each RICH in ns - [[maybe_unused]] __constant__ static std::array m_avHitTime = {13.03, 52.94}; + [[maybe_unused]] __device__ constexpr float m_avHitTime[2] = {13.03, 52.94}; /// Course (pixel) Time window for each RICH in ns - [[maybe_unused]] __constant__ static std::array m_timeWindow = {3.0, 3.0}; + [[maybe_unused]] __device__ constexpr float m_timeWindow[2] = {3.0, 3.0}; /// Enable the override of inner and out regions - [[maybe_unused]] __constant__ static std::array m_overrideRegions = {false, false}; + [[maybe_unused]] __device__ constexpr bool m_overrideRegions[2] = {false, false}; /// Size in X defining the inner pixels for each RICH - [[maybe_unused]] __constant__ static std::array m_innerPixX = {250.0, 99999.9}; + [[maybe_unused]] __device__ constexpr double m_innerPixX[2] = {250.0, 99999.9}; /// Size in Y defining the inner pixels for each RICH - [[maybe_unused]] __constant__ static std::array m_innerPixY = {300.0, 300.0}; + [[maybe_unused]] __device__ constexpr double m_innerPixY[2] = {300.0, 300.0}; /// Time resolution for inner regions in ns - [[maybe_unused]] __constant__ static std::array m_innerTimeWindow = {0.15, 0.15}; + [[maybe_unused]] __device__ constexpr float m_innerTimeWindow[2] = {0.15, 0.15}; /// Time resolution for outer regions in ns - [[maybe_unused]] __constant__ static std::array m_outerTimeWindow = {0.3, 0.3}; + [[maybe_unused]] __device__ constexpr float m_outerTimeWindow[2] = {0.3, 0.3}; /// Matrix-point transform3D, adapted from ROOT::Math __host__ __device__ inline Point transform3DTimesPoint(Transform3D fM, Point point) @@ -56,315 +57,10 @@ namespace Allen { fM[4] * point.x + fM[5] * point.y + fM[6] * point.z + fM[7], fM[8] * point.x + fM[9] * point.y + fM[10] * point.z + fM[11]}; } +} // namespace Rich - /// RICH SmartIDs class - class RichSmartID { - KeyType m_key; - - public: - // Set the RICH PD pixel row identifier - __host__ __device__ constexpr void setPixelRow(const DataType row) - { - setData(row, ShiftPixelRow, MaskPixelRow, MaskPixelRowIsSet); - } - - // Set the RICH PD pixel column identifier - __host__ __device__ constexpr void setPixelCol(const DataType col) - { - setData(col, ShiftPixelCol, MaskPixelCol, MaskPixelColIsSet); - } - - public: - __host__ __device__ RichSmartID() = default; - - __host__ __device__ RichSmartID(KeyType key) : m_key(key) {} - - // Number of bits for each data field in the word - static constexpr const BitPackType BitsPixelCol = 3; //< Number of bits for MaPMT pixel column - static constexpr const BitPackType BitsPixelRow = 3; //< Number of bits for MaPMT pixel row - static constexpr const BitPackType BitsPDNumInMod = 4; //< Number of bits for MaPMT 'number in module' - static constexpr const BitPackType BitsPDMod = 9; //< Number of bits for MaPMT module - static constexpr const BitPackType BitsPanel = 1; //< Number of bits for MaPMT panel - static constexpr const BitPackType BitsRich = 1; //< Number of bits for RICH detector - static constexpr const BitPackType BitsPixelSubRowIsSet = 1; - static constexpr const BitPackType BitsPixelColIsSet = 1; - static constexpr const BitPackType BitsPixelRowIsSet = 1; - static constexpr const BitPackType BitsPDIsSet = 1; - static constexpr const BitPackType BitsPanelIsSet = 1; - static constexpr const BitPackType BitsRichIsSet = 1; - static constexpr const BitPackType BitsLargePixel = 1; - - // The shifts - static constexpr const BitPackType ShiftPixelCol = 0; - static constexpr const BitPackType ShiftPixelRow = ShiftPixelCol + BitsPixelCol; - static constexpr const BitPackType ShiftPDNumInMod = ShiftPixelRow + BitsPixelRow; - static constexpr const BitPackType ShiftPDMod = ShiftPDNumInMod + BitsPDNumInMod; - static constexpr const BitPackType ShiftPanel = ShiftPDMod + BitsPDMod; - static constexpr const BitPackType ShiftRich = ShiftPanel + BitsPanel; - static constexpr const BitPackType ShiftPixelSubRowIsSet = ShiftRich + BitsRich; - static constexpr const BitPackType ShiftPixelColIsSet = ShiftPixelSubRowIsSet + BitsPixelSubRowIsSet; - static constexpr const BitPackType ShiftPixelRowIsSet = ShiftPixelColIsSet + BitsPixelColIsSet; - static constexpr const BitPackType ShiftPDIsSet = ShiftPixelRowIsSet + BitsPixelRowIsSet; - static constexpr const BitPackType ShiftPanelIsSet = ShiftPDIsSet + BitsPDIsSet; - static constexpr const BitPackType ShiftRichIsSet = ShiftPanelIsSet + BitsPanelIsSet; - static constexpr const BitPackType ShiftLargePixel = ShiftRichIsSet + BitsRichIsSet; - - // The masks - static constexpr const BitPackType MaskPixelCol = (BitPackType)((BitPackType {1} << BitsPixelCol) - BitPackType {1}) - << ShiftPixelCol; - static constexpr const BitPackType MaskPixelRow = (BitPackType)((BitPackType {1} << BitsPixelRow) - BitPackType {1}) - << ShiftPixelRow; - static constexpr const BitPackType MaskPDNumInMod = - (BitPackType)((BitPackType {1} << BitsPDNumInMod) - BitPackType {1}) << ShiftPDNumInMod; - static constexpr const BitPackType MaskPDMod = (BitPackType)((BitPackType {1} << BitsPDMod) - BitPackType {1}) - << ShiftPDMod; - static constexpr const BitPackType MaskPanel = (BitPackType)((BitPackType {1} << BitsPanel) - BitPackType {1}) - << ShiftPanel; - static constexpr const BitPackType MaskRich = (BitPackType)((BitPackType {1} << BitsRich) - BitPackType {1}) - << ShiftRich; - static constexpr const BitPackType MaskPixelSubRowIsSet = - (BitPackType)((BitPackType {1} << BitsPixelSubRowIsSet) - BitPackType {1}) << ShiftPixelSubRowIsSet; - static constexpr const BitPackType MaskPixelColIsSet = - (BitPackType)((BitPackType {1} << BitsPixelColIsSet) - BitPackType {1}) << ShiftPixelColIsSet; - static constexpr const BitPackType MaskPixelRowIsSet = - (BitPackType)((BitPackType {1} << BitsPixelRowIsSet) - BitPackType {1}) << ShiftPixelRowIsSet; - static constexpr const BitPackType MaskPDIsSet = (BitPackType)((BitPackType {1} << BitsPDIsSet) - BitPackType {1}) - << ShiftPDIsSet; - static constexpr const BitPackType MaskPanelIsSet = - (BitPackType)((BitPackType {1} << BitsPanelIsSet) - BitPackType {1}) << ShiftPanelIsSet; - static constexpr const BitPackType MaskRichIsSet = - (BitPackType)((BitPackType {1} << BitsRichIsSet) - BitPackType {1}) << ShiftRichIsSet; - static constexpr const BitPackType MaskLargePixel = - (BitPackType)((BitPackType {1} << BitsLargePixel) - BitPackType {1}) << ShiftLargePixel; - - // Max values - static constexpr const DataType MaxPixelCol = (DataType)(BitPackType {1} << BitsPixelCol) - DataType {1}; - static constexpr const DataType MaxPixelRow = (DataType)(BitPackType {1} << BitsPixelRow) - DataType {1}; - static constexpr const DataType MaxPDNumInMod = (DataType)(BitPackType {1} << BitsPDNumInMod) - DataType {1}; - static constexpr const DataType MaxPDMod = (DataType)(BitPackType {1} << BitsPDMod) - DataType {1}; - static constexpr const DataType MaxPanel = (DataType)(BitPackType {1} << BitsPanel) - DataType {1}; - static constexpr const DataType MaxRich = (DataType)(BitPackType {1} << BitsRich) - DataType {1}; - - // Number of bits for the channel identification (i.e. excluding any time info) - // Currently use the lowest 32 bits for this. - static constexpr const BitPackType NChannelBits = 32; - - __host__ __device__ constexpr inline void - setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept - { - m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); - } - - __host__ __device__ constexpr inline void - setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept - { - m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; - } - - __host__ __device__ constexpr inline BitPackType getData(const BitPackType shift, const BitPackType mask) const - noexcept - { - return (m_key & mask) >> shift; - } - - __host__ __device__ constexpr inline BitPackType key() const noexcept { return m_key; } - - __host__ __device__ constexpr inline bool operator==(const RichSmartID& other) const noexcept - { - return m_key == other.key(); - } - - __host__ __device__ constexpr inline auto isLargePMT() const noexcept - { - return 0 != getData(ShiftLargePixel, MaskLargePixel); - } - - __host__ __device__ constexpr inline auto rich() const noexcept { return getData(ShiftRich, MaskRich); } - - __host__ __device__ constexpr inline auto panel() const noexcept { return getData(ShiftPanel, MaskPanel); } - - __host__ __device__ constexpr inline DataType pdMod() const noexcept { return getData(ShiftPDMod, MaskPDMod); } - - __host__ __device__ constexpr inline DataType pdNumInMod() const noexcept - { - return getData(ShiftPDNumInMod, MaskPDNumInMod); - } - - __host__ __device__ constexpr inline DataType panelLocalModuleNum() const noexcept - { - return pdMod() - PanelModuleOffsets()[rich()][panel()]; - } - - __host__ __device__ constexpr inline DataType columnLocalModuleNum() const noexcept - { - return panelLocalModuleNum() % ModulesPerColumn; - } - - __host__ __device__ constexpr inline DataType numPMTsPerEC() const noexcept - { - return isLargePMT() ? HTypePMTsPerEC : RTypePMTsPerEC; - } - - __host__ __device__ constexpr inline DataType elementaryCell() const noexcept - { - return pdNumInMod() / numPMTsPerEC(); - } - - __host__ __device__ constexpr inline DataType pdNumInEC() const noexcept { return pdNumInMod() % numPMTsPerEC(); } - - __host__ __device__ constexpr inline auto pixelColIsSet() const noexcept - { - return 0 != getData(ShiftPixelColIsSet, MaskPixelColIsSet); - } - - __host__ __device__ constexpr inline auto pixelRowIsSet() const noexcept - { - return 0 != getData(ShiftPixelRowIsSet, MaskPixelRowIsSet); - } - - [[nodiscard]] __host__ __device__ constexpr bool pdIsSet() const noexcept - { - return 0 != ((key() & MaskPDIsSet) >> ShiftPDIsSet); - } - - __host__ __device__ constexpr inline DataType pixelCol() const noexcept - { - return getData(ShiftPixelCol, MaskPixelCol); - } - - __host__ __device__ constexpr inline DataType pixelRow() const noexcept - { - return getData(ShiftPixelRow, MaskPixelRow); - } - - __host__ __device__ constexpr inline DataType anodeIndex() const noexcept - { - return pixelRow() * PixelsPerCol + PixelsPerRow - 1 - pixelCol(); - } - - __host__ __device__ constexpr inline bool adcTimeIsSet() const noexcept - { - return (0 != (key() & MaPMT::MaskADCTimeIsSet) >> MaPMT::ShiftADCTimeIsSet); - } - - __host__ __device__ constexpr ADCTimeType adcTime() const - { - return ((key() & MaPMT::MaskADCTime) >> MaPMT::ShiftADCTime); - } - - __host__ __device__ constexpr auto time() const noexcept - { - return (MaPMT::MinTime + (adcTime() * MaPMT::ScaleADCToTime)); - } - - // ostream operator - __host__ friend std::ostream& operator<<(std::ostream& str, const RichSmartID& id) - { - const auto rich = id.rich(); - const auto panel = id.panel(); - str << "{ "; - str << "PMT"; - str << (id.isLargePMT() ? ":h " : ":r "); - str << (rich == 0 ? "Rich1 " : "Rich2 "); - if (rich == 0) { - str << (panel == 0 ? "Top " : "Bot "); - } - else { - str << (panel == 0 ? "L-A " : "R-C "); - } - str << "PD[Mod,NInMod]: "; - str << std::setfill('0') << std::setw(3) << id.pdMod() << ','; - str << std::setfill('0') << std::setw(2) << id.pdNumInMod() << ' '; - str << "Mod[Col,NInCol] "; - str << std::setfill('0') << std::setw(2) << id.panelLocalModuleNum() << ','; - str << std::setfill('0') << std::setw(2) << id.columnLocalModuleNum() << ' '; - str << " PD[EC,NInEC]: "; - str << id.elementaryCell() << ','; - str << id.pdNumInEC() << ' '; - - const auto pixColSet = id.pixelColIsSet(); - const auto pixRowSet = id.pixelRowIsSet(); - if (pixColSet || pixRowSet) { - if (pixColSet && pixRowSet) { - str << "Pix[Col,Row]: " << std::setfill('0') << std::setw(1) << id.pixelCol() << "," << id.pixelRow(); - } - else { - const auto fSPix = 2; - if (pixColSet) { - str << std::setfill('0') << std::setw(fSPix) << " pixCol" << id.pixelCol(); - } - if (pixRowSet) { - str << std::setfill('0') << std::setw(fSPix) << " pixRow" << id.pixelRow(); - } - } - // Include PMT derived info - if (pixColSet && pixRowSet) { - str << " Anode:" << std::setfill('0') << std::setw(2) << id.anodeIndex(); - } - } - str << " }\n"; - return str; - } - - public: - // Number of PMT pixels per row - static constexpr const DataType PixelsPerRow = 8; - // Number of PMT pixels per column - static constexpr const DataType PixelsPerCol = 8; - // Total number of PMT pixels - static constexpr const DataType TotalPixels = PixelsPerRow * PixelsPerCol; - // Number PMTs per EC for R type PMTs - static constexpr const DataType RTypePMTsPerEC = 4; - // Number PMTs per EC for H type PMTs - static constexpr const DataType HTypePMTsPerEC = 1; - // Number of ECs per module - static constexpr const DataType ECsPerModule = 4; - // Number of modules per column - static constexpr const DataType ModulesPerColumn = 6; - // Number of module columns per panel, in each RICH - static constexpr const std::array ModuleColumnsPerPanel = {{11, 14}}; - // Maximum number of module columns in any panel, RICH1 or RICH2 - static constexpr const DataType MaxModuleColumnsAnyPanel = - std::max(ModuleColumnsPerPanel[0], ModuleColumnsPerPanel[1]); - // Number of modules per panel, in each RICH - static constexpr const std::array ModulesPerPanel { - {(ModulesPerColumn * ModuleColumnsPerPanel[0]), (ModulesPerColumn * ModuleColumnsPerPanel[1])}}; - - __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() - { - return {std::array {0, ModulesPerPanel[0]}, - std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; - } - - class MaPMT { - public: - static constexpr const DataType MaxPDsPerModule = 16; - static constexpr const DataType MaxModulesPerPanel = 92; - - // Bits for time field. - static constexpr const BitPackType BitsADCTime = 16; - static constexpr const BitPackType BitsADCTimeIsSet = 1; - static constexpr const BitPackType ShiftADCTime = NChannelBits; - static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; - static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) - << ShiftADCTime; - static constexpr const BitPackType MaskADCTimeIsSet = - (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; - - // Max ADC time that can be stored - static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType {1} << BitsADCTime) - 1); - - // Parameters for conversion between float and ADC time values - static constexpr const double MinTime = -50.0; // In nanoseconds - static constexpr const double MaxTime = 150.0; // In nanoseconds - static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); - static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; - }; - }; // namespace RichSmartID -} // namespace Allen - -namespace Rich::Future::DAQ { - enum DetectorType : std::int8_t { +namespace Rich::Detector { + enum Type : std::int8_t { InvalidDetector = -1, //< Unspecified Detector Rich1 = 0, //< RICH1 detector Rich2 = 1, //< RICH2 detector @@ -386,7 +82,9 @@ namespace Rich::Future::DAQ { firstSide = 0, //< Upper panel in RICH1 or Left panel in RICH2 secondSide = 1 //< Lower panel in RICH1 or Right panel in RICH2 }; - +} // namespace Rich::Detector +namespace Rich::Decoding { + // Helper class for RichDecoding class PackedFrameSizes final { public: // Packed type @@ -426,4 +124,5 @@ namespace Rich::Future::DAQ { // The data word IntType m_data {0}; }; -} // namespace Rich::Future::DAQ +} // namespace Rich::Decoding + diff --git a/device/rich/decoding/include/RichMakePixels.cuh b/device/rich/decoding/include/RichMakePixels.cuh index 2ca91462822..53fa3aeb4b9 100644 --- a/device/rich/decoding/include/RichMakePixels.cuh +++ b/device/rich/decoding/include/RichMakePixels.cuh @@ -11,9 +11,9 @@ #pragma once #include "AlgorithmTypes.cuh" -#include +#include #include -#include + namespace rich_make_pixels { struct Parameters { HOST_INPUT(host_rich_total_number_of_hits_t, unsigned) host_rich_total_number_of_hits; diff --git a/device/rich/decoding/include/RichPD.cuh b/device/rich/decoding/include/RichPD.cuh index 142f6ac08c0..4a0214340b9 100644 --- a/device/rich/decoding/include/RichPD.cuh +++ b/device/rich/decoding/include/RichPD.cuh @@ -12,6 +12,7 @@ #pragma once #include +#include #include namespace Rich::Detector::Allen { diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index 93c1f7f448f..df5896fd78b 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -13,13 +13,13 @@ #include #include -namespace Allen { +namespace Rich::Detector::Allen { class PDPanel final { public: PDPanel() {} - using PDsArray = std::array; - using ModuleArray = std::array; + using PDsArray = std::array; + using ModuleArray = std::array; PDPanel( Rich::Future::DAQ::DetectorType rich, @@ -52,7 +52,7 @@ namespace Allen { /// Access the PD panel side __host__ __device__ inline auto side() const noexcept { return m_side; } - __host__ __device__ auto dePD(const RichSmartID smartID) const + __host__ __device__ auto dePD(const ::Allen::RichSmartID smartID) const { const Rich::Detector::Allen::PD* dePD = nullptr; if (smartID.pdIsSet()) { @@ -69,10 +69,10 @@ namespace Allen { } /// Compute the detection point for a given RichSmartID - __host__ __device__ inline auto detectionPoint(const RichSmartID id) const noexcept + __host__ __device__ inline auto detectionPoint(const ::Allen::RichSmartID id) const noexcept { const auto pd = dePD(id); - return (pd ? pd->detectionPoint(id) : Allen::Point {0, 0, 0}); + return (pd ? pd->detectionPoint(id) : ::Allen::Point {0, 0, 0}); } /// Access the global to local transform diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index 214078c3bcb..ac338002cc2 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -10,6 +10,7 @@ \*****************************************************************************/ #pragma once #include +#include namespace Allen { class RichPixel { @@ -25,7 +26,7 @@ namespace Allen { __host__ __device__ RichPixel( const Point& gPos, const Point& lPos, - const Allen::RichSmartID& smartID, + const RichSmartID& smartID, double effArea, Rich::Future::DAQ::DetectorType rich, Rich::Future::DAQ::Side side, @@ -40,7 +41,7 @@ namespace Allen { __host__ __device__ RichPixel( const Point& gPos, const Point& lPos, - const Allen::RichSmartID& smartID, + const ::Allen::RichSmartID& smartID, double effArea, Rich::Future::DAQ::DetectorType rich, Rich::Future::DAQ::Side side, @@ -62,7 +63,7 @@ namespace Allen { __host__ __device__ inline auto side() const { return m_side; } - __host__ __device__ inline Allen::RichSmartID smartID() const { return m_smartID; } + __host__ __device__ inline RichSmartID smartID() const { return m_smartID; } __host__ __device__ inline auto gloPos() const { return gPos; } @@ -91,7 +92,7 @@ namespace Allen { private: Point gPos{0.0f, 0.0f, 0.0f}; Point lPos{0.0f, 0.0f, 0.0f}; - Allen::RichSmartID m_smartID {Allen::RichSmartID()}; + RichSmartID m_smartID { RichSmartID() }; double m_effArea{0.0f}; Rich::Future::DAQ::DetectorType m_rich{Rich::Future::DAQ::DetectorType::InvalidDetector}; Rich::Future::DAQ::Side m_side{Rich::Future::DAQ::InvalidSide}; diff --git a/device/rich/decoding/include/RichSmartID.cuh b/device/rich/decoding/include/RichSmartID.cuh new file mode 100644 index 00000000000..5d9ce1b7b15 --- /dev/null +++ b/device/rich/decoding/include/RichSmartID.cuh @@ -0,0 +1,324 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once + +#include +#include +#include +#include "BackendCommon.h" +#include + +namespace Allen { + + /// RICH SmartIDs class + class RichSmartID { + KeyType m_key; + + public: + // Set the RICH PD pixel row identifier + __host__ __device__ constexpr void setPixelRow(const DataType row) + { + setData(row, ShiftPixelRow, MaskPixelRow, MaskPixelRowIsSet); + } + + // Set the RICH PD pixel column identifier + __host__ __device__ constexpr void setPixelCol(const DataType col) + { + setData(col, ShiftPixelCol, MaskPixelCol, MaskPixelColIsSet); + } + + __host__ __device__ RichSmartID() = default; + + __host__ __device__ RichSmartID(KeyType key) : m_key(key) {} + + // Number of bits for each data field in the word + static constexpr const BitPackType BitsPixelCol = 3; //< Number of bits for MaPMT pixel column + static constexpr const BitPackType BitsPixelRow = 3; //< Number of bits for MaPMT pixel row + static constexpr const BitPackType BitsPDNumInMod = 4; //< Number of bits for MaPMT 'number in module' + static constexpr const BitPackType BitsPDMod = 9; //< Number of bits for MaPMT module + static constexpr const BitPackType BitsPanel = 1; //< Number of bits for MaPMT panel + static constexpr const BitPackType BitsRich = 1; //< Number of bits for RICH detector + static constexpr const BitPackType BitsPixelSubRowIsSet = 1; + static constexpr const BitPackType BitsPixelColIsSet = 1; + static constexpr const BitPackType BitsPixelRowIsSet = 1; + static constexpr const BitPackType BitsPDIsSet = 1; + static constexpr const BitPackType BitsPanelIsSet = 1; + static constexpr const BitPackType BitsRichIsSet = 1; + static constexpr const BitPackType BitsLargePixel = 1; + + // The shifts + static constexpr const BitPackType ShiftPixelCol = 0; + static constexpr const BitPackType ShiftPixelRow = ShiftPixelCol + BitsPixelCol; + static constexpr const BitPackType ShiftPDNumInMod = ShiftPixelRow + BitsPixelRow; + static constexpr const BitPackType ShiftPDMod = ShiftPDNumInMod + BitsPDNumInMod; + static constexpr const BitPackType ShiftPanel = ShiftPDMod + BitsPDMod; + static constexpr const BitPackType ShiftRich = ShiftPanel + BitsPanel; + static constexpr const BitPackType ShiftPixelSubRowIsSet = ShiftRich + BitsRich; + static constexpr const BitPackType ShiftPixelColIsSet = ShiftPixelSubRowIsSet + BitsPixelSubRowIsSet; + static constexpr const BitPackType ShiftPixelRowIsSet = ShiftPixelColIsSet + BitsPixelColIsSet; + static constexpr const BitPackType ShiftPDIsSet = ShiftPixelRowIsSet + BitsPixelRowIsSet; + static constexpr const BitPackType ShiftPanelIsSet = ShiftPDIsSet + BitsPDIsSet; + static constexpr const BitPackType ShiftRichIsSet = ShiftPanelIsSet + BitsPanelIsSet; + static constexpr const BitPackType ShiftLargePixel = ShiftRichIsSet + BitsRichIsSet; + + // The masks + static constexpr const BitPackType MaskPixelCol = (BitPackType)((BitPackType {1} << BitsPixelCol) - BitPackType {1}) + << ShiftPixelCol; + static constexpr const BitPackType MaskPixelRow = (BitPackType)((BitPackType {1} << BitsPixelRow) - BitPackType {1}) + << ShiftPixelRow; + static constexpr const BitPackType MaskPDNumInMod = + (BitPackType)((BitPackType {1} << BitsPDNumInMod) - BitPackType {1}) << ShiftPDNumInMod; + static constexpr const BitPackType MaskPDMod = (BitPackType)((BitPackType {1} << BitsPDMod) - BitPackType {1}) + << ShiftPDMod; + static constexpr const BitPackType MaskPanel = (BitPackType)((BitPackType {1} << BitsPanel) - BitPackType {1}) + << ShiftPanel; + static constexpr const BitPackType MaskRich = (BitPackType)((BitPackType {1} << BitsRich) - BitPackType {1}) + << ShiftRich; + static constexpr const BitPackType MaskPixelSubRowIsSet = + (BitPackType)((BitPackType {1} << BitsPixelSubRowIsSet) - BitPackType {1}) << ShiftPixelSubRowIsSet; + static constexpr const BitPackType MaskPixelColIsSet = + (BitPackType)((BitPackType {1} << BitsPixelColIsSet) - BitPackType {1}) << ShiftPixelColIsSet; + static constexpr const BitPackType MaskPixelRowIsSet = + (BitPackType)((BitPackType {1} << BitsPixelRowIsSet) - BitPackType {1}) << ShiftPixelRowIsSet; + static constexpr const BitPackType MaskPDIsSet = (BitPackType)((BitPackType {1} << BitsPDIsSet) - BitPackType {1}) + << ShiftPDIsSet; + static constexpr const BitPackType MaskPanelIsSet = + (BitPackType)((BitPackType {1} << BitsPanelIsSet) - BitPackType {1}) << ShiftPanelIsSet; + static constexpr const BitPackType MaskRichIsSet = + (BitPackType)((BitPackType {1} << BitsRichIsSet) - BitPackType {1}) << ShiftRichIsSet; + static constexpr const BitPackType MaskLargePixel = + (BitPackType)((BitPackType {1} << BitsLargePixel) - BitPackType {1}) << ShiftLargePixel; + + // Max values + static constexpr const DataType MaxPixelCol = (DataType)(BitPackType {1} << BitsPixelCol) - DataType {1}; + static constexpr const DataType MaxPixelRow = (DataType)(BitPackType {1} << BitsPixelRow) - DataType {1}; + static constexpr const DataType MaxPDNumInMod = (DataType)(BitPackType {1} << BitsPDNumInMod) - DataType {1}; + static constexpr const DataType MaxPDMod = (DataType)(BitPackType {1} << BitsPDMod) - DataType {1}; + static constexpr const DataType MaxPanel = (DataType)(BitPackType {1} << BitsPanel) - DataType {1}; + static constexpr const DataType MaxRich = (DataType)(BitPackType {1} << BitsRich) - DataType {1}; + + // Number of bits for the channel identification (i.e. excluding any time info) + // Currently use the lowest 32 bits for this. + static constexpr const BitPackType NChannelBits = 32; + + __host__ __device__ constexpr inline void + setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept + { + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); + } + + __host__ __device__ constexpr inline void + setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept + { + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; + } + + __host__ __device__ constexpr inline BitPackType getData(const BitPackType shift, const BitPackType mask) const + noexcept + { + return (m_key & mask) >> shift; + } + + __host__ __device__ constexpr inline BitPackType key() const noexcept { return m_key; } + + __host__ __device__ constexpr inline bool operator==(const RichSmartID& other) const noexcept + { + return m_key == other.key(); + } + + __host__ __device__ constexpr inline auto isLargePMT() const noexcept + { + return 0 != getData(ShiftLargePixel, MaskLargePixel); + } + + __host__ __device__ constexpr inline auto rich() const noexcept { return getData(ShiftRich, MaskRich); } + + __host__ __device__ constexpr inline auto panel() const noexcept { return getData(ShiftPanel, MaskPanel); } + + __host__ __device__ constexpr inline DataType pdMod() const noexcept { return getData(ShiftPDMod, MaskPDMod); } + + __host__ __device__ constexpr inline DataType pdNumInMod() const noexcept + { + return getData(ShiftPDNumInMod, MaskPDNumInMod); + } + + __host__ __device__ constexpr inline DataType panelLocalModuleNum() const noexcept + { + return pdMod() - PanelModuleOffsets()[rich()][panel()]; + } + + __host__ __device__ constexpr inline DataType columnLocalModuleNum() const noexcept + { + return panelLocalModuleNum() % ModulesPerColumn; + } + + __host__ __device__ constexpr inline DataType numPMTsPerEC() const noexcept + { + return isLargePMT() ? HTypePMTsPerEC : RTypePMTsPerEC; + } + + __host__ __device__ constexpr inline DataType elementaryCell() const noexcept + { + return pdNumInMod() / numPMTsPerEC(); + } + + __host__ __device__ constexpr inline DataType pdNumInEC() const noexcept { return pdNumInMod() % numPMTsPerEC(); } + + __host__ __device__ constexpr inline auto pixelColIsSet() const noexcept + { + return 0 != getData(ShiftPixelColIsSet, MaskPixelColIsSet); + } + + __host__ __device__ constexpr inline auto pixelRowIsSet() const noexcept + { + return 0 != getData(ShiftPixelRowIsSet, MaskPixelRowIsSet); + } + + [[nodiscard]] __host__ __device__ constexpr bool pdIsSet() const noexcept + { + return 0 != ((key() & MaskPDIsSet) >> ShiftPDIsSet); + } + + __host__ __device__ constexpr inline DataType pixelCol() const noexcept + { + return getData(ShiftPixelCol, MaskPixelCol); + } + + __host__ __device__ constexpr inline DataType pixelRow() const noexcept + { + return getData(ShiftPixelRow, MaskPixelRow); + } + + __host__ __device__ constexpr inline DataType anodeIndex() const noexcept + { + return pixelRow() * PixelsPerCol + PixelsPerRow - 1 - pixelCol(); + } + + __host__ __device__ constexpr inline bool adcTimeIsSet() const noexcept + { + return (0 != (key() & MaPMT::MaskADCTimeIsSet) >> MaPMT::ShiftADCTimeIsSet); + } + + __host__ __device__ constexpr ADCTimeType adcTime() const + { + return ((key() & MaPMT::MaskADCTime) >> MaPMT::ShiftADCTime); + } + + __host__ __device__ constexpr auto time() const noexcept + { + return (MaPMT::MinTime + (adcTime() * MaPMT::ScaleADCToTime)); + } + + // ostream operator + __host__ friend std::ostream& operator<<(std::ostream& str, const RichSmartID& id) + { + const auto rich = id.rich(); + const auto panel = id.panel(); + str << "{ "; + str << "PMT"; + str << (id.isLargePMT() ? ":h " : ":r "); + str << (rich == 0 ? "Rich1 " : "Rich2 "); + if (rich == 0) { + str << (panel == 0 ? "Top " : "Bot "); + } + else { + str << (panel == 0 ? "L-A " : "R-C "); + } + str << "PD[Mod,NInMod]: "; + str << std::setfill('0') << std::setw(3) << id.pdMod() << ','; + str << std::setfill('0') << std::setw(2) << id.pdNumInMod() << ' '; + str << "Mod[Col,NInCol] "; + str << std::setfill('0') << std::setw(2) << id.panelLocalModuleNum() << ','; + str << std::setfill('0') << std::setw(2) << id.columnLocalModuleNum() << ' '; + str << " PD[EC,NInEC]: "; + str << id.elementaryCell() << ','; + str << id.pdNumInEC() << ' '; + + const auto pixColSet = id.pixelColIsSet(); + const auto pixRowSet = id.pixelRowIsSet(); + if (pixColSet || pixRowSet) { + if (pixColSet && pixRowSet) { + str << "Pix[Col,Row]: " << std::setfill('0') << std::setw(1) << id.pixelCol() << "," << id.pixelRow(); + } + else { + const auto fSPix = 2; + if (pixColSet) { + str << std::setfill('0') << std::setw(fSPix) << " pixCol" << id.pixelCol(); + } + if (pixRowSet) { + str << std::setfill('0') << std::setw(fSPix) << " pixRow" << id.pixelRow(); + } + } + // Include PMT derived info + if (pixColSet && pixRowSet) { + str << " Anode:" << std::setfill('0') << std::setw(2) << id.anodeIndex(); + } + } + str << " }\n"; + return str; + } + + public: + // Number of PMT pixels per row + static constexpr const DataType PixelsPerRow = 8; + // Number of PMT pixels per column + static constexpr const DataType PixelsPerCol = 8; + // Total number of PMT pixels + static constexpr const DataType TotalPixels = PixelsPerRow * PixelsPerCol; + // Number PMTs per EC for R type PMTs + static constexpr const DataType RTypePMTsPerEC = 4; + // Number PMTs per EC for H type PMTs + static constexpr const DataType HTypePMTsPerEC = 1; + // Number of ECs per module + static constexpr const DataType ECsPerModule = 4; + // Number of modules per column + static constexpr const DataType ModulesPerColumn = 6; + // Number of module columns per panel, in each RICH + static constexpr const std::array ModuleColumnsPerPanel = {{11, 14}}; + // Maximum number of module columns in any panel, RICH1 or RICH2 + static constexpr const DataType MaxModuleColumnsAnyPanel = + std::max(ModuleColumnsPerPanel[0], ModuleColumnsPerPanel[1]); + // Number of modules per panel, in each RICH + static constexpr const std::array ModulesPerPanel { + {(ModulesPerColumn * ModuleColumnsPerPanel[0]), (ModulesPerColumn * ModuleColumnsPerPanel[1])}}; + + __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() + { + return {std::array {0, ModulesPerPanel[0]}, + std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; + } + + class MaPMT { + public: + static constexpr const DataType MaxPDsPerModule = 16; + static constexpr const DataType MaxModulesPerPanel = 92; + + // Bits for time field. + static constexpr const BitPackType BitsADCTime = 16; + static constexpr const BitPackType BitsADCTimeIsSet = 1; + static constexpr const BitPackType ShiftADCTime = NChannelBits; + static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; + static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) + << ShiftADCTime; + static constexpr const BitPackType MaskADCTimeIsSet = + (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; + + // Max ADC time that can be stored + static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType {1} << BitsADCTime) - 1); + + // Parameters for conversion between float and ADC time values + static constexpr const double MinTime = -50.0; // In nanoseconds + static constexpr const double MaxTime = 150.0; // In nanoseconds + static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); + static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; + }; + }; // namespace RichSmartID +} // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh new file mode 100644 index 00000000000..695f3389174 --- /dev/null +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -0,0 +1,85 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include +#include +#include +#include + +#define PANEL_COUNT 2 + +namespace Allen { + class RichSmartIDHelper { + public: + /// Constructor from RICH detector elements + RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : m_pdPanels {&pdPanel1, &pdPanel2} {} + + RichSmartIDHelper(const std::array m_pdPanels) : m_pdPanels {m_pdPanels} {} + + __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Rich::Detector::Allen::PDPanel* + { + using DetectorType = Rich::Future::DAQ::DetectorType; + using Side = Rich::Future::DAQ::Side; + + // Determine the rich type + DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; + // Determine the side + Side side; + if (rich == DetectorType::Rich1) { + // For Rich1, 0 = top, 1 = bottom + side = (smartID.panel() == 0) ? Side::top : Side::bottom; + } + else { + // For Rich2, 0 = left, 1 = right + side = (smartID.panel() == 0) ? Side::left : Side::right; + } + + for (size_t i = 0; i < m_pdPanels.size(); i++) { + const Rich::Detector::Allen::PDPanel* pdPanel = m_pdPanels[i]; + if (pdPanel->rich() == rich && pdPanel->side() == side) { + return pdPanel; + } + } + return nullptr; + } + + __host__ __device__ inline auto panel( + const Rich::Future::DAQ::DetectorType rtype, + const Rich::Future::DAQ::Side side) const -> const Rich::Detector::Allen::PDPanel* + { + for (size_t i = 0; i < m_pdPanels.size(); i++) { + const Rich::Detector::Allen::PDPanel* pdPanel = m_pdPanels[i]; + if (pdPanel->rich() == rtype && pdPanel->side() == side) { + return pdPanel; + } + } + return nullptr; + } + + // Converts an PD RichSmartID identification into a position in global LHCb coordinates. + __host__ __device__ Point pdPosition(const Allen::RichSmartID pdid) const; + + // Converts a position in global coordinates to the corresponding RichSmartID + __host__ __device__ bool smartID(const Point& globalPoint, Allen::RichSmartID& smartid) const; + + // Converts a position in global coordinates to the local coordinate system. + __host__ __device__ Point globalToPDPanel(const Point& globalPoint) const; + + // Get the position for a given SmartID. + __host__ __device__ inline auto _globalPosition(const Allen::RichSmartID id) const + { + return panel(id)->detectionPoint(id); + } + + private: + const std::array m_pdPanels; + }; +} // namespace Allen diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index 114d6f8d1e8..dbea3606079 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -13,13 +13,13 @@ #include #include #include -#include +#include #include INSTANTIATE_ALGORITHM(rich_make_pixels::rich_make_pixels_t); /// Create a Pixel object from a given SmartID -__device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, const Allen::RichSmartID& smartID) +__device__ Allen::RichPixel make_pixel(Allen::RichSmartIDHelper* smartIDsHelper, const Allen::RichSmartID& smartID) { float effArea; // Effective area uint8_t mask = 0; // Selection mask @@ -74,7 +74,7 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDs* smartIDsHelper, cons } /// Kernel function to iterate over Events, SmartIDs, and create Pixels -__global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Allen::RichSmartIDs* smartIDsHelper) +__global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Allen::RichSmartIDHelper* smartIDsHelper) { const auto eventNumber = parameters.dev_event_list[blockIdx.x]; auto eventSmartIDCount = @@ -100,24 +100,26 @@ void rich_make_pixels::rich_make_pixels_t::operator()( const Allen::Context& context) const { // Create RICH object from dump - Allen::Rich* rich = nullptr; + Rich::Detector::Allen::Rich* rich = nullptr; const auto richValue = m_current_rich; if (richValue == 1) - rich = reinterpret_cast(constants.dev_rich_1_geometry); + rich = reinterpret_cast(constants.dev_rich_1_geometry); else - rich = reinterpret_cast(constants.dev_rich_2_geometry); + rich = reinterpret_cast(constants.dev_rich_2_geometry); // Send panels from RICH to SmartIDsHelper - std::array panels; + std::array panels; for (size_t i = 0; i < 2; i++) { panels[i] = &(rich->pdPanels()[i]); } - Allen::RichSmartIDs smartIDsHelper = Allen::RichSmartIDs(panels); - Allen::RichSmartIDs* dev_smartIDsHelper = nullptr; - Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDs)); - Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDs), Allen::memcpyHostToDevice); + // Instantiate smartIDsHelper in host and copy to device + Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); + Allen::RichSmartIDHelper* dev_smartIDsHelper = nullptr; + Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDHelper)); + Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDHelper), Allen::memcpyHostToDevice); + // call global kernel global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( arguments, dev_smartIDsHelper); Allen::free(dev_smartIDsHelper); diff --git a/device/rich/decoding/src/RichSmartIDs.cu b/device/rich/decoding/src/RichSmartIDHelper.cu similarity index 89% rename from device/rich/decoding/src/RichSmartIDs.cu rename to device/rich/decoding/src/RichSmartIDHelper.cu index 7abbcb165a4..da0e2976173 100644 --- a/device/rich/decoding/src/RichSmartIDs.cu +++ b/device/rich/decoding/src/RichSmartIDHelper.cu @@ -9,14 +9,14 @@ * or submit itself to any jurisdiction. * \*****************************************************************************/ -#include +#include #include using Point = Allen::Point; -Point Allen::RichSmartIDs::pdPosition(const Allen::RichSmartID pdid) const +Point Allen::RichSmartIDHelper::pdPosition(const Allen::RichSmartID pdid) const { - // Create temporary RichSmartIDs for two corners of the PD wafer + // Create temporary RichSmartIDHelper for two corners of the PD wafer Allen::RichSmartID id1(pdid), id0(pdid); id0.setPixelRow(1); id0.setPixelCol(1); @@ -32,7 +32,7 @@ Point Allen::RichSmartIDs::pdPosition(const Allen::RichSmartID pdid) const } // Converts a point from the global frame to the detector panel frame -Point Allen::RichSmartIDs::globalToPDPanel(const Point& globalPoint) const +Point Allen::RichSmartIDHelper::globalToPDPanel(const Point& globalPoint) const { return ( globalPoint.z < 8000.f ? -- GitLab From 465a9e99606c1c994bee294b591e5974217ee41d Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Sun, 20 Apr 2025 01:40:18 +0200 Subject: [PATCH 20/92] fixed Allen standalone bug, by using different m_smartID initialization in RichPixel class --- device/rich/decoding/include/RichDecoding.cuh | 2 +- .../rich/decoding/include/RichMakePixels.cuh | 2 +- device/rich/decoding/include/RichPD.cuh | 2 +- device/rich/decoding/include/RichPixels.cuh | 6 +- device/rich/decoding/include/RichSmartID.cuh | 324 ----------------- .../decoding/include/RichSmartIDHelper.cuh | 4 +- device/rich/decoding/include/RichSmartIDs.cuh | 342 +++++++++++++++--- device/rich/decoding/src/RichMakePixels.cu | 1 + 8 files changed, 299 insertions(+), 384 deletions(-) delete mode 100644 device/rich/decoding/include/RichSmartID.cuh diff --git a/device/rich/decoding/include/RichDecoding.cuh b/device/rich/decoding/include/RichDecoding.cuh index 80e1e01df8d..9a677fe31fb 100644 --- a/device/rich/decoding/include/RichDecoding.cuh +++ b/device/rich/decoding/include/RichDecoding.cuh @@ -11,7 +11,7 @@ #pragma once #include "AlgorithmTypes.cuh" -#include +#include namespace rich_decoding { struct Parameters { diff --git a/device/rich/decoding/include/RichMakePixels.cuh b/device/rich/decoding/include/RichMakePixels.cuh index 53fa3aeb4b9..d67f0b517f9 100644 --- a/device/rich/decoding/include/RichMakePixels.cuh +++ b/device/rich/decoding/include/RichMakePixels.cuh @@ -11,7 +11,7 @@ #pragma once #include "AlgorithmTypes.cuh" -#include +#include #include namespace rich_make_pixels { diff --git a/device/rich/decoding/include/RichPD.cuh b/device/rich/decoding/include/RichPD.cuh index 4a0214340b9..8d49bde2ee4 100644 --- a/device/rich/decoding/include/RichPD.cuh +++ b/device/rich/decoding/include/RichPD.cuh @@ -12,7 +12,7 @@ #pragma once #include -#include +#include #include namespace Rich::Detector::Allen { diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index ac338002cc2..4a7241ffc77 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -10,7 +10,7 @@ \*****************************************************************************/ #pragma once #include -#include +#include namespace Allen { class RichPixel { @@ -18,7 +18,7 @@ namespace Allen { public: // Default __host__ __device__ RichPixel() : - gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID(), m_effArea(0.0f), m_rich(Rich::Future::DAQ::DetectorType::InvalidDetector), m_side(Rich::Future::DAQ::InvalidSide), m_mask(0), + gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID({}), m_effArea(0.0f), m_rich(Rich::Future::DAQ::DetectorType::InvalidDetector), m_side(Rich::Future::DAQ::InvalidSide), m_mask(0), m_timeWindow(0.0f), m_isInnerRegion(true), m_isNull(true) {} @@ -92,7 +92,7 @@ namespace Allen { private: Point gPos{0.0f, 0.0f, 0.0f}; Point lPos{0.0f, 0.0f, 0.0f}; - RichSmartID m_smartID { RichSmartID() }; + RichSmartID m_smartID = RichSmartID{}; double m_effArea{0.0f}; Rich::Future::DAQ::DetectorType m_rich{Rich::Future::DAQ::DetectorType::InvalidDetector}; Rich::Future::DAQ::Side m_side{Rich::Future::DAQ::InvalidSide}; diff --git a/device/rich/decoding/include/RichSmartID.cuh b/device/rich/decoding/include/RichSmartID.cuh deleted file mode 100644 index 5d9ce1b7b15..00000000000 --- a/device/rich/decoding/include/RichSmartID.cuh +++ /dev/null @@ -1,324 +0,0 @@ -/*****************************************************************************\ - * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * - * * - * This software is distributed under the terms of the Apache License * - * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * - * * - * In applying this licence, CERN does not waive the privileges and immunities * - * granted to it by virtue of its status as an Intergovernmental Organization * - * or submit itself to any jurisdiction. * - \*****************************************************************************/ -#pragma once - -#include -#include -#include -#include "BackendCommon.h" -#include - -namespace Allen { - - /// RICH SmartIDs class - class RichSmartID { - KeyType m_key; - - public: - // Set the RICH PD pixel row identifier - __host__ __device__ constexpr void setPixelRow(const DataType row) - { - setData(row, ShiftPixelRow, MaskPixelRow, MaskPixelRowIsSet); - } - - // Set the RICH PD pixel column identifier - __host__ __device__ constexpr void setPixelCol(const DataType col) - { - setData(col, ShiftPixelCol, MaskPixelCol, MaskPixelColIsSet); - } - - __host__ __device__ RichSmartID() = default; - - __host__ __device__ RichSmartID(KeyType key) : m_key(key) {} - - // Number of bits for each data field in the word - static constexpr const BitPackType BitsPixelCol = 3; //< Number of bits for MaPMT pixel column - static constexpr const BitPackType BitsPixelRow = 3; //< Number of bits for MaPMT pixel row - static constexpr const BitPackType BitsPDNumInMod = 4; //< Number of bits for MaPMT 'number in module' - static constexpr const BitPackType BitsPDMod = 9; //< Number of bits for MaPMT module - static constexpr const BitPackType BitsPanel = 1; //< Number of bits for MaPMT panel - static constexpr const BitPackType BitsRich = 1; //< Number of bits for RICH detector - static constexpr const BitPackType BitsPixelSubRowIsSet = 1; - static constexpr const BitPackType BitsPixelColIsSet = 1; - static constexpr const BitPackType BitsPixelRowIsSet = 1; - static constexpr const BitPackType BitsPDIsSet = 1; - static constexpr const BitPackType BitsPanelIsSet = 1; - static constexpr const BitPackType BitsRichIsSet = 1; - static constexpr const BitPackType BitsLargePixel = 1; - - // The shifts - static constexpr const BitPackType ShiftPixelCol = 0; - static constexpr const BitPackType ShiftPixelRow = ShiftPixelCol + BitsPixelCol; - static constexpr const BitPackType ShiftPDNumInMod = ShiftPixelRow + BitsPixelRow; - static constexpr const BitPackType ShiftPDMod = ShiftPDNumInMod + BitsPDNumInMod; - static constexpr const BitPackType ShiftPanel = ShiftPDMod + BitsPDMod; - static constexpr const BitPackType ShiftRich = ShiftPanel + BitsPanel; - static constexpr const BitPackType ShiftPixelSubRowIsSet = ShiftRich + BitsRich; - static constexpr const BitPackType ShiftPixelColIsSet = ShiftPixelSubRowIsSet + BitsPixelSubRowIsSet; - static constexpr const BitPackType ShiftPixelRowIsSet = ShiftPixelColIsSet + BitsPixelColIsSet; - static constexpr const BitPackType ShiftPDIsSet = ShiftPixelRowIsSet + BitsPixelRowIsSet; - static constexpr const BitPackType ShiftPanelIsSet = ShiftPDIsSet + BitsPDIsSet; - static constexpr const BitPackType ShiftRichIsSet = ShiftPanelIsSet + BitsPanelIsSet; - static constexpr const BitPackType ShiftLargePixel = ShiftRichIsSet + BitsRichIsSet; - - // The masks - static constexpr const BitPackType MaskPixelCol = (BitPackType)((BitPackType {1} << BitsPixelCol) - BitPackType {1}) - << ShiftPixelCol; - static constexpr const BitPackType MaskPixelRow = (BitPackType)((BitPackType {1} << BitsPixelRow) - BitPackType {1}) - << ShiftPixelRow; - static constexpr const BitPackType MaskPDNumInMod = - (BitPackType)((BitPackType {1} << BitsPDNumInMod) - BitPackType {1}) << ShiftPDNumInMod; - static constexpr const BitPackType MaskPDMod = (BitPackType)((BitPackType {1} << BitsPDMod) - BitPackType {1}) - << ShiftPDMod; - static constexpr const BitPackType MaskPanel = (BitPackType)((BitPackType {1} << BitsPanel) - BitPackType {1}) - << ShiftPanel; - static constexpr const BitPackType MaskRich = (BitPackType)((BitPackType {1} << BitsRich) - BitPackType {1}) - << ShiftRich; - static constexpr const BitPackType MaskPixelSubRowIsSet = - (BitPackType)((BitPackType {1} << BitsPixelSubRowIsSet) - BitPackType {1}) << ShiftPixelSubRowIsSet; - static constexpr const BitPackType MaskPixelColIsSet = - (BitPackType)((BitPackType {1} << BitsPixelColIsSet) - BitPackType {1}) << ShiftPixelColIsSet; - static constexpr const BitPackType MaskPixelRowIsSet = - (BitPackType)((BitPackType {1} << BitsPixelRowIsSet) - BitPackType {1}) << ShiftPixelRowIsSet; - static constexpr const BitPackType MaskPDIsSet = (BitPackType)((BitPackType {1} << BitsPDIsSet) - BitPackType {1}) - << ShiftPDIsSet; - static constexpr const BitPackType MaskPanelIsSet = - (BitPackType)((BitPackType {1} << BitsPanelIsSet) - BitPackType {1}) << ShiftPanelIsSet; - static constexpr const BitPackType MaskRichIsSet = - (BitPackType)((BitPackType {1} << BitsRichIsSet) - BitPackType {1}) << ShiftRichIsSet; - static constexpr const BitPackType MaskLargePixel = - (BitPackType)((BitPackType {1} << BitsLargePixel) - BitPackType {1}) << ShiftLargePixel; - - // Max values - static constexpr const DataType MaxPixelCol = (DataType)(BitPackType {1} << BitsPixelCol) - DataType {1}; - static constexpr const DataType MaxPixelRow = (DataType)(BitPackType {1} << BitsPixelRow) - DataType {1}; - static constexpr const DataType MaxPDNumInMod = (DataType)(BitPackType {1} << BitsPDNumInMod) - DataType {1}; - static constexpr const DataType MaxPDMod = (DataType)(BitPackType {1} << BitsPDMod) - DataType {1}; - static constexpr const DataType MaxPanel = (DataType)(BitPackType {1} << BitsPanel) - DataType {1}; - static constexpr const DataType MaxRich = (DataType)(BitPackType {1} << BitsRich) - DataType {1}; - - // Number of bits for the channel identification (i.e. excluding any time info) - // Currently use the lowest 32 bits for this. - static constexpr const BitPackType NChannelBits = 32; - - __host__ __device__ constexpr inline void - setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept - { - m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); - } - - __host__ __device__ constexpr inline void - setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept - { - m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; - } - - __host__ __device__ constexpr inline BitPackType getData(const BitPackType shift, const BitPackType mask) const - noexcept - { - return (m_key & mask) >> shift; - } - - __host__ __device__ constexpr inline BitPackType key() const noexcept { return m_key; } - - __host__ __device__ constexpr inline bool operator==(const RichSmartID& other) const noexcept - { - return m_key == other.key(); - } - - __host__ __device__ constexpr inline auto isLargePMT() const noexcept - { - return 0 != getData(ShiftLargePixel, MaskLargePixel); - } - - __host__ __device__ constexpr inline auto rich() const noexcept { return getData(ShiftRich, MaskRich); } - - __host__ __device__ constexpr inline auto panel() const noexcept { return getData(ShiftPanel, MaskPanel); } - - __host__ __device__ constexpr inline DataType pdMod() const noexcept { return getData(ShiftPDMod, MaskPDMod); } - - __host__ __device__ constexpr inline DataType pdNumInMod() const noexcept - { - return getData(ShiftPDNumInMod, MaskPDNumInMod); - } - - __host__ __device__ constexpr inline DataType panelLocalModuleNum() const noexcept - { - return pdMod() - PanelModuleOffsets()[rich()][panel()]; - } - - __host__ __device__ constexpr inline DataType columnLocalModuleNum() const noexcept - { - return panelLocalModuleNum() % ModulesPerColumn; - } - - __host__ __device__ constexpr inline DataType numPMTsPerEC() const noexcept - { - return isLargePMT() ? HTypePMTsPerEC : RTypePMTsPerEC; - } - - __host__ __device__ constexpr inline DataType elementaryCell() const noexcept - { - return pdNumInMod() / numPMTsPerEC(); - } - - __host__ __device__ constexpr inline DataType pdNumInEC() const noexcept { return pdNumInMod() % numPMTsPerEC(); } - - __host__ __device__ constexpr inline auto pixelColIsSet() const noexcept - { - return 0 != getData(ShiftPixelColIsSet, MaskPixelColIsSet); - } - - __host__ __device__ constexpr inline auto pixelRowIsSet() const noexcept - { - return 0 != getData(ShiftPixelRowIsSet, MaskPixelRowIsSet); - } - - [[nodiscard]] __host__ __device__ constexpr bool pdIsSet() const noexcept - { - return 0 != ((key() & MaskPDIsSet) >> ShiftPDIsSet); - } - - __host__ __device__ constexpr inline DataType pixelCol() const noexcept - { - return getData(ShiftPixelCol, MaskPixelCol); - } - - __host__ __device__ constexpr inline DataType pixelRow() const noexcept - { - return getData(ShiftPixelRow, MaskPixelRow); - } - - __host__ __device__ constexpr inline DataType anodeIndex() const noexcept - { - return pixelRow() * PixelsPerCol + PixelsPerRow - 1 - pixelCol(); - } - - __host__ __device__ constexpr inline bool adcTimeIsSet() const noexcept - { - return (0 != (key() & MaPMT::MaskADCTimeIsSet) >> MaPMT::ShiftADCTimeIsSet); - } - - __host__ __device__ constexpr ADCTimeType adcTime() const - { - return ((key() & MaPMT::MaskADCTime) >> MaPMT::ShiftADCTime); - } - - __host__ __device__ constexpr auto time() const noexcept - { - return (MaPMT::MinTime + (adcTime() * MaPMT::ScaleADCToTime)); - } - - // ostream operator - __host__ friend std::ostream& operator<<(std::ostream& str, const RichSmartID& id) - { - const auto rich = id.rich(); - const auto panel = id.panel(); - str << "{ "; - str << "PMT"; - str << (id.isLargePMT() ? ":h " : ":r "); - str << (rich == 0 ? "Rich1 " : "Rich2 "); - if (rich == 0) { - str << (panel == 0 ? "Top " : "Bot "); - } - else { - str << (panel == 0 ? "L-A " : "R-C "); - } - str << "PD[Mod,NInMod]: "; - str << std::setfill('0') << std::setw(3) << id.pdMod() << ','; - str << std::setfill('0') << std::setw(2) << id.pdNumInMod() << ' '; - str << "Mod[Col,NInCol] "; - str << std::setfill('0') << std::setw(2) << id.panelLocalModuleNum() << ','; - str << std::setfill('0') << std::setw(2) << id.columnLocalModuleNum() << ' '; - str << " PD[EC,NInEC]: "; - str << id.elementaryCell() << ','; - str << id.pdNumInEC() << ' '; - - const auto pixColSet = id.pixelColIsSet(); - const auto pixRowSet = id.pixelRowIsSet(); - if (pixColSet || pixRowSet) { - if (pixColSet && pixRowSet) { - str << "Pix[Col,Row]: " << std::setfill('0') << std::setw(1) << id.pixelCol() << "," << id.pixelRow(); - } - else { - const auto fSPix = 2; - if (pixColSet) { - str << std::setfill('0') << std::setw(fSPix) << " pixCol" << id.pixelCol(); - } - if (pixRowSet) { - str << std::setfill('0') << std::setw(fSPix) << " pixRow" << id.pixelRow(); - } - } - // Include PMT derived info - if (pixColSet && pixRowSet) { - str << " Anode:" << std::setfill('0') << std::setw(2) << id.anodeIndex(); - } - } - str << " }\n"; - return str; - } - - public: - // Number of PMT pixels per row - static constexpr const DataType PixelsPerRow = 8; - // Number of PMT pixels per column - static constexpr const DataType PixelsPerCol = 8; - // Total number of PMT pixels - static constexpr const DataType TotalPixels = PixelsPerRow * PixelsPerCol; - // Number PMTs per EC for R type PMTs - static constexpr const DataType RTypePMTsPerEC = 4; - // Number PMTs per EC for H type PMTs - static constexpr const DataType HTypePMTsPerEC = 1; - // Number of ECs per module - static constexpr const DataType ECsPerModule = 4; - // Number of modules per column - static constexpr const DataType ModulesPerColumn = 6; - // Number of module columns per panel, in each RICH - static constexpr const std::array ModuleColumnsPerPanel = {{11, 14}}; - // Maximum number of module columns in any panel, RICH1 or RICH2 - static constexpr const DataType MaxModuleColumnsAnyPanel = - std::max(ModuleColumnsPerPanel[0], ModuleColumnsPerPanel[1]); - // Number of modules per panel, in each RICH - static constexpr const std::array ModulesPerPanel { - {(ModulesPerColumn * ModuleColumnsPerPanel[0]), (ModulesPerColumn * ModuleColumnsPerPanel[1])}}; - - __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() - { - return {std::array {0, ModulesPerPanel[0]}, - std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; - } - - class MaPMT { - public: - static constexpr const DataType MaxPDsPerModule = 16; - static constexpr const DataType MaxModulesPerPanel = 92; - - // Bits for time field. - static constexpr const BitPackType BitsADCTime = 16; - static constexpr const BitPackType BitsADCTimeIsSet = 1; - static constexpr const BitPackType ShiftADCTime = NChannelBits; - static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; - static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) - << ShiftADCTime; - static constexpr const BitPackType MaskADCTimeIsSet = - (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; - - // Max ADC time that can be stored - static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType {1} << BitsADCTime) - 1); - - // Parameters for conversion between float and ADC time values - static constexpr const double MinTime = -50.0; // In nanoseconds - static constexpr const double MaxTime = 150.0; // In nanoseconds - static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); - static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; - }; - }; // namespace RichSmartID -} // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 695f3389174..f39b46d2d5b 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -10,9 +10,9 @@ \*****************************************************************************/ #pragma once #include +#include #include #include -#include #define PANEL_COUNT 2 @@ -80,6 +80,6 @@ namespace Allen { } private: - const std::array m_pdPanels; + const std::array m_pdPanels{}; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDs.cuh b/device/rich/decoding/include/RichSmartIDs.cuh index 250c2c5b9af..b6a2b357f82 100644 --- a/device/rich/decoding/include/RichSmartIDs.cuh +++ b/device/rich/decoding/include/RichSmartIDs.cuh @@ -9,77 +9,315 @@ * or submit itself to any jurisdiction. * \*****************************************************************************/ #pragma once +#include +#include +#include +#include "BackendCommon.h" #include -#include -#include -#include - -#define PANEL_COUNT 2 namespace Allen { - class RichSmartIDs { + + /// RICH SmartIDs class + class RichSmartID { + KeyType m_key; + public: - /// Constructor from RICH detector elements - RichSmartIDs(const Allen::PDPanel& pdPanel1, const Allen::PDPanel& pdPanel2) : m_pdPanels {&pdPanel1, &pdPanel2} {} + // Set the RICH PD pixel row identifier + __host__ __device__ constexpr void setPixelRow(const DataType row) + { + setData(row, ShiftPixelRow, MaskPixelRow, MaskPixelRowIsSet); + } + + // Set the RICH PD pixel column identifier + __host__ __device__ constexpr void setPixelCol(const DataType col) + { + setData(col, ShiftPixelCol, MaskPixelCol, MaskPixelColIsSet); + } + + __host__ __device__ RichSmartID() = default; + + __host__ __device__ RichSmartID(KeyType key) : m_key(key) {} + + // Number of bits for each data field in the word + static constexpr const BitPackType BitsPixelCol = 3; //< Number of bits for MaPMT pixel column + static constexpr const BitPackType BitsPixelRow = 3; //< Number of bits for MaPMT pixel row + static constexpr const BitPackType BitsPDNumInMod = 4; //< Number of bits for MaPMT 'number in module' + static constexpr const BitPackType BitsPDMod = 9; //< Number of bits for MaPMT module + static constexpr const BitPackType BitsPanel = 1; //< Number of bits for MaPMT panel + static constexpr const BitPackType BitsRich = 1; //< Number of bits for RICH detector + static constexpr const BitPackType BitsPixelSubRowIsSet = 1; + static constexpr const BitPackType BitsPixelColIsSet = 1; + static constexpr const BitPackType BitsPixelRowIsSet = 1; + static constexpr const BitPackType BitsPDIsSet = 1; + static constexpr const BitPackType BitsPanelIsSet = 1; + static constexpr const BitPackType BitsRichIsSet = 1; + static constexpr const BitPackType BitsLargePixel = 1; + + // The shifts + static constexpr const BitPackType ShiftPixelCol = 0; + static constexpr const BitPackType ShiftPixelRow = ShiftPixelCol + BitsPixelCol; + static constexpr const BitPackType ShiftPDNumInMod = ShiftPixelRow + BitsPixelRow; + static constexpr const BitPackType ShiftPDMod = ShiftPDNumInMod + BitsPDNumInMod; + static constexpr const BitPackType ShiftPanel = ShiftPDMod + BitsPDMod; + static constexpr const BitPackType ShiftRich = ShiftPanel + BitsPanel; + static constexpr const BitPackType ShiftPixelSubRowIsSet = ShiftRich + BitsRich; + static constexpr const BitPackType ShiftPixelColIsSet = ShiftPixelSubRowIsSet + BitsPixelSubRowIsSet; + static constexpr const BitPackType ShiftPixelRowIsSet = ShiftPixelColIsSet + BitsPixelColIsSet; + static constexpr const BitPackType ShiftPDIsSet = ShiftPixelRowIsSet + BitsPixelRowIsSet; + static constexpr const BitPackType ShiftPanelIsSet = ShiftPDIsSet + BitsPDIsSet; + static constexpr const BitPackType ShiftRichIsSet = ShiftPanelIsSet + BitsPanelIsSet; + static constexpr const BitPackType ShiftLargePixel = ShiftRichIsSet + BitsRichIsSet; + + // The masks + static constexpr const BitPackType MaskPixelCol = (BitPackType)((BitPackType {1} << BitsPixelCol) - BitPackType {1}) + << ShiftPixelCol; + static constexpr const BitPackType MaskPixelRow = (BitPackType)((BitPackType {1} << BitsPixelRow) - BitPackType {1}) + << ShiftPixelRow; + static constexpr const BitPackType MaskPDNumInMod = + (BitPackType)((BitPackType {1} << BitsPDNumInMod) - BitPackType {1}) << ShiftPDNumInMod; + static constexpr const BitPackType MaskPDMod = (BitPackType)((BitPackType {1} << BitsPDMod) - BitPackType {1}) + << ShiftPDMod; + static constexpr const BitPackType MaskPanel = (BitPackType)((BitPackType {1} << BitsPanel) - BitPackType {1}) + << ShiftPanel; + static constexpr const BitPackType MaskRich = (BitPackType)((BitPackType {1} << BitsRich) - BitPackType {1}) + << ShiftRich; + static constexpr const BitPackType MaskPixelSubRowIsSet = + (BitPackType)((BitPackType {1} << BitsPixelSubRowIsSet) - BitPackType {1}) << ShiftPixelSubRowIsSet; + static constexpr const BitPackType MaskPixelColIsSet = + (BitPackType)((BitPackType {1} << BitsPixelColIsSet) - BitPackType {1}) << ShiftPixelColIsSet; + static constexpr const BitPackType MaskPixelRowIsSet = + (BitPackType)((BitPackType {1} << BitsPixelRowIsSet) - BitPackType {1}) << ShiftPixelRowIsSet; + static constexpr const BitPackType MaskPDIsSet = (BitPackType)((BitPackType {1} << BitsPDIsSet) - BitPackType {1}) + << ShiftPDIsSet; + static constexpr const BitPackType MaskPanelIsSet = + (BitPackType)((BitPackType {1} << BitsPanelIsSet) - BitPackType {1}) << ShiftPanelIsSet; + static constexpr const BitPackType MaskRichIsSet = + (BitPackType)((BitPackType {1} << BitsRichIsSet) - BitPackType {1}) << ShiftRichIsSet; + static constexpr const BitPackType MaskLargePixel = + (BitPackType)((BitPackType {1} << BitsLargePixel) - BitPackType {1}) << ShiftLargePixel; + + // Max values + static constexpr const DataType MaxPixelCol = (DataType)(BitPackType {1} << BitsPixelCol) - DataType {1}; + static constexpr const DataType MaxPixelRow = (DataType)(BitPackType {1} << BitsPixelRow) - DataType {1}; + static constexpr const DataType MaxPDNumInMod = (DataType)(BitPackType {1} << BitsPDNumInMod) - DataType {1}; + static constexpr const DataType MaxPDMod = (DataType)(BitPackType {1} << BitsPDMod) - DataType {1}; + static constexpr const DataType MaxPanel = (DataType)(BitPackType {1} << BitsPanel) - DataType {1}; + static constexpr const DataType MaxRich = (DataType)(BitPackType {1} << BitsRich) - DataType {1}; + + // Number of bits for the channel identification (i.e. excluding any time info) + // Currently use the lowest 32 bits for this. + static constexpr const BitPackType NChannelBits = 32; + + __host__ __device__ constexpr inline void + setData(const DataType value, const BitPackType shift, const BitPackType mask) noexcept + { + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask); + } + + __host__ __device__ constexpr inline void + setData(const DataType value, const BitPackType shift, const BitPackType mask, const BitPackType okMask) noexcept + { + m_key = ((BitPackType {value} << shift) & mask) | (m_key & ~mask) | okMask; + } + + __host__ __device__ constexpr inline BitPackType getData(const BitPackType shift, const BitPackType mask) const + noexcept + { + return (m_key & mask) >> shift; + } + + __host__ __device__ constexpr inline BitPackType key() const noexcept { return m_key; } + + __host__ __device__ constexpr inline bool operator==(const RichSmartID& other) const noexcept + { + return m_key == other.key(); + } + + __host__ __device__ constexpr inline auto isLargePMT() const noexcept + { + return 0 != getData(ShiftLargePixel, MaskLargePixel); + } + + __host__ __device__ constexpr inline auto rich() const noexcept { return getData(ShiftRich, MaskRich); } + + __host__ __device__ constexpr inline auto panel() const noexcept { return getData(ShiftPanel, MaskPanel); } + + __host__ __device__ constexpr inline DataType pdMod() const noexcept { return getData(ShiftPDMod, MaskPDMod); } + + __host__ __device__ constexpr inline DataType pdNumInMod() const noexcept + { + return getData(ShiftPDNumInMod, MaskPDNumInMod); + } + + __host__ __device__ constexpr inline DataType panelLocalModuleNum() const noexcept + { + return pdMod() - PanelModuleOffsets()[rich()][panel()]; + } + + __host__ __device__ constexpr inline DataType columnLocalModuleNum() const noexcept + { + return panelLocalModuleNum() % ModulesPerColumn; + } + + __host__ __device__ constexpr inline DataType numPMTsPerEC() const noexcept + { + return isLargePMT() ? HTypePMTsPerEC : RTypePMTsPerEC; + } + + __host__ __device__ constexpr inline DataType elementaryCell() const noexcept + { + return pdNumInMod() / numPMTsPerEC(); + } + + __host__ __device__ constexpr inline DataType pdNumInEC() const noexcept { return pdNumInMod() % numPMTsPerEC(); } + + __host__ __device__ constexpr inline auto pixelColIsSet() const noexcept + { + return 0 != getData(ShiftPixelColIsSet, MaskPixelColIsSet); + } - RichSmartIDs(const std::array m_pdPanels) : m_pdPanels {m_pdPanels} {} + __host__ __device__ constexpr inline auto pixelRowIsSet() const noexcept + { + return 0 != getData(ShiftPixelRowIsSet, MaskPixelRowIsSet); + } + + [[nodiscard]] __host__ __device__ constexpr bool pdIsSet() const noexcept + { + return 0 != ((key() & MaskPDIsSet) >> ShiftPDIsSet); + } - __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Allen::PDPanel* + __host__ __device__ constexpr inline DataType pixelCol() const noexcept { - using DetectorType = Rich::Future::DAQ::DetectorType; - using Side = Rich::Future::DAQ::Side; + return getData(ShiftPixelCol, MaskPixelCol); + } - // Determine the rich type - DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; - // Determine the side - Side side; - if (rich == DetectorType::Rich1) { - // For Rich1, 0 = top, 1 = bottom - side = (smartID.panel() == 0) ? Side::top : Side::bottom; + __host__ __device__ constexpr inline DataType pixelRow() const noexcept + { + return getData(ShiftPixelRow, MaskPixelRow); + } + + __host__ __device__ constexpr inline DataType anodeIndex() const noexcept + { + return pixelRow() * PixelsPerCol + PixelsPerRow - 1 - pixelCol(); + } + + __host__ __device__ constexpr inline bool adcTimeIsSet() const noexcept + { + return (0 != (key() & MaPMT::MaskADCTimeIsSet) >> MaPMT::ShiftADCTimeIsSet); + } + + __host__ __device__ constexpr ADCTimeType adcTime() const + { + return ((key() & MaPMT::MaskADCTime) >> MaPMT::ShiftADCTime); + } + + __host__ __device__ constexpr auto time() const noexcept + { + return (MaPMT::MinTime + (adcTime() * MaPMT::ScaleADCToTime)); + } + + // ostream operator + __host__ friend std::ostream& operator<<(std::ostream& str, const RichSmartID& id) + { + const auto rich = id.rich(); + const auto panel = id.panel(); + str << "{ "; + str << "PMT"; + str << (id.isLargePMT() ? ":h " : ":r "); + str << (rich == 0 ? "Rich1 " : "Rich2 "); + if (rich == 0) { + str << (panel == 0 ? "Top " : "Bot "); } else { - // For Rich2, 0 = left, 1 = right - side = (smartID.panel() == 0) ? Side::left : Side::right; + str << (panel == 0 ? "L-A " : "R-C "); } + str << "PD[Mod,NInMod]: "; + str << std::setfill('0') << std::setw(3) << id.pdMod() << ','; + str << std::setfill('0') << std::setw(2) << id.pdNumInMod() << ' '; + str << "Mod[Col,NInCol] "; + str << std::setfill('0') << std::setw(2) << id.panelLocalModuleNum() << ','; + str << std::setfill('0') << std::setw(2) << id.columnLocalModuleNum() << ' '; + str << " PD[EC,NInEC]: "; + str << id.elementaryCell() << ','; + str << id.pdNumInEC() << ' '; - for (size_t i = 0; i < m_pdPanels.size(); i++) { - const Allen::PDPanel* pdPanel = m_pdPanels[i]; - if (pdPanel->rich() == rich && pdPanel->side() == side) { - return pdPanel; + const auto pixColSet = id.pixelColIsSet(); + const auto pixRowSet = id.pixelRowIsSet(); + if (pixColSet || pixRowSet) { + if (pixColSet && pixRowSet) { + str << "Pix[Col,Row]: " << std::setfill('0') << std::setw(1) << id.pixelCol() << "," << id.pixelRow(); } - } - return nullptr; - } - - __host__ __device__ inline auto panel( - const Rich::Future::DAQ::DetectorType rtype, - const Rich::Future::DAQ::Side side) const -> const Allen::PDPanel* - { - for (size_t i = 0; i < m_pdPanels.size(); i++) { - const Allen::PDPanel* pdPanel = m_pdPanels[i]; - if (pdPanel->rich() == rtype && pdPanel->side() == side) { - return pdPanel; + else { + const auto fSPix = 2; + if (pixColSet) { + str << std::setfill('0') << std::setw(fSPix) << " pixCol" << id.pixelCol(); + } + if (pixRowSet) { + str << std::setfill('0') << std::setw(fSPix) << " pixRow" << id.pixelRow(); + } + } + // Include PMT derived info + if (pixColSet && pixRowSet) { + str << " Anode:" << std::setfill('0') << std::setw(2) << id.anodeIndex(); } } - return nullptr; + str << " }\n"; + return str; } - // Converts an PD RichSmartID identification into a position in global LHCb coordinates. - __host__ __device__ Point pdPosition(const Allen::RichSmartID pdid) const; - - // Converts a position in global coordinates to the corresponding RichSmartID - __host__ __device__ bool smartID(const Point& globalPoint, Allen::RichSmartID& smartid) const; - - // Converts a position in global coordinates to the local coordinate system. - __host__ __device__ Point globalToPDPanel(const Point& globalPoint) const; + public: + // Number of PMT pixels per row + static constexpr const DataType PixelsPerRow = 8; + // Number of PMT pixels per column + static constexpr const DataType PixelsPerCol = 8; + // Total number of PMT pixels + static constexpr const DataType TotalPixels = PixelsPerRow * PixelsPerCol; + // Number PMTs per EC for R type PMTs + static constexpr const DataType RTypePMTsPerEC = 4; + // Number PMTs per EC for H type PMTs + static constexpr const DataType HTypePMTsPerEC = 1; + // Number of ECs per module + static constexpr const DataType ECsPerModule = 4; + // Number of modules per column + static constexpr const DataType ModulesPerColumn = 6; + // Number of module columns per panel, in each RICH + static constexpr const std::array ModuleColumnsPerPanel = {{11, 14}}; + // Maximum number of module columns in any panel, RICH1 or RICH2 + static constexpr const DataType MaxModuleColumnsAnyPanel = + std::max(ModuleColumnsPerPanel[0], ModuleColumnsPerPanel[1]); + // Number of modules per panel, in each RICH + static constexpr const std::array ModulesPerPanel { + {(ModulesPerColumn * ModuleColumnsPerPanel[0]), (ModulesPerColumn * ModuleColumnsPerPanel[1])}}; - // Get the position for a given SmartID. - __host__ __device__ inline auto _globalPosition(const Allen::RichSmartID id) const + __host__ __device__ static constexpr std::array, 2> PanelModuleOffsets() { - return panel(id)->detectionPoint(id); + return {std::array {0, ModulesPerPanel[0]}, + std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; } + + class MaPMT { + public: + static constexpr const DataType MaxPDsPerModule = 16; + static constexpr const DataType MaxModulesPerPanel = 92; + + // Bits for time field. + static constexpr const BitPackType BitsADCTime = 16; + static constexpr const BitPackType BitsADCTimeIsSet = 1; + static constexpr const BitPackType ShiftADCTime = NChannelBits; + static constexpr const BitPackType ShiftADCTimeIsSet = ShiftADCTime + BitsADCTime; + static constexpr const BitPackType MaskADCTime = (BitPackType)((BitPackType {1} << BitsADCTime) - BitPackType {1}) + << ShiftADCTime; + static constexpr const BitPackType MaskADCTimeIsSet = + (BitPackType)((BitPackType {1} << BitsADCTimeIsSet) - BitPackType {1}) << ShiftADCTimeIsSet; + + // Max ADC time that can be stored + static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType {1} << BitsADCTime) - 1); - private: - const std::array m_pdPanels{}; - }; + // Parameters for conversion between float and ADC time values + static constexpr const double MinTime = -50.0; // In nanoseconds + static constexpr const double MaxTime = 150.0; // In nanoseconds + static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); + static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; + }; + }; // namespace RichSmartID } // namespace Allen diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index dbea3606079..c9cc891ccfb 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -61,6 +61,7 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDHelper* smartIDsHelper, } } + // if time checks pass, and a non-Null PD matches the SmartID, save the pix if (smartIDSelected) { if ((smartIDsHelper->panel(smartID)->dePD(smartID))) { if (!(smartIDsHelper->panel(smartID)->dePD(smartID)->getIsNull())) { -- GitLab From a1d835f98ea31787f29034fb3af3b262f8f2da76 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Sun, 20 Apr 2025 01:42:47 +0200 Subject: [PATCH 21/92] typo --- Rec/Allen/src/CompareRecAllenRichPixels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index 4e07bcd4941..e1bef45d27b 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -49,7 +49,7 @@ private: mutable Gaudi::Accumulators::Counter<> m_allen_in_rec {this, "Allen Pixels found in Rec"}; mutable Gaudi::Accumulators::Counter<> m_allen_not_in_rec {this, "Allen Pixels not found in Rec"}; mutable Gaudi::Accumulators::Counter<> m_rec_in_allen {this, "Rec Pixels found in Allen"}; - mutable Gaudi::Accumulators::Counter<> m_rec_not_in_allen {this, "Rec Pixels found in Allen"}; + mutable Gaudi::Accumulators::Counter<> m_rec_not_in_allen {this, "Rec Pixels not found in Allen"}; mutable Gaudi::Accumulators::Counter<> m_allen_null {this, "Null Allen Pixels"}; }; -- GitLab From 5f9fc6246d113cf86019fc8385161438a23f90a2 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Sat, 19 Apr 2025 23:43:20 +0000 Subject: [PATCH 22/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/54856338 --- .../BinaryDumpers/src/DumpRichGeometry.cpp | 1 - Rec/Allen/src/CompareRecAllenRichPixels.cpp | 53 ++++++++++--------- configuration/python/AllenConf/HLT1.py | 10 ++-- .../python/AllenConf/hlt1_reconstruction.py | 5 +- .../python/AllenConf/rich_reconstruction.py | 7 +-- device/rich/decoding/include/Rich.cuh | 13 +++-- device/rich/decoding/include/RichPD.cuh | 6 +-- device/rich/decoding/include/RichPDPanel.cuh | 19 ++++--- device/rich/decoding/include/RichPixels.cuh | 23 ++++---- .../decoding/include/RichSmartIDHelper.cuh | 10 ++-- device/rich/decoding/include/RichSmartIDs.cuh | 4 +- device/rich/decoding/src/RichMakePixels.cu | 8 +-- 12 files changed, 87 insertions(+), 72 deletions(-) diff --git a/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp b/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp index dfa41ea9297..1e61fa22678 100644 --- a/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp +++ b/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp @@ -122,4 +122,3 @@ StatusCode DumpRichGeometry::initialize() } void DumpRichGeometry::operator()(const Rich1Geometry_t&, const Rich2Geometry_t&) const {} - diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index e1bef45d27b..ffd12b4ec49 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -28,21 +28,22 @@ public: const Rich::Future::Rec::SIMDPixelSummaries&) const override; /// Compare the attributes of an Allen Pixel and a Rec Pixel - bool matchPixels(const Allen::RichPixel& allenPixel, - const Rich::Future::Rec::SIMDPixel& recPixelSummary, - size_t i) const { - return (allenPixel.gloPos().x == recPixelSummary.gloPos().X()[i] && - allenPixel.gloPos().y == recPixelSummary.gloPos().Y()[i] && - allenPixel.gloPos().z == recPixelSummary.gloPos().Z()[i] && - allenPixel.locPos().x == recPixelSummary.locPos().X()[i] && - allenPixel.locPos().y == recPixelSummary.locPos().Y()[i] && - allenPixel.locPos().z == recPixelSummary.locPos().Z()[i] && - allenPixel.smartID().key() == recPixelSummary.smartID()[i].key() && - allenPixel.effArea() == recPixelSummary.effArea()[i] && - static_cast(allenPixel.rich()) == static_cast(recPixelSummary.rich()) && - static_cast(allenPixel.side()) == static_cast(recPixelSummary.side()) && - allenPixel.timeWindow() == recPixelSummary.timeWindow()[i] && - allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i]); + bool matchPixels(const Allen::RichPixel& allenPixel, const Rich::Future::Rec::SIMDPixel& recPixelSummary, size_t i) + const + { + return ( + allenPixel.gloPos().x == recPixelSummary.gloPos().X()[i] && + allenPixel.gloPos().y == recPixelSummary.gloPos().Y()[i] && + allenPixel.gloPos().z == recPixelSummary.gloPos().Z()[i] && + allenPixel.locPos().x == recPixelSummary.locPos().X()[i] && + allenPixel.locPos().y == recPixelSummary.locPos().Y()[i] && + allenPixel.locPos().z == recPixelSummary.locPos().Z()[i] && + allenPixel.smartID().key() == recPixelSummary.smartID()[i].key() && + allenPixel.effArea() == recPixelSummary.effArea()[i] && + static_cast(allenPixel.rich()) == static_cast(recPixelSummary.rich()) && + static_cast(allenPixel.side()) == static_cast(recPixelSummary.side()) && + allenPixel.timeWindow() == recPixelSummary.timeWindow()[i] && + allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i]); } private: @@ -77,7 +78,7 @@ void CompareRecAllenRichPixels::operator()( // functor to check if allen pixels exist in HLT2 auto allenPixelExistsInRec = [&](const Allen::RichPixel& allenPixel) -> bool { - if (allenPixel.isNull()){ + if (allenPixel.isNull()) { ++m_allen_null; return true; // ignore invalid allen pix, assume correctedness } @@ -96,9 +97,9 @@ void CompareRecAllenRichPixels::operator()( else { ++m_allen_in_rec; return true; // ignore invalid rec pix, assume correctness - } - } // didn't find pix match - } // covered all + } + } // didn't find pix match + } // covered all ++m_allen_not_in_rec; error() << "Found an Allen pixel that does not exist in Rec" << endmsg; return false; @@ -125,23 +126,25 @@ void CompareRecAllenRichPixels::operator()( continue; } // found a match } // iterate over Allen pixels - } else { + } + else { found_current_pixel = true; // assume correctness on invalid pix to ignore it. } // valid pix found_all_pixels = found_all_pixels && found_current_pixel; - - // case: HLT2 pixels in case they are not found in Allen - } else { + + // case: HLT2 pixels in case they are not found in Allen + } + else { ++m_rec_not_in_allen; error() << "Found a Rec pixel that does not exist in Allen" << endmsg; } - } + } return found_all_pixels; }; // call allen in hlt2 functor for (auto& allenPixel : allenPixels) { - allenPixelExistsInRec(allenPixel); + allenPixelExistsInRec(allenPixel); } // call hlt2 in allen functor diff --git a/configuration/python/AllenConf/HLT1.py b/configuration/python/AllenConf/HLT1.py index 46cc123595c..e11b6823f3b 100644 --- a/configuration/python/AllenConf/HLT1.py +++ b/configuration/python/AllenConf/HLT1.py @@ -1581,13 +1581,15 @@ def setup_hlt1_node(enablePhysics=True, if with_rich: hlt1_node = CompositeNode( - "AllenWithRich", [hlt1_node, - reconstructed_objects["rich1_pixels"]["dev_rich_pixels"].producer, - reconstructed_objects["rich2_pixels"]["dev_rich_pixels"].producer + "AllenWithRich", [ + hlt1_node, reconstructed_objects["rich1_pixels"] + ["dev_rich_pixels"].producer, + reconstructed_objects["rich2_pixels"]["dev_rich_pixels"]. + producer ], NodeLogic.NONLAZY_AND, force_order=False) - + if enableRateValidator: hlt1_node = CompositeNode( "AllenRateValidation", [ diff --git a/configuration/python/AllenConf/hlt1_reconstruction.py b/configuration/python/AllenConf/hlt1_reconstruction.py index b94181e4184..6e0960b8ea7 100644 --- a/configuration/python/AllenConf/hlt1_reconstruction.py +++ b/configuration/python/AllenConf/hlt1_reconstruction.py @@ -35,6 +35,7 @@ from AllenConf.enum_types import TrackingType from AllenConf.secondary_vertex_reconstruction import make_kalman_long from AllenConf.rich_reconstruction import make_pixels + def hlt1_reconstruction(algorithm_name='', tracking_type=TrackingType.FORWARD, with_calo=True, @@ -498,8 +499,8 @@ def hlt1_reconstruction(algorithm_name='', }) if with_rich: - rich1_pixels = make_pixels(rich=1) - rich2_pixels = make_pixels(rich=2) + rich1_pixels = make_pixels(rich=1) + rich2_pixels = make_pixels(rich=2) output.update({ "rich1_pixels": rich1_pixels, diff --git a/configuration/python/AllenConf/rich_reconstruction.py b/configuration/python/AllenConf/rich_reconstruction.py index 852588c1d4c..182f02f1dc2 100644 --- a/configuration/python/AllenConf/rich_reconstruction.py +++ b/configuration/python/AllenConf/rich_reconstruction.py @@ -8,7 +8,8 @@ # granted to it by virtue of its status as an Intergovernmental Organization # # or submit itself to any jurisdiction. # ############################################################################### -from AllenCore.algorithms import (data_provider_t, rich_decoding_t, rich_make_pixels_t) +from AllenCore.algorithms import (data_provider_t, rich_decoding_t, + rich_make_pixels_t) from AllenConf.utils import initialize_number_of_events from AllenCore.generator import make_algorithm @@ -50,10 +51,10 @@ def decode_rich(rich=RICH_1): def make_pixels(decoded_rich=None, rich=RICH_1): if rich not in VALID_RICHS: raise ValueError(f"rich must be one of {VALID_RICHS}") - + if decoded_rich is None: decoded_rich = decode_rich(rich) - + number_of_hits = decoded_rich["host_rich_total_number_of_hits"] smart_ids = decoded_rich["dev_smart_ids"] hit_offsets = decoded_rich["dev_rich_hit_offsets"] diff --git a/device/rich/decoding/include/Rich.cuh b/device/rich/decoding/include/Rich.cuh index fad5a3243a5..fc9fcbf86c8 100644 --- a/device/rich/decoding/include/Rich.cuh +++ b/device/rich/decoding/include/Rich.cuh @@ -17,8 +17,11 @@ namespace Rich::Detector::Allen { public: __host__ __device__ Rich(); - __host__ __device__ Rich(const ::Rich::Future::DAQ::DetectorType m_type, const std::array< ::Rich::Detector::Allen::PDPanel, 2 > m_panels) : - m_panels(m_panels), m_type(m_type) + __host__ __device__ Rich( + const ::Rich::Future::DAQ::DetectorType m_type, + const std::array<::Rich::Detector::Allen::PDPanel, 2> m_panels) : + m_panels(m_panels), + m_type(m_type) {} __host__ __device__ inline auto rich() { return m_type; } @@ -33,7 +36,7 @@ namespace Rich::Detector::Allen { } private: - std::array m_panels{}; - ::Rich::Future::DAQ::DetectorType m_type{::Rich::Future::DAQ::DetectorType::Rich1}; + std::array m_panels {}; + ::Rich::Future::DAQ::DetectorType m_type {::Rich::Future::DAQ::DetectorType::Rich1}; }; -} // namespace Allen +} // namespace Rich::Detector::Allen diff --git a/device/rich/decoding/include/RichPD.cuh b/device/rich/decoding/include/RichPD.cuh index 8d49bde2ee4..24418b60092 100644 --- a/device/rich/decoding/include/RichPD.cuh +++ b/device/rich/decoding/include/RichPD.cuh @@ -85,9 +85,9 @@ namespace Rich::Detector::Allen { __host__ __device__ void setIsNull(bool value) { m_isNull = value; } private: - std::array m_locToGloM{}; - std::array m_zeroInPanelFrame{}; - std::uint64_t m_pdSmartID{0}; + std::array m_locToGloM {}; + std::array m_zeroInPanelFrame {}; + std::uint64_t m_pdSmartID {0}; float m_effPixelArea {0.f}; float m_numPixels {0.f}; float m_localZcoord {0.f}; diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index df5896fd78b..f6c74aa5f63 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -101,14 +101,13 @@ namespace Rich::Detector::Allen { } private: - ModuleArray m_PDs{}; - std::array m_gloToPDPanelM{}; // 3D Transform - uint32_t m_modNumOffset{0}; - std::array m_panelID{ - Rich::Future::DAQ::DetectorType::InvalidDetector, - Rich::Future::DAQ::Side::InvalidSide, - -1}; - Rich::Future::DAQ::DetectorType m_rich{Rich::Future::DAQ::DetectorType::InvalidDetector}; - Rich::Future::DAQ::Side m_side{Rich::Future::DAQ::Side::InvalidSide}; + ModuleArray m_PDs {}; + std::array m_gloToPDPanelM {}; // 3D Transform + uint32_t m_modNumOffset {0}; + std::array m_panelID {Rich::Future::DAQ::DetectorType::InvalidDetector, + Rich::Future::DAQ::Side::InvalidSide, + -1}; + Rich::Future::DAQ::DetectorType m_rich {Rich::Future::DAQ::DetectorType::InvalidDetector}; + Rich::Future::DAQ::Side m_side {Rich::Future::DAQ::Side::InvalidSide}; }; -} // namespace Allen +} // namespace Rich::Detector::Allen diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index 4a7241ffc77..81a7a32910b 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -18,7 +18,8 @@ namespace Allen { public: // Default __host__ __device__ RichPixel() : - gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID({}), m_effArea(0.0f), m_rich(Rich::Future::DAQ::DetectorType::InvalidDetector), m_side(Rich::Future::DAQ::InvalidSide), m_mask(0), + gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID({}), m_effArea(0.0f), + m_rich(Rich::Future::DAQ::DetectorType::InvalidDetector), m_side(Rich::Future::DAQ::InvalidSide), m_mask(0), m_timeWindow(0.0f), m_isInnerRegion(true), m_isNull(true) {} @@ -90,15 +91,15 @@ namespace Allen { } private: - Point gPos{0.0f, 0.0f, 0.0f}; - Point lPos{0.0f, 0.0f, 0.0f}; - RichSmartID m_smartID = RichSmartID{}; - double m_effArea{0.0f}; - Rich::Future::DAQ::DetectorType m_rich{Rich::Future::DAQ::DetectorType::InvalidDetector}; - Rich::Future::DAQ::Side m_side{Rich::Future::DAQ::InvalidSide}; - uint8_t m_mask{0}; - float m_timeWindow{0.0f}; - bool m_isInnerRegion{true}; - bool m_isNull{true}; + Point gPos {0.0f, 0.0f, 0.0f}; + Point lPos {0.0f, 0.0f, 0.0f}; + RichSmartID m_smartID = RichSmartID {}; + double m_effArea {0.0f}; + Rich::Future::DAQ::DetectorType m_rich {Rich::Future::DAQ::DetectorType::InvalidDetector}; + Rich::Future::DAQ::Side m_side {Rich::Future::DAQ::InvalidSide}; + uint8_t m_mask {0}; + float m_timeWindow {0.0f}; + bool m_isInnerRegion {true}; + bool m_isNull {true}; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index f39b46d2d5b..977f5e24287 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -20,9 +20,13 @@ namespace Allen { class RichSmartIDHelper { public: /// Constructor from RICH detector elements - RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : m_pdPanels {&pdPanel1, &pdPanel2} {} + RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : + m_pdPanels {&pdPanel1, &pdPanel2} + {} - RichSmartIDHelper(const std::array m_pdPanels) : m_pdPanels {m_pdPanels} {} + RichSmartIDHelper(const std::array m_pdPanels) : + m_pdPanels {m_pdPanels} + {} __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Rich::Detector::Allen::PDPanel* { @@ -80,6 +84,6 @@ namespace Allen { } private: - const std::array m_pdPanels{}; + const std::array m_pdPanels {}; }; } // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDs.cuh b/device/rich/decoding/include/RichSmartIDs.cuh index b6a2b357f82..3ae2c6335b0 100644 --- a/device/rich/decoding/include/RichSmartIDs.cuh +++ b/device/rich/decoding/include/RichSmartIDs.cuh @@ -294,7 +294,7 @@ namespace Allen { return {std::array {0, ModulesPerPanel[0]}, std::array {2 * ModulesPerPanel[0], (2 * ModulesPerPanel[0]) + ModulesPerPanel[1]}}; } - + class MaPMT { public: static constexpr const DataType MaxPDsPerModule = 16; @@ -319,5 +319,5 @@ namespace Allen { static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; }; - }; // namespace RichSmartID + }; // namespace RichSmartID } // namespace Allen diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index c9cc891ccfb..9ba4a852dff 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -25,8 +25,8 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDHelper* smartIDsHelper, uint8_t mask = 0; // Selection mask bool innerRegion = 1; // Inner/outer region - const auto rich = (Rich::Future::DAQ::DetectorType)smartID.rich(); - const auto side = (Rich::Future::DAQ::Side)smartID.panel(); + const auto rich = (Rich::Future::DAQ::DetectorType) smartID.rich(); + const auto side = (Rich::Future::DAQ::Side) smartID.panel(); // Functor to save a Rich pixel auto savePix = [&]() { @@ -75,7 +75,9 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDHelper* smartIDsHelper, } /// Kernel function to iterate over Events, SmartIDs, and create Pixels -__global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Allen::RichSmartIDHelper* smartIDsHelper) +__global__ void rich_make_pixels_kernel( + rich_make_pixels::Parameters parameters, + Allen::RichSmartIDHelper* smartIDsHelper) { const auto eventNumber = parameters.dev_event_list[blockIdx.x]; auto eventSmartIDCount = -- GitLab From 0f478e417f36059562848af24ae8ffa47328c3d4 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Tue, 22 Apr 2025 21:25:11 +0200 Subject: [PATCH 23/92] added binary geometry files --- .../rich_1_geometry.bin | Bin 0 -> 306312 bytes .../rich_2_geometry.bin | Bin 0 -> 306312 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 input/allen_geometries/geometry_run3_2025-v00.01/rich_1_geometry.bin create mode 100644 input/allen_geometries/geometry_run3_2025-v00.01/rich_2_geometry.bin diff --git a/input/allen_geometries/geometry_run3_2025-v00.01/rich_1_geometry.bin b/input/allen_geometries/geometry_run3_2025-v00.01/rich_1_geometry.bin new file mode 100644 index 0000000000000000000000000000000000000000..207b37c979b357378d6cc349dcd006d079ad741e GIT binary patch literal 306312 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 literal 0 HcmV?d00001 diff --git a/input/allen_geometries/geometry_run3_2025-v00.01/rich_2_geometry.bin b/input/allen_geometries/geometry_run3_2025-v00.01/rich_2_geometry.bin new file mode 100644 index 0000000000000000000000000000000000000000..df81a3f049d7c54cc7fa29e305ae3d4f66133d1f GIT binary patch literal 306312 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 P&0in3hVj4Ly#MtV9@{D3 literal 0 HcmV?d00001 -- GitLab From 7f7dc62fe751d93aacdd4952e962a24e3c378436 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Sat, 26 Apr 2025 05:52:28 +0200 Subject: [PATCH 24/92] code cleanup --- Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp b/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp index 1e61fa22678..f331aeb555e 100644 --- a/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp +++ b/Dumpers/BinaryDumpers/src/DumpRichGeometry.cpp @@ -27,7 +27,6 @@ #include "RichUtils/RichSmartIDSorter.h" // LHCb -#include #include #include @@ -36,15 +35,6 @@ #include namespace { -// paths unused while DefaultConditionKey works -#ifdef USE_DD4HEP - inline const std::string Rich1GeoCond = DeRichLocations::Rich1Path; - inline const std::string Rich2GeoCond = DeRichLocations::Rich2Path; -#else - inline const std::string Rich1GeoCond = DeRichLocations::OldRich1; - inline const std::string Rich2GeoCond = DeRichLocations::OldRich2; -#endif - struct Rich1Geometry_t { Rich1Geometry_t() = default; Rich1Geometry_t(std::vector& data, const Rich::Detector::Rich1& rich_1) -- GitLab From bcea0434f9b8ce2162fc43a065e952f121019bf0 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Sat, 26 Apr 2025 18:42:18 +0200 Subject: [PATCH 25/92] cleanup test --- Rec/Allen/src/CompareRecAllenRichPixels.cpp | 90 ++++++++++++--------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index ffd12b4ec49..7f024618e3d 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -12,6 +12,9 @@ #include "RichMakePixels.cuh" #include "RichPixels.cuh" + +// This test verifies that all valid HLT2 pixels exist in Allen, and all valid Allen pixels exist in HLT2 +// Having the same number of m_allen_found_in_hlt2, and m_hlt2_found_in_allen means success. class CompareRecAllenRichPixels final : public Gaudi::Functional::Consumer&, const std::vector&, @@ -47,11 +50,14 @@ public: } private: - mutable Gaudi::Accumulators::Counter<> m_allen_in_rec {this, "Allen Pixels found in Rec"}; - mutable Gaudi::Accumulators::Counter<> m_allen_not_in_rec {this, "Allen Pixels not found in Rec"}; - mutable Gaudi::Accumulators::Counter<> m_rec_in_allen {this, "Rec Pixels found in Allen"}; - mutable Gaudi::Accumulators::Counter<> m_rec_not_in_allen {this, "Rec Pixels not found in Allen"}; + mutable Gaudi::Accumulators::Counter<> m_allen_in_rec {this, "Allen Pixels found in HLT2"}; + mutable Gaudi::Accumulators::Counter<> m_allen_not_in_rec {this, "Allen Pixels not found in HLT2"}; + mutable Gaudi::Accumulators::Counter<> m_rec_in_allen {this, "HLT2 Pixels found in Allen"}; + mutable Gaudi::Accumulators::Counter<> m_rec_not_in_allen {this, "HLT2 Pixels not found in Allen"}; mutable Gaudi::Accumulators::Counter<> m_allen_null {this, "Null Allen Pixels"}; + mutable Gaudi::Accumulators::Counter<> m_rec_null {this, "Null HLT2 Pixels"}; + mutable Gaudi::Accumulators::Counter<> m_allen_reviewed {this, "Allen Pixels reviewed"}; + mutable Gaudi::Accumulators::Counter<> m_rec_reviewed {this, "HLT2 Pixels reviewed"}; }; DECLARE_COMPONENT(CompareRecAllenRichPixels) @@ -77,69 +83,66 @@ void CompareRecAllenRichPixels::operator()( allenPixels.insert(allenPixels.end(), allenRich2Pixels.begin(), allenRich2Pixels.end()); // functor to check if allen pixels exist in HLT2 - auto allenPixelExistsInRec = [&](const Allen::RichPixel& allenPixel) -> bool { + auto allenPixelExistsInRec = [&](const Allen::RichPixel& allenPixel) { + ++m_allen_reviewed; + // Check if pixel is valid if (allenPixel.isNull()) { ++m_allen_null; - return true; // ignore invalid allen pix, assume correctedness + return; } + // iterate over all pixel summaries for (const auto& recPixelSummary : recPixelSummaries) { - // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. + // arbitralilly use any of the vectors in a pixel summary to get the pixel count and iterate that many times. for (size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { // ensure HLT2 pixel validity if (recPixelSummary.validMask()[i]) { // check for match if (matchPixels(allenPixel, recPixelSummary, i)) { ++m_allen_in_rec; - return true; + return; } - } - else { - ++m_allen_in_rec; - return true; // ignore invalid rec pix, assume correctness - } + } // invalid HLT2 pix } // didn't find pix match - } // covered all + } // covered all HLT2 pixels ++m_allen_not_in_rec; - error() << "Found an Allen pixel that does not exist in Rec" << endmsg; - return false; + error() << "Allen pixel " << allenPixel.smartID().key()<< " not found in HLT2" << endmsg; + return; }; // functor to check if HLT2 pixels exist in Allen - auto recPixelExistsInAllen = [&](const Rich::Future::Rec::SIMDPixel& recPixelSummary) -> bool { - bool found_all_pixels = true; + auto recPixelExistsInAllen = [&](const Rich::Future::Rec::SIMDPixel& recPixelSummary) { bool found_current_pixel = true; // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. for (size_t i = 0; i < recPixelSummary.gloPos().X().size(); i++) { + ++m_rec_reviewed; if (found_current_pixel) { found_current_pixel = false; - // ensure HLT2 pixel validity if (recPixelSummary.validMask()[i]) { // iterate over Allen pixels for (const auto& allenPixel : allenPixels) { - // check for match - if (matchPixels(allenPixel, recPixelSummary, i)) { - found_current_pixel = true; - ++m_rec_in_allen; - continue; - } // found a match - } // iterate over Allen pixels - } - else { + // check allen pix validity + if (!allenPixel.isNull()){ + // check for match + if (matchPixels(allenPixel, recPixelSummary, i)) { + ++m_rec_in_allen; + found_current_pixel = true; + continue; + } // found a match + } //ignore null Allen pix + } // covered all Allen pixels + } else { + ++m_rec_null; found_current_pixel = true; // assume correctness on invalid pix to ignore it. - } // valid pix - found_all_pixels = found_all_pixels && found_current_pixel; - - // case: HLT2 pixels in case they are not found in Allen - } - else { + } // invalid HLT2 pix + } else { // didn't find pix match ++m_rec_not_in_allen; - error() << "Found a Rec pixel that does not exist in Allen" << endmsg; + error() << "HLT2 pixel " << recPixelSummary.smartID()[i].key() << " not found in Allen" << endmsg; } } - return found_all_pixels; + return; }; // call allen in hlt2 functor @@ -151,4 +154,19 @@ void CompareRecAllenRichPixels::operator()( for (auto& recPixelSummary : recPixelSummaries) { recPixelExistsInAllen(recPixelSummary); } + + // verify that all Allen pixels were accounted for + if ((m_allen_in_rec.value() + m_allen_null.value()) != m_allen_reviewed.value()) { + error() << "Found " << m_allen_in_rec.value() << " Allen pixels in HLT2, and " + << m_allen_null.value() << " Allen null pixels totalling " + << m_allen_null.value() + m_allen_in_rec.value() << ". Expected " << m_allen_reviewed.value() + << endmsg; + } + // verify that all HLT2 pixels were accounted for + if ((m_rec_in_allen.value() + m_rec_null.value()) != m_rec_reviewed.value()) { + error() << "Found " << m_rec_in_allen.value() << " HLT2 pixels in Allen, and " + << m_rec_null.value() << " HLT2 null pixels totalling " + << m_rec_null.value() + m_rec_in_allen.value() << ". Expected " << m_rec_reviewed.value() + << endmsg; + } } -- GitLab From fdd92ca8910b53b1aee99fa68b41f2c9dff02ea5 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Sat, 26 Apr 2025 16:50:55 +0000 Subject: [PATCH 26/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/55119807 --- Rec/Allen/src/CompareRecAllenRichPixels.cpp | 37 ++++++++++----------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index 7f024618e3d..8ac2e17e90f 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -12,7 +12,6 @@ #include "RichMakePixels.cuh" #include "RichPixels.cuh" - // This test verifies that all valid HLT2 pixels exist in Allen, and all valid Allen pixels exist in HLT2 // Having the same number of m_allen_found_in_hlt2, and m_hlt2_found_in_allen means success. class CompareRecAllenRichPixels final : public Gaudi::Functional::Consumer m_rec_in_allen {this, "HLT2 Pixels found in Allen"}; mutable Gaudi::Accumulators::Counter<> m_rec_not_in_allen {this, "HLT2 Pixels not found in Allen"}; mutable Gaudi::Accumulators::Counter<> m_allen_null {this, "Null Allen Pixels"}; - mutable Gaudi::Accumulators::Counter<> m_rec_null {this, "Null HLT2 Pixels"}; + mutable Gaudi::Accumulators::Counter<> m_rec_null {this, "Null HLT2 Pixels"}; mutable Gaudi::Accumulators::Counter<> m_allen_reviewed {this, "Allen Pixels reviewed"}; mutable Gaudi::Accumulators::Counter<> m_rec_reviewed {this, "HLT2 Pixels reviewed"}; }; @@ -103,10 +102,10 @@ void CompareRecAllenRichPixels::operator()( return; } } // invalid HLT2 pix - } // didn't find pix match - } // covered all HLT2 pixels + } // didn't find pix match + } // covered all HLT2 pixels ++m_allen_not_in_rec; - error() << "Allen pixel " << allenPixel.smartID().key()<< " not found in HLT2" << endmsg; + error() << "Allen pixel " << allenPixel.smartID().key() << " not found in HLT2" << endmsg; return; }; @@ -124,20 +123,22 @@ void CompareRecAllenRichPixels::operator()( // iterate over Allen pixels for (const auto& allenPixel : allenPixels) { // check allen pix validity - if (!allenPixel.isNull()){ + if (!allenPixel.isNull()) { // check for match if (matchPixels(allenPixel, recPixelSummary, i)) { ++m_rec_in_allen; found_current_pixel = true; continue; } // found a match - } //ignore null Allen pix - } // covered all Allen pixels - } else { + } // ignore null Allen pix + } // covered all Allen pixels + } + else { ++m_rec_null; found_current_pixel = true; // assume correctness on invalid pix to ignore it. - } // invalid HLT2 pix - } else { // didn't find pix match + } // invalid HLT2 pix + } + else { // didn't find pix match ++m_rec_not_in_allen; error() << "HLT2 pixel " << recPixelSummary.smartID()[i].key() << " not found in Allen" << endmsg; } @@ -157,16 +158,14 @@ void CompareRecAllenRichPixels::operator()( // verify that all Allen pixels were accounted for if ((m_allen_in_rec.value() + m_allen_null.value()) != m_allen_reviewed.value()) { - error() << "Found " << m_allen_in_rec.value() << " Allen pixels in HLT2, and " - << m_allen_null.value() << " Allen null pixels totalling " - << m_allen_null.value() + m_allen_in_rec.value() << ". Expected " << m_allen_reviewed.value() - << endmsg; + error() << "Found " << m_allen_in_rec.value() << " Allen pixels in HLT2, and " << m_allen_null.value() + << " Allen null pixels totalling " << m_allen_null.value() + m_allen_in_rec.value() << ". Expected " + << m_allen_reviewed.value() << endmsg; } // verify that all HLT2 pixels were accounted for if ((m_rec_in_allen.value() + m_rec_null.value()) != m_rec_reviewed.value()) { - error() << "Found " << m_rec_in_allen.value() << " HLT2 pixels in Allen, and " - << m_rec_null.value() << " HLT2 null pixels totalling " - << m_rec_null.value() + m_rec_in_allen.value() << ". Expected " << m_rec_reviewed.value() - << endmsg; + error() << "Found " << m_rec_in_allen.value() << " HLT2 pixels in Allen, and " << m_rec_null.value() + << " HLT2 null pixels totalling " << m_rec_null.value() + m_rec_in_allen.value() << ". Expected " + << m_rec_reviewed.value() << endmsg; } } -- GitLab From 00a0b38fa6dabe02999a447ee038f547e57b0152 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Wed, 30 Apr 2025 21:06:10 +0200 Subject: [PATCH 27/92] Create SmartIDsHelper in GPU avoiding HostToDevice copies --- device/rich/decoding/include/RichPDPanel.cuh | 20 ++++----- .../decoding/include/RichSmartIDHelper.cuh | 4 +- device/rich/decoding/src/RichMakePixels.cu | 43 +++++++++++-------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index f6c74aa5f63..29f3226b962 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -18,12 +18,12 @@ namespace Rich::Detector::Allen { public: PDPanel() {} - using PDsArray = std::array; + using PDsArray = std::array<::Rich::Detector::Allen::PD, ::Allen::RichSmartID::MaPMT::MaxPDsPerModule>; using ModuleArray = std::array; PDPanel( - Rich::Future::DAQ::DetectorType rich, - Rich::Future::DAQ::Side side, + ::Rich::Future::DAQ::DetectorType rich, + ::Rich::Future::DAQ::Side side, std::array gloToPDPanelM, ModuleArray PDs) : m_PDs(std::move(PDs)), @@ -36,10 +36,10 @@ namespace Rich::Detector::Allen { for (size_t i = 0; i < other.m_PDs.size(); ++i) { for (size_t j = 0; j < other.m_PDs[i].size(); ++j) { if (!(other.m_PDs[i][j].getIsNull())) { - m_PDs[i][j] = Rich::Detector::Allen::PD(other.m_PDs[i][j]); + m_PDs[i][j] = ::Rich::Detector::Allen::PD(other.m_PDs[i][j]); } else { - m_PDs[i][j] = Rich::Detector::Allen::PD(); + m_PDs[i][j] = ::Rich::Detector::Allen::PD(); m_PDs[i][j].setIsNull(true); } } @@ -54,7 +54,7 @@ namespace Rich::Detector::Allen { __host__ __device__ auto dePD(const ::Allen::RichSmartID smartID) const { - const Rich::Detector::Allen::PD* dePD = nullptr; + const ::Rich::Detector::Allen::PD* dePD = nullptr; if (smartID.pdIsSet()) { const auto localModNum = smartID.pdMod() - m_modNumOffset; if (localModNum < pdModules().size()) { @@ -104,10 +104,10 @@ namespace Rich::Detector::Allen { ModuleArray m_PDs {}; std::array m_gloToPDPanelM {}; // 3D Transform uint32_t m_modNumOffset {0}; - std::array m_panelID {Rich::Future::DAQ::DetectorType::InvalidDetector, - Rich::Future::DAQ::Side::InvalidSide, + std::array m_panelID {::Rich::Future::DAQ::DetectorType::InvalidDetector, + ::Rich::Future::DAQ::Side::InvalidSide, -1}; - Rich::Future::DAQ::DetectorType m_rich {Rich::Future::DAQ::DetectorType::InvalidDetector}; - Rich::Future::DAQ::Side m_side {Rich::Future::DAQ::Side::InvalidSide}; + ::Rich::Future::DAQ::DetectorType m_rich {::Rich::Future::DAQ::DetectorType::InvalidDetector}; + ::Rich::Future::DAQ::Side m_side {::Rich::Future::DAQ::Side::InvalidSide}; }; } // namespace Rich::Detector::Allen diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 977f5e24287..11e08b019cb 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -20,11 +20,11 @@ namespace Allen { class RichSmartIDHelper { public: /// Constructor from RICH detector elements - RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : + __host__ __device__ RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : m_pdPanels {&pdPanel1, &pdPanel2} {} - RichSmartIDHelper(const std::array m_pdPanels) : + __host__ __device__ RichSmartIDHelper(const std::array m_pdPanels) : m_pdPanels {m_pdPanels} {} diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index 9ba4a852dff..f9d36129270 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -19,7 +19,7 @@ INSTANTIATE_ALGORITHM(rich_make_pixels::rich_make_pixels_t); /// Create a Pixel object from a given SmartID -__device__ Allen::RichPixel make_pixel(Allen::RichSmartIDHelper* smartIDsHelper, const Allen::RichSmartID& smartID) +__device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsHelper, const Allen::RichSmartID& smartID) { float effArea; // Effective area uint8_t mask = 0; // Selection mask @@ -30,8 +30,8 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDHelper* smartIDsHelper, // Functor to save a Rich pixel auto savePix = [&]() { - const auto gPos = smartIDsHelper->_globalPosition(smartID); - const auto lPos = smartIDsHelper->globalToPDPanel(gPos); + const auto gPos = smartIDsHelper._globalPosition(smartID); + const auto lPos = smartIDsHelper.globalToPDPanel(gPos); const auto isInner = (Allen::m_overrideRegions[rich] ? (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : @@ -63,9 +63,9 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDHelper* smartIDsHelper, // if time checks pass, and a non-Null PD matches the SmartID, save the pix if (smartIDSelected) { - if ((smartIDsHelper->panel(smartID)->dePD(smartID))) { - if (!(smartIDsHelper->panel(smartID)->dePD(smartID)->getIsNull())) { - effArea = smartIDsHelper->panel(smartID)->dePD(smartID)->effectivePixelArea(); + if ((smartIDsHelper.panel(smartID)->dePD(smartID))) { + if (!(smartIDsHelper.panel(smartID)->dePD(smartID)->getIsNull())) { + effArea = smartIDsHelper.panel(smartID)->dePD(smartID)->effectivePixelArea(); innerRegion = !smartID.isLargePMT(); return savePix(); } @@ -77,8 +77,18 @@ __device__ Allen::RichPixel make_pixel(Allen::RichSmartIDHelper* smartIDsHelper, /// Kernel function to iterate over Events, SmartIDs, and create Pixels __global__ void rich_make_pixels_kernel( rich_make_pixels::Parameters parameters, - Allen::RichSmartIDHelper* smartIDsHelper) + Rich::Detector::Allen::Rich* rich) { + + // Send panels from RICH to SmartIDsHelper + std::array panels; + for (size_t i = 0; i < 2; i++) { + panels[i] = &(rich->pdPanels()[i]); + } + + // Instantiate smartIDsHelper in host and copy to device + Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); + const auto eventNumber = parameters.dev_event_list[blockIdx.x]; auto eventSmartIDCount = parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; @@ -111,19 +121,18 @@ void rich_make_pixels::rich_make_pixels_t::operator()( rich = reinterpret_cast(constants.dev_rich_2_geometry); // Send panels from RICH to SmartIDsHelper - std::array panels; - for (size_t i = 0; i < 2; i++) { - panels[i] = &(rich->pdPanels()[i]); - } + //std::array panels; + //for (size_t i = 0; i < 2; i++) { + /// panels[i] = &(rich->pdPanels()[i]); + //} // Instantiate smartIDsHelper in host and copy to device - Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); - Allen::RichSmartIDHelper* dev_smartIDsHelper = nullptr; - Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDHelper)); - Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDHelper), Allen::memcpyHostToDevice); + //Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); + //Allen::RichSmartIDHelper* dev_smartIDsHelper = nullptr; + //Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDHelper)); + //Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDHelper), Allen::memcpyHostToDevice); // call global kernel global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - arguments, dev_smartIDsHelper); - Allen::free(dev_smartIDsHelper); + arguments, rich); } -- GitLab From 93cb8be2fe63c43b0b6f89103f8660bf0db63edd Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Wed, 30 Apr 2025 19:11:43 +0000 Subject: [PATCH 28/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/55294238 --- .../decoding/include/RichSmartIDHelper.cuh | 6 ++++-- device/rich/decoding/src/RichMakePixels.cu | 20 +++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 11e08b019cb..1dcdb0345b0 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -20,11 +20,13 @@ namespace Allen { class RichSmartIDHelper { public: /// Constructor from RICH detector elements - __host__ __device__ RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : + __host__ __device__ + RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : m_pdPanels {&pdPanel1, &pdPanel2} {} - __host__ __device__ RichSmartIDHelper(const std::array m_pdPanels) : + __host__ __device__ + RichSmartIDHelper(const std::array m_pdPanels) : m_pdPanels {m_pdPanels} {} diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index f9d36129270..ed65970c624 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -19,7 +19,9 @@ INSTANTIATE_ALGORITHM(rich_make_pixels::rich_make_pixels_t); /// Create a Pixel object from a given SmartID -__device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsHelper, const Allen::RichSmartID& smartID) +__device__ Allen::RichPixel make_pixel( + const Allen::RichSmartIDHelper& smartIDsHelper, + const Allen::RichSmartID& smartID) { float effArea; // Effective area uint8_t mask = 0; // Selection mask @@ -75,9 +77,7 @@ __device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsH } /// Kernel function to iterate over Events, SmartIDs, and create Pixels -__global__ void rich_make_pixels_kernel( - rich_make_pixels::Parameters parameters, - Rich::Detector::Allen::Rich* rich) +__global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Rich::Detector::Allen::Rich* rich) { // Send panels from RICH to SmartIDsHelper @@ -121,16 +121,16 @@ void rich_make_pixels::rich_make_pixels_t::operator()( rich = reinterpret_cast(constants.dev_rich_2_geometry); // Send panels from RICH to SmartIDsHelper - //std::array panels; - //for (size_t i = 0; i < 2; i++) { + // std::array panels; + // for (size_t i = 0; i < 2; i++) { /// panels[i] = &(rich->pdPanels()[i]); //} // Instantiate smartIDsHelper in host and copy to device - //Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); - //Allen::RichSmartIDHelper* dev_smartIDsHelper = nullptr; - //Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDHelper)); - //Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDHelper), Allen::memcpyHostToDevice); + // Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); + // Allen::RichSmartIDHelper* dev_smartIDsHelper = nullptr; + // Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDHelper)); + // Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDHelper), Allen::memcpyHostToDevice); // call global kernel global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( -- GitLab From 0727756d478c7bb845836001b83eb90a9fb17306 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Sat, 3 May 2025 00:28:14 +0200 Subject: [PATCH 29/92] reduced throughput decrease to near 0% by setting up a coalesced stride on threads --- device/rich/decoding/src/RichDecoding.cu | 12 ++++++++++-- device/rich/decoding/src/RichMakePixels.cu | 7 ++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index b49cbf19dfd..12deb7b8610 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -178,7 +178,11 @@ __global__ void rich_calculate_number_of_hits( parameters.dev_rich_raw_input_types, event_number + event_start}; - for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { + // Setup coalesced stride + int tid = blockIdx.x * blockDim.x + threadIdx.x; + int stride = blockDim.x * gridDim.x; + + for (unsigned bank_number = tid; bank_number < raw_event.number_of_raw_banks; bank_number += stride) { const auto bank = raw_event.raw_bank(bank_number); const auto number_of_hits_in_raw_bank = rich_calculate_number_of_hits_in_raw_bank(bank, cable_mapping, pdmdb_mapping); @@ -406,7 +410,11 @@ __global__ void rich_decoding_kernel( parameters.dev_rich_raw_input_types, event_number + event_start}; - for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { + // Setup coalesced stride + int tid = blockIdx.x * blockDim.x + threadIdx.x; + int stride = blockDim.x * gridDim.x; + + for (unsigned bank_number = tid; bank_number < raw_event.number_of_raw_banks; bank_number += stride) { const auto bank = raw_event.raw_bank(bank_number); rich_decode_bank(bank, cable_mapping, pdmdb_mapping, event_inserted_hits, event_smart_ids); } diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index ed65970c624..f137acc17dd 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -92,7 +92,12 @@ __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, const auto eventNumber = parameters.dev_event_list[blockIdx.x]; auto eventSmartIDCount = parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; - for (unsigned smartID = threadIdx.x; smartID < eventSmartIDCount; smartID += blockDim.x) { + + // Define coalesced stride + int tid = blockIdx.x * blockDim.x + threadIdx.x; + int stride = blockDim.x * gridDim.x; + + for (unsigned smartID = tid; smartID < eventSmartIDCount; smartID += stride) { parameters.dev_rich_pixels[smartID] = make_pixel(smartIDsHelper, parameters.dev_smart_ids[smartID]); } } -- GitLab From 92df9e2095458840f65e7979daf3caf7a124c752 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Fri, 2 May 2025 22:28:54 +0000 Subject: [PATCH 30/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/55360869 --- device/rich/decoding/src/RichMakePixels.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index f137acc17dd..3d1ceeb2a34 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -92,7 +92,7 @@ __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, const auto eventNumber = parameters.dev_event_list[blockIdx.x]; auto eventSmartIDCount = parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; - + // Define coalesced stride int tid = blockIdx.x * blockDim.x + threadIdx.x; int stride = blockDim.x * gridDim.x; -- GitLab From 2d66ea02ead6874b3e5401823b2f259e2843c883 Mon Sep 17 00:00:00 2001 From: ipalmame Date: Sat, 10 May 2025 04:35:16 +0200 Subject: [PATCH 31/92] removeed ifs in order to optimize --- changes.txt | 207 ++++++++++++++++++ device/rich/decoding/include/RichPDPanel.cuh | 28 +-- device/rich/decoding/include/RichPixels.cuh | 2 + .../decoding/include/RichSmartIDHelper.cuh | 20 +- device/rich/decoding/src/RichDecoding.cu | 14 +- device/rich/decoding/src/RichMakePixels.cu | 67 ++++-- 6 files changed, 283 insertions(+), 55 deletions(-) create mode 100644 changes.txt diff --git a/changes.txt b/changes.txt new file mode 100644 index 00000000000..3ae827301b2 --- /dev/null +++ b/changes.txt @@ -0,0 +1,207 @@ +diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh +index 29f3226b96..3cab7f8087 100644 +--- a/device/rich/decoding/include/RichPDPanel.cuh ++++ b/device/rich/decoding/include/RichPDPanel.cuh +@@ -52,27 +52,29 @@ namespace Rich::Detector::Allen { + /// Access the PD panel side + __host__ __device__ inline auto side() const noexcept { return m_side; } + +- __host__ __device__ auto dePD(const ::Allen::RichSmartID smartID) const ++ __host__ __device__ ::Rich::Detector::Allen::PD dePD(const ::Allen::RichSmartID smartID) const + { +- const ::Rich::Detector::Allen::PD* dePD = nullptr; +- if (smartID.pdIsSet()) { ++ ::Rich::Detector::Allen::PD result; ++ result.setIsNull(true); ++ ++ if (!smartID.pdIsSet()) return result; ++ + const auto localModNum = smartID.pdMod() - m_modNumOffset; +- if (localModNum < pdModules().size()) { +- const auto& mod = pdModules()[localModNum]; +- if (smartID.pdNumInMod() < mod.size()) { +- const auto& pd = mod[smartID.pdNumInMod()]; +- dePD = &pd; +- } +- } +- } +- return dePD; ++ ++ const bool mod_in_bounds = (localModNum < pdModules().size()); ++ const auto& mod = mod_in_bounds ? pdModules()[localModNum] : pdModules()[0]; // Fallback to first (dummy) module if OOB ++ ++ const bool pd_in_bounds = (smartID.pdNumInMod() < mod.size()); ++ result = pd_in_bounds ? mod[smartID.pdNumInMod()] : result; // Keep default if OOB ++ ++ return result; + } + + /// Compute the detection point for a given RichSmartID + __host__ __device__ inline auto detectionPoint(const ::Allen::RichSmartID id) const noexcept + { + const auto pd = dePD(id); +- return (pd ? pd->detectionPoint(id) : ::Allen::Point {0, 0, 0}); ++ return (!pd.getIsNull() ? pd.detectionPoint(id) : ::Allen::Point {0, 0, 0}); + } + + /// Access the global to local transform +diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh +index 81a7a32910..f4a1ad63c2 100644 +--- a/device/rich/decoding/include/RichPixels.cuh ++++ b/device/rich/decoding/include/RichPixels.cuh +@@ -80,6 +80,8 @@ namespace Allen { + + __host__ __device__ inline auto isNull() const { return m_isNull; } + ++ __host__ __device__ inline void setIsNull(bool isNull) { m_isNull = isNull; } ++ + std::string toString() + { + std::stringstream ss; +diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh +index 11e08b019c..c0130c5461 100644 +--- a/device/rich/decoding/include/RichSmartIDHelper.cuh ++++ b/device/rich/decoding/include/RichSmartIDHelper.cuh +@@ -19,6 +19,9 @@ + namespace Allen { + class RichSmartIDHelper { + public: ++ ++ __host__ __device__ RichSmartIDHelper() = default; ++ + /// Constructor from RICH detector elements + __host__ __device__ RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : + m_pdPanels {&pdPanel1, &pdPanel2} +@@ -34,25 +37,28 @@ namespace Allen { + using Side = Rich::Future::DAQ::Side; + + // Determine the rich type +- DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; ++ //DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; + // Determine the side +- Side side; +- if (rich == DetectorType::Rich1) { ++ Side side = (Side) smartID.panel(); ++ ++ /*if (rich == DetectorType::Rich1) { + // For Rich1, 0 = top, 1 = bottom + side = (smartID.panel() == 0) ? Side::top : Side::bottom; + } + else { + // For Rich2, 0 = left, 1 = right + side = (smartID.panel() == 0) ? Side::left : Side::right; +- } ++ }*/ ++ //side = (Side) smartID.panel(); + +- for (size_t i = 0; i < m_pdPanels.size(); i++) { ++ /*for (size_t i = 0; i < m_pdPanels.size(); i++) { + const Rich::Detector::Allen::PDPanel* pdPanel = m_pdPanels[i]; + if (pdPanel->rich() == rich && pdPanel->side() == side) { + return pdPanel; + } +- } +- return nullptr; ++ }*/ ++ return m_pdPanels[side]; ++ // return nullptr; + } + + __host__ __device__ inline auto panel( +diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu +index f9d3612927..9bd4fac88a 100644 +--- a/device/rich/decoding/src/RichMakePixels.cu ++++ b/device/rich/decoding/src/RichMakePixels.cu +@@ -28,10 +28,17 @@ __device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsH + const auto rich = (Rich::Future::DAQ::DetectorType) smartID.rich(); + const auto side = (Rich::Future::DAQ::Side) smartID.panel(); + ++ Rich::Detector::Allen::PD pixelPD; ++ + // Functor to save a Rich pixel + auto savePix = [&]() { + const auto gPos = smartIDsHelper._globalPosition(smartID); + const auto lPos = smartIDsHelper.globalToPDPanel(gPos); ++ ++ // const auto gPos = ::Allen::Point{0,0,0}; ++ // const auto lPos = ::Allen::Point{0,0,0}; ++ ++ + const auto isInner = + (Allen::m_overrideRegions[rich] ? + (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : +@@ -48,6 +55,7 @@ __device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsH + if (Allen::m_overrideRegions[rich]) { + pixel.overrideRegions(isInner); + } ++ pixel.setIsNull(pixelPD.getIsNull()); + return pixel; + }; + +@@ -63,13 +71,11 @@ __device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsH + + // if time checks pass, and a non-Null PD matches the SmartID, save the pix + if (smartIDSelected) { +- if ((smartIDsHelper.panel(smartID)->dePD(smartID))) { +- if (!(smartIDsHelper.panel(smartID)->dePD(smartID)->getIsNull())) { +- effArea = smartIDsHelper.panel(smartID)->dePD(smartID)->effectivePixelArea(); +- innerRegion = !smartID.isLargePMT(); +- return savePix(); +- } +- } ++ const Rich::Detector::Allen::PDPanel* panel = smartIDsHelper.panel(smartID); ++ pixelPD = panel->dePD(smartID); ++ effArea = pixelPD.effectivePixelArea(); ++ innerRegion = !smartID.isLargePMT(); ++ return savePix(); + } + return Allen::RichPixel(); + } +@@ -80,20 +86,29 @@ __global__ void rich_make_pixels_kernel( + Rich::Detector::Allen::Rich* rich) + { + +- // Send panels from RICH to SmartIDsHelper +- std::array panels; +- for (size_t i = 0; i < 2; i++) { +- panels[i] = &(rich->pdPanels()[i]); +- } +- + // Instantiate smartIDsHelper in host and copy to device +- Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); ++ __shared__ Allen::RichSmartIDHelper shared_smartIDsHelper; ++ if (threadIdx.x == 0) { ++ // Send panels from RICH to SmartIDsHelper ++ std::array panels; ++ for (size_t i = 0; i < 2; i++) { ++ panels[i] = &(rich->pdPanels()[i]); ++ } ++ new (&shared_smartIDsHelper) Allen::RichSmartIDHelper(panels); ++ } ++ __syncthreads(); + + const auto eventNumber = parameters.dev_event_list[blockIdx.x]; + auto eventSmartIDCount = + parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; +- for (unsigned smartID = threadIdx.x; smartID < eventSmartIDCount; smartID += blockDim.x) { +- parameters.dev_rich_pixels[smartID] = make_pixel(smartIDsHelper, parameters.dev_smart_ids[smartID]); ++ ++ // stride ++ int tid = blockIdx.x * blockDim.x + threadIdx.x; ++ int stride = blockDim.x * gridDim.x; ++ for (unsigned smartID = tid; smartID < eventSmartIDCount; smartID += stride) { ++ parameters.dev_rich_pixels[smartID] = make_pixel(shared_smartIDsHelper, parameters.dev_smart_ids[smartID]); ++ //parameters.dev_rich_pixels[smartID] = Allen::RichPixel(); ++ + } + } + +@@ -133,6 +148,7 @@ void rich_make_pixels::rich_make_pixels_t::operator()( + //Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDHelper), Allen::memcpyHostToDevice); + + // call global kernel +- global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( ++ global_function(rich_make_pixels_kernel)(dim3(size(arguments)), dim3(64), context)( ++ //global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( + arguments, rich); + } diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index 29f3226b962..3cab7f80870 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -52,27 +52,29 @@ namespace Rich::Detector::Allen { /// Access the PD panel side __host__ __device__ inline auto side() const noexcept { return m_side; } - __host__ __device__ auto dePD(const ::Allen::RichSmartID smartID) const + __host__ __device__ ::Rich::Detector::Allen::PD dePD(const ::Allen::RichSmartID smartID) const { - const ::Rich::Detector::Allen::PD* dePD = nullptr; - if (smartID.pdIsSet()) { + ::Rich::Detector::Allen::PD result; + result.setIsNull(true); + + if (!smartID.pdIsSet()) return result; + const auto localModNum = smartID.pdMod() - m_modNumOffset; - if (localModNum < pdModules().size()) { - const auto& mod = pdModules()[localModNum]; - if (smartID.pdNumInMod() < mod.size()) { - const auto& pd = mod[smartID.pdNumInMod()]; - dePD = &pd; - } - } - } - return dePD; + + const bool mod_in_bounds = (localModNum < pdModules().size()); + const auto& mod = mod_in_bounds ? pdModules()[localModNum] : pdModules()[0]; // Fallback to first (dummy) module if OOB + + const bool pd_in_bounds = (smartID.pdNumInMod() < mod.size()); + result = pd_in_bounds ? mod[smartID.pdNumInMod()] : result; // Keep default if OOB + + return result; } /// Compute the detection point for a given RichSmartID __host__ __device__ inline auto detectionPoint(const ::Allen::RichSmartID id) const noexcept { const auto pd = dePD(id); - return (pd ? pd->detectionPoint(id) : ::Allen::Point {0, 0, 0}); + return (!pd.getIsNull() ? pd.detectionPoint(id) : ::Allen::Point {0, 0, 0}); } /// Access the global to local transform diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index 81a7a32910b..f4a1ad63c20 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -80,6 +80,8 @@ namespace Allen { __host__ __device__ inline auto isNull() const { return m_isNull; } + __host__ __device__ inline void setIsNull(bool isNull) { m_isNull = isNull; } + std::string toString() { std::stringstream ss; diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 1dcdb0345b0..e3fb85d9b3d 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -19,6 +19,9 @@ namespace Allen { class RichSmartIDHelper { public: + + __host__ __device__ RichSmartIDHelper() = default; + /// Constructor from RICH detector elements __host__ __device__ RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : @@ -36,25 +39,28 @@ namespace Allen { using Side = Rich::Future::DAQ::Side; // Determine the rich type - DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; + //DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; // Determine the side - Side side; - if (rich == DetectorType::Rich1) { + Side side = (Side) smartID.panel(); + + /*if (rich == DetectorType::Rich1) { // For Rich1, 0 = top, 1 = bottom side = (smartID.panel() == 0) ? Side::top : Side::bottom; } else { // For Rich2, 0 = left, 1 = right side = (smartID.panel() == 0) ? Side::left : Side::right; - } + }*/ + //side = (Side) smartID.panel(); - for (size_t i = 0; i < m_pdPanels.size(); i++) { + /*for (size_t i = 0; i < m_pdPanels.size(); i++) { const Rich::Detector::Allen::PDPanel* pdPanel = m_pdPanels[i]; if (pdPanel->rich() == rich && pdPanel->side() == side) { return pdPanel; } - } - return nullptr; + }*/ + return m_pdPanels[side]; + // return nullptr; } __host__ __device__ inline auto panel( diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index 12deb7b8610..9277e4cb89b 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -177,12 +177,7 @@ __global__ void rich_calculate_number_of_hits( parameters.dev_rich_raw_input_sizes, parameters.dev_rich_raw_input_types, event_number + event_start}; - - // Setup coalesced stride - int tid = blockIdx.x * blockDim.x + threadIdx.x; - int stride = blockDim.x * gridDim.x; - - for (unsigned bank_number = tid; bank_number < raw_event.number_of_raw_banks; bank_number += stride) { + for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { const auto bank = raw_event.raw_bank(bank_number); const auto number_of_hits_in_raw_bank = rich_calculate_number_of_hits_in_raw_bank(bank, cable_mapping, pdmdb_mapping); @@ -409,12 +404,7 @@ __global__ void rich_decoding_kernel( parameters.dev_rich_raw_input_sizes, parameters.dev_rich_raw_input_types, event_number + event_start}; - - // Setup coalesced stride - int tid = blockIdx.x * blockDim.x + threadIdx.x; - int stride = blockDim.x * gridDim.x; - - for (unsigned bank_number = tid; bank_number < raw_event.number_of_raw_banks; bank_number += stride) { +for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { const auto bank = raw_event.raw_bank(bank_number); rich_decode_bank(bank, cable_mapping, pdmdb_mapping, event_inserted_hits, event_smart_ids); } diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index 3d1ceeb2a34..b876d58bc34 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -30,10 +30,17 @@ __device__ Allen::RichPixel make_pixel( const auto rich = (Rich::Future::DAQ::DetectorType) smartID.rich(); const auto side = (Rich::Future::DAQ::Side) smartID.panel(); + Rich::Detector::Allen::PD pixelPD; + // Functor to save a Rich pixel auto savePix = [&]() { const auto gPos = smartIDsHelper._globalPosition(smartID); const auto lPos = smartIDsHelper.globalToPDPanel(gPos); + + // const auto gPos = ::Allen::Point{0,0,0}; + // const auto lPos = ::Allen::Point{0,0,0}; + + const auto isInner = (Allen::m_overrideRegions[rich] ? (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : @@ -50,6 +57,7 @@ __device__ Allen::RichPixel make_pixel( if (Allen::m_overrideRegions[rich]) { pixel.overrideRegions(isInner); } + pixel.setIsNull(pixelPD.getIsNull()); return pixel; }; @@ -65,13 +73,11 @@ __device__ Allen::RichPixel make_pixel( // if time checks pass, and a non-Null PD matches the SmartID, save the pix if (smartIDSelected) { - if ((smartIDsHelper.panel(smartID)->dePD(smartID))) { - if (!(smartIDsHelper.panel(smartID)->dePD(smartID)->getIsNull())) { - effArea = smartIDsHelper.panel(smartID)->dePD(smartID)->effectivePixelArea(); - innerRegion = !smartID.isLargePMT(); - return savePix(); - } - } + const Rich::Detector::Allen::PDPanel* panel = smartIDsHelper.panel(smartID); + pixelPD = panel->dePD(smartID); + effArea = pixelPD.effectivePixelArea(); + innerRegion = !smartID.isLargePMT(); + return savePix(); } return Allen::RichPixel(); } @@ -80,25 +86,30 @@ __device__ Allen::RichPixel make_pixel( __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Rich::Detector::Allen::Rich* rich) { - // Send panels from RICH to SmartIDsHelper - std::array panels; - for (size_t i = 0; i < 2; i++) { - panels[i] = &(rich->pdPanels()[i]); - } - // Instantiate smartIDsHelper in host and copy to device - Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); - - const auto eventNumber = parameters.dev_event_list[blockIdx.x]; - auto eventSmartIDCount = - parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; + __shared__ Allen::RichSmartIDHelper shared_smartIDsHelper; + if (threadIdx.x == 0) { + // Send panels from RICH to SmartIDsHelper + std::array panels; + for (size_t i = 0; i < 2; i++) { + panels[i] = &(rich->pdPanels()[i]); + } + new (&shared_smartIDsHelper) Allen::RichSmartIDHelper(panels); + } + __syncthreads(); - // Define coalesced stride - int tid = blockIdx.x * blockDim.x + threadIdx.x; + int tid = blockIdx.x * blockDim.x + threadIdx.x; int stride = blockDim.x * gridDim.x; - - for (unsigned smartID = tid; smartID < eventSmartIDCount; smartID += stride) { - parameters.dev_rich_pixels[smartID] = make_pixel(smartIDsHelper, parameters.dev_smart_ids[smartID]); + +for (int event = 0; event < parameters.dev_event_list.size(); ++event) { + uint start = parameters.dev_rich_hit_offsets[event]; + uint end = parameters.dev_rich_hit_offsets[event + 1]; + + for (uint i = start + tid; i < end; i += stride) { + if (i < parameters.dev_rich_pixels.size() && i < parameters.dev_smart_ids.size()) { + parameters.dev_rich_pixels[i] = make_pixel(shared_smartIDsHelper, parameters.dev_smart_ids[i]); + } + } } } @@ -139,5 +150,15 @@ void rich_make_pixels::rich_make_pixels_t::operator()( // call global kernel global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( + //global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( arguments, rich); +//std::cout << "pix size " << size(arguments) << '\n'; +/* for (int smartID = 0; smartID < size(arguments); smartID++){ + Allen::RichPixel* pixel = new Allen::RichPixel(); + Allen::memcpy(pixel, &(data(arguments))[smartID], sizeof(Allen::RichPixel), Allen::memcpyDeviceToHost); + std::cout << pixel->toString(); +}*/ + + + } -- GitLab From 00237f85e4e12400f64cbd22d8c45a48bb69ef44 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Sat, 10 May 2025 07:06:11 +0200 Subject: [PATCH 32/92] grid-stride is back! triple checked everything. iterating over smartIDs rather than events --- device/rich/decoding/src/RichMakePixels.cu | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index b876d58bc34..d86ce582c90 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -100,17 +100,17 @@ __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, int tid = blockIdx.x * blockDim.x + threadIdx.x; int stride = blockDim.x * gridDim.x; + +//for (int event = 0; event < parameters.dev_event_list.size(); ++event) { + //uint start = parameters.dev_rich_hit_offsets[event]; + //uint end = parameters.dev_rich_hit_offsets[event + 1]; -for (int event = 0; event < parameters.dev_event_list.size(); ++event) { - uint start = parameters.dev_rich_hit_offsets[event]; - uint end = parameters.dev_rich_hit_offsets[event + 1]; - - for (uint i = start + tid; i < end; i += stride) { + for (uint i = tid; i < parameters.dev_rich_hit_offsets[parameters.dev_event_list.size()]; i += stride) { if (i < parameters.dev_rich_pixels.size() && i < parameters.dev_smart_ids.size()) { parameters.dev_rich_pixels[i] = make_pixel(shared_smartIDsHelper, parameters.dev_smart_ids[i]); } } - } + //} } /// Function to resize Allen sequence output data structure @@ -153,11 +153,11 @@ void rich_make_pixels::rich_make_pixels_t::operator()( //global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( arguments, rich); //std::cout << "pix size " << size(arguments) << '\n'; -/* for (int smartID = 0; smartID < size(arguments); smartID++){ + for (int smartID = 0; smartID < size(arguments); smartID++){ Allen::RichPixel* pixel = new Allen::RichPixel(); Allen::memcpy(pixel, &(data(arguments))[smartID], sizeof(Allen::RichPixel), Allen::memcpyDeviceToHost); std::cout << pixel->toString(); -}*/ +} -- GitLab From 2615de12396811e84cab3059f2ce3d0d9a7977d7 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Sat, 10 May 2025 05:06:44 +0000 Subject: [PATCH 33/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/55635005 --- device/rich/decoding/include/RichPDPanel.cuh | 19 +++++---- .../decoding/include/RichSmartIDHelper.cuh | 7 ++-- device/rich/decoding/src/RichDecoding.cu | 4 +- device/rich/decoding/src/RichMakePixels.cu | 42 +++++++++---------- 4 files changed, 35 insertions(+), 37 deletions(-) diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index 3cab7f80870..a2ff84ae9ea 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -54,20 +54,21 @@ namespace Rich::Detector::Allen { __host__ __device__ ::Rich::Detector::Allen::PD dePD(const ::Allen::RichSmartID smartID) const { - ::Rich::Detector::Allen::PD result; - result.setIsNull(true); + ::Rich::Detector::Allen::PD result; + result.setIsNull(true); - if (!smartID.pdIsSet()) return result; + if (!smartID.pdIsSet()) return result; - const auto localModNum = smartID.pdMod() - m_modNumOffset; + const auto localModNum = smartID.pdMod() - m_modNumOffset; - const bool mod_in_bounds = (localModNum < pdModules().size()); - const auto& mod = mod_in_bounds ? pdModules()[localModNum] : pdModules()[0]; // Fallback to first (dummy) module if OOB + const bool mod_in_bounds = (localModNum < pdModules().size()); + const auto& mod = + mod_in_bounds ? pdModules()[localModNum] : pdModules()[0]; // Fallback to first (dummy) module if OOB - const bool pd_in_bounds = (smartID.pdNumInMod() < mod.size()); - result = pd_in_bounds ? mod[smartID.pdNumInMod()] : result; // Keep default if OOB + const bool pd_in_bounds = (smartID.pdNumInMod() < mod.size()); + result = pd_in_bounds ? mod[smartID.pdNumInMod()] : result; // Keep default if OOB - return result; + return result; } /// Compute the detection point for a given RichSmartID diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index e3fb85d9b3d..961d319753a 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -19,8 +19,7 @@ namespace Allen { class RichSmartIDHelper { public: - - __host__ __device__ RichSmartIDHelper() = default; + __host__ __device__ RichSmartIDHelper() = default; /// Constructor from RICH detector elements __host__ __device__ @@ -39,7 +38,7 @@ namespace Allen { using Side = Rich::Future::DAQ::Side; // Determine the rich type - //DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; + // DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; // Determine the side Side side = (Side) smartID.panel(); @@ -51,7 +50,7 @@ namespace Allen { // For Rich2, 0 = left, 1 = right side = (smartID.panel() == 0) ? Side::left : Side::right; }*/ - //side = (Side) smartID.panel(); + // side = (Side) smartID.panel(); /*for (size_t i = 0; i < m_pdPanels.size(); i++) { const Rich::Detector::Allen::PDPanel* pdPanel = m_pdPanels[i]; diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index 9277e4cb89b..d154740dde2 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -177,7 +177,7 @@ __global__ void rich_calculate_number_of_hits( parameters.dev_rich_raw_input_sizes, parameters.dev_rich_raw_input_types, event_number + event_start}; - for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { + for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { const auto bank = raw_event.raw_bank(bank_number); const auto number_of_hits_in_raw_bank = rich_calculate_number_of_hits_in_raw_bank(bank, cable_mapping, pdmdb_mapping); @@ -404,7 +404,7 @@ __global__ void rich_decoding_kernel( parameters.dev_rich_raw_input_sizes, parameters.dev_rich_raw_input_types, event_number + event_start}; -for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { + for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { const auto bank = raw_event.raw_bank(bank_number); rich_decode_bank(bank, cable_mapping, pdmdb_mapping, event_inserted_hits, event_smart_ids); } diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index d86ce582c90..efbe670a892 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -36,11 +36,10 @@ __device__ Allen::RichPixel make_pixel( auto savePix = [&]() { const auto gPos = smartIDsHelper._globalPosition(smartID); const auto lPos = smartIDsHelper.globalToPDPanel(gPos); - - // const auto gPos = ::Allen::Point{0,0,0}; + + // const auto gPos = ::Allen::Point{0,0,0}; // const auto lPos = ::Allen::Point{0,0,0}; - - + const auto isInner = (Allen::m_overrideRegions[rich] ? (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : @@ -98,18 +97,18 @@ __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, } __syncthreads(); - int tid = blockIdx.x * blockDim.x + threadIdx.x; + int tid = blockIdx.x * blockDim.x + threadIdx.x; int stride = blockDim.x * gridDim.x; -//for (int event = 0; event < parameters.dev_event_list.size(); ++event) { - //uint start = parameters.dev_rich_hit_offsets[event]; - //uint end = parameters.dev_rich_hit_offsets[event + 1]; - - for (uint i = tid; i < parameters.dev_rich_hit_offsets[parameters.dev_event_list.size()]; i += stride) { - if (i < parameters.dev_rich_pixels.size() && i < parameters.dev_smart_ids.size()) { + // for (int event = 0; event < parameters.dev_event_list.size(); ++event) { + // uint start = parameters.dev_rich_hit_offsets[event]; + // uint end = parameters.dev_rich_hit_offsets[event + 1]; + + for (uint i = tid; i < parameters.dev_rich_hit_offsets[parameters.dev_event_list.size()]; i += stride) { + if (i < parameters.dev_rich_pixels.size() && i < parameters.dev_smart_ids.size()) { parameters.dev_rich_pixels[i] = make_pixel(shared_smartIDsHelper, parameters.dev_smart_ids[i]); - } } + } //} } @@ -150,15 +149,14 @@ void rich_make_pixels::rich_make_pixels_t::operator()( // call global kernel global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - //global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - arguments, rich); -//std::cout << "pix size " << size(arguments) << '\n'; - for (int smartID = 0; smartID < size(arguments); smartID++){ + // global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( + arguments, + rich); + // std::cout << "pix size " << size(arguments) << '\n'; + for (int smartID = 0; smartID < size(arguments); smartID++) { Allen::RichPixel* pixel = new Allen::RichPixel(); - Allen::memcpy(pixel, &(data(arguments))[smartID], sizeof(Allen::RichPixel), Allen::memcpyDeviceToHost); - std::cout << pixel->toString(); -} - - - + Allen::memcpy( + pixel, &(data(arguments))[smartID], sizeof(Allen::RichPixel), Allen::memcpyDeviceToHost); + std::cout << pixel->toString(); + } } -- GitLab From 4b3b950e90417005ba769fd212f941a3a3c08bc0 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Mon, 12 May 2025 19:55:42 +0200 Subject: [PATCH 34/92] cleanup code --- .../decoding/include/RichSmartIDHelper.cuh | 24 +-------------- device/rich/decoding/src/RichMakePixels.cu | 29 ++----------------- 2 files changed, 4 insertions(+), 49 deletions(-) diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 961d319753a..10ecda269ef 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -34,32 +34,10 @@ namespace Allen { __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Rich::Detector::Allen::PDPanel* { - using DetectorType = Rich::Future::DAQ::DetectorType; - using Side = Rich::Future::DAQ::Side; - - // Determine the rich type - // DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; + using Side = Rich::Future::DAQ::Side; // Determine the side Side side = (Side) smartID.panel(); - - /*if (rich == DetectorType::Rich1) { - // For Rich1, 0 = top, 1 = bottom - side = (smartID.panel() == 0) ? Side::top : Side::bottom; - } - else { - // For Rich2, 0 = left, 1 = right - side = (smartID.panel() == 0) ? Side::left : Side::right; - }*/ - // side = (Side) smartID.panel(); - - /*for (size_t i = 0; i < m_pdPanels.size(); i++) { - const Rich::Detector::Allen::PDPanel* pdPanel = m_pdPanels[i]; - if (pdPanel->rich() == rich && pdPanel->side() == side) { - return pdPanel; - } - }*/ return m_pdPanels[side]; - // return nullptr; } __host__ __device__ inline auto panel( diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index efbe670a892..aef4ad0f0c5 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -85,7 +85,8 @@ __device__ Allen::RichPixel make_pixel( __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Rich::Detector::Allen::Rich* rich) { - // Instantiate smartIDsHelper in host and copy to device + // Instantiate smartIDsHelper in host and copy to device. + // Any smartID from any event may use any smartIDsHelper from any block __shared__ Allen::RichSmartIDHelper shared_smartIDsHelper; if (threadIdx.x == 0) { // Send panels from RICH to SmartIDsHelper @@ -97,19 +98,15 @@ __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, } __syncthreads(); + // Any gpu thread may create any pixel from any smartID and place it in the correct index via the offsets int tid = blockIdx.x * blockDim.x + threadIdx.x; int stride = blockDim.x * gridDim.x; - // for (int event = 0; event < parameters.dev_event_list.size(); ++event) { - // uint start = parameters.dev_rich_hit_offsets[event]; - // uint end = parameters.dev_rich_hit_offsets[event + 1]; - for (uint i = tid; i < parameters.dev_rich_hit_offsets[parameters.dev_event_list.size()]; i += stride) { if (i < parameters.dev_rich_pixels.size() && i < parameters.dev_smart_ids.size()) { parameters.dev_rich_pixels[i] = make_pixel(shared_smartIDsHelper, parameters.dev_smart_ids[i]); } } - //} } /// Function to resize Allen sequence output data structure @@ -135,28 +132,8 @@ void rich_make_pixels::rich_make_pixels_t::operator()( else rich = reinterpret_cast(constants.dev_rich_2_geometry); - // Send panels from RICH to SmartIDsHelper - // std::array panels; - // for (size_t i = 0; i < 2; i++) { - /// panels[i] = &(rich->pdPanels()[i]); - //} - - // Instantiate smartIDsHelper in host and copy to device - // Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); - // Allen::RichSmartIDHelper* dev_smartIDsHelper = nullptr; - // Allen::malloc((void**) &dev_smartIDsHelper, sizeof(Allen::RichSmartIDHelper)); - // Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDHelper), Allen::memcpyHostToDevice); - // call global kernel global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - // global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( arguments, rich); - // std::cout << "pix size " << size(arguments) << '\n'; - for (int smartID = 0; smartID < size(arguments); smartID++) { - Allen::RichPixel* pixel = new Allen::RichPixel(); - Allen::memcpy( - pixel, &(data(arguments))[smartID], sizeof(Allen::RichPixel), Allen::memcpyDeviceToHost); - std::cout << pixel->toString(); - } } -- GitLab From 122676f7ba2abe5d7cfb04bdafd8513941a3a0a1 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Mon, 12 May 2025 17:56:20 +0000 Subject: [PATCH 35/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/55711106 --- device/rich/decoding/include/RichSmartIDHelper.cuh | 2 +- device/rich/decoding/src/RichMakePixels.cu | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 10ecda269ef..a6b4c918d01 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -34,7 +34,7 @@ namespace Allen { __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Rich::Detector::Allen::PDPanel* { - using Side = Rich::Future::DAQ::Side; + using Side = Rich::Future::DAQ::Side; // Determine the side Side side = (Side) smartID.panel(); return m_pdPanels[side]; diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index aef4ad0f0c5..b60e49d7201 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -85,7 +85,7 @@ __device__ Allen::RichPixel make_pixel( __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Rich::Detector::Allen::Rich* rich) { - // Instantiate smartIDsHelper in host and copy to device. + // Instantiate smartIDsHelper in host and copy to device. // Any smartID from any event may use any smartIDsHelper from any block __shared__ Allen::RichSmartIDHelper shared_smartIDsHelper; if (threadIdx.x == 0) { @@ -134,6 +134,5 @@ void rich_make_pixels::rich_make_pixels_t::operator()( // call global kernel global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - arguments, - rich); + arguments, rich); } -- GitLab From 5ba3f6bcd3eba93d6e9932fb1dcd2f8e49030a56 Mon Sep 17 00:00:00 2001 From: ipalmame Date: Fri, 16 May 2025 18:41:26 +0200 Subject: [PATCH 36/92] transfering to device only necessary data --- configuration/python/AllenConf/:wq | 73 +++++++++++++++++++ configuration/python/AllenSequences/rich.py | 14 ++-- .../rich/decoding/include/RichMakePixels.cuh | 2 +- device/rich/decoding/include/RichPixels.cuh | 4 +- device/rich/decoding/src/RichMakePixels.cu | 66 +++++++++++++---- 5 files changed, 135 insertions(+), 24 deletions(-) create mode 100644 configuration/python/AllenConf/:wq diff --git a/configuration/python/AllenConf/:wq b/configuration/python/AllenConf/:wq new file mode 100644 index 00000000000..0854239efc4 --- /dev/null +++ b/configuration/python/AllenConf/:wq @@ -0,0 +1,73 @@ +############################################################################### +# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the Apache License # +# version 2 (Apache-2.0), copied verbatim in the file "LICENSE". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from AllenCore.algorithms import (data_provider_t, rich_decoding_t, + rich_make_pixels_t) +from AllenConf.utils import initialize_number_of_events +from AllenCore.generator import make_algorithm + +RICH_1 = 1 +RICH_2 = 2 + +VALID_RICHS = [RICH_1, RICH_2] + + +def decode_rich(rich=RICH_1): + if rich not in VALID_RICHS: + raise ValueError(f"rich must be one of {VALID_RICHS}") + + number_of_events = initialize_number_of_events() + + rich_banks = make_algorithm( + data_provider_t, name=f"rich{rich}_banks", bank_type=f"Rich{rich}") + + rich_decoding = make_algorithm( + rich_decoding_t, + name=f"rich{rich}_decoding", + host_number_of_events_t=number_of_events["host_number_of_events"], + host_raw_bank_version_t=rich_banks.host_raw_bank_version_t, + dev_rich_raw_input_t=rich_banks.dev_raw_banks_t, + dev_rich_raw_input_offsets_t=rich_banks.dev_raw_offsets_t, + dev_rich_raw_input_sizes_t=rich_banks.dev_raw_sizes_t, + dev_rich_raw_input_types_t=rich_banks.dev_raw_types_t) + + return { + "dev_smart_ids": + rich_decoding.dev_smart_ids_t, + "dev_rich_hit_offsets": + rich_decoding.dev_rich_hit_offsets_t, + "host_rich_total_number_of_hits": + rich_decoding.host_rich_total_number_of_hits_t + } + + +def make_pixels(decoded_rich=None, rich=RICH_1): + if rich not in VALID_RICHS: + raise ValueError(f"rich must be one of {VALID_RICHS}") + + if decoded_rich is None: + decoded_rich = decode_rich(rich) + + number_of_hits = decoded_rich["host_rich_total_number_of_hits"] + smart_ids = decoded_rich["dev_smart_ids"] + hit_offsets = decoded_rich["dev_rich_hit_offsets"] + + """ + rich_pixels = make_algorithm( + rich_make_pixels_t, + name=f"rich{rich}_make_pixels", + host_rich_total_number_of_hits_t=number_of_hits, + dev_smart_ids_t=smart_ids, + dev_rich_hit_offsets_t=hit_offsets, + current_rich=rich) + + return {"dev_rich_pixels": rich_pixels.dev_rich_pixels_t} + """ + return {"dev_smart_ids": rich_pixels.dev_smart_ids_t} diff --git a/configuration/python/AllenSequences/rich.py b/configuration/python/AllenSequences/rich.py index 8c424ea7914..638ea281ca5 100644 --- a/configuration/python/AllenSequences/rich.py +++ b/configuration/python/AllenSequences/rich.py @@ -17,30 +17,30 @@ decoded_rich2 = decode_rich(rich=2) rich1_decoding = CompositeNode( "Rich1Decoding", [decoded_rich1["dev_smart_ids"].producer], - NodeLogic.NONLAZY_AND, - force_order=False) + NodeLogic.NONLAZY_OR, + force_order=True) rich2_decoding = CompositeNode( "Rich2Decoding", [decoded_rich2["dev_smart_ids"].producer], - NodeLogic.NONLAZY_AND, - force_order=False) + NodeLogic.NONLAZY_OR, + force_order=True) rich1_make_pixels = CompositeNode( "Rich1MakePixels", [make_pixels(decoded_rich1, rich=1)["dev_rich_pixels"].producer], - NodeLogic.NONLAZY_AND, + NodeLogic.NONLAZY_OR, force_order=True) rich2_make_pixels = CompositeNode( "Rich2MakePixels", [make_pixels(decoded_rich2, rich=2)["dev_rich_pixels"].producer], - NodeLogic.NONLAZY_AND, + NodeLogic.NONLAZY_OR, force_order=True) rich_node = CompositeNode( "RichNode", [rich1_decoding, rich1_make_pixels, rich2_decoding, rich2_make_pixels], - NodeLogic.NONLAZY_AND, + NodeLogic.NONLAZY_OR, force_order=True) generate(rich_node) diff --git a/device/rich/decoding/include/RichMakePixels.cuh b/device/rich/decoding/include/RichMakePixels.cuh index d67f0b517f9..86cd4ab74e2 100644 --- a/device/rich/decoding/include/RichMakePixels.cuh +++ b/device/rich/decoding/include/RichMakePixels.cuh @@ -34,7 +34,7 @@ namespace rich_make_pixels { const Allen::Context&) const; private: - Allen::Property m_block_dim {this, "block_dim", {64, 1, 1}, "block dimensions"}; + Allen::Property m_block_dim {this, "block_dim", {512, 1, 1}, "block dimensions"}; Allen::Property m_current_rich {this, "current_rich", 1, "current rich"}; }; } // namespace rich_make_pixels diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index f4a1ad63c20..aca2e5cc8d7 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -82,10 +82,10 @@ namespace Allen { __host__ __device__ inline void setIsNull(bool isNull) { m_isNull = isNull; } - std::string toString() + __host__ __device__ std::string toString() { std::stringstream ss; - if (m_smartID.key() == 0) return "SmartID key is 0"; + // if (m_smartID.key() == 0) return "SmartID key is 0\n"; ss << m_smartID.key() << ',' << gPos.x << ',' << gPos.y << ',' << gPos.z << ',' << lPos.x << ',' << lPos.y << ',' << lPos.z << ',' << m_effArea << ',' << (int) m_rich << ',' << (int) m_side << ',' << (int) m_mask << ',' << m_timeWindow << ',' << m_isInnerRegion << ',' << m_isNull << '\n'; diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index b60e49d7201..7eb4076b909 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -82,12 +82,12 @@ __device__ Allen::RichPixel make_pixel( } /// Kernel function to iterate over Events, SmartIDs, and create Pixels -__global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, Rich::Detector::Allen::Rich* rich) +__global__ void rich_make_pixels_kernel(const Allen::RichSmartID* ids, size_t idsSize, Allen::RichPixel* pixels, size_t pixelsSize, Rich::Detector::Allen::Rich* rich) { // Instantiate smartIDsHelper in host and copy to device. // Any smartID from any event may use any smartIDsHelper from any block - __shared__ Allen::RichSmartIDHelper shared_smartIDsHelper; + __shared__ Allen::RichSmartIDHelper shared_smartIDsHelper; if (threadIdx.x == 0) { // Send panels from RICH to SmartIDsHelper std::array panels; @@ -97,16 +97,29 @@ __global__ void rich_make_pixels_kernel(rich_make_pixels::Parameters parameters, new (&shared_smartIDsHelper) Allen::RichSmartIDHelper(panels); } __syncthreads(); - - // Any gpu thread may create any pixel from any smartID and place it in the correct index via the offsets - int tid = blockIdx.x * blockDim.x + threadIdx.x; - int stride = blockDim.x * gridDim.x; - - for (uint i = tid; i < parameters.dev_rich_hit_offsets[parameters.dev_event_list.size()]; i += stride) { - if (i < parameters.dev_rich_pixels.size() && i < parameters.dev_smart_ids.size()) { - parameters.dev_rich_pixels[i] = make_pixel(shared_smartIDsHelper, parameters.dev_smart_ids[i]); - } - } + int global_tid = blockIdx.x * blockDim.x + threadIdx.x; + + //printf("%d\n", global_tid); + // Bounds check: ensure thread processes a valid SmartID +// if (global_tid < idsSize && + // global_tid < pixelsSize) { + int stride = blockDim.x * gridDim.x; + for (int i = global_tid; i < pixelsSize; i += stride) { + pixels[i] = make_pixel(shared_smartIDsHelper, ids[i]); +} + // } + +//printf("%s\n", parameters.dev_rich_pixels[global_tid].toString()); +/* + auto pixel = Allen::RichPixel(); + pixel.setIsNull(false); + printf("%s\n", pixel.toString()); + + parameters.dev_rich_pixels[global_tid] = pixel; +*/ +// parameters.dev_rich_pixels[global_tid] = Allen::RichPixel(); + +// } } /// Function to resize Allen sequence output data structure @@ -132,7 +145,32 @@ void rich_make_pixels::rich_make_pixels_t::operator()( else rich = reinterpret_cast(constants.dev_rich_2_geometry); + + // __global__ void rich_make_pixels_kernel(Allen::RichSmartID* ids, size_t idsSize, Allen::RichPixel* pixels, size_t pixelsSize, Rich::Detector::Allen::Rich* rich) + // call global kernel - global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - arguments, rich); + global_function(rich_make_pixels_kernel)(dim3(ceil(static_cast(size(arguments)) / 64)), dim3(64), context)( + data(arguments), size(arguments), data(arguments), size(arguments), rich); +// Allen::synchronize(context); + +/*int sizePixels = size(arguments); + std::cout << "pixels size " << sizePixels << std::endl; + std::cout << "ids size " << size(arguments) << std::endl; + int nullPixels = 0;*/ + +/*for (int smartID = 0; smartID < size(arguments); smartID++) { + // Allen::RichPixel pixel = (data(arguments))[smartID]; + std::cout << (data(arguments))[smartID].toString(); + // else {nullPixels++;} + }*/ + +/* for (int smartID = 0; smartID < size(arguments); smartID++) { + Allen::RichPixel* pixel = new Allen::RichPixel(); + Allen::memcpy( + pixel, &(data(arguments))[smartID], sizeof(Allen::RichPixel), Allen::memcpyDeviceToHost); + if (!pixel->isNull()) {std::cout << pixel->toString();} + else {nullPixels++;} + } + std::cout << "null pixels " << nullPixels << "("<< (static_cast(nullPixels) / sizePixels * 100) << "%)" < Date: Thu, 15 May 2025 06:50:48 +0200 Subject: [PATCH 37/92] fix grid stride --- device/rich/decoding/src/RichMakePixels.cu | 132 +++++++-------------- 1 file changed, 42 insertions(+), 90 deletions(-) diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index 7eb4076b909..311746d4897 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -9,51 +9,46 @@ * or submit itself to any jurisdiction. * \*****************************************************************************/ +#include "RichDefinitions.cuh" +#include "Rich.cuh" #include -#include -#include -#include +#include #include #include INSTANTIATE_ALGORITHM(rich_make_pixels::rich_make_pixels_t); /// Create a Pixel object from a given SmartID -__device__ Allen::RichPixel make_pixel( - const Allen::RichSmartIDHelper& smartIDsHelper, - const Allen::RichSmartID& smartID) +__device__ Rich::PixelReco::Pixel make_pixel( + const Rich::PixelReco::SmartIDHelper& smartIDsHelper, + const Rich::Decoding::SmartID& smartID) { float effArea; // Effective area - uint8_t mask = 0; // Selection mask bool innerRegion = 1; // Inner/outer region - const auto rich = (Rich::Future::DAQ::DetectorType) smartID.rich(); - const auto side = (Rich::Future::DAQ::Side) smartID.panel(); + const auto rich = (Rich::Detector::Type) smartID.rich(); - Rich::Detector::Allen::PD pixelPD; + Rich::Detector::PhotonDetector pixelPD; // Functor to save a Rich pixel auto savePix = [&]() { - const auto gPos = smartIDsHelper._globalPosition(smartID); - const auto lPos = smartIDsHelper.globalToPDPanel(gPos); - - // const auto gPos = ::Allen::Point{0,0,0}; - // const auto lPos = ::Allen::Point{0,0,0}; + const auto gPos = smartIDsHelper.globalPosition(smartID); // From panel local coordinates to global coordinates. + const auto lPos = smartIDsHelper.localPosition(gPos); // From global coordinates to RICH detector local coordinates. const auto isInner = - (Allen::m_overrideRegions[rich] ? - (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : + (Rich::m_overrideRegions[rich] ? + (abs(lPos.x) < float(Rich::m_innerPixX[rich]) && abs(lPos.y) < float(Rich::m_innerPixY[rich])) : innerRegion); - Allen::RichPixel pixel; + Rich::PixelReco::Pixel pixel; // 4D specific properties float timeWindow = 999999; - if (Allen::m_enable4D[rich]) { - timeWindow = isInner ? float(Allen::m_innerTimeWindow[rich]) : float(Allen::m_outerTimeWindow[rich]); + if (Rich::m_enable4D[rich]) { + timeWindow = isInner ? float(Rich::m_innerTimeWindow[rich]) : float(Rich::m_outerTimeWindow[rich]); } - pixel = Allen::RichPixel(gPos, lPos, smartID, effArea, rich, side, mask, timeWindow); - if (Allen::m_overrideRegions[rich]) { + pixel = Rich::PixelReco::Pixel(gPos, lPos, smartID, effArea, timeWindow); + if (Rich::m_overrideRegions[rich]) { pixel.overrideRegions(isInner); } pixel.setIsNull(pixelPD.getIsNull()); @@ -61,10 +56,10 @@ __device__ Allen::RichPixel make_pixel( }; bool smartIDSelected = true; - if (Allen::m_enable4D[rich]) { + if (Rich::m_enable4D[rich]) { if (smartID.adcTimeIsSet()) { const auto hitT = smartID.time(); - if (fabs(hitT - Allen::m_avHitTime[rich]) > Allen::m_timeWindow[rich]) { + if (fabsf(hitT - Rich::m_avHitTime[rich]) > Rich::m_timeWindow[rich]) { smartIDSelected = false; } } @@ -72,54 +67,32 @@ __device__ Allen::RichPixel make_pixel( // if time checks pass, and a non-Null PD matches the SmartID, save the pix if (smartIDSelected) { - const Rich::Detector::Allen::PDPanel* panel = smartIDsHelper.panel(smartID); + const Rich::Detector::PDPanel* panel = smartIDsHelper.panel(smartID); pixelPD = panel->dePD(smartID); effArea = pixelPD.effectivePixelArea(); innerRegion = !smartID.isLargePMT(); return savePix(); } - return Allen::RichPixel(); + return Rich::PixelReco::Pixel(); } /// Kernel function to iterate over Events, SmartIDs, and create Pixels -__global__ void rich_make_pixels_kernel(const Allen::RichSmartID* ids, size_t idsSize, Allen::RichPixel* pixels, size_t pixelsSize, Rich::Detector::Allen::Rich* rich) +__global__ void rich_make_pixels_kernel( + const Rich::Decoding::SmartID* ids, + Rich::PixelReco::Pixel* pixels, + size_t pixelsSize, + Rich::RichDetector* rich) { - // Instantiate smartIDsHelper in host and copy to device. // Any smartID from any event may use any smartIDsHelper from any block - __shared__ Allen::RichSmartIDHelper shared_smartIDsHelper; - if (threadIdx.x == 0) { - // Send panels from RICH to SmartIDsHelper - std::array panels; - for (size_t i = 0; i < 2; i++) { - panels[i] = &(rich->pdPanels()[i]); - } - new (&shared_smartIDsHelper) Allen::RichSmartIDHelper(panels); + Rich::PixelReco::SmartIDHelper smartIDsHelper {rich->pdPanels()[0], rich->pdPanels()[1]}; + + // pixel rec loop, grid-stride loop + uint global_tid = blockIdx.x * blockDim.x + threadIdx.x; + uint stride = blockDim.x * gridDim.x; + for (uint i = global_tid; i < pixelsSize; i += stride) { + pixels[i] = make_pixel(smartIDsHelper, ids[i]); } - __syncthreads(); - int global_tid = blockIdx.x * blockDim.x + threadIdx.x; - - //printf("%d\n", global_tid); - // Bounds check: ensure thread processes a valid SmartID -// if (global_tid < idsSize && - // global_tid < pixelsSize) { - int stride = blockDim.x * gridDim.x; - for (int i = global_tid; i < pixelsSize; i += stride) { - pixels[i] = make_pixel(shared_smartIDsHelper, ids[i]); -} - // } - -//printf("%s\n", parameters.dev_rich_pixels[global_tid].toString()); -/* - auto pixel = Allen::RichPixel(); - pixel.setIsNull(false); - printf("%s\n", pixel.toString()); - - parameters.dev_rich_pixels[global_tid] = pixel; -*/ -// parameters.dev_rich_pixels[global_tid] = Allen::RichPixel(); - -// } } /// Function to resize Allen sequence output data structure @@ -137,40 +110,19 @@ void rich_make_pixels::rich_make_pixels_t::operator()( const Constants& constants, const Allen::Context& context) const { + // Create RICH object from dump - Rich::Detector::Allen::Rich* rich = nullptr; + Rich::RichDetector* rich = nullptr; const auto richValue = m_current_rich; if (richValue == 1) - rich = reinterpret_cast(constants.dev_rich_1_geometry); + rich = constants.dev_rich_1_geometry; else - rich = reinterpret_cast(constants.dev_rich_2_geometry); - - - // __global__ void rich_make_pixels_kernel(Allen::RichSmartID* ids, size_t idsSize, Allen::RichPixel* pixels, size_t pixelsSize, Rich::Detector::Allen::Rich* rich) + rich = constants.dev_rich_2_geometry; // call global kernel - global_function(rich_make_pixels_kernel)(dim3(ceil(static_cast(size(arguments)) / 64)), dim3(64), context)( - data(arguments), size(arguments), data(arguments), size(arguments), rich); -// Allen::synchronize(context); - -/*int sizePixels = size(arguments); - std::cout << "pixels size " << sizePixels << std::endl; - std::cout << "ids size " << size(arguments) << std::endl; - int nullPixels = 0;*/ - -/*for (int smartID = 0; smartID < size(arguments); smartID++) { - // Allen::RichPixel pixel = (data(arguments))[smartID]; - std::cout << (data(arguments))[smartID].toString(); - // else {nullPixels++;} - }*/ - -/* for (int smartID = 0; smartID < size(arguments); smartID++) { - Allen::RichPixel* pixel = new Allen::RichPixel(); - Allen::memcpy( - pixel, &(data(arguments))[smartID], sizeof(Allen::RichPixel), Allen::memcpyDeviceToHost); - if (!pixel->isNull()) {std::cout << pixel->toString();} - else {nullPixels++;} - } - std::cout << "null pixels " << nullPixels << "("<< (static_cast(nullPixels) / sizePixels * 100) << "%)" <(size(arguments)) / block_dim.x)), m_block_dim, context)( + data(arguments), data(arguments), size(arguments), rich); } + -- GitLab From f51bf7a61fbc674dd3bcd72868d28892a5abd157 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Mon, 19 May 2025 19:23:22 +0200 Subject: [PATCH 38/92] code cleanup --- device/rich/decoding/include/RichPixels.cuh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh index aca2e5cc8d7..f48b412ebcb 100644 --- a/device/rich/decoding/include/RichPixels.cuh +++ b/device/rich/decoding/include/RichPixels.cuh @@ -82,7 +82,7 @@ namespace Allen { __host__ __device__ inline void setIsNull(bool isNull) { m_isNull = isNull; } - __host__ __device__ std::string toString() + __host__ std::string toString() { std::stringstream ss; // if (m_smartID.key() == 0) return "SmartID key is 0\n"; -- GitLab From fff00ecd0e1076a8153165d35eeb9e4520a002cb Mon Sep 17 00:00:00 2001 From: ipalmame Date: Wed, 28 May 2025 21:48:10 +0200 Subject: [PATCH 39/92] Addressing code review comments --- Rec/Allen/src/CompareRecAllenRichPixels.cpp | 22 +- Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp | 22 +- changes.txt | 207 ------------------ configuration/python/AllenConf/:wq | 73 ------ device/rich/decoding/include/Rich.cuh | 24 +- device/rich/decoding/include/RichDecoding.cuh | 4 +- .../rich/decoding/include/RichMakePixels.cuh | 10 +- .../include/RichPDMDBDecodeMapping.cuh | 4 +- device/rich/decoding/include/RichPDPanel.cuh | 38 ++-- .../{RichPD.cuh => RichPhotonDetector.cuh} | 60 ++--- device/rich/decoding/include/RichPixel.cuh | 98 +++++++++ device/rich/decoding/include/RichPixels.cuh | 107 --------- .../{RichSmartIDs.cuh => RichSmartID.cuh} | 21 +- .../decoding/include/RichSmartIDHelper.cuh | 46 ++-- .../include/RichTel40CableMapping.cuh | 6 +- device/rich/decoding/src/RichDecoding.cu | 78 +++---- device/rich/decoding/src/RichSmartIDHelper.cu | 27 ++- 17 files changed, 285 insertions(+), 562 deletions(-) delete mode 100644 changes.txt delete mode 100644 configuration/python/AllenConf/:wq rename device/rich/decoding/include/{RichPD.cuh => RichPhotonDetector.cuh} (62%) create mode 100644 device/rich/decoding/include/RichPixel.cuh delete mode 100644 device/rich/decoding/include/RichPixels.cuh rename device/rich/decoding/include/{RichSmartIDs.cuh => RichSmartID.cuh} (97%) diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index 8ac2e17e90f..2219ad5229f 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -10,13 +10,15 @@ // Allen #include "RichMakePixels.cuh" -#include "RichPixels.cuh" +#include "RichPixel.cuh" + +using AllenRichPixel = Rich::PixelReco::Pixel; // This test verifies that all valid HLT2 pixels exist in Allen, and all valid Allen pixels exist in HLT2 // Having the same number of m_allen_found_in_hlt2, and m_hlt2_found_in_allen means success. class CompareRecAllenRichPixels final : public Gaudi::Functional::Consumer&, - const std::vector&, + const std::vector&, + const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&)> { public: @@ -25,12 +27,12 @@ public: /// Algorithm execution void operator()( - const std::vector&, - const std::vector&, + const std::vector&, + const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&) const override; /// Compare the attributes of an Allen Pixel and a Rec Pixel - bool matchPixels(const Allen::RichPixel& allenPixel, const Rich::Future::Rec::SIMDPixel& recPixelSummary, size_t i) + bool matchPixels(const AllenRichPixel& allenPixel, const Rich::Future::Rec::SIMDPixel& recPixelSummary, size_t i) const { return ( @@ -71,18 +73,18 @@ CompareRecAllenRichPixels::CompareRecAllenRichPixels(const std::string& name, IS // When reading this code, keep in mind that recPixelSummaries contain multiple pixels, while allenRichPixels contain // individual pixels void CompareRecAllenRichPixels::operator()( - const std::vector& allenRich1Pixels, - const std::vector& allenRich2Pixels, + const std::vector& allenRich1Pixels, + const std::vector& allenRich2Pixels, const Rich::Future::Rec::SIMDPixelSummaries& recPixelSummaries) const { // Concatenate Allen Pixel vectors - std::vector allenPixels; + std::vector allenPixels; allenPixels.reserve(allenRich1Pixels.size() + allenRich2Pixels.size()); allenPixels.insert(allenPixels.end(), allenRich1Pixels.begin(), allenRich1Pixels.end()); allenPixels.insert(allenPixels.end(), allenRich2Pixels.begin(), allenRich2Pixels.end()); // functor to check if allen pixels exist in HLT2 - auto allenPixelExistsInRec = [&](const Allen::RichPixel& allenPixel) { + auto allenPixelExistsInRec = [&](const AllenRichPixel& allenPixel) { ++m_allen_reviewed; // Check if pixel is valid if (allenPixel.isNull()) { diff --git a/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp b/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp index 7d896d8cc67..a878cc6f03e 100644 --- a/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp +++ b/Rec/Allen/src/CompareRecAllenRichSmartIDs.cpp @@ -19,9 +19,11 @@ #include "RichDecoding.cuh" #include "RichPDMDBDecodeMapping.cuh" +using AllenRichSmartID = Rich::Decoding::SmartID; + class CompareRecAllenRichSmartIDs final : public Gaudi::Functional::Consumer&, - const std::vector&, + const std::vector&, + const std::vector&, const Rich::Future::DAQ::DecodedData&)> { public: @@ -30,8 +32,8 @@ public: /// Algorithm execution void operator()( - const std::vector&, - const std::vector&, + const std::vector&, + const std::vector&, const Rich::Future::DAQ::DecodedData&) const override; }; @@ -47,8 +49,8 @@ CompareRecAllenRichSmartIDs::CompareRecAllenRichSmartIDs(const std::string& name {} void CompareRecAllenRichSmartIDs::operator()( - const std::vector& allen_rich1_smart_ids, - const std::vector& allen_rich2_smart_ids, + const std::vector& allen_rich1_smart_ids, + const std::vector& allen_rich2_smart_ids, const Rich::Future::DAQ::DecodedData& rec_rich_pixels) const { auto allen_rich1_ids = allen_rich1_smart_ids; @@ -56,15 +58,15 @@ void CompareRecAllenRichSmartIDs::operator()( auto allen_rich2_ids = allen_rich2_smart_ids; std::sort(allen_rich2_ids.begin(), allen_rich2_ids.end(), [](auto a, auto b) { return a.key() < b.key(); }); - std::vector rec_rich1_ids; - std::vector rec_rich2_ids; + std::vector rec_rich1_ids; + std::vector rec_rich2_ids; auto r1i = Rich::Rich1, r2i = Rich::Rich2; for (auto& [rD, rec_ids] : std::array {std::tie(r1i, rec_rich1_ids), std::tie(r2i, rec_rich2_ids)}) { for (const auto& pD : rec_rich_pixels[rD]) { for (const auto& mD : pD) { for (const auto& pd : mD) { std::transform(pd.smartIDs().begin(), pd.smartIDs().end(), std::back_inserter(rec_ids), [](auto id) { - return Allen::RichSmartID {id.key()}; + return AllenRichSmartID {id.key()}; }); } } @@ -78,7 +80,7 @@ void CompareRecAllenRichSmartIDs::operator()( if (rec_ids.size() != allen_ids.size()) { error() << "Allen and Rec " << rich << " Smart ID containers are not the same size" << endmsg; } - std::vector only_allen, only_rec; + std::vector only_allen, only_rec; std::set_difference( allen_ids.begin(), allen_ids.end(), diff --git a/changes.txt b/changes.txt deleted file mode 100644 index 3ae827301b2..00000000000 --- a/changes.txt +++ /dev/null @@ -1,207 +0,0 @@ -diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh -index 29f3226b96..3cab7f8087 100644 ---- a/device/rich/decoding/include/RichPDPanel.cuh -+++ b/device/rich/decoding/include/RichPDPanel.cuh -@@ -52,27 +52,29 @@ namespace Rich::Detector::Allen { - /// Access the PD panel side - __host__ __device__ inline auto side() const noexcept { return m_side; } - -- __host__ __device__ auto dePD(const ::Allen::RichSmartID smartID) const -+ __host__ __device__ ::Rich::Detector::Allen::PD dePD(const ::Allen::RichSmartID smartID) const - { -- const ::Rich::Detector::Allen::PD* dePD = nullptr; -- if (smartID.pdIsSet()) { -+ ::Rich::Detector::Allen::PD result; -+ result.setIsNull(true); -+ -+ if (!smartID.pdIsSet()) return result; -+ - const auto localModNum = smartID.pdMod() - m_modNumOffset; -- if (localModNum < pdModules().size()) { -- const auto& mod = pdModules()[localModNum]; -- if (smartID.pdNumInMod() < mod.size()) { -- const auto& pd = mod[smartID.pdNumInMod()]; -- dePD = &pd; -- } -- } -- } -- return dePD; -+ -+ const bool mod_in_bounds = (localModNum < pdModules().size()); -+ const auto& mod = mod_in_bounds ? pdModules()[localModNum] : pdModules()[0]; // Fallback to first (dummy) module if OOB -+ -+ const bool pd_in_bounds = (smartID.pdNumInMod() < mod.size()); -+ result = pd_in_bounds ? mod[smartID.pdNumInMod()] : result; // Keep default if OOB -+ -+ return result; - } - - /// Compute the detection point for a given RichSmartID - __host__ __device__ inline auto detectionPoint(const ::Allen::RichSmartID id) const noexcept - { - const auto pd = dePD(id); -- return (pd ? pd->detectionPoint(id) : ::Allen::Point {0, 0, 0}); -+ return (!pd.getIsNull() ? pd.detectionPoint(id) : ::Allen::Point {0, 0, 0}); - } - - /// Access the global to local transform -diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh -index 81a7a32910..f4a1ad63c2 100644 ---- a/device/rich/decoding/include/RichPixels.cuh -+++ b/device/rich/decoding/include/RichPixels.cuh -@@ -80,6 +80,8 @@ namespace Allen { - - __host__ __device__ inline auto isNull() const { return m_isNull; } - -+ __host__ __device__ inline void setIsNull(bool isNull) { m_isNull = isNull; } -+ - std::string toString() - { - std::stringstream ss; -diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh -index 11e08b019c..c0130c5461 100644 ---- a/device/rich/decoding/include/RichSmartIDHelper.cuh -+++ b/device/rich/decoding/include/RichSmartIDHelper.cuh -@@ -19,6 +19,9 @@ - namespace Allen { - class RichSmartIDHelper { - public: -+ -+ __host__ __device__ RichSmartIDHelper() = default; -+ - /// Constructor from RICH detector elements - __host__ __device__ RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : - m_pdPanels {&pdPanel1, &pdPanel2} -@@ -34,25 +37,28 @@ namespace Allen { - using Side = Rich::Future::DAQ::Side; - - // Determine the rich type -- DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; -+ //DetectorType rich = (smartID.rich() == 0) ? DetectorType::Rich1 : DetectorType::Rich2; - // Determine the side -- Side side; -- if (rich == DetectorType::Rich1) { -+ Side side = (Side) smartID.panel(); -+ -+ /*if (rich == DetectorType::Rich1) { - // For Rich1, 0 = top, 1 = bottom - side = (smartID.panel() == 0) ? Side::top : Side::bottom; - } - else { - // For Rich2, 0 = left, 1 = right - side = (smartID.panel() == 0) ? Side::left : Side::right; -- } -+ }*/ -+ //side = (Side) smartID.panel(); - -- for (size_t i = 0; i < m_pdPanels.size(); i++) { -+ /*for (size_t i = 0; i < m_pdPanels.size(); i++) { - const Rich::Detector::Allen::PDPanel* pdPanel = m_pdPanels[i]; - if (pdPanel->rich() == rich && pdPanel->side() == side) { - return pdPanel; - } -- } -- return nullptr; -+ }*/ -+ return m_pdPanels[side]; -+ // return nullptr; - } - - __host__ __device__ inline auto panel( -diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu -index f9d3612927..9bd4fac88a 100644 ---- a/device/rich/decoding/src/RichMakePixels.cu -+++ b/device/rich/decoding/src/RichMakePixels.cu -@@ -28,10 +28,17 @@ __device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsH - const auto rich = (Rich::Future::DAQ::DetectorType) smartID.rich(); - const auto side = (Rich::Future::DAQ::Side) smartID.panel(); - -+ Rich::Detector::Allen::PD pixelPD; -+ - // Functor to save a Rich pixel - auto savePix = [&]() { - const auto gPos = smartIDsHelper._globalPosition(smartID); - const auto lPos = smartIDsHelper.globalToPDPanel(gPos); -+ -+ // const auto gPos = ::Allen::Point{0,0,0}; -+ // const auto lPos = ::Allen::Point{0,0,0}; -+ -+ - const auto isInner = - (Allen::m_overrideRegions[rich] ? - (abs(lPos.x) < float(Allen::m_innerPixX[rich]) && abs(lPos.y) < float(Allen::m_innerPixY[rich])) : -@@ -48,6 +55,7 @@ __device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsH - if (Allen::m_overrideRegions[rich]) { - pixel.overrideRegions(isInner); - } -+ pixel.setIsNull(pixelPD.getIsNull()); - return pixel; - }; - -@@ -63,13 +71,11 @@ __device__ Allen::RichPixel make_pixel(const Allen::RichSmartIDHelper& smartIDsH - - // if time checks pass, and a non-Null PD matches the SmartID, save the pix - if (smartIDSelected) { -- if ((smartIDsHelper.panel(smartID)->dePD(smartID))) { -- if (!(smartIDsHelper.panel(smartID)->dePD(smartID)->getIsNull())) { -- effArea = smartIDsHelper.panel(smartID)->dePD(smartID)->effectivePixelArea(); -- innerRegion = !smartID.isLargePMT(); -- return savePix(); -- } -- } -+ const Rich::Detector::Allen::PDPanel* panel = smartIDsHelper.panel(smartID); -+ pixelPD = panel->dePD(smartID); -+ effArea = pixelPD.effectivePixelArea(); -+ innerRegion = !smartID.isLargePMT(); -+ return savePix(); - } - return Allen::RichPixel(); - } -@@ -80,20 +86,29 @@ __global__ void rich_make_pixels_kernel( - Rich::Detector::Allen::Rich* rich) - { - -- // Send panels from RICH to SmartIDsHelper -- std::array panels; -- for (size_t i = 0; i < 2; i++) { -- panels[i] = &(rich->pdPanels()[i]); -- } -- - // Instantiate smartIDsHelper in host and copy to device -- Allen::RichSmartIDHelper smartIDsHelper = Allen::RichSmartIDHelper(panels); -+ __shared__ Allen::RichSmartIDHelper shared_smartIDsHelper; -+ if (threadIdx.x == 0) { -+ // Send panels from RICH to SmartIDsHelper -+ std::array panels; -+ for (size_t i = 0; i < 2; i++) { -+ panels[i] = &(rich->pdPanels()[i]); -+ } -+ new (&shared_smartIDsHelper) Allen::RichSmartIDHelper(panels); -+ } -+ __syncthreads(); - - const auto eventNumber = parameters.dev_event_list[blockIdx.x]; - auto eventSmartIDCount = - parameters.dev_rich_hit_offsets[eventNumber + 1] - parameters.dev_rich_hit_offsets[eventNumber]; -- for (unsigned smartID = threadIdx.x; smartID < eventSmartIDCount; smartID += blockDim.x) { -- parameters.dev_rich_pixels[smartID] = make_pixel(smartIDsHelper, parameters.dev_smart_ids[smartID]); -+ -+ // stride -+ int tid = blockIdx.x * blockDim.x + threadIdx.x; -+ int stride = blockDim.x * gridDim.x; -+ for (unsigned smartID = tid; smartID < eventSmartIDCount; smartID += stride) { -+ parameters.dev_rich_pixels[smartID] = make_pixel(shared_smartIDsHelper, parameters.dev_smart_ids[smartID]); -+ //parameters.dev_rich_pixels[smartID] = Allen::RichPixel(); -+ - } - } - -@@ -133,6 +148,7 @@ void rich_make_pixels::rich_make_pixels_t::operator()( - //Allen::memcpy(dev_smartIDsHelper, &smartIDsHelper, sizeof(Allen::RichSmartIDHelper), Allen::memcpyHostToDevice); - - // call global kernel -- global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( -+ global_function(rich_make_pixels_kernel)(dim3(size(arguments)), dim3(64), context)( -+ //global_function(rich_make_pixels_kernel)(dim3(size(arguments)), m_block_dim, context)( - arguments, rich); - } diff --git a/configuration/python/AllenConf/:wq b/configuration/python/AllenConf/:wq deleted file mode 100644 index 0854239efc4..00000000000 --- a/configuration/python/AllenConf/:wq +++ /dev/null @@ -1,73 +0,0 @@ -############################################################################### -# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the Apache License # -# version 2 (Apache-2.0), copied verbatim in the file "LICENSE". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -from AllenCore.algorithms import (data_provider_t, rich_decoding_t, - rich_make_pixels_t) -from AllenConf.utils import initialize_number_of_events -from AllenCore.generator import make_algorithm - -RICH_1 = 1 -RICH_2 = 2 - -VALID_RICHS = [RICH_1, RICH_2] - - -def decode_rich(rich=RICH_1): - if rich not in VALID_RICHS: - raise ValueError(f"rich must be one of {VALID_RICHS}") - - number_of_events = initialize_number_of_events() - - rich_banks = make_algorithm( - data_provider_t, name=f"rich{rich}_banks", bank_type=f"Rich{rich}") - - rich_decoding = make_algorithm( - rich_decoding_t, - name=f"rich{rich}_decoding", - host_number_of_events_t=number_of_events["host_number_of_events"], - host_raw_bank_version_t=rich_banks.host_raw_bank_version_t, - dev_rich_raw_input_t=rich_banks.dev_raw_banks_t, - dev_rich_raw_input_offsets_t=rich_banks.dev_raw_offsets_t, - dev_rich_raw_input_sizes_t=rich_banks.dev_raw_sizes_t, - dev_rich_raw_input_types_t=rich_banks.dev_raw_types_t) - - return { - "dev_smart_ids": - rich_decoding.dev_smart_ids_t, - "dev_rich_hit_offsets": - rich_decoding.dev_rich_hit_offsets_t, - "host_rich_total_number_of_hits": - rich_decoding.host_rich_total_number_of_hits_t - } - - -def make_pixels(decoded_rich=None, rich=RICH_1): - if rich not in VALID_RICHS: - raise ValueError(f"rich must be one of {VALID_RICHS}") - - if decoded_rich is None: - decoded_rich = decode_rich(rich) - - number_of_hits = decoded_rich["host_rich_total_number_of_hits"] - smart_ids = decoded_rich["dev_smart_ids"] - hit_offsets = decoded_rich["dev_rich_hit_offsets"] - - """ - rich_pixels = make_algorithm( - rich_make_pixels_t, - name=f"rich{rich}_make_pixels", - host_rich_total_number_of_hits_t=number_of_hits, - dev_smart_ids_t=smart_ids, - dev_rich_hit_offsets_t=hit_offsets, - current_rich=rich) - - return {"dev_rich_pixels": rich_pixels.dev_rich_pixels_t} - """ - return {"dev_smart_ids": rich_pixels.dev_smart_ids_t} diff --git a/device/rich/decoding/include/Rich.cuh b/device/rich/decoding/include/Rich.cuh index fc9fcbf86c8..7014b7074ef 100644 --- a/device/rich/decoding/include/Rich.cuh +++ b/device/rich/decoding/include/Rich.cuh @@ -12,31 +12,31 @@ #include #include -namespace Rich::Detector::Allen { - class Rich { + +namespace Rich { + class RichDetector final { public: - __host__ __device__ Rich(); + __host__ __device__ RichDetector() = default; - __host__ __device__ Rich( - const ::Rich::Future::DAQ::DetectorType m_type, - const std::array<::Rich::Detector::Allen::PDPanel, 2> m_panels) : + __host__ __device__ RichDetector( + const Detector::Type m_type, + const std::array m_panels) : m_panels(m_panels), m_type(m_type) {} __host__ __device__ inline auto rich() { return m_type; } - /// Access PD Panels __host__ __device__ inline auto& pdPanels() { return m_panels; } /// Access PD Panel for a given side - __host__ __device__ inline auto pdPanel(const ::Rich::Future::DAQ::Side panel) noexcept + __host__ __device__ inline auto pdPanel(const Detector::Side side) noexcept { - return &(pdPanels()[panel]); + return &(pdPanels()[side]); } private: - std::array m_panels {}; - ::Rich::Future::DAQ::DetectorType m_type {::Rich::Future::DAQ::DetectorType::Rich1}; + std::array m_panels {}; + Detector::Type m_type {Detector::Type::InvalidDetector}; }; -} // namespace Rich::Detector::Allen +} // namespace Rich::Detector diff --git a/device/rich/decoding/include/RichDecoding.cuh b/device/rich/decoding/include/RichDecoding.cuh index 9a677fe31fb..156fe8b57e7 100644 --- a/device/rich/decoding/include/RichDecoding.cuh +++ b/device/rich/decoding/include/RichDecoding.cuh @@ -11,7 +11,7 @@ #pragma once #include "AlgorithmTypes.cuh" -#include +#include namespace rich_decoding { struct Parameters { @@ -24,7 +24,7 @@ namespace rich_decoding { DEVICE_INPUT(dev_rich_raw_input_types_t, uint) dev_rich_raw_input_types; DEVICE_OUTPUT(dev_rich_hit_offsets_t, unsigned) dev_rich_hit_offsets; HOST_OUTPUT(host_rich_total_number_of_hits_t, unsigned) host_rich_total_number_of_hits; - DEVICE_OUTPUT(dev_smart_ids_t, Allen::RichSmartID) dev_smart_ids; + DEVICE_OUTPUT(dev_smart_ids_t, Rich::Decoding::SmartID) dev_smart_ids; }; struct rich_decoding_t : public DeviceAlgorithm, Parameters { diff --git a/device/rich/decoding/include/RichMakePixels.cuh b/device/rich/decoding/include/RichMakePixels.cuh index 86cd4ab74e2..773fac3fa93 100644 --- a/device/rich/decoding/include/RichMakePixels.cuh +++ b/device/rich/decoding/include/RichMakePixels.cuh @@ -11,17 +11,17 @@ #pragma once #include "AlgorithmTypes.cuh" -#include -#include +#include +#include namespace rich_make_pixels { struct Parameters { HOST_INPUT(host_rich_total_number_of_hits_t, unsigned) host_rich_total_number_of_hits; MASK_INPUT(dev_event_list_t) dev_event_list; - DEVICE_INPUT(dev_smart_ids_t, Allen::RichSmartID) dev_smart_ids; + DEVICE_INPUT(dev_smart_ids_t, Rich::Decoding::SmartID) dev_smart_ids; DEVICE_INPUT(dev_rich_hit_offsets_t, unsigned) dev_rich_hit_offsets; DEVICE_OUTPUT(dev_rich_hits_t, char) dev_rich_hits; - DEVICE_OUTPUT(dev_rich_pixels_t, Allen::RichPixel) dev_rich_pixels; + DEVICE_OUTPUT(dev_rich_pixels_t, Rich::PixelReco::Pixel) dev_rich_pixels; }; struct rich_make_pixels_t : public DeviceAlgorithm, Parameters { @@ -34,7 +34,7 @@ namespace rich_make_pixels { const Allen::Context&) const; private: - Allen::Property m_block_dim {this, "block_dim", {512, 1, 1}, "block dimensions"}; + Allen::Property m_block_dim {this, "block_dim", {64, 1, 1}, "block dimensions"}; Allen::Property m_current_rich {this, "current_rich", 1, "current rich"}; }; } // namespace rich_make_pixels diff --git a/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh b/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh index 79ca73274d7..67343cf799e 100644 --- a/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh +++ b/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh @@ -21,7 +21,7 @@ #include #include -namespace Rich::Future::DAQ::Allen { +namespace Rich::Decoding { /// Helper class for RICH PDMDB readout mapping class PDMDBDecodeMapping final { @@ -110,7 +110,7 @@ namespace Rich::Future::DAQ::Allen { /// Get PDMDB data for given Tel40 data __host__ __device__ inline const auto& getFrameData(const Tel40CableMapping::Tel40LinkData& cData) const { - const auto rich = cData.smartID.getData(::Allen::RichSmartID::ShiftRich, ::Allen::RichSmartID::MaskRich); + const auto rich = cData.smartID.getData(SmartID::ShiftRich, SmartID::MaskRich); return getFrameData(rich, cData.pdmdbNum, cData.linkNum, cData.isHType); } diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index a2ff84ae9ea..d465f429f9f 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -10,20 +10,20 @@ \*****************************************************************************/ #pragma once #include -#include +#include #include -namespace Rich::Detector::Allen { - class PDPanel final { +namespace Rich::Detector { + class PDPanel { public: PDPanel() {} - using PDsArray = std::array<::Rich::Detector::Allen::PD, ::Allen::RichSmartID::MaPMT::MaxPDsPerModule>; - using ModuleArray = std::array; + using PDArray = std::array; + using ModuleArray = std::array; PDPanel( - ::Rich::Future::DAQ::DetectorType rich, - ::Rich::Future::DAQ::Side side, + Type rich, + Side side, std::array gloToPDPanelM, ModuleArray PDs) : m_PDs(std::move(PDs)), @@ -36,10 +36,10 @@ namespace Rich::Detector::Allen { for (size_t i = 0; i < other.m_PDs.size(); ++i) { for (size_t j = 0; j < other.m_PDs[i].size(); ++j) { if (!(other.m_PDs[i][j].getIsNull())) { - m_PDs[i][j] = ::Rich::Detector::Allen::PD(other.m_PDs[i][j]); + m_PDs[i][j] = PhotonDetector(other.m_PDs[i][j]); } else { - m_PDs[i][j] = ::Rich::Detector::Allen::PD(); + m_PDs[i][j] = PhotonDetector(); m_PDs[i][j].setIsNull(true); } } @@ -52,9 +52,9 @@ namespace Rich::Detector::Allen { /// Access the PD panel side __host__ __device__ inline auto side() const noexcept { return m_side; } - __host__ __device__ ::Rich::Detector::Allen::PD dePD(const ::Allen::RichSmartID smartID) const + __host__ __device__ PhotonDetector dePD(const Decoding::SmartID smartID) const { - ::Rich::Detector::Allen::PD result; + PhotonDetector result; result.setIsNull(true); if (!smartID.pdIsSet()) return result; @@ -71,14 +71,14 @@ namespace Rich::Detector::Allen { return result; } - /// Compute the detection point for a given RichSmartID - __host__ __device__ inline auto detectionPoint(const ::Allen::RichSmartID id) const noexcept + /// Compute the global detection point for a given RichSmartID + __host__ __device__ inline auto globalDetectionPoint(const Decoding::SmartID id) const noexcept { const auto pd = dePD(id); - return (!pd.getIsNull() ? pd.detectionPoint(id) : ::Allen::Point {0, 0, 0}); + return (!pd.getIsNull() ? pd.globalDetectionPoint(id) : Point {0, 0, 0}); } - /// Access the global to local transform + /// Access the global to local transform __host__ __device__ inline const auto& globalToPDPanel() const noexcept { return m_gloToPDPanelM; } /// Access all owned PD Modules @@ -107,10 +107,10 @@ namespace Rich::Detector::Allen { ModuleArray m_PDs {}; std::array m_gloToPDPanelM {}; // 3D Transform uint32_t m_modNumOffset {0}; - std::array m_panelID {::Rich::Future::DAQ::DetectorType::InvalidDetector, - ::Rich::Future::DAQ::Side::InvalidSide, + std::array m_panelID {Type::InvalidDetector, + Side::InvalidSide, -1}; - ::Rich::Future::DAQ::DetectorType m_rich {::Rich::Future::DAQ::DetectorType::InvalidDetector}; - ::Rich::Future::DAQ::Side m_side {::Rich::Future::DAQ::Side::InvalidSide}; + Type m_rich {Type::InvalidDetector}; + Side m_side {Side::InvalidSide}; }; } // namespace Rich::Detector::Allen diff --git a/device/rich/decoding/include/RichPD.cuh b/device/rich/decoding/include/RichPhotonDetector.cuh similarity index 62% rename from device/rich/decoding/include/RichPD.cuh rename to device/rich/decoding/include/RichPhotonDetector.cuh index 24418b60092..48930132cd6 100644 --- a/device/rich/decoding/include/RichPD.cuh +++ b/device/rich/decoding/include/RichPhotonDetector.cuh @@ -12,49 +12,53 @@ #pragma once #include -#include +#include #include -namespace Rich::Detector::Allen { - class PD final { - using FP = ::Allen::FP; - using Point = ::Allen::Point; +namespace Rich::Detector { + class PhotonDetector { + //using FP = Rich::FP; + //using Point = Rich::Point; public: /// Default constructor - __host__ __device__ PD() = default; + __host__ __device__ PhotonDetector() = default; /// Copy assignment operator - __host__ __device__ PD& operator=(const PD&) = default; + __host__ __device__ PhotonDetector& operator=(const PhotonDetector&) = default; /// Copy Constructor - __host__ __device__ PD(const PD& pd) : + __host__ __device__ PhotonDetector(const PhotonDetector& pd) : m_locToGloM(pd.m_locToGloM), m_zeroInPanelFrame(pd.m_zeroInPanelFrame), m_pdSmartID(pd.m_pdSmartID), m_effPixelArea(pd.m_effPixelArea), m_numPixels(pd.m_numPixels), m_localZcoord(pd.m_localZcoord), - m_NumPixColFrac(pd.m_NumPixColFrac), m_NumPixRowFrac(pd.m_NumPixRowFrac), - m_EffectivePixelXSize(pd.m_EffectivePixelXSize), m_EffectivePixelYSize(pd.m_EffectivePixelYSize), + m_numPixColFrac(pd.m_numPixColFrac), m_numPixRowFrac(pd.m_numPixRowFrac), + m_effectivePixelXSize(pd.m_effectivePixelXSize), m_effectivePixelYSize(pd.m_effectivePixelYSize), m_isHType(pd.m_isHType), m_isNull(pd.m_isNull) {} __host__ __device__ inline auto pdSmartID() const { return m_pdSmartID; } - __host__ __device__ inline auto detectionPoint(const ::Allen::RichSmartID id) const noexcept + __host__ __device__ inline auto panelDetectionPoint(const Decoding::SmartID id) const noexcept { const auto fPixCol = id.pixelCol(); const auto fPixRow = id.pixelRow(); - const auto xh = (fPixCol - m_NumPixColFrac) * m_EffectivePixelXSize; - const auto yh = (fPixRow - m_NumPixRowFrac) * m_EffectivePixelYSize; - return ::Allen::transform3DTimesPoint(localToGlobal(), Point {xh, yh, m_localZcoord}); + const auto xh = (fPixCol - m_numPixColFrac) * m_effectivePixelXSize; + const auto yh = (fPixRow - m_numPixRowFrac) * m_effectivePixelYSize; + return Point {xh, yh, m_localZcoord}; } - __host__ __device__ inline float get_EffectivePixelXSize() const noexcept { return m_EffectivePixelXSize; } - __host__ __device__ inline float get_EffectivePixelYSize() const noexcept { return m_EffectivePixelYSize; } - __host__ __device__ inline float get_localZcoord() const noexcept { return m_localZcoord; } - __host__ __device__ inline float get_NumPixRowFrac() const { return m_NumPixRowFrac; } + __host__ __device__ inline auto globalDetectionPoint(const Decoding::SmartID id) const noexcept + { + return transform3DTimesPoint(localToGlobal(), panelDetectionPoint(id)); + } + + __host__ __device__ inline float getEffectivePixelXSize() const noexcept { return m_effectivePixelXSize; } + __host__ __device__ inline float getEffectivePixelYSize() const noexcept { return m_effectivePixelYSize; } + __host__ __device__ inline float getLocalZcoord() const noexcept { return m_localZcoord; } + __host__ __device__ inline float getNumPixRowFrac() const { return m_numPixRowFrac; } + __host__ __device__ inline float getNumPixColFrac() const noexcept { return m_numPixColFrac; } /// Effective pixel area __host__ __device__ inline auto effectivePixelArea() const noexcept { return m_effPixelArea; } - __host__ __device__ inline float get_NumPixColFrac() const noexcept { return m_NumPixColFrac; } - /// Access the local to global transform __host__ __device__ inline const std::array& localToGlobal() const noexcept { return m_locToGloM; } @@ -71,10 +75,10 @@ namespace Rich::Detector::Allen { << "effPixelArea: " << m_effPixelArea << ", " << "numPixels: " << m_numPixels << ", " << "localZcoord: " << m_localZcoord << ", " - << "NumPixColFrac: " << m_NumPixColFrac << ", " - << "NumPixRowFrac: " << m_NumPixRowFrac << ", " - << "EffectivePixelXSize: " << m_EffectivePixelXSize << ", " - << "EffectivePixelYSize: " << m_EffectivePixelYSize << ", " + << "NumPixColFrac: " << m_numPixColFrac << ", " + << "NumPixRowFrac: " << m_numPixRowFrac << ", " + << "EffectivePixelXSize: " << m_effectivePixelXSize << ", " + << "EffectivePixelYSize: " << m_effectivePixelYSize << ", " << "pdSmartID: " << m_pdSmartID << ", " << "isHType: " << (m_isHType ? "true" : "false") << "isNull: " << (m_isNull ? "true" : "false") << " }"; return oss.str(); @@ -91,10 +95,10 @@ namespace Rich::Detector::Allen { float m_effPixelArea {0.f}; float m_numPixels {0.f}; float m_localZcoord {0.f}; - float m_NumPixColFrac {0.f}; - float m_NumPixRowFrac {0.f}; - float m_EffectivePixelXSize {0.f}; - float m_EffectivePixelYSize {0.f}; + float m_numPixColFrac {0.f}; + float m_numPixRowFrac {0.f}; + float m_effectivePixelXSize {0.f}; + float m_effectivePixelYSize {0.f}; bool m_isHType {false}; bool m_isNull {false}; }; diff --git a/device/rich/decoding/include/RichPixel.cuh b/device/rich/decoding/include/RichPixel.cuh new file mode 100644 index 00000000000..e10a3258e7b --- /dev/null +++ b/device/rich/decoding/include/RichPixel.cuh @@ -0,0 +1,98 @@ +/*****************************************************************************\ + * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ +#pragma once +#include +#include + +namespace Rich::PixelReco { +class Pixel { +public: + // Default constructor + __host__ __device__ Pixel() + : gPos({0.0f, 0.0f, 0.0f}), + lPos({0.0f, 0.0f, 0.0f}), + m_smartID({}), + m_effArea(0.0f), + m_timeWindow(0.0f) + { + m_flags.setIsNull(true); + m_flags.setIsInnerRegion(true); + } + + // 3D + __host__ __device__ Pixel(const Point& g, const Point& l, const Decoding::SmartID& sid, float area) + : gPos(g), lPos(l), m_smartID(sid), m_effArea(area), m_timeWindow(0.0f) + { + m_flags.setIsNull(false); + m_flags.setIsInnerRegion(!sid.isLargePMT()); + } + + // 4D constructor + __host__ __device__ Pixel(const Point& g, const Point& l, const Decoding::SmartID& sid, float area, float time) + : gPos(g), lPos(l), m_smartID(sid), m_effArea(area), m_timeWindow(time) + { + m_flags.setIsNull(false); + m_flags.setIsInnerRegion(!sid.isLargePMT()); + } + + __host__ __device__ bool isNull() const { return m_flags.isNull(); } + __host__ __device__ bool isInnerRegion() const { return m_flags.isInnerRegion(); } + __host__ __device__ void setIsNull(bool v) { m_flags.setIsNull(v); } + __host__ __device__ void overrideRegions(bool inner) { m_flags.setIsInnerRegion(inner); } + + __host__ __device__ inline auto rich() const { return m_smartID.rich(); } + __host__ __device__ inline auto side() const { return m_smartID.side(); } + + __host__ __device__ auto smartID() const { return m_smartID; } + __host__ __device__ auto gloPos() const { return gPos; } + __host__ __device__ auto locPos() const { return lPos; } + __host__ __device__ auto effArea() const { return m_effArea; } + __host__ __device__ auto timeWindow() const { return m_timeWindow; } + + __host__ std::string toString() { + std::stringstream ss; + ss << m_smartID.key() << ',' << gPos.x << ',' << gPos.y << ',' << gPos.z << ',' << lPos.x << ',' << lPos.y << ',' + << lPos.z << ',' << m_effArea << ',' << (int)smartID().rich() << ',' << (int)smartID().side() << ',' + << m_timeWindow << ',' << isInnerRegion() << ',' << isNull() << '\n'; + return ss.str(); + } + +private: + Point gPos, lPos; + Decoding::SmartID m_smartID; + float m_effArea = 0.0f; + float m_timeWindow = 0.0f; + + struct Flags { + uint8_t value = 0; + static constexpr uint8_t IsInnerRegionMask = 1 << 0; + static constexpr uint8_t IsNullMask = 1 << 1; + + __host__ __device__ bool isInnerRegion() const { + return value & IsInnerRegionMask; + } + + __host__ __device__ bool isNull() const { + return value & IsNullMask; + } + + __host__ __device__ void setIsInnerRegion(bool v) { + if (v) value |= IsInnerRegionMask; + else value &= ~IsInnerRegionMask; + } + + __host__ __device__ void setIsNull(bool v) { + if (v) value |= IsNullMask; + else value &= ~IsNullMask; + } + } m_flags; +}; +} // namespace Rich::PixelReco diff --git a/device/rich/decoding/include/RichPixels.cuh b/device/rich/decoding/include/RichPixels.cuh deleted file mode 100644 index f48b412ebcb..00000000000 --- a/device/rich/decoding/include/RichPixels.cuh +++ /dev/null @@ -1,107 +0,0 @@ -/*****************************************************************************\ - * (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * - * * - * This software is distributed under the terms of the Apache License * - * version 2 (Apache-2.0), copied verbatim in the file "COPYING". * - * * - * In applying this licence, CERN does not waive the privileges and immunities * - * granted to it by virtue of its status as an Intergovernmental Organization * - * or submit itself to any jurisdiction. * - \*****************************************************************************/ -#pragma once -#include -#include - -namespace Allen { - class RichPixel { - - public: - // Default - __host__ __device__ RichPixel() : - gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID({}), m_effArea(0.0f), - m_rich(Rich::Future::DAQ::DetectorType::InvalidDetector), m_side(Rich::Future::DAQ::InvalidSide), m_mask(0), - m_timeWindow(0.0f), m_isInnerRegion(true), m_isNull(true) - {} - - // 3D - __host__ __device__ RichPixel( - const Point& gPos, - const Point& lPos, - const RichSmartID& smartID, - double effArea, - Rich::Future::DAQ::DetectorType rich, - Rich::Future::DAQ::Side side, - uint8_t mask) : - gPos(gPos), - lPos(lPos), m_smartID(smartID), m_effArea(effArea), m_rich(rich), m_side(side), m_mask(mask), m_isNull(false) - { - m_isInnerRegion = !smartID.isLargePMT(); - } - - // 4D - __host__ __device__ RichPixel( - const Point& gPos, - const Point& lPos, - const ::Allen::RichSmartID& smartID, - double effArea, - Rich::Future::DAQ::DetectorType rich, - Rich::Future::DAQ::Side side, - uint8_t mask, - float timeWindow) : - gPos(gPos), - lPos(lPos), m_smartID(smartID), m_effArea(effArea), m_rich(rich), m_side(side), m_mask(mask), - m_timeWindow(timeWindow), m_isNull(false) - { - m_isInnerRegion = !smartID.isLargePMT(); - } - - __host__ __device__ inline void overrideRegions(const bool isInnerRegion) noexcept - { - m_isInnerRegion = isInnerRegion; - } - - __host__ __device__ inline auto rich() const { return m_rich; } - - __host__ __device__ inline auto side() const { return m_side; } - - __host__ __device__ inline RichSmartID smartID() const { return m_smartID; } - - __host__ __device__ inline auto gloPos() const { return gPos; } - - __host__ __device__ inline auto locPos() const { return lPos; } - - __host__ __device__ inline auto effArea() const { return m_effArea; } - - __host__ __device__ inline auto mask() const { return m_mask; } - - __host__ __device__ inline auto timeWindow() const { return m_timeWindow; } - - __host__ __device__ inline auto isInnerRegion() const { return m_isInnerRegion; } - - __host__ __device__ inline auto isNull() const { return m_isNull; } - - __host__ __device__ inline void setIsNull(bool isNull) { m_isNull = isNull; } - - __host__ std::string toString() - { - std::stringstream ss; - // if (m_smartID.key() == 0) return "SmartID key is 0\n"; - ss << m_smartID.key() << ',' << gPos.x << ',' << gPos.y << ',' << gPos.z << ',' << lPos.x << ',' << lPos.y << ',' - << lPos.z << ',' << m_effArea << ',' << (int) m_rich << ',' << (int) m_side << ',' << (int) m_mask << ',' - << m_timeWindow << ',' << m_isInnerRegion << ',' << m_isNull << '\n'; - return ss.str(); - } - - private: - Point gPos {0.0f, 0.0f, 0.0f}; - Point lPos {0.0f, 0.0f, 0.0f}; - RichSmartID m_smartID = RichSmartID {}; - double m_effArea {0.0f}; - Rich::Future::DAQ::DetectorType m_rich {Rich::Future::DAQ::DetectorType::InvalidDetector}; - Rich::Future::DAQ::Side m_side {Rich::Future::DAQ::InvalidSide}; - uint8_t m_mask {0}; - float m_timeWindow {0.0f}; - bool m_isInnerRegion {true}; - bool m_isNull {true}; - }; -} // namespace Allen diff --git a/device/rich/decoding/include/RichSmartIDs.cuh b/device/rich/decoding/include/RichSmartID.cuh similarity index 97% rename from device/rich/decoding/include/RichSmartIDs.cuh rename to device/rich/decoding/include/RichSmartID.cuh index 3ae2c6335b0..dfc229a59e4 100644 --- a/device/rich/decoding/include/RichSmartIDs.cuh +++ b/device/rich/decoding/include/RichSmartID.cuh @@ -15,10 +15,8 @@ #include "BackendCommon.h" #include -namespace Allen { - - /// RICH SmartIDs class - class RichSmartID { +namespace Rich::Decoding { + class SmartID { KeyType m_key; public: @@ -34,9 +32,9 @@ namespace Allen { setData(col, ShiftPixelCol, MaskPixelCol, MaskPixelColIsSet); } - __host__ __device__ RichSmartID() = default; + __host__ __device__ SmartID() = default; - __host__ __device__ RichSmartID(KeyType key) : m_key(key) {} + __host__ __device__ SmartID(KeyType key) : m_key(key) {} // Number of bits for each data field in the word static constexpr const BitPackType BitsPixelCol = 3; //< Number of bits for MaPMT pixel column @@ -128,7 +126,7 @@ namespace Allen { __host__ __device__ constexpr inline BitPackType key() const noexcept { return m_key; } - __host__ __device__ constexpr inline bool operator==(const RichSmartID& other) const noexcept + __host__ __device__ constexpr inline bool operator==(const SmartID& other) const noexcept { return m_key == other.key(); } @@ -142,6 +140,9 @@ namespace Allen { __host__ __device__ constexpr inline auto panel() const noexcept { return getData(ShiftPanel, MaskPanel); } + __host__ __device__ constexpr inline auto side() const noexcept { return panel(); } + + __host__ __device__ constexpr inline DataType pdMod() const noexcept { return getData(ShiftPDMod, MaskPDMod); } __host__ __device__ constexpr inline DataType pdNumInMod() const noexcept @@ -217,7 +218,7 @@ namespace Allen { } // ostream operator - __host__ friend std::ostream& operator<<(std::ostream& str, const RichSmartID& id) + __host__ friend std::ostream& operator<<(std::ostream& str, const SmartID& id) { const auto rich = id.rich(); const auto panel = id.panel(); @@ -319,5 +320,5 @@ namespace Allen { static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; }; - }; // namespace RichSmartID -} // namespace Allen + }; // namespace SmartID +} // namespace RichDecoding diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index a6b4c918d01..2cec4707007 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -10,42 +10,41 @@ \*****************************************************************************/ #pragma once #include -#include +#include #include -#include +#include #define PANEL_COUNT 2 -namespace Allen { - class RichSmartIDHelper { +namespace Rich::PixelReco { + class SmartIDHelper { public: - __host__ __device__ RichSmartIDHelper() = default; + __host__ __device__ SmartIDHelper() = default; /// Constructor from RICH detector elements __host__ __device__ - RichSmartIDHelper(const Rich::Detector::Allen::PDPanel& pdPanel1, const Rich::Detector::Allen::PDPanel& pdPanel2) : + SmartIDHelper(const Detector::PDPanel& pdPanel1, const Detector::PDPanel& pdPanel2) : m_pdPanels {&pdPanel1, &pdPanel2} {} __host__ __device__ - RichSmartIDHelper(const std::array m_pdPanels) : + SmartIDHelper(const std::array m_pdPanels) : m_pdPanels {m_pdPanels} {} - __host__ __device__ inline auto panel(Allen::RichSmartID smartID) const -> const Rich::Detector::Allen::PDPanel* - { - using Side = Rich::Future::DAQ::Side; + __host__ __device__ inline auto panel(Decoding::SmartID smartID) const -> const Detector::PDPanel* + { // Determine the side - Side side = (Side) smartID.panel(); + Detector::Side side = (Detector::Side) smartID.panel(); return m_pdPanels[side]; } __host__ __device__ inline auto panel( - const Rich::Future::DAQ::DetectorType rtype, - const Rich::Future::DAQ::Side side) const -> const Rich::Detector::Allen::PDPanel* + const Detector::Type rtype, + const Detector::Side side) const -> const Detector::PDPanel* { for (size_t i = 0; i < m_pdPanels.size(); i++) { - const Rich::Detector::Allen::PDPanel* pdPanel = m_pdPanels[i]; + const Detector::PDPanel* pdPanel = m_pdPanels[i]; if (pdPanel->rich() == rtype && pdPanel->side() == side) { return pdPanel; } @@ -54,21 +53,26 @@ namespace Allen { } // Converts an PD RichSmartID identification into a position in global LHCb coordinates. - __host__ __device__ Point pdPosition(const Allen::RichSmartID pdid) const; + __host__ __device__ Point pdPosition(const Decoding::SmartID pdid) const; // Converts a position in global coordinates to the corresponding RichSmartID - __host__ __device__ bool smartID(const Point& globalPoint, Allen::RichSmartID& smartid) const; + __host__ __device__ bool smartID(const Point& globalPoint, Decoding::SmartID& smartid) const; // Converts a position in global coordinates to the local coordinate system. __host__ __device__ Point globalToPDPanel(const Point& globalPoint) const; - // Get the position for a given SmartID. - __host__ __device__ inline auto _globalPosition(const Allen::RichSmartID id) const + // Get the position for a given SmartID at the LHCb general level. + __host__ __device__ inline auto globalPosition(const Decoding::SmartID id) const + { + return panel(id)->globalDetectionPoint(id); + } + // Get the position for a given SmartID at the detector local coordinates. + __host__ __device__ inline auto localPosition(const Point globalPoint) const { - return panel(id)->detectionPoint(id); + return globalToPDPanel(globalPoint); } private: - const std::array m_pdPanels {}; + const std::array m_pdPanels {}; }; -} // namespace Allen +} // namespace PixelReco diff --git a/device/rich/decoding/include/RichTel40CableMapping.cuh b/device/rich/decoding/include/RichTel40CableMapping.cuh index 303d6051224..2dab4675cec 100644 --- a/device/rich/decoding/include/RichTel40CableMapping.cuh +++ b/device/rich/decoding/include/RichTel40CableMapping.cuh @@ -13,7 +13,7 @@ #include #include -namespace Rich::Future::DAQ::Allen { +namespace Rich::Decoding { /// Helper class for RICH PMT data format encoding class Tel40CableMapping final { @@ -22,7 +22,7 @@ namespace Rich::Future::DAQ::Allen { class Tel40LinkData final { public: /// RICH SmartID - ::Allen::RichSmartID smartID; + SmartID smartID; /// Module Number int32_t moduleNum; /// Source ID @@ -136,4 +136,4 @@ namespace Rich::Future::DAQ::Allen { int m_mappingVer {-1}; }; -} // namespace Rich::Future::DAQ::Allen \ No newline at end of file +} // namespace Rich::Future::DAQ::Allen diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index d154740dde2..62bc7f07e09 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -18,13 +18,13 @@ INSTANTIATE_ALGORITHM(rich_decoding::rich_decoding_t) __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const Allen::RawBank& bank, - const Rich::Future::DAQ::Allen::Tel40CableMapping* cable_mapping, - const Rich::Future::DAQ::Allen::PDMDBDecodeMapping* pdmdb_mapping) + const Rich::Decoding::Tel40CableMapping* cable_mapping, + const Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping) { unsigned number_of_hits = 0; std::array< - Rich::Future::DAQ::PackedFrameSizes::IntType, - Rich::Future::DAQ::Allen::Tel40CableMapping::MaxConnectionsPerTel40> + Rich::Decoding::PackedFrameSizes::IntType, + Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40> connSizes {}; auto tel40ID = bank.source_id; @@ -39,7 +39,7 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( for (; iWord < nPackedSizeW && dataW != bankEnd; ++dataW, ++iWord, iPayloadWord += 2) { // Extract the sizes from the packed word - const Rich::Future::DAQ::PackedFrameSizes sizes(*dataW); + const Rich::Decoding::PackedFrameSizes sizes(*dataW); // extract sizes for each packed value connSizes[iPayloadWord] = sizes.size1(); connSizes[iPayloadWord + 1] = sizes.size0(); @@ -166,8 +166,8 @@ template __global__ void rich_calculate_number_of_hits( rich_decoding::Parameters parameters, const unsigned event_start, - const Rich::Future::DAQ::Allen::Tel40CableMapping* cable_mapping, - const Rich::Future::DAQ::Allen::PDMDBDecodeMapping* pdmdb_mapping) + const Rich::Decoding::Tel40CableMapping* cable_mapping, + const Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping) { const auto event_number = parameters.dev_event_list[blockIdx.x]; @@ -189,14 +189,14 @@ __global__ void rich_calculate_number_of_hits( __device__ void rich_decode_bank( const Allen::RawBank& bank, - const Rich::Future::DAQ::Allen::Tel40CableMapping* cable_mapping, - const Rich::Future::DAQ::Allen::PDMDBDecodeMapping* pdmdb_mapping, + const Rich::Decoding::Tel40CableMapping* cable_mapping, + const Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping, unsigned* event_inserted_hits, - Allen::RichSmartID* event_smart_ids) + Rich::Decoding::SmartID* event_smart_ids) { std::array< - Rich::Future::DAQ::PackedFrameSizes::IntType, - Rich::Future::DAQ::Allen::Tel40CableMapping::MaxConnectionsPerTel40> + Rich::Decoding::PackedFrameSizes::IntType, + Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40> connSizes {}; auto tel40ID = bank.source_id; @@ -211,7 +211,7 @@ __device__ void rich_decode_bank( for (; iWord < nPackedSizeW && dataW != bankEnd; ++dataW, ++iWord, iPayloadWord += 2) { // Extract the sizes from the packed word - const Rich::Future::DAQ::PackedFrameSizes sizes(*dataW); + const Rich::Decoding::PackedFrameSizes sizes(*dataW); // extract sizes for each packed value connSizes[iPayloadWord] = sizes.size1(); connSizes[iPayloadWord + 1] = sizes.size0(); @@ -260,29 +260,29 @@ __device__ void rich_decode_bank( // so cannot make this a hard error if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { // make a smart ID - auto hitID = Allen::RichSmartID {cData.smartID}; // sets RICH, side, module and PMT type + auto hitID = Rich::Decoding::SmartID {cData.smartID}; // sets RICH, side, module and PMT type // Add the PMT and pixel info const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; hitID.setData( cData.moduleNum, - Allen::RichSmartID::ShiftPDMod, - Allen::RichSmartID::MaskPDMod, - Allen::RichSmartID::MaskPDIsSet); - hitID.setData(nInMod, Allen::RichSmartID::ShiftPDNumInMod, Allen::RichSmartID::MaskPDNumInMod); + Rich::Decoding::SmartID::ShiftPDMod, + Rich::Decoding::SmartID::MaskPDMod, + Rich::Decoding::SmartID::MaskPDIsSet); + hitID.setData(nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); const auto row = aData.anode / 8; const auto col = 8 - 1 - (aData.anode % 8); hitID.setData( row, - Allen::RichSmartID::ShiftPixelRow, - Allen::RichSmartID::MaskPixelRow, - Allen::RichSmartID::MaskPixelRowIsSet); + Rich::Decoding::SmartID::ShiftPixelRow, + Rich::Decoding::SmartID::MaskPixelRow, + Rich::Decoding::SmartID::MaskPixelRowIsSet); hitID.setData( col, - Allen::RichSmartID::ShiftPixelCol, - Allen::RichSmartID::MaskPixelCol, - Allen::RichSmartID::MaskPixelColIsSet); + Rich::Decoding::SmartID::ShiftPixelCol, + Rich::Decoding::SmartID::MaskPixelCol, + Rich::Decoding::SmartID::MaskPixelColIsSet); const auto insert_index = atomicAdd(event_inserted_hits, 1); event_smart_ids[insert_index] = hitID; @@ -336,29 +336,29 @@ __device__ void rich_decode_bank( if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { // make a smart ID - auto hitID = Allen::RichSmartID {cData.smartID}; // sets RICH, side, module and PMT type + auto hitID = Rich::Decoding::SmartID {cData.smartID}; // sets RICH, side, module and PMT type // Add the PMT and pixel info const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; hitID.setData( cData.moduleNum, - Allen::RichSmartID::ShiftPDMod, - Allen::RichSmartID::MaskPDMod, - Allen::RichSmartID::MaskPDIsSet); - hitID.setData(nInMod, Allen::RichSmartID::ShiftPDNumInMod, Allen::RichSmartID::MaskPDNumInMod); + Rich::Decoding::SmartID::ShiftPDMod, + Rich::Decoding::SmartID::MaskPDMod, + Rich::Decoding::SmartID::MaskPDIsSet); + hitID.setData(nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); const auto row = aData.anode / 8; const auto col = 8 - 1 - (aData.anode % 8); hitID.setData( row, - Allen::RichSmartID::ShiftPixelRow, - Allen::RichSmartID::MaskPixelRow, - Allen::RichSmartID::MaskPixelRowIsSet); + Rich::Decoding::SmartID::ShiftPixelRow, + Rich::Decoding::SmartID::MaskPixelRow, + Rich::Decoding::SmartID::MaskPixelRowIsSet); hitID.setData( col, - Allen::RichSmartID::ShiftPixelCol, - Allen::RichSmartID::MaskPixelCol, - Allen::RichSmartID::MaskPixelColIsSet); + Rich::Decoding::SmartID::ShiftPixelCol, + Rich::Decoding::SmartID::MaskPixelCol, + Rich::Decoding::SmartID::MaskPixelColIsSet); const auto insert_index = atomicAdd(event_inserted_hits, 1); event_smart_ids[insert_index] = hitID; @@ -389,8 +389,8 @@ template __global__ void rich_decoding_kernel( rich_decoding::Parameters parameters, const unsigned event_start, - const Rich::Future::DAQ::Allen::Tel40CableMapping* cable_mapping, - const Rich::Future::DAQ::Allen::PDMDBDecodeMapping* pdmdb_mapping, + const Rich::Decoding::Tel40CableMapping* cable_mapping, + const Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping, unsigned* dev_rich_number_of_inserted_hits) { const auto event_number = parameters.dev_event_list[blockIdx.x]; @@ -430,9 +430,9 @@ void rich_decoding::rich_decoding_t::operator()( throw StrException("Rich bank version not supported (" + std::to_string(bank_version) + ")"); } - auto cable_mapping = reinterpret_cast(constants.dev_rich_cable_mapping); + auto cable_mapping = reinterpret_cast(constants.dev_rich_cable_mapping); auto pdmdb_mapping = - reinterpret_cast(constants.dev_rich_pdmdb_mapping); + reinterpret_cast(constants.dev_rich_pdmdb_mapping); // Calculate number of hits into dev_rich_hit_offsets_t Allen::memset_async(arguments, 0, context); diff --git a/device/rich/decoding/src/RichSmartIDHelper.cu b/device/rich/decoding/src/RichSmartIDHelper.cu index da0e2976173..459f7d9b358 100644 --- a/device/rich/decoding/src/RichSmartIDHelper.cu +++ b/device/rich/decoding/src/RichSmartIDHelper.cu @@ -12,19 +12,18 @@ #include #include -using Point = Allen::Point; -Point Allen::RichSmartIDHelper::pdPosition(const Allen::RichSmartID pdid) const +Rich::Point Rich::PixelReco::SmartIDHelper::pdPosition(const Rich::Decoding::SmartID pdid) const { // Create temporary RichSmartIDHelper for two corners of the PD wafer - Allen::RichSmartID id1(pdid), id0(pdid); + Rich::Decoding::SmartID id1(pdid), id0(pdid); id0.setPixelRow(1); id0.setPixelCol(1); id1.setPixelRow(6); id1.setPixelCol(6); // Get position of each of these pixels - const auto a = _globalPosition(id0); - const auto b = _globalPosition(id1); + const auto a = globalPosition(id0); + const auto b = globalPosition(id1); // Return average position (i.e. PD centre) return Point {0.5f * (a.x + b.x), // 0.5f * (a.y + b.y), // @@ -32,24 +31,24 @@ Point Allen::RichSmartIDHelper::pdPosition(const Allen::RichSmartID pdid) const } // Converts a point from the global frame to the detector panel frame -Point Allen::RichSmartIDHelper::globalToPDPanel(const Point& globalPoint) const +Rich::Point Rich::PixelReco::SmartIDHelper::globalToPDPanel(const Rich::Point& globalPoint) const { return ( globalPoint.z < 8000.f ? // RICH1 (globalPoint.y > 0.f ? - Allen::transform3DTimesPoint( - panel(Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::top)->globalToPDPanel(), + Rich::transform3DTimesPoint( + panel(Rich::Detector::Type::Rich1, Rich::Detector::Side::top)->globalToPDPanel(), globalPoint) : - Allen::transform3DTimesPoint( - panel(Rich::Future::DAQ::DetectorType::Rich1, Rich::Future::DAQ::Side::bottom)->globalToPDPanel(), + Rich::transform3DTimesPoint( + panel(Rich::Detector::Type::Rich1, Rich::Detector::Side::bottom)->globalToPDPanel(), globalPoint)) : // RICH2 (globalPoint.x > 0.f ? - Allen::transform3DTimesPoint( - panel(Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::left)->globalToPDPanel(), + Rich::transform3DTimesPoint( + panel(Rich::Detector::Type::Rich2, Rich::Detector::Side::left)->globalToPDPanel(), globalPoint) : - Allen::transform3DTimesPoint( - panel(Rich::Future::DAQ::DetectorType::Rich2, Rich::Future::DAQ::Side::right)->globalToPDPanel(), + Rich::transform3DTimesPoint( + panel(Rich::Detector::Type::Rich2, Rich::Detector::Side::right)->globalToPDPanel(), globalPoint))); } -- GitLab From c394b63eb7ed8bd8a7705477847d3df0bdf77775 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Wed, 28 May 2025 19:48:53 +0000 Subject: [PATCH 40/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/56763590 --- device/rich/decoding/include/Rich.cuh | 15 +- .../include/RichPDMDBDecodeMapping.cuh | 2 +- device/rich/decoding/include/RichPDPanel.cuh | 17 +-- .../decoding/include/RichPhotonDetector.cuh | 6 +- device/rich/decoding/include/RichPixel.cuh | 141 +++++++++--------- device/rich/decoding/include/RichSmartID.cuh | 3 +- .../decoding/include/RichSmartIDHelper.cuh | 15 +- .../include/RichTel40CableMapping.cuh | 2 +- device/rich/decoding/src/RichDecoding.cu | 14 +- device/rich/decoding/src/RichSmartIDHelper.cu | 13 +- 10 files changed, 100 insertions(+), 128 deletions(-) diff --git a/device/rich/decoding/include/Rich.cuh b/device/rich/decoding/include/Rich.cuh index 7014b7074ef..1cbf167933c 100644 --- a/device/rich/decoding/include/Rich.cuh +++ b/device/rich/decoding/include/Rich.cuh @@ -12,17 +12,13 @@ #include #include - namespace Rich { class RichDetector final { public: __host__ __device__ RichDetector() = default; - __host__ __device__ RichDetector( - const Detector::Type m_type, - const std::array m_panels) : - m_panels(m_panels), - m_type(m_type) + __host__ __device__ RichDetector(const Detector::Type m_type, const std::array m_panels) : + m_panels(m_panels), m_type(m_type) {} __host__ __device__ inline auto rich() { return m_type; } @@ -30,13 +26,10 @@ namespace Rich { __host__ __device__ inline auto& pdPanels() { return m_panels; } /// Access PD Panel for a given side - __host__ __device__ inline auto pdPanel(const Detector::Side side) noexcept - { - return &(pdPanels()[side]); - } + __host__ __device__ inline auto pdPanel(const Detector::Side side) noexcept { return &(pdPanels()[side]); } private: std::array m_panels {}; Detector::Type m_type {Detector::Type::InvalidDetector}; }; -} // namespace Rich::Detector +} // namespace Rich diff --git a/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh b/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh index 67343cf799e..ab2c292db5f 100644 --- a/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh +++ b/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh @@ -130,4 +130,4 @@ namespace Rich::Decoding { int m_mappingVer {-1}; }; -} // namespace Rich::Future::DAQ::Allen +} // namespace Rich::Decoding diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/rich/decoding/include/RichPDPanel.cuh index d465f429f9f..654d58ea1de 100644 --- a/device/rich/decoding/include/RichPDPanel.cuh +++ b/device/rich/decoding/include/RichPDPanel.cuh @@ -21,13 +21,8 @@ namespace Rich::Detector { using PDArray = std::array; using ModuleArray = std::array; - PDPanel( - Type rich, - Side side, - std::array gloToPDPanelM, - ModuleArray PDs) : - m_PDs(std::move(PDs)), - m_gloToPDPanelM(gloToPDPanelM), m_panelID({rich, side, 0}), m_rich(rich), m_side(side) + PDPanel(Type rich, Side side, std::array gloToPDPanelM, ModuleArray PDs) : + m_PDs(std::move(PDs)), m_gloToPDPanelM(gloToPDPanelM), m_panelID({rich, side, 0}), m_rich(rich), m_side(side) {} PDPanel(const PDPanel& other) : @@ -78,7 +73,7 @@ namespace Rich::Detector { return (!pd.getIsNull() ? pd.globalDetectionPoint(id) : Point {0, 0, 0}); } - /// Access the global to local transform + /// Access the global to local transform __host__ __device__ inline const auto& globalToPDPanel() const noexcept { return m_gloToPDPanelM; } /// Access all owned PD Modules @@ -107,10 +102,8 @@ namespace Rich::Detector { ModuleArray m_PDs {}; std::array m_gloToPDPanelM {}; // 3D Transform uint32_t m_modNumOffset {0}; - std::array m_panelID {Type::InvalidDetector, - Side::InvalidSide, - -1}; + std::array m_panelID {Type::InvalidDetector, Side::InvalidSide, -1}; Type m_rich {Type::InvalidDetector}; Side m_side {Side::InvalidSide}; }; -} // namespace Rich::Detector::Allen +} // namespace Rich::Detector diff --git a/device/rich/decoding/include/RichPhotonDetector.cuh b/device/rich/decoding/include/RichPhotonDetector.cuh index 48930132cd6..0c7a99bed89 100644 --- a/device/rich/decoding/include/RichPhotonDetector.cuh +++ b/device/rich/decoding/include/RichPhotonDetector.cuh @@ -17,8 +17,8 @@ namespace Rich::Detector { class PhotonDetector { - //using FP = Rich::FP; - //using Point = Rich::Point; + // using FP = Rich::FP; + // using Point = Rich::Point; public: /// Default constructor @@ -102,4 +102,4 @@ namespace Rich::Detector { bool m_isHType {false}; bool m_isNull {false}; }; -} // namespace Rich::Detector::Allen +} // namespace Rich::Detector diff --git a/device/rich/decoding/include/RichPixel.cuh b/device/rich/decoding/include/RichPixel.cuh index e10a3258e7b..71326db401f 100644 --- a/device/rich/decoding/include/RichPixel.cuh +++ b/device/rich/decoding/include/RichPixel.cuh @@ -13,86 +13,85 @@ #include namespace Rich::PixelReco { -class Pixel { -public: - // Default constructor - __host__ __device__ Pixel() - : gPos({0.0f, 0.0f, 0.0f}), - lPos({0.0f, 0.0f, 0.0f}), - m_smartID({}), - m_effArea(0.0f), - m_timeWindow(0.0f) - { - m_flags.setIsNull(true); - m_flags.setIsInnerRegion(true); - } + class Pixel { + public: + // Default constructor + __host__ __device__ Pixel() : + gPos({0.0f, 0.0f, 0.0f}), lPos({0.0f, 0.0f, 0.0f}), m_smartID({}), m_effArea(0.0f), m_timeWindow(0.0f) + { + m_flags.setIsNull(true); + m_flags.setIsInnerRegion(true); + } - // 3D - __host__ __device__ Pixel(const Point& g, const Point& l, const Decoding::SmartID& sid, float area) - : gPos(g), lPos(l), m_smartID(sid), m_effArea(area), m_timeWindow(0.0f) - { - m_flags.setIsNull(false); - m_flags.setIsInnerRegion(!sid.isLargePMT()); - } + // 3D + __host__ __device__ Pixel(const Point& g, const Point& l, const Decoding::SmartID& sid, float area) : + gPos(g), lPos(l), m_smartID(sid), m_effArea(area), m_timeWindow(0.0f) + { + m_flags.setIsNull(false); + m_flags.setIsInnerRegion(!sid.isLargePMT()); + } - // 4D constructor - __host__ __device__ Pixel(const Point& g, const Point& l, const Decoding::SmartID& sid, float area, float time) - : gPos(g), lPos(l), m_smartID(sid), m_effArea(area), m_timeWindow(time) - { - m_flags.setIsNull(false); - m_flags.setIsInnerRegion(!sid.isLargePMT()); - } + // 4D constructor + __host__ __device__ Pixel(const Point& g, const Point& l, const Decoding::SmartID& sid, float area, float time) : + gPos(g), lPos(l), m_smartID(sid), m_effArea(area), m_timeWindow(time) + { + m_flags.setIsNull(false); + m_flags.setIsInnerRegion(!sid.isLargePMT()); + } - __host__ __device__ bool isNull() const { return m_flags.isNull(); } - __host__ __device__ bool isInnerRegion() const { return m_flags.isInnerRegion(); } - __host__ __device__ void setIsNull(bool v) { m_flags.setIsNull(v); } - __host__ __device__ void overrideRegions(bool inner) { m_flags.setIsInnerRegion(inner); } + __host__ __device__ bool isNull() const { return m_flags.isNull(); } + __host__ __device__ bool isInnerRegion() const { return m_flags.isInnerRegion(); } + __host__ __device__ void setIsNull(bool v) { m_flags.setIsNull(v); } + __host__ __device__ void overrideRegions(bool inner) { m_flags.setIsInnerRegion(inner); } - __host__ __device__ inline auto rich() const { return m_smartID.rich(); } - __host__ __device__ inline auto side() const { return m_smartID.side(); } + __host__ __device__ inline auto rich() const { return m_smartID.rich(); } + __host__ __device__ inline auto side() const { return m_smartID.side(); } - __host__ __device__ auto smartID() const { return m_smartID; } - __host__ __device__ auto gloPos() const { return gPos; } - __host__ __device__ auto locPos() const { return lPos; } - __host__ __device__ auto effArea() const { return m_effArea; } - __host__ __device__ auto timeWindow() const { return m_timeWindow; } + __host__ __device__ auto smartID() const { return m_smartID; } + __host__ __device__ auto gloPos() const { return gPos; } + __host__ __device__ auto locPos() const { return lPos; } + __host__ __device__ auto effArea() const { return m_effArea; } + __host__ __device__ auto timeWindow() const { return m_timeWindow; } - __host__ std::string toString() { - std::stringstream ss; - ss << m_smartID.key() << ',' << gPos.x << ',' << gPos.y << ',' << gPos.z << ',' << lPos.x << ',' << lPos.y << ',' - << lPos.z << ',' << m_effArea << ',' << (int)smartID().rich() << ',' << (int)smartID().side() << ',' - << m_timeWindow << ',' << isInnerRegion() << ',' << isNull() << '\n'; - return ss.str(); - } + __host__ std::string toString() + { + std::stringstream ss; + ss << m_smartID.key() << ',' << gPos.x << ',' << gPos.y << ',' << gPos.z << ',' << lPos.x << ',' << lPos.y << ',' + << lPos.z << ',' << m_effArea << ',' << (int) smartID().rich() << ',' << (int) smartID().side() << ',' + << m_timeWindow << ',' << isInnerRegion() << ',' << isNull() << '\n'; + return ss.str(); + } -private: - Point gPos, lPos; - Decoding::SmartID m_smartID; - float m_effArea = 0.0f; - float m_timeWindow = 0.0f; - - struct Flags { - uint8_t value = 0; - static constexpr uint8_t IsInnerRegionMask = 1 << 0; - static constexpr uint8_t IsNullMask = 1 << 1; + private: + Point gPos, lPos; + Decoding::SmartID m_smartID; + float m_effArea = 0.0f; + float m_timeWindow = 0.0f; - __host__ __device__ bool isInnerRegion() const { - return value & IsInnerRegionMask; - } + struct Flags { + uint8_t value = 0; + static constexpr uint8_t IsInnerRegionMask = 1 << 0; + static constexpr uint8_t IsNullMask = 1 << 1; - __host__ __device__ bool isNull() const { - return value & IsNullMask; - } + __host__ __device__ bool isInnerRegion() const { return value & IsInnerRegionMask; } - __host__ __device__ void setIsInnerRegion(bool v) { - if (v) value |= IsInnerRegionMask; - else value &= ~IsInnerRegionMask; - } + __host__ __device__ bool isNull() const { return value & IsNullMask; } - __host__ __device__ void setIsNull(bool v) { - if (v) value |= IsNullMask; - else value &= ~IsNullMask; - } - } m_flags; -}; + __host__ __device__ void setIsInnerRegion(bool v) + { + if (v) + value |= IsInnerRegionMask; + else + value &= ~IsInnerRegionMask; + } + + __host__ __device__ void setIsNull(bool v) + { + if (v) + value |= IsNullMask; + else + value &= ~IsNullMask; + } + } m_flags; + }; } // namespace Rich::PixelReco diff --git a/device/rich/decoding/include/RichSmartID.cuh b/device/rich/decoding/include/RichSmartID.cuh index dfc229a59e4..37e30568833 100644 --- a/device/rich/decoding/include/RichSmartID.cuh +++ b/device/rich/decoding/include/RichSmartID.cuh @@ -142,7 +142,6 @@ namespace Rich::Decoding { __host__ __device__ constexpr inline auto side() const noexcept { return panel(); } - __host__ __device__ constexpr inline DataType pdMod() const noexcept { return getData(ShiftPDMod, MaskPDMod); } __host__ __device__ constexpr inline DataType pdNumInMod() const noexcept @@ -321,4 +320,4 @@ namespace Rich::Decoding { static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; }; }; // namespace SmartID -} // namespace RichDecoding +} // namespace Rich::Decoding diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 2cec4707007..0cd30be5a5d 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -22,26 +22,23 @@ namespace Rich::PixelReco { __host__ __device__ SmartIDHelper() = default; /// Constructor from RICH detector elements - __host__ __device__ - SmartIDHelper(const Detector::PDPanel& pdPanel1, const Detector::PDPanel& pdPanel2) : + __host__ __device__ SmartIDHelper(const Detector::PDPanel& pdPanel1, const Detector::PDPanel& pdPanel2) : m_pdPanels {&pdPanel1, &pdPanel2} {} - __host__ __device__ - SmartIDHelper(const std::array m_pdPanels) : + __host__ __device__ SmartIDHelper(const std::array m_pdPanels) : m_pdPanels {m_pdPanels} {} __host__ __device__ inline auto panel(Decoding::SmartID smartID) const -> const Detector::PDPanel* - { + { // Determine the side Detector::Side side = (Detector::Side) smartID.panel(); return m_pdPanels[side]; } - __host__ __device__ inline auto panel( - const Detector::Type rtype, - const Detector::Side side) const -> const Detector::PDPanel* + __host__ __device__ inline auto panel(const Detector::Type rtype, const Detector::Side side) const + -> const Detector::PDPanel* { for (size_t i = 0; i < m_pdPanels.size(); i++) { const Detector::PDPanel* pdPanel = m_pdPanels[i]; @@ -75,4 +72,4 @@ namespace Rich::PixelReco { private: const std::array m_pdPanels {}; }; -} // namespace PixelReco +} // namespace Rich::PixelReco diff --git a/device/rich/decoding/include/RichTel40CableMapping.cuh b/device/rich/decoding/include/RichTel40CableMapping.cuh index 2dab4675cec..af57713ef3a 100644 --- a/device/rich/decoding/include/RichTel40CableMapping.cuh +++ b/device/rich/decoding/include/RichTel40CableMapping.cuh @@ -136,4 +136,4 @@ namespace Rich::Decoding { int m_mappingVer {-1}; }; -} // namespace Rich::Future::DAQ::Allen +} // namespace Rich::Decoding diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index 62bc7f07e09..fb29e072f43 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -22,9 +22,7 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping) { unsigned number_of_hits = 0; - std::array< - Rich::Decoding::PackedFrameSizes::IntType, - Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40> + std::array connSizes {}; auto tel40ID = bank.source_id; @@ -194,9 +192,7 @@ __device__ void rich_decode_bank( unsigned* event_inserted_hits, Rich::Decoding::SmartID* event_smart_ids) { - std::array< - Rich::Decoding::PackedFrameSizes::IntType, - Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40> + std::array connSizes {}; auto tel40ID = bank.source_id; @@ -345,7 +341,8 @@ __device__ void rich_decode_bank( Rich::Decoding::SmartID::ShiftPDMod, Rich::Decoding::SmartID::MaskPDMod, Rich::Decoding::SmartID::MaskPDIsSet); - hitID.setData(nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); + hitID.setData( + nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); const auto row = aData.anode / 8; const auto col = 8 - 1 - (aData.anode % 8); @@ -431,8 +428,7 @@ void rich_decoding::rich_decoding_t::operator()( } auto cable_mapping = reinterpret_cast(constants.dev_rich_cable_mapping); - auto pdmdb_mapping = - reinterpret_cast(constants.dev_rich_pdmdb_mapping); + auto pdmdb_mapping = reinterpret_cast(constants.dev_rich_pdmdb_mapping); // Calculate number of hits into dev_rich_hit_offsets_t Allen::memset_async(arguments, 0, context); diff --git a/device/rich/decoding/src/RichSmartIDHelper.cu b/device/rich/decoding/src/RichSmartIDHelper.cu index 459f7d9b358..df24b441a4a 100644 --- a/device/rich/decoding/src/RichSmartIDHelper.cu +++ b/device/rich/decoding/src/RichSmartIDHelper.cu @@ -12,7 +12,6 @@ #include #include - Rich::Point Rich::PixelReco::SmartIDHelper::pdPosition(const Rich::Decoding::SmartID pdid) const { // Create temporary RichSmartIDHelper for two corners of the PD wafer @@ -38,17 +37,13 @@ Rich::Point Rich::PixelReco::SmartIDHelper::globalToPDPanel(const Rich::Point& g // RICH1 (globalPoint.y > 0.f ? Rich::transform3DTimesPoint( - panel(Rich::Detector::Type::Rich1, Rich::Detector::Side::top)->globalToPDPanel(), - globalPoint) : + panel(Rich::Detector::Type::Rich1, Rich::Detector::Side::top)->globalToPDPanel(), globalPoint) : Rich::transform3DTimesPoint( - panel(Rich::Detector::Type::Rich1, Rich::Detector::Side::bottom)->globalToPDPanel(), - globalPoint)) : + panel(Rich::Detector::Type::Rich1, Rich::Detector::Side::bottom)->globalToPDPanel(), globalPoint)) : // RICH2 (globalPoint.x > 0.f ? Rich::transform3DTimesPoint( - panel(Rich::Detector::Type::Rich2, Rich::Detector::Side::left)->globalToPDPanel(), - globalPoint) : + panel(Rich::Detector::Type::Rich2, Rich::Detector::Side::left)->globalToPDPanel(), globalPoint) : Rich::transform3DTimesPoint( - panel(Rich::Detector::Type::Rich2, Rich::Detector::Side::right)->globalToPDPanel(), - globalPoint))); + panel(Rich::Detector::Type::Rich2, Rich::Detector::Side::right)->globalToPDPanel(), globalPoint))); } -- GitLab From 5a76c5986628df049c5991676eb210343d77853d Mon Sep 17 00:00:00 2001 From: ipalmame Date: Tue, 3 Jun 2025 22:27:16 +0200 Subject: [PATCH 41/92] Added custom RICH geometry consumer and refactor event_model files --- device/event_model/CMakeLists.txt | 1 + .../rich}/include/Rich.cuh | 4 +- .../rich}/include/RichDefinitions.cuh | 0 .../rich}/include/RichPDPanel.cuh | 0 .../rich}/include/RichPhotonDetector.cuh | 0 .../rich}/include/RichSmartID.cuh | 0 .../non_event_data/include/Consumers.h | 22 +++++++ .../non_event_data/src/RichGeometry.cpp | 58 +++++++++++++++++++ main/src/RegisterConsumers.cpp | 6 +- stream/sequence/include/Constants.cuh | 19 +++--- 10 files changed, 94 insertions(+), 16 deletions(-) rename device/{rich/decoding => event_model/rich}/include/Rich.cuh (96%) rename device/{rich/decoding => event_model/rich}/include/RichDefinitions.cuh (100%) rename device/{rich/decoding => event_model/rich}/include/RichPDPanel.cuh (100%) rename device/{rich/decoding => event_model/rich}/include/RichPhotonDetector.cuh (100%) rename device/{rich/decoding => event_model/rich}/include/RichSmartID.cuh (100%) create mode 100644 integration/non_event_data/src/RichGeometry.cpp diff --git a/device/event_model/CMakeLists.txt b/device/event_model/CMakeLists.txt index 93d7e315a51..49be1f19fa7 100644 --- a/device/event_model/CMakeLists.txt +++ b/device/event_model/CMakeLists.txt @@ -27,6 +27,7 @@ target_include_directories(EventModel INTERFACE $ $ $ + $ $) target_link_libraries(EventModel INTERFACE AllenCommon) diff --git a/device/rich/decoding/include/Rich.cuh b/device/event_model/rich/include/Rich.cuh similarity index 96% rename from device/rich/decoding/include/Rich.cuh rename to device/event_model/rich/include/Rich.cuh index 1cbf167933c..7b09dc67a34 100644 --- a/device/rich/decoding/include/Rich.cuh +++ b/device/event_model/rich/include/Rich.cuh @@ -9,8 +9,8 @@ * or submit itself to any jurisdiction. * \*****************************************************************************/ #pragma once -#include -#include +#include "RichDefinitions.cuh" +#include "RichPDPanel.cuh" namespace Rich { class RichDetector final { diff --git a/device/rich/decoding/include/RichDefinitions.cuh b/device/event_model/rich/include/RichDefinitions.cuh similarity index 100% rename from device/rich/decoding/include/RichDefinitions.cuh rename to device/event_model/rich/include/RichDefinitions.cuh diff --git a/device/rich/decoding/include/RichPDPanel.cuh b/device/event_model/rich/include/RichPDPanel.cuh similarity index 100% rename from device/rich/decoding/include/RichPDPanel.cuh rename to device/event_model/rich/include/RichPDPanel.cuh diff --git a/device/rich/decoding/include/RichPhotonDetector.cuh b/device/event_model/rich/include/RichPhotonDetector.cuh similarity index 100% rename from device/rich/decoding/include/RichPhotonDetector.cuh rename to device/event_model/rich/include/RichPhotonDetector.cuh diff --git a/device/rich/decoding/include/RichSmartID.cuh b/device/event_model/rich/include/RichSmartID.cuh similarity index 100% rename from device/rich/decoding/include/RichSmartID.cuh rename to device/event_model/rich/include/RichSmartID.cuh diff --git a/integration/non_event_data/include/Consumers.h b/integration/non_event_data/include/Consumers.h index 619d9329ab5..17cd2f6e036 100644 --- a/integration/non_event_data/include/Consumers.h +++ b/integration/non_event_data/include/Consumers.h @@ -49,6 +49,28 @@ namespace Consumers { std::reference_wrapper m_constants; }; + struct Rich1Geometry final : public Allen::NonEventData::Consumer { + public: + Rich1Geometry(Constants& constants); + + void consume(std::vector const& dev_rich_1_geometry) override; + + private: + void initialize(const std::vector& data); + std::reference_wrapper m_constants; + }; + + struct Rich2Geometry final : public Allen::NonEventData::Consumer { + public: + Rich2Geometry(Constants& constants); + + void consume(std::vector const& dev_rich_2_geometry) override; + + private: + void initialize(const std::vector& data); + std::reference_wrapper m_constants; + }; + struct UTBoards final : public Allen::NonEventData::Consumer { public: UTBoards(Constants& constants); diff --git a/integration/non_event_data/src/RichGeometry.cpp b/integration/non_event_data/src/RichGeometry.cpp new file mode 100644 index 00000000000..0dedd7721dd --- /dev/null +++ b/integration/non_event_data/src/RichGeometry.cpp @@ -0,0 +1,58 @@ +/*****************************************************************************\ + * * (c) Copyright 2018-2020 CERN for the benefit of the LHCb Collaboration * + * * * + * * This software is distributed under the terms of the Apache License * + * * version 2 (Apache-2.0), copied verbatim in the file "LICENSE". * + * * * + * * In applying this licence, CERN does not waive the privileges and immunities * + * * granted to it by virtue of its status as an Intergovernmental Organization * + * * or submit itself to any jurisdiction. * + * \*****************************************************************************/ +#include + +#include +#include +#include +#include "Rich.cuh" + +namespace { + using std::string; + using std::to_string; + using std::vector; +} // namespace + +Consumers::Rich1Geometry::Rich1Geometry(Constants& constants) : m_constants {constants} {} + +void Consumers::Rich1Geometry::initialize(vector const&) +{ + Allen::malloc((void**) &m_constants.get().dev_rich_1_geometry, sizeof(Rich::RichDetector)); +} + +void Consumers::Rich1Geometry::consume(vector const& data) +{ + auto& dev_rich_1_geometry = m_constants.get().dev_rich_1_geometry; + if (dev_rich_1_geometry == nullptr) { + initialize(data); + } + auto& host_rich_1_geometry = m_constants.get().host_rich_1_geometry; + host_rich_1_geometry = data; + Allen::memcpy(dev_rich_1_geometry, host_rich_1_geometry.data(), sizeof(Rich::RichDetector), Allen::memcpyHostToDevice); +} + +Consumers::Rich2Geometry::Rich2Geometry(Constants& constants) : m_constants {constants} {} + +void Consumers::Rich2Geometry::initialize(vector const&) +{ + Allen::malloc((void**) &m_constants.get().dev_rich_2_geometry, sizeof(Rich::RichDetector)); +} + +void Consumers::Rich2Geometry::consume(vector const& data) +{ + auto& dev_rich_2_geometry = m_constants.get().dev_rich_2_geometry; + if (dev_rich_2_geometry == nullptr) { + initialize(data); + } + auto& host_rich_2_geometry = m_constants.get().host_rich_2_geometry; + host_rich_2_geometry = data; + Allen::memcpy(dev_rich_2_geometry, host_rich_2_geometry.data(), sizeof(Rich::RichDetector), Allen::memcpyHostToDevice); +} diff --git a/main/src/RegisterConsumers.cpp b/main/src/RegisterConsumers.cpp index b600f3aa945..26a68e13578 100644 --- a/main/src/RegisterConsumers.cpp +++ b/main/src/RegisterConsumers.cpp @@ -99,8 +99,7 @@ void register_consumers( std::make_tuple( Allen::NonEventData::Rich1Geometry {}, [&constants]() { - return std::make_unique( - constants.host_rich_1_geometry, constants.dev_rich_1_geometry); + return std::make_unique(constants); }, BankTypes::Rich1), std::make_tuple( @@ -120,8 +119,7 @@ void register_consumers( std::make_tuple( Allen::NonEventData::Rich2Geometry {}, [&constants]() { - return std::make_unique( - constants.host_rich_2_geometry, constants.dev_rich_2_geometry); + return std::make_unique(constants); }, BankTypes::Rich2)); diff --git a/stream/sequence/include/Constants.cuh b/stream/sequence/include/Constants.cuh index 9e748818906..e35851e12cc 100644 --- a/stream/sequence/include/Constants.cuh +++ b/stream/sequence/include/Constants.cuh @@ -43,14 +43,13 @@ namespace MatchUpstreamMuon { namespace TrackMatchingConsts { struct MagnetParametrization; } -namespace Rich::Future::DAQ::Allen { +namespace Rich::Deocoding { class PDMDBDecodeMapping; class Tel40CableMapping; -} // namespace Rich::Future::DAQ::Allen -namespace Allen { - class Rich1; - class Rich2; -} // namespace Allen +} // namespace Rich::Decoding +namespace Rich { + class RichDetector; +} // namespace Rich namespace UT::Constants { struct UTLayerGeometry; @@ -161,10 +160,10 @@ struct Constants { std::vector host_rich_1_geometry; std::vector host_rich_2_geometry; - char* dev_rich_pdmdb_mapping; - char* dev_rich_cable_mapping; - char* dev_rich_1_geometry; - char* dev_rich_2_geometry; + char* dev_rich_pdmdb_mapping = nullptr; + char* dev_rich_cable_mapping = nullptr; + Rich::RichDetector* dev_rich_1_geometry = nullptr; + Rich::RichDetector* dev_rich_2_geometry = nullptr; /** * @brief Reserves and initializes constants. -- GitLab From ba9a0c10d929afcc5365b6db10cfb13e1bed95c7 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 6 Jun 2025 02:47:17 +0200 Subject: [PATCH 42/92] Remove unnecessary constructors, constants to constexprs, RegisterProducers and consumers fix for decoding --- device/event_model/rich/include/Rich.cuh | 2 +- .../rich}/include/RichPDMDBDecodeMapping.cuh | 0 .../rich/include/RichPhotonDetector.cuh | 10 ----- ...DPanel.cuh => RichPhotonDetectorPanel.cuh} | 20 --------- .../rich}/include/RichPixel.cuh | 0 .../event_model/rich/include/RichSmartID.cuh | 8 ++-- .../rich}/include/RichTel40CableMapping.cuh | 1 + .../decoding/include/RichSmartIDHelper.cuh | 2 +- device/rich/decoding/src/RichDecoding.cu | 4 +- .../non_event_data/include/Consumers.h | 22 ++++++++++ .../non_event_data/src/RichGeometry.cpp | 42 +++++++++++++++++++ main/src/RegisterConsumers.cpp | 15 +++---- stream/sequence/include/Constants.cuh | 7 ++-- 13 files changed, 81 insertions(+), 52 deletions(-) rename device/{rich/decoding => event_model/rich}/include/RichPDMDBDecodeMapping.cuh (100%) rename device/event_model/rich/include/{RichPDPanel.cuh => RichPhotonDetectorPanel.cuh} (82%) rename device/{rich/decoding => event_model/rich}/include/RichPixel.cuh (100%) rename device/{rich/decoding => event_model/rich}/include/RichTel40CableMapping.cuh (99%) diff --git a/device/event_model/rich/include/Rich.cuh b/device/event_model/rich/include/Rich.cuh index 7b09dc67a34..734e87325ba 100644 --- a/device/event_model/rich/include/Rich.cuh +++ b/device/event_model/rich/include/Rich.cuh @@ -10,7 +10,7 @@ \*****************************************************************************/ #pragma once #include "RichDefinitions.cuh" -#include "RichPDPanel.cuh" +#include "RichPhotonDetectorPanel.cuh" namespace Rich { class RichDetector final { diff --git a/device/rich/decoding/include/RichPDMDBDecodeMapping.cuh b/device/event_model/rich/include/RichPDMDBDecodeMapping.cuh similarity index 100% rename from device/rich/decoding/include/RichPDMDBDecodeMapping.cuh rename to device/event_model/rich/include/RichPDMDBDecodeMapping.cuh diff --git a/device/event_model/rich/include/RichPhotonDetector.cuh b/device/event_model/rich/include/RichPhotonDetector.cuh index 0c7a99bed89..1147a8783b0 100644 --- a/device/event_model/rich/include/RichPhotonDetector.cuh +++ b/device/event_model/rich/include/RichPhotonDetector.cuh @@ -23,16 +23,6 @@ namespace Rich::Detector { public: /// Default constructor __host__ __device__ PhotonDetector() = default; - /// Copy assignment operator - __host__ __device__ PhotonDetector& operator=(const PhotonDetector&) = default; - /// Copy Constructor - __host__ __device__ PhotonDetector(const PhotonDetector& pd) : - m_locToGloM(pd.m_locToGloM), m_zeroInPanelFrame(pd.m_zeroInPanelFrame), m_pdSmartID(pd.m_pdSmartID), - m_effPixelArea(pd.m_effPixelArea), m_numPixels(pd.m_numPixels), m_localZcoord(pd.m_localZcoord), - m_numPixColFrac(pd.m_numPixColFrac), m_numPixRowFrac(pd.m_numPixRowFrac), - m_effectivePixelXSize(pd.m_effectivePixelXSize), m_effectivePixelYSize(pd.m_effectivePixelYSize), - m_isHType(pd.m_isHType), m_isNull(pd.m_isNull) - {} __host__ __device__ inline auto pdSmartID() const { return m_pdSmartID; } diff --git a/device/event_model/rich/include/RichPDPanel.cuh b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh similarity index 82% rename from device/event_model/rich/include/RichPDPanel.cuh rename to device/event_model/rich/include/RichPhotonDetectorPanel.cuh index 654d58ea1de..3de6a6e16f7 100644 --- a/device/event_model/rich/include/RichPDPanel.cuh +++ b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh @@ -21,26 +21,6 @@ namespace Rich::Detector { using PDArray = std::array; using ModuleArray = std::array; - PDPanel(Type rich, Side side, std::array gloToPDPanelM, ModuleArray PDs) : - m_PDs(std::move(PDs)), m_gloToPDPanelM(gloToPDPanelM), m_panelID({rich, side, 0}), m_rich(rich), m_side(side) - {} - - PDPanel(const PDPanel& other) : - m_gloToPDPanelM(other.m_gloToPDPanelM), m_panelID(other.m_panelID), m_rich(other.m_rich), m_side(other.m_side) - { - for (size_t i = 0; i < other.m_PDs.size(); ++i) { - for (size_t j = 0; j < other.m_PDs[i].size(); ++j) { - if (!(other.m_PDs[i][j].getIsNull())) { - m_PDs[i][j] = PhotonDetector(other.m_PDs[i][j]); - } - else { - m_PDs[i][j] = PhotonDetector(); - m_PDs[i][j].setIsNull(true); - } - } - } - } - /// Access the RICH detector type __host__ __device__ inline auto rich() const noexcept { return m_rich; } diff --git a/device/rich/decoding/include/RichPixel.cuh b/device/event_model/rich/include/RichPixel.cuh similarity index 100% rename from device/rich/decoding/include/RichPixel.cuh rename to device/event_model/rich/include/RichPixel.cuh diff --git a/device/event_model/rich/include/RichSmartID.cuh b/device/event_model/rich/include/RichSmartID.cuh index 37e30568833..0e552c07403 100644 --- a/device/event_model/rich/include/RichSmartID.cuh +++ b/device/event_model/rich/include/RichSmartID.cuh @@ -314,10 +314,10 @@ namespace Rich::Decoding { static constexpr const ADCTimeType MaxADCTime = static_cast((BitPackType {1} << BitsADCTime) - 1); // Parameters for conversion between float and ADC time values - static constexpr const double MinTime = -50.0; // In nanoseconds - static constexpr const double MaxTime = 150.0; // In nanoseconds - static constexpr const double ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); - static constexpr const double ScaleADCToTime = 1.0 / ScaleTimeToADC; + static constexpr const float MinTime = -50.0f; // In nanoseconds + static constexpr const float MaxTime = 150.0f; // In nanoseconds + static constexpr const float ScaleTimeToADC = MaxADCTime / (MaxTime - MinTime); + static constexpr const float ScaleADCToTime = 1.0f / ScaleTimeToADC; }; }; // namespace SmartID } // namespace Rich::Decoding diff --git a/device/rich/decoding/include/RichTel40CableMapping.cuh b/device/event_model/rich/include/RichTel40CableMapping.cuh similarity index 99% rename from device/rich/decoding/include/RichTel40CableMapping.cuh rename to device/event_model/rich/include/RichTel40CableMapping.cuh index af57713ef3a..0fc0a67783d 100644 --- a/device/rich/decoding/include/RichTel40CableMapping.cuh +++ b/device/event_model/rich/include/RichTel40CableMapping.cuh @@ -12,6 +12,7 @@ #include #include +#include namespace Rich::Decoding { /// Helper class for RICH PMT data format encoding diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 0cd30be5a5d..9d6770f851f 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -11,7 +11,7 @@ #pragma once #include #include -#include +#include #include #define PANEL_COUNT 2 diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index fb29e072f43..2d24cd16b62 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -427,8 +427,8 @@ void rich_decoding::rich_decoding_t::operator()( throw StrException("Rich bank version not supported (" + std::to_string(bank_version) + ")"); } - auto cable_mapping = reinterpret_cast(constants.dev_rich_cable_mapping); - auto pdmdb_mapping = reinterpret_cast(constants.dev_rich_pdmdb_mapping); + Rich::Decoding::Tel40CableMapping* cable_mapping = constants.dev_rich_cable_mapping; + Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping = constants.dev_rich_pdmdb_mapping; // Calculate number of hits into dev_rich_hit_offsets_t Allen::memset_async(arguments, 0, context); diff --git a/integration/non_event_data/include/Consumers.h b/integration/non_event_data/include/Consumers.h index 17cd2f6e036..7320230851a 100644 --- a/integration/non_event_data/include/Consumers.h +++ b/integration/non_event_data/include/Consumers.h @@ -49,6 +49,28 @@ namespace Consumers { std::reference_wrapper m_constants; }; + struct RichPDMDBDecodeMapping final : public Allen::NonEventData::Consumer { + public: + RichPDMDBDecodeMapping(Constants& constants); + + void consume(std::vector const& dev_rich_pdmdb_mapping) override; + + private: + void initialize(const std::vector& data); + std::reference_wrapper m_constants; + }; + + struct RichTel40CableMapping final : public Allen::NonEventData::Consumer { + public: + RichTel40CableMapping(Constants& constants); + + void consume(std::vector const& dev_rich_cable_mapping) override; + + private: + void initialize(const std::vector& data); + std::reference_wrapper m_constants; + }; + struct Rich1Geometry final : public Allen::NonEventData::Consumer { public: Rich1Geometry(Constants& constants); diff --git a/integration/non_event_data/src/RichGeometry.cpp b/integration/non_event_data/src/RichGeometry.cpp index 0dedd7721dd..e5fc253820b 100644 --- a/integration/non_event_data/src/RichGeometry.cpp +++ b/integration/non_event_data/src/RichGeometry.cpp @@ -13,6 +13,8 @@ #include #include #include +#include "RichPDMDBDecodeMapping.cuh" +#include "RichTel40CableMapping.cuh" #include "Rich.cuh" namespace { @@ -21,6 +23,45 @@ namespace { using std::vector; } // namespace +// PDMDB mapping +Consumers::RichPDMDBDecodeMapping::RichPDMDBDecodeMapping(Constants& constants) : m_constants {constants} {} + +void Consumers::RichPDMDBDecodeMapping::initialize(vector const&) +{ + Allen::malloc((void**) &m_constants.get().dev_rich_pdmdb_mapping, sizeof(Rich::Decoding::PDMDBDecodeMapping)); +} + +void Consumers::RichPDMDBDecodeMapping::consume(vector const& data) +{ + auto& dev_rich_pdmdb_mapping = m_constants.get().dev_rich_pdmdb_mapping; + if (dev_rich_pdmdb_mapping == nullptr) { + initialize(data); + } + auto& host_rich_pdmdb_mapping = m_constants.get().host_rich_pdmdb_mapping; + host_rich_pdmdb_mapping = data; + Allen::memcpy(dev_rich_pdmdb_mapping, host_rich_pdmdb_mapping.data(), sizeof(Rich::Decoding::PDMDBDecodeMapping), Allen::memcpyHostToDevice); +} + +// Tel40 cable mapping +Consumers::RichTel40CableMapping::RichTel40CableMapping(Constants& constants) : m_constants {constants} {} + +void Consumers::RichTel40CableMapping::initialize(vector const&) +{ + Allen::malloc((void**) &m_constants.get().dev_rich_cable_mapping, sizeof(Rich::Decoding::Tel40CableMapping)); +} + +void Consumers::RichTel40CableMapping::consume(vector const& data) +{ + auto& dev_rich_cable_mapping = m_constants.get().dev_rich_cable_mapping; + if (dev_rich_cable_mapping == nullptr) { + initialize(data); + } + auto& host_rich_cable_mapping = m_constants.get().host_rich_cable_mapping; + host_rich_cable_mapping = data; + Allen::memcpy(dev_rich_cable_mapping, host_rich_cable_mapping.data(), sizeof(Rich::Decoding::Tel40CableMapping), Allen::memcpyHostToDevice); +} + +// RICH 1 geometry Consumers::Rich1Geometry::Rich1Geometry(Constants& constants) : m_constants {constants} {} void Consumers::Rich1Geometry::initialize(vector const&) @@ -39,6 +80,7 @@ void Consumers::Rich1Geometry::consume(vector const& data) Allen::memcpy(dev_rich_1_geometry, host_rich_1_geometry.data(), sizeof(Rich::RichDetector), Allen::memcpyHostToDevice); } +// RICH 2 geometry Consumers::Rich2Geometry::Rich2Geometry(Constants& constants) : m_constants {constants} {} void Consumers::Rich2Geometry::initialize(vector const&) diff --git a/main/src/RegisterConsumers.cpp b/main/src/RegisterConsumers.cpp index 26a68e13578..55a5b3b2f31 100644 --- a/main/src/RegisterConsumers.cpp +++ b/main/src/RegisterConsumers.cpp @@ -78,22 +78,19 @@ void register_consumers( std::make_tuple( Allen::NonEventData::RichPDMDBMapping {}, [&constants]() { - return std::make_unique( - constants.host_rich_pdmdb_mapping, constants.dev_rich_pdmdb_mapping); + return std::make_unique(constants); }, BankTypes::Rich1), std::make_tuple( Allen::NonEventData::RichCableMapping {}, [&constants]() { - return std::make_unique( - constants.host_rich_cable_mapping, constants.dev_rich_cable_mapping); + return std::make_unique(constants); }, BankTypes::Rich1), std::make_tuple( Allen::NonEventData::RichPDMDBMapping {}, [&constants]() { - return std::make_unique( - constants.host_rich_pdmdb_mapping, constants.dev_rich_pdmdb_mapping); + return std::make_unique(constants); }, BankTypes::Rich1), std::make_tuple( @@ -105,15 +102,13 @@ void register_consumers( std::make_tuple( Allen::NonEventData::RichPDMDBMapping {}, [&constants]() { - return std::make_unique( - constants.host_rich_pdmdb_mapping, constants.dev_rich_pdmdb_mapping); + return std::make_unique(constants); }, BankTypes::Rich2), std::make_tuple( Allen::NonEventData::RichCableMapping {}, [&constants]() { - return std::make_unique( - constants.host_rich_cable_mapping, constants.dev_rich_cable_mapping); + return std::make_unique(constants); }, BankTypes::Rich2), std::make_tuple( diff --git a/stream/sequence/include/Constants.cuh b/stream/sequence/include/Constants.cuh index e35851e12cc..c56ab5c6d38 100644 --- a/stream/sequence/include/Constants.cuh +++ b/stream/sequence/include/Constants.cuh @@ -43,14 +43,13 @@ namespace MatchUpstreamMuon { namespace TrackMatchingConsts { struct MagnetParametrization; } -namespace Rich::Deocoding { +namespace Rich::Decoding { class PDMDBDecodeMapping; class Tel40CableMapping; } // namespace Rich::Decoding namespace Rich { class RichDetector; } // namespace Rich - namespace UT::Constants { struct UTLayerGeometry; } @@ -160,8 +159,8 @@ struct Constants { std::vector host_rich_1_geometry; std::vector host_rich_2_geometry; - char* dev_rich_pdmdb_mapping = nullptr; - char* dev_rich_cable_mapping = nullptr; + Rich::Decoding::PDMDBDecodeMapping* dev_rich_pdmdb_mapping = nullptr; + Rich::Decoding::Tel40CableMapping* dev_rich_cable_mapping = nullptr; Rich::RichDetector* dev_rich_1_geometry = nullptr; Rich::RichDetector* dev_rich_2_geometry = nullptr; -- GitLab From 990fd245e34266f53a7351a2030ba7d22536756d Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Fri, 6 Jun 2025 00:47:52 +0000 Subject: [PATCH 43/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/57097819 --- .../non_event_data/include/Consumers.h | 8 +++--- .../non_event_data/src/RichGeometry.cpp | 18 +++++++++--- main/src/RegisterConsumers.cpp | 28 +++++-------------- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/integration/non_event_data/include/Consumers.h b/integration/non_event_data/include/Consumers.h index 7320230851a..81300672f9b 100644 --- a/integration/non_event_data/include/Consumers.h +++ b/integration/non_event_data/include/Consumers.h @@ -49,7 +49,7 @@ namespace Consumers { std::reference_wrapper m_constants; }; - struct RichPDMDBDecodeMapping final : public Allen::NonEventData::Consumer { + struct RichPDMDBDecodeMapping final : public Allen::NonEventData::Consumer { public: RichPDMDBDecodeMapping(Constants& constants); @@ -60,7 +60,7 @@ namespace Consumers { std::reference_wrapper m_constants; }; - struct RichTel40CableMapping final : public Allen::NonEventData::Consumer { + struct RichTel40CableMapping final : public Allen::NonEventData::Consumer { public: RichTel40CableMapping(Constants& constants); @@ -71,7 +71,7 @@ namespace Consumers { std::reference_wrapper m_constants; }; - struct Rich1Geometry final : public Allen::NonEventData::Consumer { + struct Rich1Geometry final : public Allen::NonEventData::Consumer { public: Rich1Geometry(Constants& constants); @@ -82,7 +82,7 @@ namespace Consumers { std::reference_wrapper m_constants; }; - struct Rich2Geometry final : public Allen::NonEventData::Consumer { + struct Rich2Geometry final : public Allen::NonEventData::Consumer { public: Rich2Geometry(Constants& constants); diff --git a/integration/non_event_data/src/RichGeometry.cpp b/integration/non_event_data/src/RichGeometry.cpp index e5fc253820b..d4c58739047 100644 --- a/integration/non_event_data/src/RichGeometry.cpp +++ b/integration/non_event_data/src/RichGeometry.cpp @@ -39,7 +39,11 @@ void Consumers::RichPDMDBDecodeMapping::consume(vector const& data) } auto& host_rich_pdmdb_mapping = m_constants.get().host_rich_pdmdb_mapping; host_rich_pdmdb_mapping = data; - Allen::memcpy(dev_rich_pdmdb_mapping, host_rich_pdmdb_mapping.data(), sizeof(Rich::Decoding::PDMDBDecodeMapping), Allen::memcpyHostToDevice); + Allen::memcpy( + dev_rich_pdmdb_mapping, + host_rich_pdmdb_mapping.data(), + sizeof(Rich::Decoding::PDMDBDecodeMapping), + Allen::memcpyHostToDevice); } // Tel40 cable mapping @@ -58,7 +62,11 @@ void Consumers::RichTel40CableMapping::consume(vector const& data) } auto& host_rich_cable_mapping = m_constants.get().host_rich_cable_mapping; host_rich_cable_mapping = data; - Allen::memcpy(dev_rich_cable_mapping, host_rich_cable_mapping.data(), sizeof(Rich::Decoding::Tel40CableMapping), Allen::memcpyHostToDevice); + Allen::memcpy( + dev_rich_cable_mapping, + host_rich_cable_mapping.data(), + sizeof(Rich::Decoding::Tel40CableMapping), + Allen::memcpyHostToDevice); } // RICH 1 geometry @@ -77,7 +85,8 @@ void Consumers::Rich1Geometry::consume(vector const& data) } auto& host_rich_1_geometry = m_constants.get().host_rich_1_geometry; host_rich_1_geometry = data; - Allen::memcpy(dev_rich_1_geometry, host_rich_1_geometry.data(), sizeof(Rich::RichDetector), Allen::memcpyHostToDevice); + Allen::memcpy( + dev_rich_1_geometry, host_rich_1_geometry.data(), sizeof(Rich::RichDetector), Allen::memcpyHostToDevice); } // RICH 2 geometry @@ -96,5 +105,6 @@ void Consumers::Rich2Geometry::consume(vector const& data) } auto& host_rich_2_geometry = m_constants.get().host_rich_2_geometry; host_rich_2_geometry = data; - Allen::memcpy(dev_rich_2_geometry, host_rich_2_geometry.data(), sizeof(Rich::RichDetector), Allen::memcpyHostToDevice); + Allen::memcpy( + dev_rich_2_geometry, host_rich_2_geometry.data(), sizeof(Rich::RichDetector), Allen::memcpyHostToDevice); } diff --git a/main/src/RegisterConsumers.cpp b/main/src/RegisterConsumers.cpp index 55a5b3b2f31..1e7a6a2e940 100644 --- a/main/src/RegisterConsumers.cpp +++ b/main/src/RegisterConsumers.cpp @@ -77,45 +77,31 @@ void register_consumers( BankTypes::MUON), std::make_tuple( Allen::NonEventData::RichPDMDBMapping {}, - [&constants]() { - return std::make_unique(constants); - }, + [&constants]() { return std::make_unique(constants); }, BankTypes::Rich1), std::make_tuple( Allen::NonEventData::RichCableMapping {}, - [&constants]() { - return std::make_unique(constants); - }, + [&constants]() { return std::make_unique(constants); }, BankTypes::Rich1), std::make_tuple( Allen::NonEventData::RichPDMDBMapping {}, - [&constants]() { - return std::make_unique(constants); - }, + [&constants]() { return std::make_unique(constants); }, BankTypes::Rich1), std::make_tuple( Allen::NonEventData::Rich1Geometry {}, - [&constants]() { - return std::make_unique(constants); - }, + [&constants]() { return std::make_unique(constants); }, BankTypes::Rich1), std::make_tuple( Allen::NonEventData::RichPDMDBMapping {}, - [&constants]() { - return std::make_unique(constants); - }, + [&constants]() { return std::make_unique(constants); }, BankTypes::Rich2), std::make_tuple( Allen::NonEventData::RichCableMapping {}, - [&constants]() { - return std::make_unique(constants); - }, + [&constants]() { return std::make_unique(constants); }, BankTypes::Rich2), std::make_tuple( Allen::NonEventData::Rich2Geometry {}, - [&constants]() { - return std::make_unique(constants); - }, + [&constants]() { return std::make_unique(constants); }, BankTypes::Rich2)); const auto unconditional_consumers = std::make_tuple( -- GitLab From 97504f1a147de2247d520b5cc301951b9947239d Mon Sep 17 00:00:00 2001 From: ipalmame Date: Fri, 6 Jun 2025 20:29:46 +0200 Subject: [PATCH 44/92] Restored copy constructors --- .../rich/include/RichPhotonDetector.cuh | 12 +++++++++++ .../rich/include/RichPhotonDetectorPanel.cuh | 21 +++++++++++++++++++ .../decoding/include/RichSmartIDHelper.cuh | 12 ++++------- device/rich/decoding/src/RichSmartIDHelper.cu | 2 +- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/device/event_model/rich/include/RichPhotonDetector.cuh b/device/event_model/rich/include/RichPhotonDetector.cuh index 1147a8783b0..b99eb49e7d1 100644 --- a/device/event_model/rich/include/RichPhotonDetector.cuh +++ b/device/event_model/rich/include/RichPhotonDetector.cuh @@ -35,6 +35,18 @@ namespace Rich::Detector { return Point {xh, yh, m_localZcoord}; } + +/// Copy assignment operator + __host__ __device__ PhotonDetector& operator=(const PhotonDetector&) = default; + /// Copy Constructor + __host__ __device__ PhotonDetector(const PhotonDetector& pd) : + m_locToGloM(pd.m_locToGloM), m_zeroInPanelFrame(pd.m_zeroInPanelFrame), m_pdSmartID(pd.m_pdSmartID), + m_effPixelArea(pd.m_effPixelArea), m_numPixels(pd.m_numPixels), m_localZcoord(pd.m_localZcoord), + m_numPixColFrac(pd.m_numPixColFrac), m_numPixRowFrac(pd.m_numPixRowFrac), + m_effectivePixelXSize(pd.m_effectivePixelXSize), m_effectivePixelYSize(pd.m_effectivePixelYSize), + m_isHType(pd.m_isHType), m_isNull(pd.m_isNull) + {} + __host__ __device__ inline auto globalDetectionPoint(const Decoding::SmartID id) const noexcept { return transform3DTimesPoint(localToGlobal(), panelDetectionPoint(id)); diff --git a/device/event_model/rich/include/RichPhotonDetectorPanel.cuh b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh index 3de6a6e16f7..52d8c1180f0 100644 --- a/device/event_model/rich/include/RichPhotonDetectorPanel.cuh +++ b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh @@ -21,6 +21,27 @@ namespace Rich::Detector { using PDArray = std::array; using ModuleArray = std::array; +PDPanel(Type rich, Side side, std::array gloToPDPanelM, ModuleArray PDs) : + m_PDs(std::move(PDs)), m_gloToPDPanelM(gloToPDPanelM), m_panelID({rich, side, 0}), m_rich(rich), m_side(side) + {} + + PDPanel(const PDPanel& other) : + m_gloToPDPanelM(other.m_gloToPDPanelM), m_panelID(other.m_panelID), m_rich(other.m_rich), m_side(other.m_side) + { + for (size_t i = 0; i < other.m_PDs.size(); ++i) { + for (size_t j = 0; j < other.m_PDs[i].size(); ++j) { + if (!(other.m_PDs[i][j].getIsNull())) { + m_PDs[i][j] = PhotonDetector(other.m_PDs[i][j]); + } + else { + m_PDs[i][j] = PhotonDetector(); + m_PDs[i][j].setIsNull(true); + } + } + } + } + + /// Access the RICH detector type __host__ __device__ inline auto rich() const noexcept { return m_rich; } diff --git a/device/rich/decoding/include/RichSmartIDHelper.cuh b/device/rich/decoding/include/RichSmartIDHelper.cuh index 9d6770f851f..e9252549f97 100644 --- a/device/rich/decoding/include/RichSmartIDHelper.cuh +++ b/device/rich/decoding/include/RichSmartIDHelper.cuh @@ -26,11 +26,7 @@ namespace Rich::PixelReco { m_pdPanels {&pdPanel1, &pdPanel2} {} - __host__ __device__ SmartIDHelper(const std::array m_pdPanels) : - m_pdPanels {m_pdPanels} - {} - - __host__ __device__ inline auto panel(Decoding::SmartID smartID) const -> const Detector::PDPanel* + __host__ __device__ inline auto panel(const Decoding::SmartID& smartID) const -> const Detector::PDPanel* { // Determine the side Detector::Side side = (Detector::Side) smartID.panel(); @@ -50,7 +46,7 @@ namespace Rich::PixelReco { } // Converts an PD RichSmartID identification into a position in global LHCb coordinates. - __host__ __device__ Point pdPosition(const Decoding::SmartID pdid) const; + __host__ __device__ Point pdPosition(const Decoding::SmartID& pdid) const; // Converts a position in global coordinates to the corresponding RichSmartID __host__ __device__ bool smartID(const Point& globalPoint, Decoding::SmartID& smartid) const; @@ -59,12 +55,12 @@ namespace Rich::PixelReco { __host__ __device__ Point globalToPDPanel(const Point& globalPoint) const; // Get the position for a given SmartID at the LHCb general level. - __host__ __device__ inline auto globalPosition(const Decoding::SmartID id) const + __host__ __device__ inline auto globalPosition(const Decoding::SmartID& id) const { return panel(id)->globalDetectionPoint(id); } // Get the position for a given SmartID at the detector local coordinates. - __host__ __device__ inline auto localPosition(const Point globalPoint) const + __host__ __device__ inline auto localPosition(const Point& globalPoint) const { return globalToPDPanel(globalPoint); } diff --git a/device/rich/decoding/src/RichSmartIDHelper.cu b/device/rich/decoding/src/RichSmartIDHelper.cu index df24b441a4a..f5594ede74d 100644 --- a/device/rich/decoding/src/RichSmartIDHelper.cu +++ b/device/rich/decoding/src/RichSmartIDHelper.cu @@ -12,7 +12,7 @@ #include #include -Rich::Point Rich::PixelReco::SmartIDHelper::pdPosition(const Rich::Decoding::SmartID pdid) const +Rich::Point Rich::PixelReco::SmartIDHelper::pdPosition(const Rich::Decoding::SmartID& pdid) const { // Create temporary RichSmartIDHelper for two corners of the PD wafer Rich::Decoding::SmartID id1(pdid), id0(pdid); -- GitLab From e3a5628c01198b6c0e8176599f6360ac2b6ecf02 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Tue, 10 Jun 2025 17:47:13 +0200 Subject: [PATCH 45/92] add back ci sequence --- ...matching_and_downstream_with_parkf_rich.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 configuration/python/AllenSequences/hlt1_pp_forward_then_matching_and_downstream_with_parkf_rich.py diff --git a/configuration/python/AllenSequences/hlt1_pp_forward_then_matching_and_downstream_with_parkf_rich.py b/configuration/python/AllenSequences/hlt1_pp_forward_then_matching_and_downstream_with_parkf_rich.py new file mode 100644 index 00000000000..8f4d3e4b053 --- /dev/null +++ b/configuration/python/AllenSequences/hlt1_pp_forward_then_matching_and_downstream_with_parkf_rich.py @@ -0,0 +1,20 @@ +############################################################################### +# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the Apache License # +# version 2 (Apache-2.0), copied verbatim in the file "LICENSE". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from AllenConf.HLT1 import setup_hlt1_node +from AllenCore.generator import generate +from AllenConf.enum_types import TrackingType + +hlt1_node = setup_hlt1_node( + tracking_type=TrackingType.FORWARD_THEN_MATCHING, + enableDownstream=True, + with_fullKF=True, + with_rich=True) +generate(hlt1_node) -- GitLab From 74d17dbf0d12cfbdf58dc03e52103671afbf9077 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Tue, 10 Jun 2025 15:47:51 +0000 Subject: [PATCH 46/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/57265084 --- device/event_model/rich/include/RichPhotonDetector.cuh | 3 +-- device/event_model/rich/include/RichPhotonDetectorPanel.cuh | 3 +-- device/rich/decoding/src/RichMakePixels.cu | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/device/event_model/rich/include/RichPhotonDetector.cuh b/device/event_model/rich/include/RichPhotonDetector.cuh index b99eb49e7d1..3a5fe73ac52 100644 --- a/device/event_model/rich/include/RichPhotonDetector.cuh +++ b/device/event_model/rich/include/RichPhotonDetector.cuh @@ -35,8 +35,7 @@ namespace Rich::Detector { return Point {xh, yh, m_localZcoord}; } - -/// Copy assignment operator + /// Copy assignment operator __host__ __device__ PhotonDetector& operator=(const PhotonDetector&) = default; /// Copy Constructor __host__ __device__ PhotonDetector(const PhotonDetector& pd) : diff --git a/device/event_model/rich/include/RichPhotonDetectorPanel.cuh b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh index 52d8c1180f0..654d58ea1de 100644 --- a/device/event_model/rich/include/RichPhotonDetectorPanel.cuh +++ b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh @@ -21,7 +21,7 @@ namespace Rich::Detector { using PDArray = std::array; using ModuleArray = std::array; -PDPanel(Type rich, Side side, std::array gloToPDPanelM, ModuleArray PDs) : + PDPanel(Type rich, Side side, std::array gloToPDPanelM, ModuleArray PDs) : m_PDs(std::move(PDs)), m_gloToPDPanelM(gloToPDPanelM), m_panelID({rich, side, 0}), m_rich(rich), m_side(side) {} @@ -41,7 +41,6 @@ PDPanel(Type rich, Side side, std::array gloToPDPanelM, ModuleArray P } } - /// Access the RICH detector type __host__ __device__ inline auto rich() const noexcept { return m_rich; } diff --git a/device/rich/decoding/src/RichMakePixels.cu b/device/rich/decoding/src/RichMakePixels.cu index 311746d4897..13213c320e1 100644 --- a/device/rich/decoding/src/RichMakePixels.cu +++ b/device/rich/decoding/src/RichMakePixels.cu @@ -125,4 +125,3 @@ void rich_make_pixels::rich_make_pixels_t::operator()( dim3(ceil(static_cast(size(arguments)) / block_dim.x)), m_block_dim, context)( data(arguments), data(arguments), size(arguments), rich); } - -- GitLab From c696bae03a69264bc1504d4767814c351597cb28 Mon Sep 17 00:00:00 2001 From: ipalmame Date: Wed, 11 Jun 2025 01:53:59 +0200 Subject: [PATCH 47/92] Removed copy constructors --- device/event_model/rich/include/Rich.cuh | 6 +++--- .../rich/include/RichPhotonDetectorPanel.cuh | 18 +++--------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/device/event_model/rich/include/Rich.cuh b/device/event_model/rich/include/Rich.cuh index 734e87325ba..eda04ed7b3e 100644 --- a/device/event_model/rich/include/Rich.cuh +++ b/device/event_model/rich/include/Rich.cuh @@ -17,9 +17,9 @@ namespace Rich { public: __host__ __device__ RichDetector() = default; - __host__ __device__ RichDetector(const Detector::Type m_type, const std::array m_panels) : - m_panels(m_panels), m_type(m_type) - {} + RichDetector(const RichDetector&) = delete; + + RichDetector& operator=(const RichDetector&) = delete; __host__ __device__ inline auto rich() { return m_type; } diff --git a/device/event_model/rich/include/RichPhotonDetectorPanel.cuh b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh index 654d58ea1de..1b6d65c46ed 100644 --- a/device/event_model/rich/include/RichPhotonDetectorPanel.cuh +++ b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh @@ -25,21 +25,9 @@ namespace Rich::Detector { m_PDs(std::move(PDs)), m_gloToPDPanelM(gloToPDPanelM), m_panelID({rich, side, 0}), m_rich(rich), m_side(side) {} - PDPanel(const PDPanel& other) : - m_gloToPDPanelM(other.m_gloToPDPanelM), m_panelID(other.m_panelID), m_rich(other.m_rich), m_side(other.m_side) - { - for (size_t i = 0; i < other.m_PDs.size(); ++i) { - for (size_t j = 0; j < other.m_PDs[i].size(); ++j) { - if (!(other.m_PDs[i][j].getIsNull())) { - m_PDs[i][j] = PhotonDetector(other.m_PDs[i][j]); - } - else { - m_PDs[i][j] = PhotonDetector(); - m_PDs[i][j].setIsNull(true); - } - } - } - } + PDPanel(const PDPanel&) = delete; + + PDPanel& operator=(const PDPanel&) = delete; /// Access the RICH detector type __host__ __device__ inline auto rich() const noexcept { return m_rich; } -- GitLab From 7d0b4d7c9a90bc214b963bfd67da452a438d8403 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Tue, 10 Jun 2025 23:54:38 +0000 Subject: [PATCH 48/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/57276654 --- device/event_model/rich/include/Rich.cuh | 2 +- device/event_model/rich/include/RichPhotonDetectorPanel.cuh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/device/event_model/rich/include/Rich.cuh b/device/event_model/rich/include/Rich.cuh index eda04ed7b3e..9730bf58749 100644 --- a/device/event_model/rich/include/Rich.cuh +++ b/device/event_model/rich/include/Rich.cuh @@ -18,7 +18,7 @@ namespace Rich { __host__ __device__ RichDetector() = default; RichDetector(const RichDetector&) = delete; - + RichDetector& operator=(const RichDetector&) = delete; __host__ __device__ inline auto rich() { return m_type; } diff --git a/device/event_model/rich/include/RichPhotonDetectorPanel.cuh b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh index 1b6d65c46ed..873f1954d81 100644 --- a/device/event_model/rich/include/RichPhotonDetectorPanel.cuh +++ b/device/event_model/rich/include/RichPhotonDetectorPanel.cuh @@ -25,9 +25,9 @@ namespace Rich::Detector { m_PDs(std::move(PDs)), m_gloToPDPanelM(gloToPDPanelM), m_panelID({rich, side, 0}), m_rich(rich), m_side(side) {} - PDPanel(const PDPanel&) = delete; - - PDPanel& operator=(const PDPanel&) = delete; + PDPanel(const PDPanel&) = delete; + + PDPanel& operator=(const PDPanel&) = delete; /// Access the RICH detector type __host__ __device__ inline auto rich() const noexcept { return m_rich; } -- GitLab From 090b4608b54e07c0c57234b418a37199b63ce518 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Tue, 10 Jun 2025 18:20:29 -0600 Subject: [PATCH 49/92] remove comments --- device/event_model/rich/include/RichPhotonDetector.cuh | 3 --- 1 file changed, 3 deletions(-) diff --git a/device/event_model/rich/include/RichPhotonDetector.cuh b/device/event_model/rich/include/RichPhotonDetector.cuh index 3a5fe73ac52..ced775d8c13 100644 --- a/device/event_model/rich/include/RichPhotonDetector.cuh +++ b/device/event_model/rich/include/RichPhotonDetector.cuh @@ -17,9 +17,6 @@ namespace Rich::Detector { class PhotonDetector { - // using FP = Rich::FP; - // using Point = Rich::Point; - public: /// Default constructor __host__ __device__ PhotonDetector() = default; -- GitLab From 24a5c30995f2583c51381bec62eccf8c5e5b9393 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Thu, 12 Jun 2025 22:45:13 +0200 Subject: [PATCH 50/92] warp intrinsics on richDecoding --- device/rich/decoding/include/RichDecoding.cuh | 2 +- device/rich/decoding/src/RichDecoding.cu | 51 ++++++++++++++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/device/rich/decoding/include/RichDecoding.cuh b/device/rich/decoding/include/RichDecoding.cuh index 156fe8b57e7..2146d998cc6 100644 --- a/device/rich/decoding/include/RichDecoding.cuh +++ b/device/rich/decoding/include/RichDecoding.cuh @@ -37,6 +37,6 @@ namespace rich_decoding { const Allen::Context&) const; private: - Allen::Property m_block_dim {this, "block_dim", {64, 1, 1}, "block dimensions"}; + Allen::Property m_block_dim {this, "block_dim", {32, 32, 1}, "block dimensions"}; }; } // namespace rich_decoding diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index 2d24cd16b62..1e6be0fed0c 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -13,6 +13,8 @@ #include #include #include +#include +#include INSTANTIATE_ALGORITHM(rich_decoding::rich_decoding_t) @@ -22,8 +24,10 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping) { unsigned number_of_hits = 0; - std::array - connSizes {}; + //std::array + // connSizes {}; + + __shared__ Rich::Decoding::PackedFrameSizes::IntType connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; auto tel40ID = bank.source_id; const auto& connMeta = cable_mapping->tel40Meta(tel40ID); @@ -35,15 +39,25 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( auto iPayloadWord = 0u; auto iWord = 0u; + const auto& connData = cable_mapping->tel40Data(tel40ID); +#if defined(TARGET_DEVICE_CUDA) + for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks + uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); + auto idx = __popc(active & __lanemask_lt()); // count the number of active before the current thread + const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); + connSizes[idx] = iWord % 2 ? sizes.size0() : sizes.size1(); +} + +#elif defined(TARGET_DEVICE_CPU) + for (; iWord < nPackedSizeW && dataW != bankEnd; ++dataW, ++iWord, iPayloadWord += 2) { - // Extract the sizes from the packed word + //Extract the sizes from the packed word const Rich::Decoding::PackedFrameSizes sizes(*dataW); // extract sizes for each packed value connSizes[iPayloadWord] = sizes.size1(); connSizes[iPayloadWord + 1] = sizes.size0(); } - const auto& connData = cable_mapping->tel40Data(tel40ID); if (connMeta.hasInactiveLinks) { for (unsigned iL = 0; iL < connData.size(); ++iL) { if (!connData[iL].isActive) { @@ -52,13 +66,15 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( } connSizes[iL] = 0; } - } + } } +#endif + // finally loop over payload words and decode hits // note iterator starts from where the above header loop ended... unsigned iLink {0}; - while (dataW != bankEnd && iLink < connSizes.size()) { + while (dataW != bankEnd && iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40 /**connSizes.size()**/) { // Do we have any words to decode for this link if (connSizes[iLink] > 0) { // Get the Tel40 Data for this connection @@ -175,7 +191,7 @@ __global__ void rich_calculate_number_of_hits( parameters.dev_rich_raw_input_sizes, parameters.dev_rich_raw_input_types, event_number + event_start}; - for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { + for (unsigned bank_number = threadIdx.y; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.y) { const auto bank = raw_event.raw_bank(bank_number); const auto number_of_hits_in_raw_bank = rich_calculate_number_of_hits_in_raw_bank(bank, cable_mapping, pdmdb_mapping); @@ -192,8 +208,9 @@ __device__ void rich_decode_bank( unsigned* event_inserted_hits, Rich::Decoding::SmartID* event_smart_ids) { - std::array - connSizes {}; + //std::array + //connSizes {}; + __shared__ Rich::Decoding::PackedFrameSizes::IntType connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; auto tel40ID = bank.source_id; const auto& connMeta = cable_mapping->tel40Meta(tel40ID); @@ -204,7 +221,16 @@ __device__ void rich_decode_bank( auto bankEnd = bank.data + bank.size; auto iPayloadWord = 0u; auto iWord = 0u; + const auto& connData = cable_mapping->tel40Data(tel40ID); +#if defined(TARGET_DEVICE_CUDA) + for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks + uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); + auto idx = __popc(active & __lanemask_lt()); // count the number of active before the current thread + const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); + connSizes[idx] = iWord % 2 ? sizes.size0() : sizes.size1(); + } +#elif defined(TARGET_DEVICE_CPU) for (; iWord < nPackedSizeW && dataW != bankEnd; ++dataW, ++iWord, iPayloadWord += 2) { // Extract the sizes from the packed word const Rich::Decoding::PackedFrameSizes sizes(*dataW); @@ -212,8 +238,7 @@ __device__ void rich_decode_bank( connSizes[iPayloadWord] = sizes.size1(); connSizes[iPayloadWord + 1] = sizes.size0(); } - - const auto& connData = cable_mapping->tel40Data(tel40ID); + if (connMeta.hasInactiveLinks) { for (unsigned iL = 0; iL < connData.size(); ++iL) { if (!connData[iL].isActive) { @@ -224,11 +249,11 @@ __device__ void rich_decode_bank( } } } - +#endif // finally loop over payload words and decode hits // note iterator starts from where the above header loop ended... unsigned iLink {0}; - while (dataW != bankEnd && iLink < connSizes.size()) { + while (dataW != bankEnd && iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40 /*connSizes.size()*/) { // Do we have any words to decode for this link if (connSizes[iLink] > 0) { // Get the Tel40 Data for this connection -- GitLab From 5f5859809c7cc6aa27e6559882f2b0e1b79bdf85 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 13 Jun 2025 19:14:37 +0200 Subject: [PATCH 51/92] progress into warpIntrinsics, some pixels correctly created --- device/rich/decoding/src/RichDecoding.cu | 87 +++++++++++++++++------- 1 file changed, 63 insertions(+), 24 deletions(-) diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index 1e6be0fed0c..3a87e427ba9 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -13,8 +13,7 @@ #include #include #include -#include -#include +#include INSTANTIATE_ALGORITHM(rich_decoding::rich_decoding_t) @@ -35,11 +34,32 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const auto nPackedSizeW = (nSizeWords / 2) + (nSizeWords % 2); auto dataW = bank.data; + __shared__ auto processedWords = 0; auto bankEnd = bank.data + bank.size; - auto iPayloadWord = 0u; - auto iWord = 0u; - const auto& connData = cable_mapping->tel40Data(tel40ID); + + // index = iWord = dataW = (iPayloadWord/2) + if (threadIdx.x ==0) + std::cout << "DEBUG IPM JRG 1" << std::endl; + for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { + const auto wordPtr = dataW + iWord; + if (wordPtr != bankEnd) { + Allen::warp::atomic_increment(&processedWords); + //if (iWord < bank.size) { + //const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); + // Extract the sizes from the packed word + const Rich::Decoding::PackedFrameSizes sizes(*wordPtr); + // extract sizes for each packed value + unsigned iPayloadWord = iWord * 2; + connSizes[iPayloadWord] = sizes.size1(); + connSizes[iPayloadWord + 1] = sizes.size0(); + } + } + __syncthreads(); + + if (threadIdx.x ==0) + std::cout << "DEBUG IPM JRG 2.1" << std::endl; + #if defined(TARGET_DEVICE_CUDA) for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); @@ -49,15 +69,6 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( } #elif defined(TARGET_DEVICE_CPU) - - for (; iWord < nPackedSizeW && dataW != bankEnd; ++dataW, ++iWord, iPayloadWord += 2) { - //Extract the sizes from the packed word - const Rich::Decoding::PackedFrameSizes sizes(*dataW); - // extract sizes for each packed value - connSizes[iPayloadWord] = sizes.size1(); - connSizes[iPayloadWord + 1] = sizes.size0(); - } - if (connMeta.hasInactiveLinks) { for (unsigned iL = 0; iL < connData.size(); ++iL) { if (!connData[iL].isActive) { @@ -71,6 +82,8 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( #endif + dataW += processedWords + 1; + __syncthreads(); // finally loop over payload words and decode hits // note iterator starts from where the above header loop ended... unsigned iLink {0}; @@ -218,10 +231,32 @@ __device__ void rich_decode_bank( const auto nPackedSizeW = (nSizeWords / 2) + (nSizeWords % 2); auto dataW = bank.data; + __shared__ auto processedWords = 0; auto bankEnd = bank.data + bank.size; - auto iPayloadWord = 0u; - auto iWord = 0u; const auto& connData = cable_mapping->tel40Data(tel40ID); + + // index = iWord = dataW = (iPayloadWord/2) + if (threadIdx.x ==0) + std::cout << "DEBUG IPM JRG 1" << std::endl; + for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { + const auto wordPtr = dataW + iWord; + if (wordPtr != bankEnd) { + Allen::warp::atomic_increment(&processedWords); + //if (iWord < bank.size) { + //const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); + // Extract the sizes from the packed word + const Rich::Decoding::PackedFrameSizes sizes(*wordPtr); + // extract sizes for each packed value + unsigned iPayloadWord = iWord * 2; + connSizes[iPayloadWord] = sizes.size1(); + connSizes[iPayloadWord + 1] = sizes.size0(); + } + } + __syncthreads(); + + if (threadIdx.x ==0) + std::cout << "DEBUG IPM JRG 2" << std::endl; + #if defined(TARGET_DEVICE_CUDA) for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); @@ -230,15 +265,8 @@ __device__ void rich_decode_bank( connSizes[idx] = iWord % 2 ? sizes.size0() : sizes.size1(); } + #elif defined(TARGET_DEVICE_CPU) - for (; iWord < nPackedSizeW && dataW != bankEnd; ++dataW, ++iWord, iPayloadWord += 2) { - // Extract the sizes from the packed word - const Rich::Decoding::PackedFrameSizes sizes(*dataW); - // extract sizes for each packed value - connSizes[iPayloadWord] = sizes.size1(); - connSizes[iPayloadWord + 1] = sizes.size0(); - } - if (connMeta.hasInactiveLinks) { for (unsigned iL = 0; iL < connData.size(); ++iL) { if (!connData[iL].isActive) { @@ -250,6 +278,13 @@ __device__ void rich_decode_bank( } } #endif + + if (threadIdx.x ==0) + std::cout << "DEBUG IPM JRG 3" << std::endl; + + dataW += processedWords + 1; + __syncthreads(); + // finally loop over payload words and decode hits // note iterator starts from where the above header loop ended... unsigned iLink {0}; @@ -405,6 +440,10 @@ __device__ void rich_decode_bank( // move to next Tel40 link ++iLink; } // data word loop + if (threadIdx.x ==0) + std::cout << "DEBUG IPM JRG 2" << std::endl; + + } template -- GitLab From 51eb12813e3ef01fae415b74756aea3e7a549c30 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 13 Jun 2025 19:52:59 +0200 Subject: [PATCH 52/92] CPU version working, While loop yet to parallelize --- device/rich/decoding/src/RichDecoding.cu | 87 +++++++----------------- 1 file changed, 26 insertions(+), 61 deletions(-) diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index 3a87e427ba9..9101829da00 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -23,8 +23,6 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping) { unsigned number_of_hits = 0; - //std::array - // connSizes {}; __shared__ Rich::Decoding::PackedFrameSizes::IntType connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; @@ -39,14 +37,10 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const auto& connData = cable_mapping->tel40Data(tel40ID); // index = iWord = dataW = (iPayloadWord/2) - if (threadIdx.x ==0) - std::cout << "DEBUG IPM JRG 1" << std::endl; for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { const auto wordPtr = dataW + iWord; if (wordPtr != bankEnd) { Allen::warp::atomic_increment(&processedWords); - //if (iWord < bank.size) { - //const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); // Extract the sizes from the packed word const Rich::Decoding::PackedFrameSizes sizes(*wordPtr); // extract sizes for each packed value @@ -57,9 +51,6 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( } __syncthreads(); - if (threadIdx.x ==0) - std::cout << "DEBUG IPM JRG 2.1" << std::endl; - #if defined(TARGET_DEVICE_CUDA) for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); @@ -69,23 +60,26 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( } #elif defined(TARGET_DEVICE_CPU) - if (connMeta.hasInactiveLinks) { - for (unsigned iL = 0; iL < connData.size(); ++iL) { - if (!connData[iL].isActive) { - for (auto i = connData.size() - 1; i > iL; --i) { - connSizes[i] = connSizes[i - 1]; + // Sequentially + if (threadIdx.x == 0) { + if (connMeta.hasInactiveLinks) { + for (unsigned iL = 0; iL < connData.size(); ++iL) { + if (!connData[iL].isActive) { + for (auto i = connData.size() - 1; i > iL; --i) { + connSizes[i] = connSizes[i - 1]; + } + connSizes[iL] = 0; } - connSizes[iL] = 0; } - } + } } #endif - - dataW += processedWords + 1; - __syncthreads(); + // finally loop over payload words and decode hits // note iterator starts from where the above header loop ended... + dataW += processedWords; + __syncthreads(); unsigned iLink {0}; while (dataW != bankEnd && iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40 /**connSizes.size()**/) { // Do we have any words to decode for this link @@ -166,26 +160,19 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( number_of_hits++; } } - } // bit is on } // loop over word bits - } // word has any data - } // loop over all NZS words - // Finally skip the read NZS words iW += nNZSwords; dataW += nNZSwords; } } - } // no data for this link, so just move on - // move to next Tel40 link ++iLink; } // data word loop - return number_of_hits; } @@ -221,8 +208,6 @@ __device__ void rich_decode_bank( unsigned* event_inserted_hits, Rich::Decoding::SmartID* event_smart_ids) { - //std::array - //connSizes {}; __shared__ Rich::Decoding::PackedFrameSizes::IntType connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; auto tel40ID = bank.source_id; @@ -236,14 +221,10 @@ __device__ void rich_decode_bank( const auto& connData = cable_mapping->tel40Data(tel40ID); // index = iWord = dataW = (iPayloadWord/2) - if (threadIdx.x ==0) - std::cout << "DEBUG IPM JRG 1" << std::endl; for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { const auto wordPtr = dataW + iWord; if (wordPtr != bankEnd) { Allen::warp::atomic_increment(&processedWords); - //if (iWord < bank.size) { - //const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); // Extract the sizes from the packed word const Rich::Decoding::PackedFrameSizes sizes(*wordPtr); // extract sizes for each packed value @@ -254,40 +235,34 @@ __device__ void rich_decode_bank( } __syncthreads(); - if (threadIdx.x ==0) - std::cout << "DEBUG IPM JRG 2" << std::endl; - #if defined(TARGET_DEVICE_CUDA) - for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks + for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, using blockDim.y to dispatch between banks uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); auto idx = __popc(active & __lanemask_lt()); // count the number of active before the current thread const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); connSizes[idx] = iWord % 2 ? sizes.size0() : sizes.size1(); } - #elif defined(TARGET_DEVICE_CPU) - if (connMeta.hasInactiveLinks) { - for (unsigned iL = 0; iL < connData.size(); ++iL) { - if (!connData[iL].isActive) { - for (auto i = connData.size() - 1; i > iL; --i) { - connSizes[i] = connSizes[i - 1]; + if (threadIdx.x == 0) { + if (connMeta.hasInactiveLinks) { + for (unsigned iL = 0; iL < connData.size(); ++iL) { + if (!connData[iL].isActive) { + for (auto i = connData.size() - 1; i > iL; --i) { + connSizes[i] = connSizes[i - 1]; + } + connSizes[iL] = 0; } - connSizes[iL] = 0; } } } #endif - if (threadIdx.x ==0) - std::cout << "DEBUG IPM JRG 3" << std::endl; - - dataW += processedWords + 1; - __syncthreads(); - // finally loop over payload words and decode hits // note iterator starts from where the above header loop ended... - unsigned iLink {0}; + dataW += processedWords; + __syncthreads(); + unsigned iLink {0}; while (dataW != bankEnd && iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40 /*connSizes.size()*/) { // Do we have any words to decode for this link if (connSizes[iLink] > 0) { @@ -421,29 +396,19 @@ __device__ void rich_decode_bank( event_smart_ids[insert_index] = hitID; } } - } // bit is on } // loop over word bits - } // word has any data - } // loop over all NZS words - // Finally skip the read NZS words iW += nNZSwords; dataW += nNZSwords; } } - } // no data for this link, so just move on - // move to next Tel40 link ++iLink; } // data word loop - if (threadIdx.x ==0) - std::cout << "DEBUG IPM JRG 2" << std::endl; - - } template @@ -465,7 +430,7 @@ __global__ void rich_decoding_kernel( parameters.dev_rich_raw_input_sizes, parameters.dev_rich_raw_input_types, event_number + event_start}; - for (unsigned bank_number = threadIdx.x; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.x) { + for (unsigned bank_number = threadIdx.y; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.y) { const auto bank = raw_event.raw_bank(bank_number); rich_decode_bank(bank, cable_mapping, pdmdb_mapping, event_inserted_hits, event_smart_ids); } -- GitLab From adfed63dbd8da5b1eefc22decb30a9291b240a7c Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 13 Jun 2025 20:38:07 +0200 Subject: [PATCH 53/92] one thread per link in While loop done, CPU fully working, will proceed to test GPU --- device/rich/decoding/src/RichDecoding.cu | 461 +++++++++++------------ 1 file changed, 230 insertions(+), 231 deletions(-) diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index 9101829da00..e4939c35ff7 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -80,98 +80,98 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( // note iterator starts from where the above header loop ended... dataW += processedWords; __syncthreads(); - unsigned iLink {0}; - while (dataW != bankEnd && iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40 /**connSizes.size()**/) { - // Do we have any words to decode for this link - if (connSizes[iLink] > 0) { - // Get the Tel40 Data for this connection - const auto& cData = connData[iLink]; - - // get the PDMDB data - const auto& frameData = pdmdb_mapping->getFrameData(cData); - - // Loop over the words for this link - uint16_t iW = 0; - while (iW < connSizes[iLink] && dataW != bankEnd) { - - // check MSB for this word - const auto isNZS = (0x80 & *dataW) != 0; - - if (!isNZS) { - // ZS decoding... word is bit index - - // load the anode data for this bit - if ((unsigned) (*dataW) < frameData.size()) { - const auto& aData = frameData[*dataW]; - - // Data 'could' be invalid, e.g. radiation-induced-upsets - // so cannot make this a hard error - if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { - number_of_hits++; + for (unsigned iLink = threadIdx.x; iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; iLink += blockDim.x) { + if (dataW != bankEnd) { + // Do we have any words to decode for this link + if (connSizes[iLink] > 0) { + // Get the Tel40 Data for this connection + const auto& cData = connData[iLink]; + + // get the PDMDB data + const auto& frameData = pdmdb_mapping->getFrameData(cData); + + // Loop over the words for this link + uint16_t iW = 0; + while (iW < connSizes[iLink] && dataW != bankEnd) { + + // check MSB for this word + const auto isNZS = (0x80 & *dataW) != 0; + + if (!isNZS) { + // ZS decoding... word is bit index + + // load the anode data for this bit + if ((unsigned) (*dataW) < frameData.size()) { + const auto& aData = frameData[*dataW]; + + // Data 'could' be invalid, e.g. radiation-induced-upsets + // so cannot make this a hard error + if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { + number_of_hits++; + } } - } - - // move to next word - ++iW; - ++dataW; - } - else { - // NZS decoding... - - // which half of the payload are we in ? - const bool firstHalf = (0 == iW && connSizes[iLink] > 5); - // Number of words to decode depends on which half of the payload we are in - const auto nNZSwords = (firstHalf ? 6 : 5); - // bit offset per half - const auto halfBitOffset = (firstHalf ? 39 : 0); - - // look forward last NZS word and read backwards to match frame bit order - for (auto iNZS = nNZSwords - 1; iNZS >= 0; --iNZS) { - - // read the NZS word - auto nzsW = *(dataW + iNZS); - // if word zero clear MSB as this is the NZS flag - if (0 == iNZS) { - nzsW &= 0x7F; - } - - // does this word hold any active bits ? - if (nzsW > 0) { - // Bit offset for this word - const auto bitOffset = halfBitOffset + (8 * (nNZSwords - 1 - iNZS)); - - // word has data so loop over bits to extract - for (auto iLB = 0; iLB < 8; ++iLB) { - // is bit on ? - // if ( isBitOn( nzsW, iLB ) ) { - if ((nzsW & (1 << iLB)) != 0) { - - // form frame bit value - const auto bit = iLB + bitOffset; - - // load the anode data for this bit - if ((size_t)(bit) < frameData.size()) { - const auto& aData = frameData[bit]; - - // Data 'could' be invalid, e.g. radiation-induced-upsets - // so cannot make this a hard error - if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { - number_of_hits++; + // move to next word + ++iW; + ++dataW; + } + else { + // NZS decoding... + + // which half of the payload are we in ? + const bool firstHalf = (0 == iW && connSizes[iLink] > 5); + // Number of words to decode depends on which half of the payload we are in + const auto nNZSwords = (firstHalf ? 6 : 5); + // bit offset per half + const auto halfBitOffset = (firstHalf ? 39 : 0); + + // look forward last NZS word and read backwards to match frame bit order + for (auto iNZS = nNZSwords - 1; iNZS >= 0; --iNZS) { + + // read the NZS word + auto nzsW = *(dataW + iNZS); + // if word zero clear MSB as this is the NZS flag + if (0 == iNZS) { + nzsW &= 0x7F; + } + + // does this word hold any active bits ? + if (nzsW > 0) { + + // Bit offset for this word + const auto bitOffset = halfBitOffset + (8 * (nNZSwords - 1 - iNZS)); + + // word has data so loop over bits to extract + for (auto iLB = 0; iLB < 8; ++iLB) { + // is bit on ? + // if ( isBitOn( nzsW, iLB ) ) { + if ((nzsW & (1 << iLB)) != 0) { + + // form frame bit value + const auto bit = iLB + bitOffset; + + // load the anode data for this bit + if ((size_t)(bit) < frameData.size()) { + const auto& aData = frameData[bit]; + + // Data 'could' be invalid, e.g. radiation-induced-upsets + // so cannot make this a hard error + if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { + number_of_hits++; + } } - } - } // bit is on - } // loop over word bits - } // word has any data - } // loop over all NZS words - // Finally skip the read NZS words - iW += nNZSwords; - dataW += nNZSwords; + } // bit is on + } // loop over word bits + } // word has any data + } // loop over all NZS words + // Finally skip the read NZS words + iW += nNZSwords; + dataW += nNZSwords; + } } - } - } // no data for this link, so just move on - // move to next Tel40 link - ++iLink; + } // no data for this link, so just move on + // move to next Tel40 link + } // bankEnd reached } // data word loop return number_of_hits; } @@ -262,152 +262,151 @@ __device__ void rich_decode_bank( // note iterator starts from where the above header loop ended... dataW += processedWords; __syncthreads(); - unsigned iLink {0}; - while (dataW != bankEnd && iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40 /*connSizes.size()*/) { - // Do we have any words to decode for this link - if (connSizes[iLink] > 0) { - // Get the Tel40 Data for this connection - const auto& cData = connData[iLink]; - - // get the PDMDB data - const auto& frameData = pdmdb_mapping->getFrameData(cData); - - // Loop over the words for this link - uint16_t iW = 0; - while (iW < connSizes[iLink] && dataW != bankEnd) { - - // check MSB for this word - const auto isNZS = (0x80 & *dataW) != 0; - - if (!isNZS) { - // ZS decoding... word is bit index - - // load the anode data for this bit - if ((unsigned) (*dataW) < frameData.size()) { - - const auto& aData = frameData[*dataW]; - - // Data 'could' be invalid, e.g. radiation-induced-upsets - // so cannot make this a hard error - if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { - // make a smart ID - auto hitID = Rich::Decoding::SmartID {cData.smartID}; // sets RICH, side, module and PMT type - - // Add the PMT and pixel info - const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; - hitID.setData( - cData.moduleNum, - Rich::Decoding::SmartID::ShiftPDMod, - Rich::Decoding::SmartID::MaskPDMod, - Rich::Decoding::SmartID::MaskPDIsSet); - hitID.setData(nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); - - const auto row = aData.anode / 8; - const auto col = 8 - 1 - (aData.anode % 8); - hitID.setData( - row, - Rich::Decoding::SmartID::ShiftPixelRow, - Rich::Decoding::SmartID::MaskPixelRow, - Rich::Decoding::SmartID::MaskPixelRowIsSet); - hitID.setData( - col, - Rich::Decoding::SmartID::ShiftPixelCol, - Rich::Decoding::SmartID::MaskPixelCol, - Rich::Decoding::SmartID::MaskPixelColIsSet); - - const auto insert_index = atomicAdd(event_inserted_hits, 1); - event_smart_ids[insert_index] = hitID; - } - } - - // move to next word - ++iW; - ++dataW; - } - else { - // NZS decoding... - - // which half of the payload are we in ? - const bool firstHalf = (0 == iW && connSizes[iLink] > 5); - // Number of words to decode depends on which half of the payload we are in - const auto nNZSwords = (firstHalf ? 6 : 5); - // bit offset per half - const auto halfBitOffset = (firstHalf ? 39 : 0); - - // look forward last NZS word and read backwards to match frame bit order - for (auto iNZS = nNZSwords - 1; iNZS >= 0; --iNZS) { - - // read the NZS word - auto nzsW = *(dataW + iNZS); - // if word zero clear MSB as this is the NZS flag - if (0 == iNZS) { - nzsW &= 0x7F; + for (unsigned iLink = threadIdx.x; iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; iLink += blockDim.x) { + if (dataW != bankEnd) { + // Do we have any words to decode for this link + if (connSizes[iLink] > 0) { + // Get the Tel40 Data for this connection + const auto& cData = connData[iLink]; + + // get the PDMDB data + const auto& frameData = pdmdb_mapping->getFrameData(cData); + + // Loop over the words for this link + uint16_t iW = 0; + while (iW < connSizes[iLink] && dataW != bankEnd) { + + // check MSB for this word + const auto isNZS = (0x80 & *dataW) != 0; + + if (!isNZS) { + // ZS decoding... word is bit index + + // load the anode data for this bit + if ((unsigned) (*dataW) < frameData.size()) { + + const auto& aData = frameData[*dataW]; + + // Data 'could' be invalid, e.g. radiation-induced-upsets + // so cannot make this a hard error + if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { + // make a smart ID + auto hitID = Rich::Decoding::SmartID {cData.smartID}; // sets RICH, side, module and PMT type + + // Add the PMT and pixel info + const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; + hitID.setData( + cData.moduleNum, + Rich::Decoding::SmartID::ShiftPDMod, + Rich::Decoding::SmartID::MaskPDMod, + Rich::Decoding::SmartID::MaskPDIsSet); + hitID.setData(nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); + + const auto row = aData.anode / 8; + const auto col = 8 - 1 - (aData.anode % 8); + hitID.setData( + row, + Rich::Decoding::SmartID::ShiftPixelRow, + Rich::Decoding::SmartID::MaskPixelRow, + Rich::Decoding::SmartID::MaskPixelRowIsSet); + hitID.setData( + col, + Rich::Decoding::SmartID::ShiftPixelCol, + Rich::Decoding::SmartID::MaskPixelCol, + Rich::Decoding::SmartID::MaskPixelColIsSet); + + const auto insert_index = atomicAdd(event_inserted_hits, 1); + event_smart_ids[insert_index] = hitID; + } } - // does this word hold any active bits ? - if (nzsW > 0) { - - // Bit offset for this word - const auto bitOffset = halfBitOffset + (8 * (nNZSwords - 1 - iNZS)); - - // word has data so loop over bits to extract - for (auto iLB = 0; iLB < 8; ++iLB) { - // is bit on ? - // if ( isBitOn( nzsW, iLB ) ) { - if ((nzsW & (1 << iLB)) != 0) { - - // form frame bit value - const auto bit = iLB + bitOffset; - - // load the anode data for this bit - if ((size_t)(bit) < frameData.size()) { - const auto& aData = frameData[bit]; - // Data 'could' be invalid, e.g. radiation-induced-upsets - // so cannot make this a hard error - if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { - - // make a smart ID - auto hitID = Rich::Decoding::SmartID {cData.smartID}; // sets RICH, side, module and PMT type - - // Add the PMT and pixel info - const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; - hitID.setData( - cData.moduleNum, - Rich::Decoding::SmartID::ShiftPDMod, - Rich::Decoding::SmartID::MaskPDMod, - Rich::Decoding::SmartID::MaskPDIsSet); - hitID.setData( - nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); - - const auto row = aData.anode / 8; - const auto col = 8 - 1 - (aData.anode % 8); - hitID.setData( - row, - Rich::Decoding::SmartID::ShiftPixelRow, - Rich::Decoding::SmartID::MaskPixelRow, - Rich::Decoding::SmartID::MaskPixelRowIsSet); - hitID.setData( - col, - Rich::Decoding::SmartID::ShiftPixelCol, - Rich::Decoding::SmartID::MaskPixelCol, - Rich::Decoding::SmartID::MaskPixelColIsSet); - - const auto insert_index = atomicAdd(event_inserted_hits, 1); - event_smart_ids[insert_index] = hitID; + // move to next word + ++iW; + ++dataW; + } + else { + // NZS decoding... + + // which half of the payload are we in ? + const bool firstHalf = (0 == iW && connSizes[iLink] > 5); + // Number of words to decode depends on which half of the payload we are in + const auto nNZSwords = (firstHalf ? 6 : 5); + // bit offset per half + const auto halfBitOffset = (firstHalf ? 39 : 0); + + // look forward last NZS word and read backwards to match frame bit order + for (auto iNZS = nNZSwords - 1; iNZS >= 0; --iNZS) { + + // read the NZS word + auto nzsW = *(dataW + iNZS); + // if word zero clear MSB as this is the NZS flag + if (0 == iNZS) { + nzsW &= 0x7F; + } + + // does this word hold any active bits ? + if (nzsW > 0) { + + // Bit offset for this word + const auto bitOffset = halfBitOffset + (8 * (nNZSwords - 1 - iNZS)); + + // word has data so loop over bits to extract + for (auto iLB = 0; iLB < 8; ++iLB) { + // is bit on ? + // if ( isBitOn( nzsW, iLB ) ) { + if ((nzsW & (1 << iLB)) != 0) { + + // form frame bit value + const auto bit = iLB + bitOffset; + + // load the anode data for this bit + if ((size_t)(bit) < frameData.size()) { + const auto& aData = frameData[bit]; + // Data 'could' be invalid, e.g. radiation-induced-upsets + // so cannot make this a hard error + if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { + + // make a smart ID + auto hitID = Rich::Decoding::SmartID {cData.smartID}; // sets RICH, side, module and PMT type + + // Add the PMT and pixel info + const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; + hitID.setData( + cData.moduleNum, + Rich::Decoding::SmartID::ShiftPDMod, + Rich::Decoding::SmartID::MaskPDMod, + Rich::Decoding::SmartID::MaskPDIsSet); + hitID.setData( + nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); + + const auto row = aData.anode / 8; + const auto col = 8 - 1 - (aData.anode % 8); + hitID.setData( + row, + Rich::Decoding::SmartID::ShiftPixelRow, + Rich::Decoding::SmartID::MaskPixelRow, + Rich::Decoding::SmartID::MaskPixelRowIsSet); + hitID.setData( + col, + Rich::Decoding::SmartID::ShiftPixelCol, + Rich::Decoding::SmartID::MaskPixelCol, + Rich::Decoding::SmartID::MaskPixelColIsSet); + + const auto insert_index = atomicAdd(event_inserted_hits, 1); + event_smart_ids[insert_index] = hitID; + } } - } - } // bit is on - } // loop over word bits - } // word has any data - } // loop over all NZS words - // Finally skip the read NZS words - iW += nNZSwords; - dataW += nNZSwords; - } - } - } // no data for this link, so just move on - // move to next Tel40 link - ++iLink; + } // bit is on + } // loop over word bits + } // word has any data + } // loop over all NZS words + // Finally skip the read NZS words + iW += nNZSwords; + dataW += nNZSwords; + } + } // no data for this link, so just move on + }// move to next Tel40 link + } // bankEnd reached } // data word loop } -- GitLab From 1b146105a6d48a7fcc3e008382f5ca165ea63f55 Mon Sep 17 00:00:00 2001 From: Josef Ruzicka Gonzalez Date: Fri, 13 Jun 2025 21:02:30 +0200 Subject: [PATCH 54/92] CUDA compilable --- device/rich/decoding/src/RichDecoding.cu | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index e4939c35ff7..a062b359be2 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -32,9 +32,12 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const auto nPackedSizeW = (nSizeWords / 2) + (nSizeWords % 2); auto dataW = bank.data; - __shared__ auto processedWords = 0; + __shared__ unsigned processedWords; auto bankEnd = bank.data + bank.size; const auto& connData = cable_mapping->tel40Data(tel40ID); + + if (threadIdx.x == 0) { processedWords = 0; } + __syncthreads(); // index = iWord = dataW = (iPayloadWord/2) for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { @@ -216,9 +219,12 @@ __device__ void rich_decode_bank( const auto nPackedSizeW = (nSizeWords / 2) + (nSizeWords % 2); auto dataW = bank.data; - __shared__ auto processedWords = 0; + __shared__ unsigned processedWords; auto bankEnd = bank.data + bank.size; const auto& connData = cable_mapping->tel40Data(tel40ID); + + if (threadIdx.x == 0) { processedWords = 0; } + __syncthreads(); // index = iWord = dataW = (iPayloadWord/2) for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { -- GitLab From f13e5db64dca6e49867afe7e8e59421a8ef2b5a0 Mon Sep 17 00:00:00 2001 From: Gitlab CI Date: Fri, 13 Jun 2025 19:03:01 +0000 Subject: [PATCH 55/92] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Allen/-/jobs/57424418 --- device/rich/decoding/src/RichDecoding.cu | 65 ++++++++++++++---------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index a062b359be2..f652bb85a8b 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -24,7 +24,8 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( { unsigned number_of_hits = 0; - __shared__ Rich::Decoding::PackedFrameSizes::IntType connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; + __shared__ Rich::Decoding::PackedFrameSizes::IntType + connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; auto tel40ID = bank.source_id; const auto& connMeta = cable_mapping->tel40Meta(tel40ID); @@ -35,11 +36,13 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( __shared__ unsigned processedWords; auto bankEnd = bank.data + bank.size; const auto& connData = cable_mapping->tel40Data(tel40ID); - - if (threadIdx.x == 0) { processedWords = 0; } + + if (threadIdx.x == 0) { + processedWords = 0; + } __syncthreads(); - // index = iWord = dataW = (iPayloadWord/2) + // index = iWord = dataW = (iPayloadWord/2) for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { const auto wordPtr = dataW + iWord; if (wordPtr != bankEnd) { @@ -55,12 +58,13 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( __syncthreads(); #if defined(TARGET_DEVICE_CUDA) - for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks - uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); - auto idx = __popc(active & __lanemask_lt()); // count the number of active before the current thread - const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); - connSizes[idx] = iWord % 2 ? sizes.size0() : sizes.size1(); -} + for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; + iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks + uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); + auto idx = __popc(active & __lanemask_lt()); // count the number of active before the current thread + const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); + connSizes[idx] = iWord % 2 ? sizes.size0() : sizes.size1(); + } #elif defined(TARGET_DEVICE_CPU) // Sequentially @@ -78,12 +82,13 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( } #endif - + // finally loop over payload words and decode hits // note iterator starts from where the above header loop ended... dataW += processedWords; __syncthreads(); - for (unsigned iLink = threadIdx.x; iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; iLink += blockDim.x) { + for (unsigned iLink = threadIdx.x; iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; + iLink += blockDim.x) { if (dataW != bankEnd) { // Do we have any words to decode for this link if (connSizes[iLink] > 0) { @@ -165,8 +170,8 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( } } // bit is on } // loop over word bits - } // word has any data - } // loop over all NZS words + } // word has any data + } // loop over all NZS words // Finally skip the read NZS words iW += nNZSwords; dataW += nNZSwords; @@ -175,7 +180,7 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( } // no data for this link, so just move on // move to next Tel40 link } // bankEnd reached - } // data word loop + } // data word loop return number_of_hits; } @@ -211,7 +216,8 @@ __device__ void rich_decode_bank( unsigned* event_inserted_hits, Rich::Decoding::SmartID* event_smart_ids) { - __shared__ Rich::Decoding::PackedFrameSizes::IntType connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; + __shared__ Rich::Decoding::PackedFrameSizes::IntType + connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; auto tel40ID = bank.source_id; const auto& connMeta = cable_mapping->tel40Meta(tel40ID); @@ -222,11 +228,13 @@ __device__ void rich_decode_bank( __shared__ unsigned processedWords; auto bankEnd = bank.data + bank.size; const auto& connData = cable_mapping->tel40Data(tel40ID); - - if (threadIdx.x == 0) { processedWords = 0; } + + if (threadIdx.x == 0) { + processedWords = 0; + } __syncthreads(); - // index = iWord = dataW = (iPayloadWord/2) + // index = iWord = dataW = (iPayloadWord/2) for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { const auto wordPtr = dataW + iWord; if (wordPtr != bankEnd) { @@ -242,7 +250,8 @@ __device__ void rich_decode_bank( __syncthreads(); #if defined(TARGET_DEVICE_CUDA) - for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { // assume blockDim.x == 32, using blockDim.y to dispatch between banks + for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; + iWord += blockDim.x) { // assume blockDim.x == 32, using blockDim.y to dispatch between banks uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); auto idx = __popc(active & __lanemask_lt()); // count the number of active before the current thread const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); @@ -268,7 +277,8 @@ __device__ void rich_decode_bank( // note iterator starts from where the above header loop ended... dataW += processedWords; __syncthreads(); - for (unsigned iLink = threadIdx.x; iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; iLink += blockDim.x) { + for (unsigned iLink = threadIdx.x; iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; + iLink += blockDim.x) { if (dataW != bankEnd) { // Do we have any words to decode for this link if (connSizes[iLink] > 0) { @@ -306,7 +316,8 @@ __device__ void rich_decode_bank( Rich::Decoding::SmartID::ShiftPDMod, Rich::Decoding::SmartID::MaskPDMod, Rich::Decoding::SmartID::MaskPDIsSet); - hitID.setData(nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); + hitID.setData( + nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); const auto row = aData.anode / 8; const auto col = 8 - 1 - (aData.anode % 8); @@ -404,16 +415,16 @@ __device__ void rich_decode_bank( } } // bit is on } // loop over word bits - } // word has any data - } // loop over all NZS words + } // word has any data + } // loop over all NZS words // Finally skip the read NZS words iW += nNZSwords; dataW += nNZSwords; } } // no data for this link, so just move on - }// move to next Tel40 link - } // bankEnd reached - } // data word loop + } // move to next Tel40 link + } // bankEnd reached + } // data word loop } template -- GitLab From bf32227b53411127e94fb6fe1a640ada9567acfd Mon Sep 17 00:00:00 2001 From: ipalmame Date: Fri, 20 Jun 2025 21:36:32 +0200 Subject: [PATCH 56/92] Threshold aware test and CPU optimized decoding --- Rec/Allen/src/CompareRecAllenRichPixels.cpp | 149 ++- device/rich/decoding/include/RichDecoding.cuh | 3 + device/rich/decoding/src/RichDecoding.cu | 586 ++++++------ lb-format | 867 ++++++++++++++++++ 4 files changed, 1264 insertions(+), 341 deletions(-) create mode 100644 lb-format diff --git a/Rec/Allen/src/CompareRecAllenRichPixels.cpp b/Rec/Allen/src/CompareRecAllenRichPixels.cpp index 2219ad5229f..d14eba0eaf5 100644 --- a/Rec/Allen/src/CompareRecAllenRichPixels.cpp +++ b/Rec/Allen/src/CompareRecAllenRichPixels.cpp @@ -1,6 +1,13 @@ -/***************************************************************************** \ - * (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * -\*****************************************************************************/ +/*****************************************************************************\ * (c) Copyright 2018-2020 CERN for the benefit of the LHCb Collaboration * + * * + * This software is distributed under the terms of the Apache License * + * version 2 (Apache-2.0), copied verbatim in the file "LICENSE". * + * * + * In applying this licence, CERN does not waive the privileges and immunities * + * granted to it by virtue of its status as an Intergovernmental Organization * + * or submit itself to any jurisdiction. * + \*****************************************************************************/ + // Gaudi #include "GaudiAlg/Consumer.h" #include "Gaudi/Accumulators.h" @@ -12,8 +19,41 @@ #include "RichMakePixels.cuh" #include "RichPixel.cuh" +// std +#include +#include + using AllenRichPixel = Rich::PixelReco::Pixel; +enum ReturnState { + IS_NULL, + NOT_EXISTS, + EXISTS +}; + +void printPixelAttributes( + const std::string& label, + float gx, float gy, float gz, + float lx, float ly, float lz, + uint32_t smartIDKey, + float effArea, + int rich, + int side, + float timeWindow, + bool isInnerRegion +) { + std::cout << std::fixed << std::setprecision(std::numeric_limits::max_digits10); + std::cout << label << ": "; + std::cout << "GP=(" << gx << "," << gy << "," << gz << "), "; + std::cout << "LP=(" << lx << "," << ly << "," << lz << "), "; + std::cout << "SID=" << smartIDKey << ", "; + std::cout << "EA=" << effArea << ", "; + std::cout << "R=" << rich << ", "; + std::cout << "S=" << side << ", "; + std::cout << "TW=" << timeWindow << ", "; + std::cout << "IR=" << isInnerRegion << "\n"; +} + // This test verifies that all valid HLT2 pixels exist in Allen, and all valid Allen pixels exist in HLT2 // Having the same number of m_allen_found_in_hlt2, and m_hlt2_found_in_allen means success. class CompareRecAllenRichPixels final : public Gaudi::Functional::Consumer&, const std::vector&, const Rich::Future::Rec::SIMDPixelSummaries&) const override; + +/// Compare the attributes of an Allen Pixel and a Rec Pixel +bool matchPixels(const AllenRichPixel& allenPixel, const Rich::Future::Rec::SIMDPixel& recPixelSummary, size_t i) const +{ + auto equal = [](float a, float b, float tol = 1e-3f) { + return std::abs(a - b) < tol; + }; + + return ( + equal(allenPixel.gloPos().x, recPixelSummary.gloPos().X()[i]) && + equal(allenPixel.gloPos().y, recPixelSummary.gloPos().Y()[i]) && + equal(allenPixel.gloPos().z, recPixelSummary.gloPos().Z()[i]) && + + equal(allenPixel.locPos().x, recPixelSummary.locPos().X()[i]) && + equal(allenPixel.locPos().y, recPixelSummary.locPos().Y()[i]) && + equal(allenPixel.locPos().z, recPixelSummary.locPos().Z()[i]) && + + allenPixel.smartID().key() == recPixelSummary.smartID()[i].key() && + equal(allenPixel.effArea(), recPixelSummary.effArea()[i]) && + + static_cast(allenPixel.rich()) == static_cast(recPixelSummary.rich()) && + static_cast(allenPixel.side()) == static_cast(recPixelSummary.side()) && + + equal(allenPixel.timeWindow(), recPixelSummary.timeWindow()[i]) && + allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i] + ); +} + - /// Compare the attributes of an Allen Pixel and a Rec Pixel - bool matchPixels(const AllenRichPixel& allenPixel, const Rich::Future::Rec::SIMDPixel& recPixelSummary, size_t i) - const - { - return ( - allenPixel.gloPos().x == recPixelSummary.gloPos().X()[i] && - allenPixel.gloPos().y == recPixelSummary.gloPos().Y()[i] && - allenPixel.gloPos().z == recPixelSummary.gloPos().Z()[i] && - allenPixel.locPos().x == recPixelSummary.locPos().X()[i] && - allenPixel.locPos().y == recPixelSummary.locPos().Y()[i] && - allenPixel.locPos().z == recPixelSummary.locPos().Z()[i] && - allenPixel.smartID().key() == recPixelSummary.smartID()[i].key() && - allenPixel.effArea() == recPixelSummary.effArea()[i] && - static_cast(allenPixel.rich()) == static_cast(recPixelSummary.rich()) && - static_cast(allenPixel.side()) == static_cast(recPixelSummary.side()) && - allenPixel.timeWindow() == recPixelSummary.timeWindow()[i] && - allenPixel.isInnerRegion() == recPixelSummary.isInnerRegion()[i]); - } private: mutable Gaudi::Accumulators::Counter<> m_allen_in_rec {this, "Allen Pixels found in HLT2"}; @@ -83,13 +133,14 @@ void CompareRecAllenRichPixels::operator()( allenPixels.insert(allenPixels.end(), allenRich1Pixels.begin(), allenRich1Pixels.end()); allenPixels.insert(allenPixels.end(), allenRich2Pixels.begin(), allenRich2Pixels.end()); - // functor to check if allen pixels exist in HLT2 - auto allenPixelExistsInRec = [&](const AllenRichPixel& allenPixel) { + +// functor to check if allen pixels exist in HLT2 + auto allenPixelExistsInRec = [&](const AllenRichPixel& allenPixel) -> ReturnState { ++m_allen_reviewed; // Check if pixel is valid if (allenPixel.isNull()) { ++m_allen_null; - return; + return ReturnState::IS_NULL; } // iterate over all pixel summaries @@ -101,18 +152,19 @@ void CompareRecAllenRichPixels::operator()( // check for match if (matchPixels(allenPixel, recPixelSummary, i)) { ++m_allen_in_rec; - return; + return ReturnState::EXISTS; } } // invalid HLT2 pix } // didn't find pix match } // covered all HLT2 pixels ++m_allen_not_in_rec; error() << "Allen pixel " << allenPixel.smartID().key() << " not found in HLT2" << endmsg; - return; + return ReturnState::NOT_EXISTS; }; // functor to check if HLT2 pixels exist in Allen - auto recPixelExistsInAllen = [&](const Rich::Future::Rec::SIMDPixel& recPixelSummary) { + auto recPixelExistsInAllen = [&](const Rich::Future::Rec::SIMDPixel& recPixelSummary) -> std::vector { + std::vector summaryStates; bool found_current_pixel = true; // arbitralilly use any of the vector in a pixel summary to get the pixel count and iterate that many times. @@ -130,6 +182,7 @@ void CompareRecAllenRichPixels::operator()( if (matchPixels(allenPixel, recPixelSummary, i)) { ++m_rec_in_allen; found_current_pixel = true; + summaryStates.push_back(ReturnState::EXISTS); continue; } // found a match } // ignore null Allen pix @@ -138,25 +191,59 @@ void CompareRecAllenRichPixels::operator()( else { ++m_rec_null; found_current_pixel = true; // assume correctness on invalid pix to ignore it. + + summaryStates.push_back(ReturnState::IS_NULL); } // invalid HLT2 pix } else { // didn't find pix match ++m_rec_not_in_allen; + summaryStates.push_back(ReturnState::NOT_EXISTS); error() << "HLT2 pixel " << recPixelSummary.smartID()[i].key() << " not found in Allen" << endmsg; } } - return; + return summaryStates; }; // call allen in hlt2 functor for (auto& allenPixel : allenPixels) { - allenPixelExistsInRec(allenPixel); + ReturnState state = allenPixelExistsInRec(allenPixel); + if (state == ReturnState::NOT_EXISTS) { +printPixelAttributes( + "Allen", + allenPixel.gloPos().x, allenPixel.gloPos().y, allenPixel.gloPos().z, + allenPixel.locPos().x, allenPixel.locPos().y, allenPixel.locPos().z, + allenPixel.smartID().key(), + allenPixel.effArea(), + static_cast(allenPixel.rich()), + static_cast(allenPixel.side()), + allenPixel.timeWindow(), + allenPixel.isInnerRegion() +); +} + } // call hlt2 in allen functor - for (auto& recPixelSummary : recPixelSummaries) { - recPixelExistsInAllen(recPixelSummary); + +for (auto& recPixelSummary : recPixelSummaries) { + std::vector summaryStates = recPixelExistsInAllen(recPixelSummary); + for (size_t i = 0; i < summaryStates.size(); ++i) { + if (summaryStates[i] == ReturnState::NOT_EXISTS) { +printPixelAttributes( + "Rec", + recPixelSummary.gloPos().X()[i], recPixelSummary.gloPos().Y()[i], recPixelSummary.gloPos().Z()[i], + recPixelSummary.locPos().X()[i], recPixelSummary.locPos().Y()[i], recPixelSummary.locPos().Z()[i], + recPixelSummary.smartID()[i].key(), + recPixelSummary.effArea()[i], + static_cast(recPixelSummary.rich()), + static_cast(recPixelSummary.side()), + recPixelSummary.timeWindow()[i], + recPixelSummary.isInnerRegion()[i] +); + } } +} + // verify that all Allen pixels were accounted for if ((m_allen_in_rec.value() + m_allen_null.value()) != m_allen_reviewed.value()) { diff --git a/device/rich/decoding/include/RichDecoding.cuh b/device/rich/decoding/include/RichDecoding.cuh index 2146d998cc6..2a73ef6498a 100644 --- a/device/rich/decoding/include/RichDecoding.cuh +++ b/device/rich/decoding/include/RichDecoding.cuh @@ -37,6 +37,9 @@ namespace rich_decoding { const Allen::Context&) const; private: + // Changed to use 2D block dimensions: 32x32 threads for better parallelism + // 32 threads in x-dimension for warp-level operations + // 32 threads in y-dimension for bank-level parallelism Allen::Property m_block_dim {this, "block_dim", {32, 32, 1}, "block dimensions"}; }; } // namespace rich_decoding diff --git a/device/rich/decoding/src/RichDecoding.cu b/device/rich/decoding/src/RichDecoding.cu index f652bb85a8b..6e713b871fc 100644 --- a/device/rich/decoding/src/RichDecoding.cu +++ b/device/rich/decoding/src/RichDecoding.cu @@ -13,19 +13,36 @@ #include #include #include -#include INSTANTIATE_ALGORITHM(rich_decoding::rich_decoding_t) +// CUDA compatibility macros +#if defined(TARGET_DEVICE_CUDA) +#define BALLOT_SYNC(mask, predicate) __ballot_sync(mask, predicate) +#define POPC(x) __popc(x) +#define LANEMASK_LT() __lanemask_lt() +#define SYNCTHREADS() __syncthreads() +#else + +// CPU fallback implementations +#define BALLOT_SYNC(mask, predicate) (predicate ? 1u : 0u) +#define POPC(x) __builtin_popcount(x) +#define LANEMASK_LT() 0u +#define SYNCTHREADS() +#endif + __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const Allen::RawBank& bank, const Rich::Decoding::Tel40CableMapping* cable_mapping, const Rich::Decoding::PDMDBDecodeMapping* pdmdb_mapping) { - unsigned number_of_hits = 0; + __shared__ Rich::Decoding::PackedFrameSizes::IntType connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; + __shared__ unsigned hit_count; - __shared__ Rich::Decoding::PackedFrameSizes::IntType - connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; + // Initialize shared memory + if (threadIdx.x == 0) { + hit_count = 0; + } auto tel40ID = bank.source_id; const auto& connMeta = cable_mapping->tel40Meta(tel40ID); @@ -33,155 +50,128 @@ __device__ unsigned rich_calculate_number_of_hits_in_raw_bank( const auto nPackedSizeW = (nSizeWords / 2) + (nSizeWords % 2); auto dataW = bank.data; - __shared__ unsigned processedWords; auto bankEnd = bank.data + bank.size; + const auto& connData = cable_mapping->tel40Data(tel40ID); - if (threadIdx.x == 0) { - processedWords = 0; + // Initialize connSizes array in parallel + for (unsigned i = threadIdx.x; i < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; i += blockDim.x) { + connSizes[i] = 0; } - __syncthreads(); - // index = iWord = dataW = (iPayloadWord/2) + SYNCTHREADS(); + + // Extract sizes with proper synchronization for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { - const auto wordPtr = dataW + iWord; - if (wordPtr != bankEnd) { - Allen::warp::atomic_increment(&processedWords); - // Extract the sizes from the packed word - const Rich::Decoding::PackedFrameSizes sizes(*wordPtr); - // extract sizes for each packed value - unsigned iPayloadWord = iWord * 2; - connSizes[iPayloadWord] = sizes.size1(); - connSizes[iPayloadWord + 1] = sizes.size0(); + if (iWord < nPackedSizeW && dataW + iWord < bankEnd) { + const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); + + auto iPayloadWord = iWord * 2; + if (iPayloadWord < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40) { + connSizes[iPayloadWord] = sizes.size1(); + } + if (iPayloadWord + 1 < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40 && + iPayloadWord + 1 < nSizeWords) { + connSizes[iPayloadWord + 1] = sizes.size0(); + } } } - __syncthreads(); -#if defined(TARGET_DEVICE_CUDA) - for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; - iWord += blockDim.x) { // assume blockDim.x == 32, you could use blockDim.y to dispatch between banks - uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); - auto idx = __popc(active & __lanemask_lt()); // count the number of active before the current thread - const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); - connSizes[idx] = iWord % 2 ? sizes.size0() : sizes.size1(); - } + SYNCTHREADS(); -#elif defined(TARGET_DEVICE_CPU) - // Sequentially - if (threadIdx.x == 0) { - if (connMeta.hasInactiveLinks) { - for (unsigned iL = 0; iL < connData.size(); ++iL) { - if (!connData[iL].isActive) { + // Handle inactive links with proper synchronization + if (connMeta.hasInactiveLinks) { + // Process one inactive link at a time to avoid race conditions + for (unsigned iL = 0; iL < connData.size(); ++iL) { + if (!connData[iL].isActive) { + // Only one thread performs the shift operation + if (threadIdx.x == 0) { for (auto i = connData.size() - 1; i > iL; --i) { connSizes[i] = connSizes[i - 1]; } connSizes[iL] = 0; } + SYNCTHREADS(); } } } -#endif - - // finally loop over payload words and decode hits - // note iterator starts from where the above header loop ended... - dataW += processedWords; - __syncthreads(); - for (unsigned iLink = threadIdx.x; iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; - iLink += blockDim.x) { - if (dataW != bankEnd) { - // Do we have any words to decode for this link - if (connSizes[iLink] > 0) { - // Get the Tel40 Data for this connection - const auto& cData = connData[iLink]; - - // get the PDMDB data - const auto& frameData = pdmdb_mapping->getFrameData(cData); - - // Loop over the words for this link - uint16_t iW = 0; - while (iW < connSizes[iLink] && dataW != bankEnd) { - - // check MSB for this word - const auto isNZS = (0x80 & *dataW) != 0; - - if (!isNZS) { - // ZS decoding... word is bit index - - // load the anode data for this bit - if ((unsigned) (*dataW) < frameData.size()) { - const auto& aData = frameData[*dataW]; - - // Data 'could' be invalid, e.g. radiation-induced-upsets - // so cannot make this a hard error - if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { - number_of_hits++; - } - } - - // move to next word - ++iW; - ++dataW; - } - else { - // NZS decoding... - - // which half of the payload are we in ? - const bool firstHalf = (0 == iW && connSizes[iLink] > 5); - // Number of words to decode depends on which half of the payload we are in - const auto nNZSwords = (firstHalf ? 6 : 5); - // bit offset per half - const auto halfBitOffset = (firstHalf ? 39 : 0); - - // look forward last NZS word and read backwards to match frame bit order - for (auto iNZS = nNZSwords - 1; iNZS >= 0; --iNZS) { - - // read the NZS word - auto nzsW = *(dataW + iNZS); - // if word zero clear MSB as this is the NZS flag - if (0 == iNZS) { - nzsW &= 0x7F; - } + // Process links - each thread processes a subset of links to avoid overlap + unsigned local_hits = 0; + const unsigned links_per_thread = (connData.size() + blockDim.x - 1) / blockDim.x; + const unsigned start_link = threadIdx.x * links_per_thread; + const unsigned end_link = min(start_link + links_per_thread, (unsigned)connData.size()); + + for (unsigned iLink = start_link; iLink < end_link && iLink < 24; ++iLink) { + if (connSizes[iLink] > 0) { + const auto& cData = connData[iLink]; + const auto& frameData = pdmdb_mapping->getFrameData(cData); + + // Calculate starting position for this link's data + unsigned dataOffset = nPackedSizeW; + for (unsigned i = 0; i < iLink; ++i) { + dataOffset += connSizes[i]; + } - // does this word hold any active bits ? - if (nzsW > 0) { + auto linkDataW = dataW + dataOffset; - // Bit offset for this word - const auto bitOffset = halfBitOffset + (8 * (nNZSwords - 1 - iNZS)); + // Process words for this link + uint16_t iW = 0; + while (iW < connSizes[iLink] && linkDataW < bankEnd) { + const auto isNZS = (0x80 & *linkDataW) != 0; - // word has data so loop over bits to extract - for (auto iLB = 0; iLB < 8; ++iLB) { - // is bit on ? - // if ( isBitOn( nzsW, iLB ) ) { - if ((nzsW & (1 << iLB)) != 0) { + if (!isNZS) { + // ZS decoding + if ((unsigned)(*linkDataW) < frameData.size()) { + const auto& aData = frameData[*linkDataW]; + if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { + local_hits++; + } + } + ++iW; + ++linkDataW; + } + else { + // NZS decoding + const bool firstHalf = (0 == iW && connSizes[iLink] > 5); + const auto nNZSwords = (firstHalf ? 6 : 5); + const auto halfBitOffset = (firstHalf ? 39 : 0); + + for (auto iNZS = nNZSwords - 1; iNZS >= 0; --iNZS) { + auto nzsW = *(linkDataW + iNZS); + if (0 == iNZS) { + nzsW &= 0x7F; + } - // form frame bit value - const auto bit = iLB + bitOffset; + if (nzsW > 0) { + const auto bitOffset = halfBitOffset + (8 * (nNZSwords - 1 - iNZS)); - // load the anode data for this bit - if ((size_t)(bit) < frameData.size()) { - const auto& aData = frameData[bit]; + for (auto iLB = 0; iLB < 8; ++iLB) { + if ((nzsW & (1 << iLB)) != 0) { + const auto bit = iLB + bitOffset; - // Data 'could' be invalid, e.g. radiation-induced-upsets - // so cannot make this a hard error - if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { - number_of_hits++; - } + if ((size_t)(bit) < frameData.size()) { + const auto& aData = frameData[bit]; + if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { + local_hits++; } - } // bit is on - } // loop over word bits - } // word has any data - } // loop over all NZS words - // Finally skip the read NZS words - iW += nNZSwords; - dataW += nNZSwords; + } + } + } + } } + iW += nNZSwords; + linkDataW += nNZSwords; } - } // no data for this link, so just move on - // move to next Tel40 link - } // bankEnd reached - } // data word loop - return number_of_hits; + } + } + } + + // Aggregate hits using atomic operation + atomicAdd(&hit_count, local_hits); + SYNCTHREADS(); + + return hit_count; } template @@ -199,13 +189,21 @@ __global__ void rich_calculate_number_of_hits( parameters.dev_rich_raw_input_sizes, parameters.dev_rich_raw_input_types, event_number + event_start}; - for (unsigned bank_number = threadIdx.y; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.y) { + + // Use y-dimension for bank parallelism, ensuring no overlap + const unsigned banks_per_thread_y = (raw_event.number_of_raw_banks + blockDim.y - 1) / blockDim.y; + const unsigned start_bank = threadIdx.y * banks_per_thread_y; + const unsigned end_bank = min(start_bank + banks_per_thread_y, raw_event.number_of_raw_banks); + + unsigned total_hits = 0; + for (unsigned bank_number = start_bank; bank_number < end_bank; ++bank_number) { const auto bank = raw_event.raw_bank(bank_number); - const auto number_of_hits_in_raw_bank = - rich_calculate_number_of_hits_in_raw_bank(bank, cable_mapping, pdmdb_mapping); - if (number_of_hits_in_raw_bank > 0) { - atomicAdd(parameters.dev_rich_hit_offsets + event_number, number_of_hits_in_raw_bank); - } + total_hits += rich_calculate_number_of_hits_in_raw_bank(bank, cable_mapping, pdmdb_mapping); + } + + // Store result atomically + if (total_hits > 0) { + atomicAdd(¶meters.dev_rich_hit_offsets[event_number], total_hits); } } @@ -216,8 +214,7 @@ __device__ void rich_decode_bank( unsigned* event_inserted_hits, Rich::Decoding::SmartID* event_smart_ids) { - __shared__ Rich::Decoding::PackedFrameSizes::IntType - connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; + __shared__ Rich::Decoding::PackedFrameSizes::IntType connSizes[Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40]; auto tel40ID = bank.source_id; const auto& connMeta = cable_mapping->tel40Meta(tel40ID); @@ -225,206 +222,168 @@ __device__ void rich_decode_bank( const auto nPackedSizeW = (nSizeWords / 2) + (nSizeWords % 2); auto dataW = bank.data; - __shared__ unsigned processedWords; auto bankEnd = bank.data + bank.size; + const auto& connData = cable_mapping->tel40Data(tel40ID); - if (threadIdx.x == 0) { - processedWords = 0; + // Initialize connSizes array + for (unsigned i = threadIdx.x; i < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; i += blockDim.x) { + connSizes[i] = 0; } - __syncthreads(); - // index = iWord = dataW = (iPayloadWord/2) + SYNCTHREADS(); + + // Parallel extraction of sizes using thread coordination for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; iWord += blockDim.x) { - const auto wordPtr = dataW + iWord; - if (wordPtr != bankEnd) { - Allen::warp::atomic_increment(&processedWords); - // Extract the sizes from the packed word - const Rich::Decoding::PackedFrameSizes sizes(*wordPtr); - // extract sizes for each packed value - unsigned iPayloadWord = iWord * 2; - connSizes[iPayloadWord] = sizes.size1(); - connSizes[iPayloadWord + 1] = sizes.size0(); + if (iWord < nPackedSizeW && dataW + iWord < bankEnd) { + const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); + + auto iPayloadWord = iWord * 2; + if (iPayloadWord < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40) { + connSizes[iPayloadWord] = sizes.size1(); + } + if (iPayloadWord + 1 < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40 && + iPayloadWord + 1 < nSizeWords) { + connSizes[iPayloadWord + 1] = sizes.size0(); + } } } - __syncthreads(); -#if defined(TARGET_DEVICE_CUDA) - for (unsigned iWord = threadIdx.x; iWord < nPackedSizeW; - iWord += blockDim.x) { // assume blockDim.x == 32, using blockDim.y to dispatch between banks - uint32_t active = __ballot_sync(0xFFFFFFFF, iWord < bank.size && connData[iWord].isActive); - auto idx = __popc(active & __lanemask_lt()); // count the number of active before the current thread - const Rich::Decoding::PackedFrameSizes sizes(dataW[iWord]); - connSizes[idx] = iWord % 2 ? sizes.size0() : sizes.size1(); - } + SYNCTHREADS(); -#elif defined(TARGET_DEVICE_CPU) - if (threadIdx.x == 0) { - if (connMeta.hasInactiveLinks) { - for (unsigned iL = 0; iL < connData.size(); ++iL) { - if (!connData[iL].isActive) { + // Handle inactive links with proper synchronization + if (connMeta.hasInactiveLinks) { + for (unsigned iL = 0; iL < connData.size(); ++iL) { + if (!connData[iL].isActive) { + // Only one thread performs the shift operation + if (threadIdx.x == 0) { for (auto i = connData.size() - 1; i > iL; --i) { connSizes[i] = connSizes[i - 1]; } connSizes[iL] = 0; } + SYNCTHREADS(); } } } -#endif - // finally loop over payload words and decode hits - // note iterator starts from where the above header loop ended... - dataW += processedWords; - __syncthreads(); - for (unsigned iLink = threadIdx.x; iLink < Rich::Decoding::Tel40CableMapping::MaxConnectionsPerTel40; - iLink += blockDim.x) { - if (dataW != bankEnd) { - // Do we have any words to decode for this link - if (connSizes[iLink] > 0) { - // Get the Tel40 Data for this connection - const auto& cData = connData[iLink]; - - // get the PDMDB data - const auto& frameData = pdmdb_mapping->getFrameData(cData); - - // Loop over the words for this link - uint16_t iW = 0; - while (iW < connSizes[iLink] && dataW != bankEnd) { - - // check MSB for this word - const auto isNZS = (0x80 & *dataW) != 0; - - if (!isNZS) { - // ZS decoding... word is bit index - - // load the anode data for this bit - if ((unsigned) (*dataW) < frameData.size()) { - - const auto& aData = frameData[*dataW]; - - // Data 'could' be invalid, e.g. radiation-induced-upsets - // so cannot make this a hard error - if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { - // make a smart ID - auto hitID = Rich::Decoding::SmartID {cData.smartID}; // sets RICH, side, module and PMT type - - // Add the PMT and pixel info - const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; - hitID.setData( - cData.moduleNum, - Rich::Decoding::SmartID::ShiftPDMod, - Rich::Decoding::SmartID::MaskPDMod, - Rich::Decoding::SmartID::MaskPDIsSet); - hitID.setData( - nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); - - const auto row = aData.anode / 8; - const auto col = 8 - 1 - (aData.anode % 8); - hitID.setData( - row, - Rich::Decoding::SmartID::ShiftPixelRow, - Rich::Decoding::SmartID::MaskPixelRow, - Rich::Decoding::SmartID::MaskPixelRowIsSet); - hitID.setData( - col, - Rich::Decoding::SmartID::ShiftPixelCol, - Rich::Decoding::SmartID::MaskPixelCol, - Rich::Decoding::SmartID::MaskPixelColIsSet); - - const auto insert_index = atomicAdd(event_inserted_hits, 1); - event_smart_ids[insert_index] = hitID; - } - } + // Process links - distribute work to avoid overlaps + const unsigned links_per_thread = (connData.size() + blockDim.x - 1) / blockDim.x; + const unsigned start_link = threadIdx.x * links_per_thread; + const unsigned end_link = min(start_link + links_per_thread, (unsigned)connData.size()); - // move to next word - ++iW; - ++dataW; + for (unsigned iLink = start_link; iLink < end_link && iLink < 24; ++iLink) { + if (connSizes[iLink] > 0) { + const auto& cData = connData[iLink]; + const auto& frameData = pdmdb_mapping->getFrameData(cData); + + // Calculate starting position for this link's data + unsigned dataOffset = nPackedSizeW; + for (unsigned i = 0; i < iLink; ++i) { + dataOffset += connSizes[i]; + } + + auto linkDataW = dataW + dataOffset; + + uint16_t iW = 0; + while (iW < connSizes[iLink] && linkDataW < bankEnd) { + const auto isNZS = (0x80 & *linkDataW) != 0; + + if (!isNZS) { + // ZS decoding + if ((unsigned)(*linkDataW) < frameData.size()) { + const auto& aData = frameData[*linkDataW]; + if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { + auto hitID = Rich::Decoding::SmartID {cData.smartID}; + + const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; + hitID.setData( + cData.moduleNum, + Rich::Decoding::SmartID::ShiftPDMod, + Rich::Decoding::SmartID::MaskPDMod, + Rich::Decoding::SmartID::MaskPDIsSet); + hitID.setData(nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); + + const auto row = aData.anode / 8; + const auto col = 8 - 1 - (aData.anode % 8); + hitID.setData( + row, + Rich::Decoding::SmartID::ShiftPixelRow, + Rich::Decoding::SmartID::MaskPixelRow, + Rich::Decoding::SmartID::MaskPixelRowIsSet); + hitID.setData( + col, + Rich::Decoding::SmartID::ShiftPixelCol, + Rich::Decoding::SmartID::MaskPixelCol, + Rich::Decoding::SmartID::MaskPixelColIsSet); + + const auto insert_index = atomicAdd(event_inserted_hits, 1); + event_smart_ids[insert_index] = hitID; + } } - else { - // NZS decoding... - - // which half of the payload are we in ? - const bool firstHalf = (0 == iW && connSizes[iLink] > 5); - // Number of words to decode depends on which half of the payload we are in - const auto nNZSwords = (firstHalf ? 6 : 5); - // bit offset per half - const auto halfBitOffset = (firstHalf ? 39 : 0); - - // look forward last NZS word and read backwards to match frame bit order - for (auto iNZS = nNZSwords - 1; iNZS >= 0; --iNZS) { - - // read the NZS word - auto nzsW = *(dataW + iNZS); - // if word zero clear MSB as this is the NZS flag - if (0 == iNZS) { - nzsW &= 0x7F; - } + ++iW; + ++linkDataW; + } + else { + // NZS decoding + const bool firstHalf = (0 == iW && connSizes[iLink] > 5); + const auto nNZSwords = (firstHalf ? 6 : 5); + const auto halfBitOffset = (firstHalf ? 39 : 0); + + for (auto iNZS = nNZSwords - 1; iNZS >= 0; --iNZS) { + auto nzsW = *(linkDataW + iNZS); + if (0 == iNZS) { + nzsW &= 0x7F; + } - // does this word hold any active bits ? - if (nzsW > 0) { - - // Bit offset for this word - const auto bitOffset = halfBitOffset + (8 * (nNZSwords - 1 - iNZS)); - - // word has data so loop over bits to extract - for (auto iLB = 0; iLB < 8; ++iLB) { - // is bit on ? - // if ( isBitOn( nzsW, iLB ) ) { - if ((nzsW & (1 << iLB)) != 0) { - - // form frame bit value - const auto bit = iLB + bitOffset; - - // load the anode data for this bit - if ((size_t)(bit) < frameData.size()) { - const auto& aData = frameData[bit]; - // Data 'could' be invalid, e.g. radiation-induced-upsets - // so cannot make this a hard error - if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { - - // make a smart ID - auto hitID = Rich::Decoding::SmartID {cData.smartID}; // sets RICH, side, module and PMT type - - // Add the PMT and pixel info - const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; - hitID.setData( - cData.moduleNum, - Rich::Decoding::SmartID::ShiftPDMod, - Rich::Decoding::SmartID::MaskPDMod, - Rich::Decoding::SmartID::MaskPDIsSet); - hitID.setData( - nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); - - const auto row = aData.anode / 8; - const auto col = 8 - 1 - (aData.anode % 8); - hitID.setData( - row, - Rich::Decoding::SmartID::ShiftPixelRow, - Rich::Decoding::SmartID::MaskPixelRow, - Rich::Decoding::SmartID::MaskPixelRowIsSet); - hitID.setData( - col, - Rich::Decoding::SmartID::ShiftPixelCol, - Rich::Decoding::SmartID::MaskPixelCol, - Rich::Decoding::SmartID::MaskPixelColIsSet); - - const auto insert_index = atomicAdd(event_inserted_hits, 1); - event_smart_ids[insert_index] = hitID; - } + if (nzsW > 0) { + const auto bitOffset = halfBitOffset + (8 * (nNZSwords - 1 - iNZS)); + + for (auto iLB = 0; iLB < 8; ++iLB) { + if ((nzsW & (1 << iLB)) != 0) { + const auto bit = iLB + bitOffset; + + if ((size_t)(bit) < frameData.size()) { + const auto& aData = frameData[bit]; + if (aData.ec != -1 && aData.pmtInEC != -1 && aData.anode != -1) { + auto hitID = Rich::Decoding::SmartID {cData.smartID}; + + const auto nInMod = (aData.ec * (0 != ((hitID.key() >> 27) & 0x1) ? 1 : 4)) + aData.pmtInEC; + hitID.setData( + cData.moduleNum, + Rich::Decoding::SmartID::ShiftPDMod, + Rich::Decoding::SmartID::MaskPDMod, + Rich::Decoding::SmartID::MaskPDIsSet); + hitID.setData( + nInMod, Rich::Decoding::SmartID::ShiftPDNumInMod, Rich::Decoding::SmartID::MaskPDNumInMod); + + const auto row = aData.anode / 8; + const auto col = 8 - 1 - (aData.anode % 8); + hitID.setData( + row, + Rich::Decoding::SmartID::ShiftPixelRow, + Rich::Decoding::SmartID::MaskPixelRow, + Rich::Decoding::SmartID::MaskPixelRowIsSet); + hitID.setData( + col, + Rich::Decoding::SmartID::ShiftPixelCol, + Rich::Decoding::SmartID::MaskPixelCol, + Rich::Decoding::SmartID::MaskPixelColIsSet); + + const auto insert_index = atomicAdd(event_inserted_hits, 1); + event_smart_ids[insert_index] = hitID; } - } // bit is on - } // loop over word bits - } // word has any data - } // loop over all NZS words - // Finally skip the read NZS words - iW += nNZSwords; - dataW += nNZSwords; + } + } + } + } } - } // no data for this link, so just move on - } // move to next Tel40 link - } // bankEnd reached - } // data word loop + iW += nNZSwords; + linkDataW += nNZSwords; + } + } + } + } } template @@ -446,7 +405,13 @@ __global__ void rich_decoding_kernel( parameters.dev_rich_raw_input_sizes, parameters.dev_rich_raw_input_types, event_number + event_start}; - for (unsigned bank_number = threadIdx.y; bank_number < raw_event.number_of_raw_banks; bank_number += blockDim.y) { + + // Use threadIdx.y to dispatch between banks with proper distribution + const unsigned banks_per_thread_y = (raw_event.number_of_raw_banks + blockDim.y - 1) / blockDim.y; + const unsigned start_bank = threadIdx.y * banks_per_thread_y; + const unsigned end_bank = min(start_bank + banks_per_thread_y, raw_event.number_of_raw_banks); + + for (unsigned bank_number = start_bank; bank_number < end_bank; ++bank_number) { const auto bank = raw_event.raw_bank(bank_number); rich_decode_bank(bank, cable_mapping, pdmdb_mapping, event_inserted_hits, event_smart_ids); } @@ -504,3 +469,4 @@ void rich_decoding::rich_decoding_t::operator()( print(arguments); } } + diff --git a/lb-format b/lb-format new file mode 100644 index 00000000000..07e04459db1 --- /dev/null +++ b/lb-format @@ -0,0 +1,867 @@ +#!/usr/bin/env python +############################################################################### +# (c) Copyright 2018 CERN # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +""" +Helpers to manipulate source files +Check that each git tracked source file in the current directory contains a +copyright statement. +""" + +import os +import re +from datetime import date +from itertools import islice +from shutil import which + +COPYRIGHT_SIGNATURE = re.compile(r"\bcopyright\b", re.IGNORECASE) +CHECKED_FILES = re.compile( + r".*(\.(i?[ch](pp|xx|c)?|cc|hh|py|cuh?|C|cmake|[yx]ml|qm[ts]|dtd|xsd|ent|bat|[cz]?sh|js|jsx|css|html?)|" + r"CMakeLists.txt|Jenkinsfile)$" +) + +COPYRIGHT_STATEMENT = """ +(c) Copyright {} CERN for the benefit of the LHCb Collaboration +""" + +GPL3_STATEMENT = """ +This software is distributed under the terms of the GNU General Public +Licence version 3 (GPL Version 3), copied verbatim in the file "{}". + +In applying this licence, CERN does not waive the privileges and immunities +granted to it by virtue of its status as an Intergovernmental Organization +or submit itself to any jurisdiction. +""" + +APACHE2_STATEMENT = """ +This software is distributed under the terms of the Apache License +version 2 (Apache-2.0), copied verbatim in the file "{}". + +In applying this licence, CERN does not waive the privileges and immunities +granted to it by virtue of its status as an Intergovernmental Organization +or submit itself to any jurisdiction. +""" + +licenses = {"GPL-3.0-only": GPL3_STATEMENT, "Apache-2.0": APACHE2_STATEMENT} + +# see https://www.python.org/dev/peps/pep-0263 for the regex +ENCODING_DECLARATION = re.compile(rb"^[ \t\f]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)") + +CLANG_FORMAT_VERSION = "8" +YAPF_VERSION = "0.24.0" +FORMATTABLE_LANGUAGES = ["c", "py"] + + +def is_script(path): + """ + Check if a given file starts with the magic sequence '#!'. + """ + with open(path, "rb") as f: + return f.read(2) == b"#!" + + +def to_check(path): + """ + Check if path is meant to contain a copyright statement. + """ + return os.path.isfile(path) and (bool(CHECKED_FILES.match(path)) or is_script(path)) + + +def is_empty(path): + """ + Check if file is empty or virtually empty (only spaces). + """ + + def only_blanks(): + with open(path) as f: + for l in f: + if l.strip(): + return False + return True + + zero_size = os.stat(path).st_size == 0 + return zero_size or only_blanks() + + +def has_copyright(path): + """ + Check if there's a copyright signature in the first 100 lines of a file. + """ + with open(path) as f: + return any(COPYRIGHT_SIGNATURE.search(l) for l in islice(f, 100)) + + +def get_files(reference=None): + """ + Return iterable with the list of names of files to check. + """ + from subprocess import check_output + + if reference is None: + all = ( + path.decode() + for path in check_output(["git", "ls-files", "-z"]) + .rstrip(b"\x00") + .split(b"\x00") + ) + else: + prefix_len = len(check_output(["git", "rev-parse", "--show-prefix"]).strip()) + all = ( + path[prefix_len:].decode() + for path in check_output( + [ + "git", + "diff", + "--name-only", + "--no-renames", + "--diff-filter=MA", + "-z", + reference + "...", + ".", + ] + ) + .rstrip(b"\x00") + .split(b"\x00") + ) + return (path for path in all if to_check(path)) + + +def report(filenames, inverted=False, target=None, license="GPL-3.0-only"): + """ + Print a report with the list of filenames. + + If porcelain is True, print only the names without descriptive message. + """ + print( + ("The following {} files {}contain a copyright statement:\n- ").format( + len(filenames), "" if inverted else "do not " + ), + end="", + ) + print("\n- ".join(filenames)) + if not inverted: + license_arg = f" --license={license}" if license != "GPL-3.0-only" else "" + if target: + print( + f"\nYou can fix the {len(filenames)} files without copyright statement " + f"with:\n\n $ lb-check-copyright --porcelain {target}{license_arg} " + f"| xargs -r lb-add-copyright{license_arg}\n" + ) + else: + print( + f"\nyou can fix them with the command lb-add-copyright{license_arg}\n" + ) + + +def to_comment(text, lang_family="#", width=80): + r""" + Convert a chunk of text into comment for source files. + + The parameter lang_family can be used to tune the style of the comment: + + - 'c' for C/C++ + - '#' (default) for Python, shell, etc. + - 'xml' for XML files + + >>> print(to_comment('a\nb\nc\n'), end='') + ############################################################################### + # a # + # b # + # c # + ############################################################################### + >>> print(to_comment('a\nb\nc\n', 'c'), end='') + /*****************************************************************************\ + * a * + * b * + * c * + \*****************************************************************************/ + >>> print(to_comment('a\nb\nc\n', 'xml'), end='') + + """ + if lang_family == "c": + head = "/{}\\".format((width - 3) * "*") + line = "* {:%d} *" % (width - 5) + tail = "\\{}/".format((width - 3) * "*") + elif lang_family in ("#", "py"): + head = (width - 1) * "#" + line = "# {:%d} #" % (width - 5) + tail = head + elif lang_family == "xml": + head = "" + else: + msg = f"invalid language family: {lang_family}" + raise ValueError(msg) + + data = [head] + data.extend(line.format(l.rstrip()).rstrip() for l in text.splitlines()) + data.append(tail) + data.append("") + return "\n".join(data) + + +def lang_family(path): + """ + Detect language family of a file. + """ + if re.match(r".*\.(xml|xsd|dtd|html?|qm[ts]|ent)$", path): + return "xml" + if re.match( + r"(.*\.(i?[ch](pp|xx|c)?|cuh?|cc|hh|C|opts|js|jsx|css)|" r"Jenkinsfile)$", path + ): + return "c" + if re.match(r".*\.py$", path) or re.match(r"^#!.*python", open(path).readline(120)): + return "py" + return "#" + + +def find_encoding_declaration_line(lines, limit=2): + """ + Look for encoding declaration line (PEP-263) in a file and return the index + of the line containing it, or None if not found. + """ + for i, l in enumerate(islice(lines, limit)): + if ENCODING_DECLARATION.match(l): + return i + return None + + +def add_copyright_to_file(path, year=None, license_fn=None, add_license="GPL-3.0-only"): + """ + Add copyright statement to the given file for the specified year (or range + of years). If the year argument is not specified, the current year is + used. + """ + lang = lang_family(path) + statement = COPYRIGHT_STATEMENT.format(year or date.today().year) + statement += licenses[add_license].format(license_fn or "COPYING") + + text = to_comment(statement.strip(), lang) + with open(path, "rb") as f: + data = f.readlines() + + offset = 0 + encoding_offset = find_encoding_declaration_line(data) + if encoding_offset is not None: + offset = encoding_offset + 1 + elif data and data[0].startswith(b"#!"): + offset = 1 + elif lang == "xml": + offset = 1 if not path.endswith(".ent") else 0 + for l in data: + if l.strip(): + # lcgdict selection files are a bit special + if b"lcgdict" in l or b" - """ - if lang_family == "c": - head = "/{}\\".format((width - 3) * "*") - line = "* {:%d} *" % (width - 5) - tail = "\\{}/".format((width - 3) * "*") - elif lang_family in ("#", "py"): - head = (width - 1) * "#" - line = "# {:%d} #" % (width - 5) - tail = head - elif lang_family == "xml": - head = "" - else: - msg = f"invalid language family: {lang_family}" - raise ValueError(msg) - - data = [head] - data.extend(line.format(l.rstrip()).rstrip() for l in text.splitlines()) - data.append(tail) - data.append("") - return "\n".join(data) - - -def lang_family(path): - """ - Detect language family of a file. - """ - if re.match(r".*\.(xml|xsd|dtd|html?|qm[ts]|ent)$", path): - return "xml" - if re.match( - r"(.*\.(i?[ch](pp|xx|c)?|cuh?|cc|hh|C|opts|js|jsx|css)|" r"Jenkinsfile)$", path - ): - return "c" - if re.match(r".*\.py$", path) or re.match(r"^#!.*python", open(path).readline(120)): - return "py" - return "#" - - -def find_encoding_declaration_line(lines, limit=2): - """ - Look for encoding declaration line (PEP-263) in a file and return the index - of the line containing it, or None if not found. - """ - for i, l in enumerate(islice(lines, limit)): - if ENCODING_DECLARATION.match(l): - return i - return None - - -def add_copyright_to_file(path, year=None, license_fn=None, add_license="GPL-3.0-only"): - """ - Add copyright statement to the given file for the specified year (or range - of years). If the year argument is not specified, the current year is - used. - """ - lang = lang_family(path) - statement = COPYRIGHT_STATEMENT.format(year or date.today().year) - statement += licenses[add_license].format(license_fn or "COPYING") - - text = to_comment(statement.strip(), lang) - with open(path, "rb") as f: - data = f.readlines() - - offset = 0 - encoding_offset = find_encoding_declaration_line(data) - if encoding_offset is not None: - offset = encoding_offset + 1 - elif data and data[0].startswith(b"#!"): - offset = 1 - elif lang == "xml": - offset = 1 if not path.endswith(".ent") else 0 - for l in data: - if l.strip(): - # lcgdict selection files are a bit special - if b"lcgdict" in l or b"