Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-10 07:50:02

0001 #pragma once
0002 /**
0003 SCF.h : Lightweight access to CSGFoundry geometry loaded from CFBASE directory
0004 ================================================================================
0005 
0006 Using this from the A side is distinctly dodgy as it relies on the CFBASE 
0007 directory geometry matching the current geometry.
0008 
0009 Use from the B side is more acceptable as B side running is a debugging 
0010 exercise subservient to A side running so in that situation can rely on 
0011 CFBASE directory and it is then up to the user to ensure in the A-B matching 
0012 that are using an appropriate CFBASE directory that matches. 
0013 
0014 Could also argue that might as well use the CSG/CSGFoundry geometry rather than 
0015 this lightweight alternative which can be loaded on the B side and it always
0016 created on the A side anyhow ? 
0017 
0018 **/
0019 
0020 
0021 #include <string>
0022 #include <sstream>
0023 #include <vector>
0024 #include "NP.hh"
0025 #include "SSys.hh"
0026 #include "SEventConfig.hh"
0027 #include "SName.h"
0028 
0029 #include "scuda.h"
0030 #include "squad.h"
0031 #include "sqat4.h"
0032 
0033 
0034 struct SCF
0035 {
0036     static SCF* INSTANCE ; 
0037     static SCF* Create(); 
0038     static SCF* Get() ; 
0039 
0040 
0041 
0042     static void ReadNames(const char* path_, std::vector<std::string>& names ); 
0043 
0044     template<typename T>
0045     static void LoadVec( std::vector<T>& vec, const char* dir, const char* name ); 
0046 
0047     static int  Index(const char* name, const std::vector<std::string>& names, unsigned max_count ); 
0048 
0049     std::vector<std::string> bnd ; 
0050     std::vector<std::string> msh ; 
0051     std::vector<std::string> pri ; 
0052     std::vector<qat4>       inst ;
0053 
0054     SCF(); 
0055     std::string desc() const ; 
0056 
0057     int getPrimIdx( const char* soname) const ; 
0058     int getMeshIdx( const char* soname) const ;  
0059     int getBoundary(const char* spec)   const ;  
0060 
0061     const qat4* getInst(unsigned instIdx) const ;
0062     const qat4* getInputPhotonFrame(const char* ipf_) const ; 
0063     const qat4* getInputPhotonFrame() const ; 
0064 
0065 }; 
0066 
0067 
0068 SCF* SCF::INSTANCE = nullptr ; 
0069 SCF* SCF::Create()
0070 {
0071     bool has_CFBASE = SSys::hasenvvar("CFBASE") ; 
0072     //if(!has_CFBASE) std::cerr << "SCF::Create BUT no CFBASE envvar " << std::endl ; 
0073     return has_CFBASE ? new SCF : nullptr ;  
0074 }
0075 SCF* SCF::Get(){  return INSTANCE ; }
0076 
0077 
0078 SCF::SCF()
0079 {
0080     ReadNames( "$CFBASE/CSGFoundry/SSim/bnd_names.txt", bnd ); 
0081     ReadNames( "$CFBASE/CSGFoundry/meshname.txt", msh ); 
0082     ReadNames( "$CFBASE/CSGFoundry/primname.txt", pri ); 
0083     LoadVec<qat4>( inst, "$CFBASE/CSGFoundry", "inst.npy" ); 
0084     INSTANCE = this ; 
0085 }
0086 
0087 std::string SCF::desc() const
0088 {
0089     std::stringstream ss ; 
0090     ss << "SCF::desc"
0091        << " bnd.size " << bnd.size() 
0092        << " msh.size " << msh.size() 
0093        << " pri.size " << pri.size() 
0094        << " inst.size " << inst.size() 
0095        ;
0096 
0097     std::string s = ss.str();
0098     return s ; 
0099 }
0100 
0101 void SCF::ReadNames(const char* path_, std::vector<std::string>& names ) // static
0102 {
0103     const char* path = SPath::Resolve(path_, NOOP); 
0104     NP::ReadNames(path, names); 
0105     std::cout << "SCF::ReadNames " << "path " << path << " names.size " << names.size() << std::endl ;
0106     for(unsigned i=0 ; i < names.size() ; i++) std::cout << std::setw(4) << i << " : " << names[i] << std::endl ;  
0107 }
0108 
0109 template<typename T>
0110 void SCF::LoadVec( std::vector<T>& vec, const char* dir_, const char* name )
0111 {
0112     const char* dir = SPath::Resolve(dir_, DIRPATH); 
0113     NP* a = NP::Load(dir, name);
0114     if( a == nullptr ) std::cout << "SCF::LoadVec FAIL dir_ " << dir_ << " name " << name << std::endl; 
0115     if( a == nullptr ) return ; 
0116     assert(a); 
0117     assert( a->shape.size()  == 3 ); 
0118     unsigned ni = a->shape[0] ; 
0119     //unsigned nj = a->shape[1] ; 
0120     //unsigned nk = a->shape[2] ; 
0121 
0122     vec.clear(); 
0123     vec.resize(ni); 
0124     memcpy( vec.data(),  a->bytes(), sizeof(T)*ni ); 
0125 }
0126 
0127 
0128 
0129 
0130 
0131 int SCF::Index(const char* name, const std::vector<std::string>& names, unsigned max_count )
0132 {
0133     unsigned count = 0 ; 
0134     int index = NP::NameIndex( name, count, names );
0135     assert( max_count == 0 || count <= max_count );  
0136     return index ; 
0137 }
0138 
0139 /**
0140 SCF::getPrimIdx
0141 ------------------------
0142 
0143 HMM: this will not match Opticks in full geometry where meshnames 
0144 appear repeatedly for many prim. 
0145 
0146 HMM: potentially with live running could fix this by holding origin 
0147 pointers to maintain the source G4VPhysicalVolume for every CSGPrim ?  
0148 
0149 This would require the Geant4 SCFTest to do a translation to 
0150 CSG on the fly and use that.  Given the heavy dependencies of 
0151 the translation currently this solution not convenient.  
0152 
0153 This is a capability that needs to wait for the new more direct G4->CSG "Geo" impl.
0154 The as yet uncreated "Geo" full node tree needs to retain the connection
0155 to the origin physical volumes and copyNo which needs to be carried into 
0156 the CSG model : possibly with just the nodeindex. 
0157 Then in SCF can reproduce the identity.    
0158 
0159 **/
0160 
0161 int SCF::getPrimIdx( const char* soname) const { return Index(soname, pri, 0 ); }
0162 int SCF::getMeshIdx( const char* soname) const { return Index(soname, msh, 1 ); }
0163 int SCF::getBoundary(const char* spec) const {   return Index(spec,   bnd, 1 ); }
0164 
0165 const qat4* SCF::getInst(unsigned instIdx)   const { return instIdx  < inst.size()  ? inst.data()  + instIdx  : nullptr ; }
0166 
0167 const qat4* SCF::getInputPhotonFrame(const char* ipf_) const 
0168 {
0169     int ipf = ipf_ ? SName::ParseIntString(ipf_, -1) : -1 ; 
0170     const qat4* q = ipf > -1 ? getInst( ipf ) : nullptr ;
0171     return q ; 
0172 }
0173 const qat4* SCF::getInputPhotonFrame() const 
0174 {
0175     const char* ipf_ = SEventConfig::InputPhotonFrame(); 
0176     return getInputPhotonFrame(ipf_); 
0177 }
0178 
0179 
0180