Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #pragma once
0002 /**
0003 SPrd : used by QSimTest/fake_propagate
0004 =========================================
0005 
0006 This was moved from QPrd
0007 
0008 Dummy per-ray-data enabling pure-CUDA (no OptiX, no geometry)
0009 testing of propagation using QSimTest MOCK_PROPAGATE.
0010 
0011 The basis vectors of are obtained from the below envvars
0012 which have constexpr defaults.
0013 
0014 SPRD_BND
0015     boundary spec strings that that are converted into boundary_idx
0016     The CustomART PMT geometry simplification caused name change::
0017 
0018         Pyrex/NNVTMCPPMT_PMT_20inch_photocathode_logsurf2/NNVTMCPPMT_PMT_20inch_photocathode_logsurf1/Vacuum
0019         Pyrex/NNVTMCPPMT_PMT_20inch_photocathode_mirror_logsurf/NNVTMCPPMT_PMT_20inch_photocathode_mirror_logsurf/Vacuum
0020 
0021 SPRD_NRMT
0022     float4 strings parsed into nrmt:(normals,distance)
0023 
0024 SPRD_LPOSCOST
0025     space delimited floats with local intersect position cosine theta, range: -1. to 1.
0026     This value is only relevant when mocking intersects onto special surfaces.
0027 
0028 SPRD_IDENTITY
0029     space delimited ints with identity, which corresponds to sensor_identifier, aka lpmtid.
0030     This value is only relevant when mocking intersects onto special surfaces.
0031 
0032 **/
0033 
0034 #include <vector>
0035 #include <string>
0036 
0037 struct float4 ;
0038 struct quad2 ;
0039 struct SBnd ;
0040 struct NP ;
0041 
0042 struct SPrd
0043 {
0044     static constexpr const bool VERBOSE = true ;
0045     static constexpr const char* SPRD_NRMT_DEFAULT = "0,0,1,100 0,0,1,200 0,0,1,300 0,0,-1,400" ;
0046     static constexpr const char* SPRD_LPOSCOST_DEFAULT = "0,0,0,0.5" ;
0047     static constexpr const char* SPRD_IDENTITY_DEFAULT = "0,0,0,1001" ;
0048     static constexpr const char* SPRD_BND_DEFAULT = R"LITERAL(
0049     Acrylic///LS
0050     Water///Acrylic
0051     Water///Pyrex
0052     Pyrex/NNVTMCPPMT_PMT_20inch_photocathode_mirror_logsurf/NNVTMCPPMT_PMT_20inch_photocathode_mirror_logsurf/Vacuum
0053     )LITERAL" ;
0054 
0055     const char*         bnd_sequence ;
0056     const NP*           bnd ;
0057     const SBnd*         sbnd ;
0058     int                 rc ;
0059 
0060     std::vector<float4> nrmt ;
0061     std::vector<float>  lposcost;
0062     std::vector<int >   identity ;
0063     std::vector<int>    bnd_idx ;
0064 
0065     std::vector<quad2>  prd ;
0066 
0067     SPrd(const NP* bnd);
0068     void init();
0069     void init_evec();
0070     void init_prd();
0071 
0072     std::string desc() const ;
0073     int getNumBounce() const ;
0074 
0075     NP* fake_prd(int num_photon, int num_bounce ) const ;
0076 
0077 };
0078 
0079 
0080 
0081 #include "ssys.h"
0082 #include "scuda.h"
0083 #include "squad.h"
0084 #include "NP.hh"
0085 #include "SBnd.h"
0086 
0087 
0088 inline SPrd::SPrd(const NP* bnd_)
0089     :
0090     bnd_sequence(ssys::getenvvar("SPRD_BND", SPRD_BND_DEFAULT )),
0091     bnd(bnd_),
0092     sbnd(bnd ? new SBnd(bnd) : nullptr),
0093     rc(0)
0094 {
0095     init();
0096 }
0097 
0098 inline void SPrd::init()
0099 {
0100     init_evec();
0101     init_prd();
0102 }
0103 
0104 /**
0105 SPrd::init_evec
0106 -----------------
0107 
0108 Sensitive to envvars SPRD_BND, SPRD_NRMT, SPRD_IDENTITY, SPRD_LPOSCOST
0109 
0110 **/
0111 
0112 inline void SPrd::init_evec()
0113 {
0114     assert(sbnd);
0115     bool has_all = sbnd->hasAllBoundaryIndices( bnd_sequence, '\n' );
0116 
0117     if(!has_all)
0118     {
0119         std::cerr
0120             << "SPrd::init_evec"
0121             << " THE GEOMETRY DOES NOT HAVE ALL THE BOUNDARY INDICES "
0122             << std::endl
0123             << "["
0124             << std::endl
0125             << ( bnd_sequence ? bnd_sequence : "-" )
0126             << std::endl
0127             << "]"
0128             << std::endl
0129             ;
0130         rc = 101 ;
0131         return ;
0132     }
0133 
0134     sbnd->getBoundaryIndices( bnd_idx, bnd_sequence, '\n' );
0135 
0136     ssys::fill_evec<int>  (identity, "SPRD_IDENTITY", SPRD_IDENTITY_DEFAULT, ',' );
0137     ssys::fill_evec<float>(lposcost, "SPRD_LPOSCOST", SPRD_LPOSCOST_DEFAULT, ',' );
0138 
0139     qvals( nrmt, "SPRD_NRMT", SPRD_NRMT_DEFAULT, true );
0140 
0141     int num_bnd_idx  = bnd_idx.size() ;
0142     int num_nrmt     = nrmt.size() ;
0143     int num_identity = identity.size() ;
0144     int num_lposcost = lposcost.size() ;
0145 
0146     bool consistent =
0147                       num_bnd_idx == num_nrmt  &&
0148                       num_bnd_idx == num_identity &&
0149                       num_bnd_idx == num_lposcost
0150                     ;
0151 
0152     if(!consistent) std::cerr
0153         << "SPrd::init_evec : INCONSISTENT MOCKING "
0154         << " all four num MUST MATCH  "
0155         << std::endl
0156         << desc()
0157         ;
0158     assert(consistent);
0159 }
0160 
0161 
0162 
0163 /**
0164 SPrd::init_prd
0165 --------------------
0166 
0167 **/
0168 
0169 inline void SPrd::init_prd()
0170 {
0171     int num_prd = bnd_idx.size() ;
0172     prd.resize(num_prd);  // vector of quad2
0173 
0174     for(int i=0 ; i < num_prd ; i++)
0175     {
0176         quad2& pr = prd[i] ;
0177         pr.zero();
0178 
0179         pr.q0.f = nrmt[i] ;
0180         pr.set_globalPrimIdx_boundary( 0u, bnd_idx[i] );
0181         pr.set_iindex_identity( 0, identity[i] );
0182         pr.set_lpos( lposcost[i], 0.f );    // SPrd::init_prd testing dummy PRD
0183     }
0184 }
0185 
0186 
0187 
0188 inline std::string SPrd::desc() const
0189 {
0190     std::stringstream ss ;
0191     ss << "SPrd::desc"
0192         << " num_bnd_idx " << bnd_idx.size()
0193         << " num_nrmt " << nrmt.size()
0194         << " num_identity " << identity.size()
0195         << " num_lposcost " << lposcost.size()
0196         << std::endl
0197         << ( bnd_sequence ? bnd_sequence : "-" )
0198         << std::endl
0199         ;
0200 
0201     ss << "SPrd.sbn.descBoundaryIndices" << std::endl ;
0202     ss << sbnd->descBoundaryIndices( bnd_idx );
0203     ss << "SPrd.nrmt" << std::endl ;
0204     for(int i=0 ; i < int(nrmt.size()) ; i++ ) ss << nrmt[i] << std::endl ;
0205     ss << "SPrd.prd" << std::endl ;
0206     for(int i=0 ; i < int(prd.size()) ; i++ )  ss << prd[i].desc() << std::endl ;
0207 
0208     std::string str = ss.str();
0209     return str ;
0210 }
0211 
0212 
0213 inline int SPrd::getNumBounce() const
0214 {
0215     return bnd_idx.size();
0216 }
0217 
0218 
0219 /**
0220 SPrd::fake_prd
0221 ----------------
0222 
0223 Canonical use from QSimTest::fake_propagate
0224 
0225 Duplicate the sequence of fake prd for all photon,
0226 if the num_bounce exceeds the prd obtained from environment
0227 the prd is wrapped within the photon bounces.
0228 
0229 **/
0230 
0231 inline NP* SPrd::fake_prd(int num_photon, int num_bounce) const
0232 {
0233     int num_prd = prd.size();
0234     int ni = num_photon ;
0235     int nj = num_bounce ;
0236 
0237     if(VERBOSE) std::cout
0238         << "SPrd::fake_prd"
0239         << " ni:num_photon " << num_photon
0240         << " nj:num_bounce " << num_bounce
0241         << " num_prd " << num_prd
0242         << std::endl
0243         ;
0244 
0245     NP* a_prd = NP::Make<float>(ni, nj, 2, 4 );
0246     quad2* prd_v = (quad2*)a_prd->values<float>();
0247 
0248     for(int i=0 ; i < ni ; i++)
0249         for(int j=0 ; j < nj ; j++)
0250             prd_v[i*nj+j] = prd[j % num_prd] ; // wrap prd into array when not enough
0251 
0252     return a_prd ;
0253 }
0254 
0255