Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-18 08:30:23

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2025 Minjung Kim, Joshua Sobaljic, Shujie Li
0003 
0004 #pragma once
0005 
0006 #include <DD4hep/DetElement.h>
0007 #include <DD4hep/Detector.h>
0008 #include <DD4hep/Readout.h>
0009 #include <DDRec/CellIDPositionConverter.h>
0010 #include <TGeoMatrix.h>
0011 #include <TGeoVolume.h>
0012 #include <edm4eic/RawTrackerHitCollection.h>
0013 #include <edm4hep/EventHeaderCollection.h>
0014 
0015 #include <cstddef>
0016 #include <cstdint>
0017 #include <map>
0018 #include <memory>
0019 #include <random>
0020 #include <string>
0021 #include <string_view>
0022 #include <vector>
0023 
0024 #include "RandomNoisePixelConfig.h"
0025 #include "algorithms/algorithm.h"
0026 #include "algorithms/interfaces/UniqueIDGenSvc.h"
0027 #include "algorithms/interfaces/WithPodConfig.h"
0028 
0029 namespace eicrecon {
0030 
0031 using RandomNoisePixelAlgorithm =
0032     algorithms::Algorithm<algorithms::Input<edm4hep::EventHeaderCollection>,
0033                           algorithms::Output<edm4eic::RawTrackerHitCollection>>;
0034 
0035 class RandomNoisePixel : public RandomNoisePixelAlgorithm,
0036                          public WithPodConfig<RandomNoisePixelConfig> {
0037 public:
0038   explicit RandomNoisePixel(std::string_view name)
0039       : RandomNoisePixelAlgorithm{
0040             name,
0041             {"EventHeader"},
0042             {"outputRawHitCollection"},
0043             "Generates noise-only RawTrackerHits from a global per-pixel occupancy."} {}
0044 
0045   // Read the static detector geometry once and build compact pixel lookup tables.
0046   void init();
0047 
0048   // Generate one event's noise hits from the cached geometry and the EventHeader seed.
0049   void process(const Input&, const Output&) const final;
0050 
0051   // The two pixel coordinates used by each supported DD4hep segmentation.
0052   enum class GridKind { CartesianXY, CartesianXZ, CylindricalPhiZ };
0053 
0054   // One contiguous run of valid pixels in a fixed second-coordinate row.
0055   // Example: for CartesianGridXZ, secondIndex is z and [firstMin, firstMax] is x.
0056   struct PixelRow {
0057     std::int64_t secondIndex    = 0;
0058     std::int64_t firstMin       = 0;
0059     std::int64_t firstMax       = -1;
0060     std::uint64_t cumulativeEnd = 0;
0061   };
0062 
0063   // Compact description of every addressable pixel in one sensor shape.
0064   // Rectangles need only four limits. Trapezoids use one PixelRow per valid row.
0065   struct PixelLayout {
0066     GridKind kind = GridKind::CartesianXY;
0067     std::string firstField;
0068     std::string secondField;
0069     bool rectangular       = false;
0070     std::int64_t firstMin  = 0;
0071     std::int64_t firstMax  = -1;
0072     std::int64_t secondMin = 0;
0073     std::int64_t secondMax = -1;
0074     std::vector<PixelRow> rows;
0075     std::uint64_t totalPixels = 0;
0076   };
0077 
0078   // Geometry needed only while constructing the persistent pixel cache in init().
0079   // Keeping it separate avoids retaining one TGeo transform throughout event processing.
0080   struct SensitiveComponentGeometry {
0081     std::string detectorName;
0082     int layer                = 0;
0083     const TGeoVolume* volume = nullptr;
0084     TGeoHMatrix localToWorldTransform;
0085   };
0086 
0087   // Event-time pixel metadata for one placed sensitive silicon component.
0088   // baseVolumeID identifies the physical sensor; layout supplies its pixel fields.
0089   struct SensitiveComponent {
0090     std::string detectorName;
0091     int layer                  = 0;
0092     std::uint64_t baseVolumeID = 0;
0093     std::shared_ptr<const PixelLayout> layout;
0094     std::uint64_t pixelCount = 0;
0095   };
0096 
0097   // All sensitive components belonging to one detector/layer sampling group.
0098   // cumulativePixels supports pixel-count-weighted component selection.
0099   struct LayerGeometry {
0100     std::string detectorName;
0101     int layer = 0;
0102     std::vector<std::size_t> componentIndices;
0103     std::vector<std::uint64_t> cumulativePixels;
0104     std::uint64_t totalPixels = 0;
0105   };
0106 
0107 private:
0108   // Traverse the layer children of one DD4hep detector system.
0109   void collectDetectorComponents(const dd4hep::DetElement& detector,
0110                                  std::vector<SensitiveComponentGeometry>& componentGeometry);
0111 
0112   // Find sensitive module/component placements and preserve their detector layer IDs.
0113   void collectLayerComponents(const std::string& detectorName, const dd4hep::DetElement& layer,
0114                               std::vector<SensitiveComponentGeometry>& componentGeometry);
0115 
0116   // Determine each sensor's base cell ID and compact discrete pixel layout.
0117   void cachePixelLayouts(const std::vector<SensitiveComponentGeometry>& componentGeometry);
0118 
0119   // Group cached components by detector/layer and calculate cumulative pixel counts.
0120   void buildLayers();
0121 
0122   // Produce a deterministic seed from a required EventHeader collection.
0123   std::uint64_t seedFromEventHeader(const edm4hep::EventHeaderCollection& headers) const;
0124 
0125   // Select one addressable pixel from a component and encode its complete cell ID.
0126   std::uint64_t randomCellID(const SensitiveComponent& component, std::mt19937_64& rng) const;
0127 
0128   // Draw and create the Poisson-distributed noise hits for one detector layer.
0129   void addNoiseHitsForLayer(const LayerGeometry& layer,
0130                             std::map<std::uint64_t, edm4eic::MutableRawTrackerHit>& hitMap,
0131                             std::mt19937_64& rng) const;
0132 
0133   dd4hep::Readout m_readout;
0134   std::vector<SensitiveComponent> m_components;
0135   std::vector<LayerGeometry> m_layers;
0136   const dd4hep::Detector* m_dd4hepGeo                     = nullptr;
0137   const dd4hep::rec::CellIDPositionConverter* m_converter = nullptr;
0138   const algorithms::UniqueIDGenSvc& m_uid                 = algorithms::UniqueIDGenSvc::instance();
0139 };
0140 
0141 } // namespace eicrecon