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
0047
0048
0049
0050
0051
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() ;
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
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
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