Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:37

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/ext/detail/HitProcessor.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <memory>
0010 #include <string>
0011 #include <utility>
0012 #include <vector>
0013 #include <G4TouchableHandle.hh>
0014 
0015 #include "corecel/Macros.hh"
0016 #include "corecel/cont/EnumArray.hh"
0017 #include "celeritas/Types.hh"
0018 #include "celeritas/geo/GeoFwd.hh"
0019 #include "celeritas/user/DetectorSteps.hh"
0020 #include "celeritas/user/StepData.hh"
0021 
0022 #include "TouchableUpdaterInterface.hh"
0023 
0024 class G4LogicalVolume;
0025 class G4ParticleDefinition;
0026 class G4Step;
0027 class G4StepPoint;
0028 class G4Track;
0029 class G4VSensitiveDetector;
0030 
0031 namespace celeritas
0032 {
0033 struct StepSelection;
0034 struct DetectorStepOutput;
0035 
0036 namespace detail
0037 {
0038 //---------------------------------------------------------------------------//
0039 /*!
0040  * Transfer Celeritas sensitive detector hits to Geant4.
0041  *
0042  * This serves a similar purpose to the \c G4FastSimHitMaker class for
0043  * generating hit objects.
0044  *
0045  * \warning This class \b must be thread-local because the sensitive
0046  * detectors it points to are thread-local objects. Furthermore, Geant4
0047  * thread-local object allocators for the navigation state and tracks mean this
0048  * class \b must be destroyed on the same thread on which it was created.
0049  *
0050  * Call operator:
0051  * - Loop over detector steps
0052  * - Update step attributes based on hit selection for the detector (TODO:
0053  *   selection is global for now)
0054  * - Call the local detector (based on detector ID from map) with the step
0055  *
0056  * Compare to Geant4 updating step/track info:
0057  * - \c G4VParticleChange::UpdateStepInfo
0058  * - \c G4ParticleChangeForTransport::UpdateStepForAlongStep
0059  * - \c G4ParticleChangeForTransport::UpdateStepForPostStep
0060  * - \c G4StackManager::PrepareNewEvent
0061  * - \c G4SteppingManager::ProcessSecondariesFromParticleChange
0062  * - \c G4Step::UpdateTrack
0063  */
0064 class HitProcessor
0065 {
0066   public:
0067     //!@{
0068     //! \name Type aliases
0069     using StepStateHostRef = HostRef<StepStateData>;
0070     using StepStateDeviceRef = DeviceRef<StepStateData>;
0071     using SPConstGeo = std::shared_ptr<GeoParams const>;
0072     using SPConstVecLV
0073         = std::shared_ptr<std::vector<G4LogicalVolume const*> const>;
0074     using VecParticle = std::vector<G4ParticleDefinition const*>;
0075     using StepPointBool = EnumArray<StepPoint, bool>;
0076     //!@}
0077 
0078   public:
0079     // Construct from volumes that have SDs and step selection
0080     HitProcessor(SPConstVecLV detector_volumes,
0081                  SPConstGeo const& geo,
0082                  VecParticle const& particles,
0083                  StepSelection const& selection,
0084                  StepPointBool const& locate_touchable);
0085 
0086     // Log on destruction
0087     ~HitProcessor();
0088     CELER_DEFAULT_MOVE_DELETE_COPY(HitProcessor);
0089 
0090     // Process CPU-generated hits
0091     void operator()(StepStateHostRef const&);
0092 
0093     // Process device-generated hits
0094     void operator()(StepStateDeviceRef const&);
0095 
0096     // Generate and call hits from a detector output (for testing)
0097     void operator()(DetectorStepOutput const& out) const;
0098 
0099     // Generate and call hits from a single detector hit
0100     void operator()(DetectorStepOutput const& out, size_type i) const;
0101 
0102     // Access detector volume corresponding to an ID
0103     inline G4LogicalVolume const* detector_volume(DetectorId) const;
0104 
0105     // Access thread-local SD corresponding to an ID
0106     inline G4VSensitiveDetector* detector(DetectorId) const;
0107 
0108     // Get and reset the hits counted (generally once per event)
0109     inline size_type exchange_hits();
0110 
0111   private:
0112     //! Detector volumes for navigation updating
0113     SPConstVecLV detector_volumes_;
0114     //! Map detector IDs to sensitive detectors
0115     std::vector<G4VSensitiveDetector*> detectors_;
0116     //! Temporary CPU hit information
0117     DetectorStepOutput steps_;
0118 
0119     //! Temporary step
0120     std::unique_ptr<G4Step> step_;
0121     //! Step points
0122     EnumArray<StepPoint, G4StepPoint*> step_points_{{nullptr, nullptr}};
0123     //! Tracks for each particle type
0124     std::vector<std::unique_ptr<G4Track>> tracks_;
0125 
0126     //! Geant4 reference-counted pointer to a G4VTouchable
0127     EnumArray<StepPoint, G4TouchableHandle> touch_handle_;
0128     //! Navigator for finding points
0129     std::unique_ptr<TouchableUpdaterInterface> update_touchable_;
0130     //! Whether geometry-related step status can be updated
0131     bool step_post_status_{false};
0132 
0133     //! Accumulated number of hits
0134     size_type num_hits_;
0135 
0136     void update_track(ParticleId id) const;
0137 };
0138 
0139 //---------------------------------------------------------------------------//
0140 // INLINE DEFINITIONS
0141 //---------------------------------------------------------------------------//
0142 /*!
0143  * Access detector volume corresponding to an ID.
0144  */
0145 G4LogicalVolume const* HitProcessor::detector_volume(DetectorId did) const
0146 {
0147     CELER_EXPECT(did < detector_volumes_->size());
0148     return (*detector_volumes_)[did.unchecked_get()];
0149 }
0150 
0151 //---------------------------------------------------------------------------//
0152 /*!
0153  * Access thread-local sensitive detector corresponding to an ID.
0154  */
0155 G4VSensitiveDetector* HitProcessor::detector(DetectorId did) const
0156 {
0157     CELER_EXPECT(did < detectors_.size());
0158     return detectors_[did.unchecked_get()];
0159 }
0160 
0161 //---------------------------------------------------------------------------//
0162 /*!
0163  * Get and reset number of hits counted (generally once per event).
0164  */
0165 size_type HitProcessor::exchange_hits()
0166 {
0167     return std::exchange(num_hits_, size_type{0});
0168 }
0169 
0170 //---------------------------------------------------------------------------//
0171 }  // namespace detail
0172 }  // namespace celeritas