Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #pragma once
0002 /**
0003 spho.h : photon labelling used by genstep collection
0004 ========================================================
0005 
0006 After cfg4/CPho
0007 
0008 isSameLineage
0009     does not require the same reemission generation
0010 
0011 isIdentical
0012     requires isSameLineage and same reemission generation
0013 
0014 NB spho lacks gentype, to get that must reference corresponding sgs struct using the gs index
0015 
0016 NB having reemission generations larger than zero DOES NOT mean the
0017 photon originally came from scintillaton.
0018 For example in a case where no photons are coming from scint,
0019 reemission of initially Cerenkov photons may still happen,
0020 resulting in potentially multiple reemission generations.
0021 
0022 **/
0023 
0024 #include <array>
0025 #include <string>
0026 
0027 struct spho_uchar4 { unsigned char x,y,z,w ; };
0028 
0029 union spho_uuc4 {
0030     unsigned    u   ;
0031     spho_uchar4 uc4 ;
0032 };
0033 
0034 
0035 
0036 
0037 struct spho // WIP: unsigned ?
0038 {
0039     static constexpr const int N = 4 ;
0040 
0041     int gs ; // 0-based genstep index within the event
0042     int ix ; // 0-based photon index within the genstep
0043     int id ; // 0-based photon identity index within the event
0044 
0045     spho_uchar4 uc4 ;
0046     // uc4.x : gen : 0-based reemission index incremented at each reemission
0047     // uc4.y : eph : eg junoSD_PMT_v2::ProcessHits eph enumeration
0048     // uc4.z : ext : unused
0049     // uc4.w : photon point flag TO/BT/BR/SC/AB/SD/SR/... etc
0050 
0051     unsigned uc4packed() const ;
0052 
0053     int gen() const ;
0054     int eph() const ;
0055     int ext() const ;
0056     int flg() const ;
0057 
0058     void set_gen(int gn) ;
0059     void set_eph(int ep) ;
0060     void set_ext(int ex) ;
0061     void set_flg(int fg) ;
0062 
0063     static spho MakePho(int gs_, int ix_, int id_ );
0064     static spho Fabricate(int track_id);
0065     static void FabricateInplace( int track_id, int* label );
0066     void set_fabricated_(int track_id );
0067 
0068     static spho Placeholder() ;
0069 
0070     bool isSameLineage(const spho& other) const { return gs == other.gs && ix == other.ix && id == other.id ; }
0071     bool isIdentical(const spho& other) const { return isSameLineage(other) && uc4.x == other.uc4.x ; }
0072 
0073     bool isPlaceholder() const { return gs == -1 ; }
0074     bool isDefined() const {     return gs != -1 ; }
0075 
0076     spho make_nextgen() const ; // formerly make_reemit
0077     std::string desc() const ;
0078 
0079     const int* cdata() const ;
0080     int* data();
0081     void serialize( std::array<int, 4>& a ) const ;
0082     void load( const std::array<int, 4>& a );
0083 
0084 };
0085 
0086 
0087 #include <cassert>
0088 #include <sstream>
0089 #include <iomanip>
0090 
0091 inline unsigned spho::uc4packed() const
0092 {
0093     spho_uuc4 uuc4 ;
0094     uuc4.uc4 = uc4 ;
0095     return uuc4.u ;
0096 }
0097 
0098 inline int spho::gen() const { return int(uc4.x); }
0099 inline int spho::eph() const { return int(uc4.y); }
0100 inline int spho::ext() const { return int(uc4.z); }
0101 inline int spho::flg() const { return int(uc4.w); }
0102 
0103 inline void spho::set_gen(int gn) { uc4.x = (unsigned char)(gn) ; }
0104 inline void spho::set_eph(int ep) { uc4.y = (unsigned char)(ep) ; }
0105 inline void spho::set_ext(int ex) { uc4.z = (unsigned char)(ex) ; }
0106 inline void spho::set_flg(int fg) { uc4.w = (unsigned char)(fg) ; }
0107 
0108 
0109 inline spho spho::MakePho(int gs_, int ix_, int id_) // static
0110 {
0111     spho ph = {gs_, ix_, id_, {0,0,0,0} } ;
0112     return ph ;
0113 }
0114 /**
0115 spho::Fabricate
0116 ---------------
0117 
0118 *Fabricate* is not normally used, as C+S photons are always
0119 labelled at generation by U4::GenPhotonEnd
0120 
0121 However as a workaround for torch/input photons that lack labels
0122 this method is used from U4Recorder::PreUserTrackingAction_Optical
0123 to provide a standin label based only on a 0-based track_id.
0124 
0125 **/
0126 inline spho spho::Fabricate(int track_id) // static
0127 {
0128     assert( track_id >= 0 );
0129     spho fab = {0, track_id, track_id, {0,0,0,0} };
0130     return fab ;
0131 }
0132 
0133 inline void spho::FabricateInplace( int track_id, int* label )
0134 {
0135     spho& q = reinterpret_cast<spho&>(*label);
0136     q.set_fabricated_(track_id);
0137 }
0138 
0139 inline void spho::set_fabricated_(int track_id )
0140 {
0141     assert( track_id >= 0 );
0142     gs = 0 ;
0143     ix = track_id ;
0144     id = track_id ;
0145     set_gen(0);
0146     set_eph(0);
0147     set_ext(0);
0148     set_flg(0);
0149 }
0150 
0151 
0152 inline spho spho::Placeholder() // static
0153 {
0154     spho inv = {-1, -1, -1, {0,0,0,0} };
0155     return inv ;
0156 }
0157 inline spho spho::make_nextgen() const
0158 {
0159     spho nextgen = *this ;
0160     nextgen.uc4.x += 1 ;
0161     return nextgen ;
0162 }
0163 
0164 inline std::string spho::desc() const
0165 {
0166     std::stringstream ss ;
0167     ss << "spho" ;
0168     if(isPlaceholder())
0169     {
0170         ss << " isPlaceholder " ;
0171     }
0172     else
0173     {
0174         ss << " (gs:ix:id:gn "
0175            << std::setw(3) << gs
0176            << std::setw(4) << ix
0177            << std::setw(5) << id
0178            << "["
0179            << std::setw(3) << int(uc4.x) << ","
0180            << std::setw(3) << int(uc4.y) << ","
0181            << std::setw(3) << int(uc4.z) << ","
0182            << std::setw(3) << int(uc4.w)
0183            << "]"
0184            << ")"
0185            ;
0186     }
0187     std::string s = ss.str();
0188     return s ;
0189 }
0190 
0191 
0192 
0193 inline int* spho::data()
0194 {
0195     return &gs ;
0196 }
0197 inline const int* spho::cdata() const
0198 {
0199     return &gs ;
0200 }
0201 inline void spho::serialize( std::array<int, 4>& a ) const
0202 {
0203     assert( a.size() == N );
0204     const int* ptr = cdata() ;
0205     for(int i=0 ; i < N ; i++ ) a[i] = ptr[i] ;
0206 }
0207 inline void spho::load( const std::array<int, 4>& a )
0208 {
0209     assert( a.size() == N );
0210     int* ptr = data() ;
0211     for(int i=0 ; i < N ; i++ ) ptr[i] = a[i] ;
0212 }
0213 
0214 
0215 
0216 
0217 inline std::ostream& operator<<(std::ostream& os, const spho& p)
0218 {
0219     os << p.desc() ;
0220     return os;
0221 }
0222 
0223 
0224