Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #pragma once
0002 
0003 #include <string>
0004 #include <ostream>
0005 #include <sstream>
0006 
0007 #include "NP.hh"
0008 #include "sstr.h"
0009 
0010 
0011 class G4VPhysicalVolume ; 
0012 
0013 struct U4Volume
0014 {
0015     static const G4VPhysicalVolume* FindPV( const G4VPhysicalVolume* top,  const char* qname, int mode=sstr::MATCH_ALL, int maxdeth=-1 );
0016     static void FindPV_r( const G4VPhysicalVolume* pv,  const char* qname, int mode, std::vector<const G4VPhysicalVolume*>& pvs, int depth, int maxdepth ); 
0017 
0018 
0019     static const G4VPhysicalVolume* FindPVSub( const G4VPhysicalVolume* top, const char* sub ); 
0020     static const G4VPhysicalVolume* FindPV_WithSolidName(   const G4VPhysicalVolume* top, const char* q_soname, unsigned ordinal, unsigned& count  ) ; 
0021     static void               FindPV_WithSolidName_r( const G4VPhysicalVolume* pv,  const char* q_soname, std::vector<const G4VPhysicalVolume*>& pvs, int depth ) ; 
0022 
0023 
0024     static std::string Traverse( const G4VPhysicalVolume* pv, const char* label=nullptr ); 
0025     static std::string Traverse( const G4LogicalVolume*   lv, const char* label=nullptr ); 
0026     static void Traverse_r(const G4VPhysicalVolume* pv, int depth, size_t sib, const char* label, std::ostream& ss ); 
0027     static std::string DescPV(const G4VPhysicalVolume* pv); 
0028     static std::string DescLV(const G4LogicalVolume* lv); 
0029 
0030 
0031     static void GetPV(const G4VPhysicalVolume* top);
0032     static void GetPV_(const G4VPhysicalVolume*  top,  std::vector<const G4VPhysicalVolume*>& pvs ); 
0033     static void GetPV_r(const G4VPhysicalVolume* pv,  int depth, std::vector<const G4VPhysicalVolume*>& pvs ); 
0034 
0035 
0036 
0037     template <typename T> 
0038     static void WriteStoreNames(const char* dir, const char* name); 
0039 
0040     static void WriteTreeNames( std::vector<const G4VPhysicalVolume*>& pvs , const char* dir, const char* name, const char* opt); 
0041 
0042     static void WriteNames( const G4VPhysicalVolume* top, const char* dir  ); 
0043 };
0044 
0045 /**
0046 U4Volume::FindPV
0047 ------------------
0048 
0049 Find volume named *qname* at or beneath *start_pv*
0050 This is slow when used from stepping around in large geometries. 
0051 *maxdepth* when not -1 restricts the recursion depth to search
0052 
0053 **/
0054 
0055 inline const G4VPhysicalVolume*  U4Volume::FindPV( const G4VPhysicalVolume* start_pv,  const char* qname, int mode, int maxdepth ) 
0056 {
0057     std::vector<const G4VPhysicalVolume*> pvs ; 
0058     FindPV_r(start_pv, qname, mode, pvs, 0, maxdepth ); 
0059     return pvs.size() == 1 ? pvs[0] : nullptr ; 
0060 }
0061 inline void U4Volume::FindPV_r( const G4VPhysicalVolume* pv,  const char* qname, int mode, std::vector<const G4VPhysicalVolume*>& pvs, int depth, int maxdepth ) 
0062 {
0063     if(maxdepth > -1 && depth > maxdepth) return ;   
0064     const G4String& name_ = pv->GetName(); 
0065     const char* name = name_.c_str() ; 
0066     if(sstr::Match_(name, qname, mode)) pvs.push_back( pv ); 
0067     const G4LogicalVolume* lv = pv->GetLogicalVolume() ;
0068     for (size_t i=0 ; i < size_t(lv->GetNoDaughters()) ; i++ ) FindPV_r( lv->GetDaughter(i), qname, mode, pvs, depth+1, maxdepth ); 
0069 }
0070 
0071 
0072 
0073 
0074 
0075 inline const G4VPhysicalVolume* U4Volume::FindPVSub( const G4VPhysicalVolume* top, const char* sub )
0076 {
0077     int spare = -99 ; 
0078     int ordinal_ = -99 ; 
0079     const char* q_soname = sstr::ParseStringIntInt(sub, spare, ordinal_ ); 
0080     assert( spare == 0 && ordinal_ > -1 );  
0081     unsigned ordinal = ordinal_ ; 
0082     unsigned count = 0 ; 
0083     const G4VPhysicalVolume* pv_sub = U4Volume::FindPV_WithSolidName( top, q_soname, ordinal, count );  
0084 
0085     LOG(info)
0086         << " sub " << sub
0087         << " q_soname " << q_soname
0088         << " ordinal " << ordinal 
0089         << " count " << count 
0090         << " pv_sub " << pv_sub
0091         << " pv_sub.GetName " << ( pv_sub ? pv_sub->GetName() : "" )
0092         ;   
0093 
0094     assert( count > 0 && ordinal < count );  
0095     return pv_sub ; 
0096 }
0097 
0098 
0099 inline const G4VPhysicalVolume* U4Volume::FindPV_WithSolidName( const G4VPhysicalVolume* top,  const char* q_soname, unsigned ordinal, unsigned& count  ) 
0100 {
0101     std::vector<const G4VPhysicalVolume*> pvs ; 
0102     FindPV_WithSolidName_r(top, q_soname, pvs, 0 ); 
0103     count = pvs.size();   
0104     return ordinal < pvs.size() ? pvs[ordinal] : nullptr ; 
0105 }
0106 inline void U4Volume::FindPV_WithSolidName_r( const G4VPhysicalVolume* pv,  const char* q_soname, std::vector<const G4VPhysicalVolume*>& pvs, int depth ) 
0107 {
0108     const G4LogicalVolume* lv = pv->GetLogicalVolume(); 
0109     const G4VSolid* so = lv->GetSolid(); 
0110      
0111     G4String soname_ = so->GetName() ;  // curiously by value 
0112     const char* soname = soname_.c_str(); 
0113 
0114     bool match = sstr::MatchStart( soname, q_soname ); 
0115 
0116     if(match) pvs.push_back( pv );
0117 
0118     for (size_t i=0 ; i < size_t(lv->GetNoDaughters()) ; i++ ) FindPV_WithSolidName_r( lv->GetDaughter(i), q_soname, pvs, depth+1 ); 
0119 }
0120 
0121 
0122 
0123 
0124 
0125 
0126 
0127 
0128 
0129 
0130 
0131 
0132 
0133 
0134 
0135 
0136 inline std::string U4Volume::Traverse( const G4VPhysicalVolume* pv, const char* label )
0137 {
0138     std::stringstream ss ; 
0139     Traverse_r( pv, 0, 0, label, ss );
0140     std::string s = ss.str(); 
0141     return s ; 
0142 }
0143 
0144 inline std::string U4Volume::Traverse( const G4LogicalVolume* lv, const char* label )
0145 {
0146     std::stringstream ss ; 
0147     for (size_t i=0 ; i < size_t(lv->GetNoDaughters()) ; i++ ) Traverse_r( lv->GetDaughter(i), 0, i, label, ss  ); 
0148     std::string s = ss.str(); 
0149     return s ; 
0150 }
0151 
0152 inline void U4Volume::Traverse_r( const G4VPhysicalVolume* pv, int depth, size_t sib, const char* label, std::ostream& ss )
0153 {
0154     const G4LogicalVolume* lv = pv->GetLogicalVolume() ;
0155 
0156     if(label) ss << " label " << std::setw(10) << label ; 
0157     ss
0158         << " dep " << std::setw(2) << depth 
0159         << " sib " << std::setw(2) << sib 
0160         << " " << DescPV(pv) 
0161         << " " << DescLV(lv) 
0162         << std::endl 
0163         ; 
0164     for (size_t i=0 ; i < size_t(lv->GetNoDaughters()) ; i++ ) Traverse_r( lv->GetDaughter(i), depth+1, i, label, ss ); 
0165 }
0166 
0167 
0168 inline std::string U4Volume::DescPV(const G4VPhysicalVolume* pv)
0169 {
0170     std::stringstream ss ; 
0171     ss
0172         << "DescPV "
0173         << std::setw(20) << pv->GetName()   
0174         ;
0175     std::string s = ss.str(); 
0176     return s ; 
0177 }
0178 
0179 inline std::string U4Volume::DescLV(const G4LogicalVolume* lv)
0180 {
0181     const G4VSolid* so = lv->GetSolid();
0182     const G4Material* mt = lv->GetMaterial() ;
0183     const G4String& mtname = mt->GetName()  ; 
0184     G4String soname = so->GetName();
0185     size_t num_daughters = size_t(lv->GetNoDaughters()) ; 
0186 
0187     std::stringstream ss ; 
0188     ss
0189         << "DescLV "
0190         << std::setw(20) << lv->GetName()   
0191         << " nd " << std::setw(4) << num_daughters
0192         << " mt " << std::setw(8) << mtname
0193         << " so " << soname
0194         ;
0195 
0196     std::string s = ss.str(); 
0197     return s ; 
0198 }
0199 
0200 
0201 
0202 
0203 
0204 
0205 
0206 inline void U4Volume::GetPV(const G4VPhysicalVolume* top)
0207 {
0208     std::vector<const G4VPhysicalVolume*> pvs ; 
0209     GetPV_(top, pvs ); 
0210 }
0211 inline void U4Volume::GetPV_(const G4VPhysicalVolume*  top,  std::vector<const G4VPhysicalVolume*>& pvs )
0212 {
0213     GetPV_r(top, 0, pvs); 
0214 }
0215 inline void U4Volume::GetPV_r(const G4VPhysicalVolume* pv,  int depth, std::vector<const G4VPhysicalVolume*>& pvs )
0216 {
0217     pvs.push_back(pv); 
0218     const G4LogicalVolume* lv = pv->GetLogicalVolume() ;
0219     for (size_t i=0 ; i < size_t(lv->GetNoDaughters()) ; i++ ) GetPV_r( lv->GetDaughter(i), depth+1, pvs ); 
0220 }
0221 
0222 
0223 template <typename T>
0224 inline void U4Volume::WriteStoreNames(const char* dir, const char* name)
0225 {
0226     T* store = T::GetInstance() ; 
0227     std::vector<std::string> names ; 
0228     typedef typename T::const_iterator IT ; 
0229     for(IT it=store->begin() ; it != store->end() ; it++) names.push_back((*it)->GetName()) ; 
0230     NP::WriteNames(dir, name, names); 
0231 }
0232 
0233 
0234 #include "G4LogicalVolumeStore.hh"
0235 template void U4Volume::WriteStoreNames<G4LogicalVolumeStore>(const char*, const char* ); 
0236 
0237 #include "G4PhysicalVolumeStore.hh"
0238 template void U4Volume::WriteStoreNames<G4PhysicalVolumeStore>(const char*, const char* ); 
0239 
0240 
0241 
0242 
0243 inline void U4Volume::WriteTreeNames( std::vector<const G4VPhysicalVolume*>& pvs , const char* dir, const char* name, const char* opt)
0244 {
0245     bool P = strchr(opt, 'P') != nullptr ; 
0246     bool L = strchr(opt, 'L') != nullptr ; 
0247     bool S = strchr(opt, 'S') != nullptr ; 
0248 
0249     std::vector<std::string> names ; 
0250     for(unsigned i=0 ; i < pvs.size() ; i++)
0251     {
0252         const G4VPhysicalVolume* pv = pvs[i] ;  
0253         const G4LogicalVolume* lv = pv->GetLogicalVolume() ;
0254         const G4VSolid* so = lv->GetSolid(); 
0255        
0256         if(P) names.push_back(pv->GetName()); 
0257         if(L) names.push_back(lv->GetName()); 
0258         if(S) names.push_back(so->GetName()); 
0259     }
0260 
0261     LOG(info) << "  names.size " << names.size() << " opt " << opt << " P " << P << " L " << L <<  " S " << S << " name " << name ; 
0262     NP::WriteNames(dir, name, names); 
0263 }
0264 
0265 
0266 
0267 /**
0268 U4Volume::WriteNames
0269 --------------------------
0270 
0271 *WriteStoreNames* just writes the name of each LV and PV once
0272 
0273 *WriteTreeNames* repeatedly writes the names of LV, PV and SO 
0274 for every node of the full volume tree.
0275 
0276 ::
0277 
0278     epsilon:U4VolumeMaker_PVG_WriteNames blyth$ wc -l *.txt
0279          139 G4LogicalVolumeStore.txt
0280        51028 G4PhysicalVolumeStore.txt
0281       336653 L.txt
0282       336653 P.txt
0283      1009959 PLS.txt
0284       336653 S.txt
0285      2071085 total
0286 
0287 
0288 **/
0289 
0290 inline void U4Volume::WriteNames(const G4VPhysicalVolume* top, const char* dir )
0291 {
0292     WriteStoreNames<G4LogicalVolumeStore>( dir, "G4LogicalVolumeStore.txt" );  
0293     WriteStoreNames<G4PhysicalVolumeStore>(dir, "G4PhysicalVolumeStore.txt" );  
0294 
0295     std::vector<const G4VPhysicalVolume*> pvs ; 
0296     GetPV_(top, pvs ); 
0297     LOG(info) 
0298         << " dir " << dir 
0299         << "  pvs.size " << pvs.size()
0300         ; 
0301 
0302     WriteTreeNames(pvs, dir, "P.txt", "P" ); 
0303     WriteTreeNames(pvs, dir, "L.txt", "L" ); 
0304     WriteTreeNames(pvs, dir, "S.txt", "S" ); 
0305     WriteTreeNames(pvs, dir, "PLS.txt", "PLS" ); 
0306 }
0307 
0308