Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:32

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2022-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file celeritas/user/RootStepWriter.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <array>
0011 
0012 #include "corecel/Config.hh"
0013 
0014 #include "corecel/Assert.hh"
0015 #include "celeritas/ext/RootUniquePtr.hh"
0016 
0017 #include "StepInterface.hh"
0018 
0019 class TTree;
0020 
0021 namespace celeritas
0022 {
0023 //---------------------------------------------------------------------------//
0024 class ParticleParams;
0025 class RootFileManager;
0026 
0027 //---------------------------------------------------------------------------//
0028 //! Input to \c make_write_filter (below) for filtering ROOT MC truth output
0029 struct SimpleRootFilterInput
0030 {
0031     static inline constexpr size_type unspecified{static_cast<size_type>(-1)};
0032 
0033     std::vector<size_type> track_id;
0034     size_type event_id = unspecified;
0035     size_type parent_id = unspecified;
0036     size_type action_id = unspecified;
0037 
0038     //! True if any filtering is being applied
0039     explicit operator bool() const
0040     {
0041         return !track_id.empty() || event_id != unspecified
0042                || parent_id != unspecified || action_id != unspecified;
0043     }
0044 };
0045 
0046 //---------------------------------------------------------------------------//
0047 /*!
0048  * Write "MC truth" data to ROOT at every step.
0049  *
0050  * `TTree::Fill()` is called for each step and thread id, making each ROOT
0051  * entry a step. Since the ROOT data is stored in branches with primitive types
0052  * instead of a full struct, no dictionaries are needed for reading the output
0053  * file.
0054  *
0055  * The step data that is written to the ROOT file can be filtered by providing
0056  * a user-defined `WriteFilter` function.
0057  */
0058 class RootStepWriter final : public StepInterface
0059 {
0060   public:
0061     // Unspecified step attribute data value
0062     static inline constexpr size_type unspecified{static_cast<size_type>(-1)};
0063 
0064     //! Truth step point data; Naming convention must match StepPointStateData
0065     struct TStepPoint
0066     {
0067         size_type volume_id = unspecified;
0068         real_type energy = 0;  //!< [MeV]
0069         real_type time = 0;  //!< [time]
0070         std::array<real_type, 3> pos{0, 0, 0};  //!< [len]
0071         std::array<real_type, 3> dir{0, 0, 0};
0072     };
0073 
0074     //! Truth step data; Naming convention must match StepStateData
0075     struct TStepData
0076     {
0077         size_type event_id = unspecified;
0078         size_type track_id = unspecified;
0079         size_type parent_id = unspecified;
0080         size_type action_id = unspecified;
0081         size_type track_step_count = unspecified;
0082         int particle = 0;  //!< PDG number
0083         real_type energy_deposition = 0;  //!< [MeV]
0084         real_type step_length = 0;  //!< [len]
0085         EnumArray<StepPoint, TStepPoint> points;
0086     };
0087 
0088   public:
0089     //!@{
0090     //! \name Type aliases
0091     using SPRootFileManager = std::shared_ptr<RootFileManager>;
0092     using SPParticleParams = std::shared_ptr<ParticleParams const>;
0093     using WriteFilter = std::function<bool(TStepData const&)>;
0094     //!@}
0095 
0096     // Construct with step data writer filter
0097     RootStepWriter(SPRootFileManager root_manager,
0098                    SPParticleParams particle_params,
0099                    StepSelection selection,
0100                    WriteFilter filter);
0101 
0102     // Construct and store all step data
0103     RootStepWriter(SPRootFileManager root_manager,
0104                    SPParticleParams particle_params,
0105                    StepSelection selection);
0106 
0107     // Set number of entries stored in memory before being flushed to disk
0108     void set_auto_flush(long num_entries);
0109 
0110     // Process step data on the host and fill step tree
0111     void process_steps(HostStepState) final;
0112 
0113     // Device execution is not currently implemented
0114     void process_steps(DeviceStepState) final
0115     {
0116         CELER_NOT_IMPLEMENTED("RootStepWriter with device data");
0117     }
0118 
0119     // Selection of data to be stored
0120     StepSelection selection() const final { return selection_; }
0121 
0122     // No detector filtering selection is implemented
0123     Filters filters() const final { return {}; }
0124 
0125   private:
0126     // Create steps tree based on selection_ booleans
0127     void make_tree();
0128 
0129   private:
0130     SPRootFileManager root_manager_;
0131     SPParticleParams particles_;
0132     StepSelection selection_;
0133     UPRootTreeWritable tstep_tree_;
0134     TStepData tstep_;  // Members are used as refs of the TTree branches
0135     std::function<bool(TStepData const&)> filter_;
0136 };
0137 
0138 //---------------------------------------------------------------------------//
0139 // FREE FUNCTIONS
0140 //---------------------------------------------------------------------------//
0141 // Create a write filter for some simple IDs
0142 RootStepWriter::WriteFilter make_write_filter(SimpleRootFilterInput const&);
0143 
0144 //---------------------------------------------------------------------------//
0145 #if !CELERITAS_USE_ROOT
0146 inline RootStepWriter::RootStepWriter(SPRootFileManager,
0147                                       SPParticleParams,
0148                                       StepSelection,
0149                                       WriteFilter)
0150 {
0151     CELER_NOT_CONFIGURED("ROOT");
0152 }
0153 
0154 inline void RootStepWriter::process_steps(HostStepState)
0155 {
0156     CELER_NOT_CONFIGURED("ROOT");
0157 }
0158 
0159 inline RootStepWriter::WriteFilter
0160 make_write_filter(SimpleRootFilterInput const&)
0161 {
0162     return nullptr;
0163 }
0164 
0165 #endif
0166 
0167 //---------------------------------------------------------------------------//
0168 }  // namespace celeritas