Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 08:52:22

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/io/ImportOpticalMaterial.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <map>
0010 #include <vector>
0011 
0012 #include "celeritas/inp/Grid.hh"
0013 
0014 #include "ImportUnits.hh"
0015 
0016 namespace celeritas
0017 {
0018 //---------------------------------------------------------------------------//
0019 /*!
0020  * Store basic properties for different scintillation component types.
0021  *
0022  * Fast/intermediate/slow/etc scintillation components can be used for both
0023  * particle- and material-dependent spectra, as well as material-only spectra.
0024  */
0025 struct ImportScintComponent
0026 {
0027     double yield_frac{};  //!< Fraction of total scintillation yield
0028     double lambda_mean{};  //!< Mean wavelength [len]
0029     double lambda_sigma{};  //!< Standard deviation of wavelength [len]
0030     double rise_time{};  //!< Rise time [time]
0031     double fall_time{};  //!< Decay time [time]
0032 
0033     //! Whether all data are assigned and valid
0034     explicit operator bool() const
0035     {
0036         return yield_frac > 0 && lambda_mean > 0 && lambda_sigma > 0
0037                && rise_time >= 0 && fall_time > 0;
0038     }
0039 };
0040 
0041 //---------------------------------------------------------------------------//
0042 /*!
0043  * Store material-only scintillation spectrum information.
0044  *
0045  * In contrast to Geant4, we can have an arbitrary number of components for
0046  * scintillation spectra.
0047  */
0048 struct ImportMaterialScintSpectrum
0049 {
0050     double yield_per_energy{};  //!< Expected num photons per eloss [1/MeV]
0051     std::vector<ImportScintComponent> components;
0052 
0053     //! Whether all data are assigned and valid
0054     explicit operator bool() const
0055     {
0056         return yield_per_energy > 0 && !components.empty();
0057     }
0058 };
0059 
0060 //---------------------------------------------------------------------------//
0061 /*!
0062  * Store per-particle material scintillation spectrum information.
0063  *
0064  * The yield vector is the only necessary element, needed to calculate the
0065  * yield based on the particle energy-loss during the stepping loop.
0066  * Components may not be assigned---they are the equivalent of
0067  * \c k[Particle]ScintillationYield[i] in \c G4MaterialPropertiesIndex.hh
0068  */
0069 struct ImportParticleScintSpectrum
0070 {
0071     static constexpr auto x_units{ImportUnits::mev};
0072     static constexpr auto y_units{ImportUnits::unitless};
0073 
0074     inp::Grid yield_vector;  //!< Particle yield per energy bin
0075     std::vector<ImportScintComponent> components;  //!< Scintillation
0076                                                    //!< components
0077 
0078     //! Whether all data are assigned and valid
0079     explicit operator bool() const { return static_cast<bool>(yield_vector); }
0080 };
0081 
0082 //---------------------------------------------------------------------------//
0083 /*!
0084  * Store optical properties for scintillation.
0085  */
0086 struct ImportScintData
0087 {
0088     using PDGint = int;
0089     using IPSS = ImportParticleScintSpectrum;
0090 
0091     ImportMaterialScintSpectrum material;  //!< Material scintillation data
0092     std::map<PDGint, IPSS> particles;  //!< Particle scintillation data
0093     double resolution_scale{};  //!< Scales the stdev of photon distribution
0094 
0095     //! Whether all data are assigned and valid
0096     explicit operator bool() const
0097     {
0098         return (static_cast<bool>(material) || !particles.empty())
0099                && resolution_scale >= 0;
0100     }
0101 };
0102 
0103 //---------------------------------------------------------------------------//
0104 /*!
0105  * Store optical material properties for Rayleigh scattering.
0106  *
0107  * The isothermal compressibility is used to calculate the Rayleigh mean free
0108  * path if no mean free paths are provided.
0109  */
0110 struct ImportOpticalRayleigh
0111 {
0112     double scale_factor{1};  //!< Scale the scattering length (optional)
0113     double compressibility{};  //!< Isothermal compressibility
0114 
0115     //! Whether all data are assigned and valid
0116     explicit operator bool() const
0117     {
0118         return scale_factor > 0 && compressibility > 0;
0119     }
0120 };
0121 
0122 //---------------------------------------------------------------------------//
0123 /*!
0124  * Store common optical material properties.
0125  */
0126 struct ImportOpticalProperty
0127 {
0128     inp::Grid refractive_index;
0129 
0130     //! Whether all data are assigned and valid
0131     explicit operator bool() const
0132     {
0133         return static_cast<bool>(refractive_index);
0134     }
0135 };
0136 
0137 //---------------------------------------------------------------------------//
0138 /*!
0139  * Store optical photon wavelength shifting properties.
0140  *
0141  * The component vector represents the relative population as a function of the
0142  * re-emission energy. It is used to define an inverse CDF needed to sample the
0143  * re-emitted optical photon energy.
0144  */
0145 struct ImportWavelengthShift
0146 {
0147     double mean_num_photons{};  //!< Mean number of re-emitted photons
0148     double time_constant{};  //!< Time delay between absorption and re-emission
0149     inp::Grid component;  //!< Re-emission population [MeV, unitless]
0150 
0151     //! Whether all data are assigned and valid
0152     explicit operator bool() const
0153     {
0154         return mean_num_photons > 0 && time_constant > 0
0155                && static_cast<bool>(component);
0156     }
0157 };
0158 
0159 //---------------------------------------------------------------------------//
0160 /*!
0161  * Store optical material properties.
0162  *
0163  * \todo boolean for enabling cherenkov in the material?? DUNE e.g. disables
0164  * cherenkov globally.
0165  */
0166 struct ImportOpticalMaterial
0167 {
0168     ImportOpticalProperty properties;
0169     ImportScintData scintillation;
0170 
0171     //!@{
0172     //! \name Optical process data
0173     ImportOpticalRayleigh rayleigh;
0174     ImportWavelengthShift wls;
0175     //!@}
0176 
0177     //! Whether minimal useful data is stored
0178     explicit operator bool() const { return static_cast<bool>(properties); }
0179 };
0180 
0181 //---------------------------------------------------------------------------//
0182 }  // namespace celeritas