Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-09 10:15:02

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/optical/action/detail/DetectorExecutor.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "celeritas/Types.hh"
0010 #include "celeritas/optical/CoreTrackView.hh"
0011 #include "celeritas/optical/DetectorData.hh"
0012 #include "celeritas/optical/SimTrackView.hh"
0013 
0014 namespace celeritas
0015 {
0016 namespace optical
0017 {
0018 namespace detail
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Populate detector state buffer at the end of a step.
0023  *
0024  * All tracks have hits copied into the state buffer. If the track is not alive
0025  * or is not in a detector region, an invalid hit is set in the corresponding
0026  * buffer track slot.
0027  *
0028  * Detection can occur after a surface crossing \em or (for coupled EM
0029  * problems) if an optical photon is emitted inside a detector region.
0030  *
0031  * When a track generates a valid hit, it is killed (absorbed by the detector).
0032  *
0033  * \note This is called by \em all track slots, which is necessary to clear the
0034  * outgoing detector hits. We could break this into a "reset" kernel that
0035  * applies to all slots, and a "fill" kernel that applies only to valid slots.
0036  */
0037 struct DetectorExecutor
0038 {
0039     NativeRef<DetectorStateData> detector_state_;
0040 
0041     // Copy track hit into the state buffer
0042     inline CELER_FUNCTION void operator()(CoreTrackView const&) const;
0043 };
0044 
0045 //---------------------------------------------------------------------------//
0046 // INLINE DEFINITIONS
0047 //---------------------------------------------------------------------------//
0048 /*!
0049  * Copy track hit into the state buffer.
0050  */
0051 CELER_FUNCTION void DetectorExecutor::operator()(
0052     CoreTrackView const& track) const
0053 {
0054     auto& hit = detector_state_.detector_hits[track.track_slot_id()];
0055     // Clear the hit if inactive, errored, or not detected
0056     hit.detector = {};
0057 
0058     auto sim = track.sim();
0059 
0060     if (!is_track_valid(sim.status()))
0061     {
0062         // Inactive or errored
0063         return;
0064     }
0065     if (track.surface_physics().is_crossing_boundary())
0066     {
0067         // Boundary crossing not yet completed, so not yet detected!
0068         return;
0069     }
0070 
0071     auto geometry = track.geometry();
0072     if (geometry.is_outside())
0073     {
0074         // Killed by leaving geometry; no detection
0075         return;
0076     }
0077 
0078     auto const detectors = track.detectors();
0079     auto const volume_id = geometry.volume_id();
0080     auto const detector_id = detectors.detector_id(volume_id);
0081 
0082     if (!detector_id)
0083     {
0084         // Not in a detector
0085         return;
0086     }
0087 
0088     // Score a valid hit
0089     hit.detector = detector_id;
0090     hit.primary = sim.primary_id();
0091     hit.energy = track.particle().energy();
0092     hit.time = sim.time();
0093     hit.position = geometry.pos();
0094     hit.volume_instance = geometry.volume_instance_id();
0095     hit.num_steps = sim.num_steps();
0096     hit.path_length = sim.step_length();
0097 
0098     // Construct unique instance ID from geometry volume path
0099     auto accum = track.volumes().path_accumulator();
0100     hit.unique_instance = {};
0101     geometry.foreach_volume_path([&](VolumeLevelId, VolumeInstanceId vi) {
0102         hit.unique_instance = accum(hit.unique_instance, vi);
0103     });
0104 
0105     // Kill the track
0106     sim.status(TrackStatus::killed);
0107 }
0108 
0109 //---------------------------------------------------------------------------//
0110 }  // namespace detail
0111 }  // namespace optical
0112 }  // namespace celeritas