File indexing completed on 2026-04-09 07:49:45
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
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
0106
0107
0108
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
0165
0166
0167
0168
0169 inline void SPrd::init_prd()
0170 {
0171 int num_prd = bnd_idx.size() ;
0172 prd.resize(num_prd);
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 );
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
0221
0222
0223
0224
0225
0226
0227
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] ;
0251
0252 return a_prd ;
0253 }
0254
0255