Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:44

0001 #pragma once
0002 /**
0003 SPMTAccessor.h
0004 ===============
0005 
0006 Provides access to JUNO PMT data during standalone
0007 optical only testing WITH_CUSTOM4 and without j/PMTSim.
0008 For example::
0009 
0010    ~/opticks/g4cx/tests/G4CXTest_GEOM.sh
0011    ~/opticks/g4cx/tests/G4CXApp.h
0012    ~/opticks/u4/U4Physics.hh
0013    ~/opticks/u4/U4Physics.cc
0014 
0015 Attempt to provide standalone access to JUNO PMT data
0016 without depending on junosw, using SPMT.h which is
0017 how the data is passed to QPMT.hh and onto the GPU
0018 in qpmt.h
0019 
0020 **/
0021 
0022 
0023 #include <cstdlib>
0024 #include "sstr.h"
0025 #include "SPMT.h"
0026 
0027 #ifdef WITH_CUSTOM4
0028 #include "C4IPMTAccessor.h"
0029 struct SPMTAccessor : public C4IPMTAccessor
0030 #else
0031 struct SPMTAccessor
0032 #endif
0033 {
0034     static constexpr const char* TYPENAME = "SPMTAccessor" ;
0035     static SPMTAccessor* Load(const char* path);
0036     SPMTAccessor(const SPMT* pmt );
0037     const SPMT* pmt ;
0038     bool VERBOSE ;
0039 
0040     //[C4IPMTAccessor protocol methods
0041     int         get_num_lpmt() const ;
0042     double      get_qescale( int pmtid ) const ;
0043     int         get_pmtcat( int pmtid ) const ;
0044     double      get_pmtid_qe( int pmtid, double energy_MeV ) const ;
0045     void        get_stackspec( std::array<double, 16>& ss, int pmtcat, double energy_eV ) const ;
0046     const char* get_typename() const ;
0047     //]
0048 
0049     static std::string Desc(std::array<double, 16>& ss );
0050 };
0051 
0052 
0053 inline SPMTAccessor* SPMTAccessor::Load(const char* path)
0054 {
0055     SPMT* pmt = SPMT::CreateFromJPMT(path);
0056     //if(pmt == nullptr) return nullptr ;
0057 
0058     SPMTAccessor* accessor = new SPMTAccessor(pmt);
0059     assert( accessor );
0060     return accessor ;
0061 }
0062 
0063 inline SPMTAccessor::SPMTAccessor( const SPMT* _pmt )
0064     :
0065     pmt(_pmt),
0066     VERBOSE(getenv("SPMTAccessor__VERBOSE") != nullptr)
0067 {
0068 }
0069 
0070 inline int SPMTAccessor::get_num_lpmt() const
0071 {
0072     return s_pmt::NUM_CD_LPMT ;
0073 }
0074 
0075 inline double SPMTAccessor::get_qescale( int pmtid ) const
0076 {
0077     float qs = pmt->get_qescale_from_lpmtid(pmtid);
0078     return qs ;
0079 }
0080 inline int SPMTAccessor::get_pmtcat( int pmtid ) const
0081 {
0082     int cat = pmt->get_lpmtcat_from_lpmtid(pmtid) ;
0083 
0084     if(VERBOSE) std::cout
0085         << "SPMTAccessor::get_pmtcat"
0086         << " pmtid " << pmtid
0087         << " cat " << cat
0088         << std::endl
0089         ;
0090 
0091     return cat ;
0092 }
0093 
0094 
0095 
0096 /**
0097 SPMTAccessor::get_pmtid_qe
0098 ----------------------------
0099 
0100 From C4CustomART::doIt it is apparent that PMTAccessor which
0101 SPMTAccessor aims to stand in for in standalone running
0102 without j/PMTSim is inconsistent in its energy units.
0103 
0104 +----------------------------+-------------+
0105 |  Method                    | energy unit |
0106 +============================+=============+
0107 | PMTAccessor::get_pmtid_qe  | energy_MeV  |
0108 +----------------------------+-------------+
0109 | PMTAccessor::get_stackspec | energy_eV   |
0110 +----------------------------+-------------+
0111 
0112 **/
0113 
0114 inline double SPMTAccessor::get_pmtid_qe( int lpmtid, double energy_MeV ) const
0115 {
0116     int lpmtidx = s_pmt::lpmtidx_from_pmtid(lpmtid);
0117 
0118     float energy_eV = energy_MeV*1e6 ;
0119     float qe = pmt->get_lpmtidx_qe(lpmtidx, energy_eV) ;
0120 
0121     if(VERBOSE) std::cout
0122         << "SPMTAccessor::get_pmtid_qe"
0123         << " lpmtid " << lpmtid
0124         << " lpmtidx " << lpmtidx
0125         << " energy_MeV " << std::scientific << energy_MeV
0126         << " energy_eV " << std::scientific << energy_eV
0127         << " qe " << std::scientific << qe
0128         << std::endl
0129         ;
0130 
0131     return qe ;
0132 }
0133 
0134 inline void SPMTAccessor::get_stackspec( std::array<double, 16>& spec, int pmtcat, double energy_eV_ ) const
0135 {
0136     float energy_eV = energy_eV_ ;
0137     quad4 q_spec ;
0138     pmt->get_stackspec(q_spec, pmtcat, energy_eV);
0139 
0140     const float* qq = q_spec.cdata();
0141     for(int i=0 ; i < 16 ; i++) spec[i] = double(qq[i]) ;
0142 
0143 #ifdef DEBUG
0144     if(VERBOSE) std::cout
0145         << "SPMTAccessor::get_stackspec"
0146         << " pmtcat " << pmtcat
0147         << " energy " << std::scientific << energy
0148         << std::endl
0149         << Desc(spec)
0150         << std::endl
0151         ;
0152 #endif
0153 
0154 }
0155 
0156 inline std::string SPMTAccessor::Desc(std::array<double, 16>& spec ) // static
0157 {
0158     std::stringstream ss ;
0159     ss << "SPMTAccessor::Desc" << std::endl ;
0160     for(int i=0 ; i < 16 ; i++) ss
0161         << ( i % 4 == 0 ? "\n" : " " )
0162         << std::setw(10) << std::fixed  << spec[i] << " "
0163         << ( i == 15 ? "\n" : " " )
0164         ;
0165 
0166     std::string str = ss.str() ;
0167     return str ;
0168 }
0169 
0170 
0171 
0172 inline const char* SPMTAccessor::get_typename() const
0173 {
0174     return TYPENAME ;
0175 }
0176 
0177 
0178 
0179