File indexing completed on 2026-04-09 07:50:04
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
0035
0036
0037
0038
0039
0040
0041
0042
0043 #include <map>
0044 #include <algorithm>
0045 #include <string>
0046 #include <sstream>
0047 #include <csignal>
0048
0049 #include <glm/glm.hpp>
0050 #include "G4VPhysicalVolume.hh"
0051 #include "G4LogicalVolume.hh"
0052 #include "G4PVPlacement.hh"
0053 #include "G4Material.hh"
0054 #include "G4LogicalSurface.hh"
0055 #include "G4OpRayleigh.hh"
0056 #include "G4OpticalPhoton.hh"
0057
0058 #include "NP.hh"
0059
0060 #include "sdigest.h"
0061 #include "sfreq.h"
0062 #include "stree.h"
0063 #include "suniquename.h"
0064 #include "snd.hh"
0065 #include "sdomain.h"
0066 #include "sstr.h"
0067 #include "ssys.h"
0068
0069 #include "SSimtrace.h"
0070 #include "SEventConfig.hh"
0071
0072 #include "U4SensorIdentifier.h"
0073 #include "U4SensorIdentifierDefault.h"
0074
0075 #include "U4Transform.h"
0076 #include "U4Material.hh"
0077 #include "U4Mat.h"
0078
0079 #include "U4Surface.h"
0080 #include "U4SurfacePerfect.h"
0081 #include "U4SurfaceArray.h"
0082
0083 #include "U4Mesh.h"
0084 #include "U4Scint.h"
0085
0086 #include "U4Solid.h"
0087 #include "U4PhysicsTable.h"
0088 #include "U4MaterialTable.h"
0089 #include "U4TreeBorder.h"
0090 #include "U4Recorder.hh"
0091
0092 #include <plog/Log.h>
0093
0094
0095 struct U4Tree
0096 {
0097 static constexpr const plog::Severity LEVEL = plog::info ;
0098 friend struct U4SimtraceTest ;
0099 friend struct U4SimtraceSimpleTest ;
0100
0101 stree* st ;
0102 const G4VPhysicalVolume* const top ;
0103 U4SensorIdentifier* sid ;
0104 int level ;
0105
0106
0107 std::map<const G4LogicalVolume* const, int> lvidx ;
0108 std::vector<const G4VPhysicalVolume*> pvs ;
0109 std::vector<const G4Material*> materials ;
0110 std::vector<const G4LogicalSurface*> surfaces ;
0111 int num_surface_standard ;
0112 std::vector<const G4VSolid*> solids ;
0113 U4PhysicsTable<G4OpRayleigh>* rayleigh_table ;
0114 U4Scint* scint ;
0115
0116
0117 static constexpr const char* __DISABLE_OSUR_IMPLICIT = "U4Tree__DISABLE_OSUR_IMPLICIT" ;
0118 static constexpr const char* __DISABLE_ISUR_IMPLICIT = "U4Tree__DISABLE_ISUR_IMPLICIT" ;
0119 static constexpr const char* __MATERIAL_DEBUG = "U4Tree__MATERIAL_DEBUG" ;
0120 static constexpr const char* __SOLID_DEBUG = "U4Tree__SOLID_DEBUG" ;
0121 bool enable_osur ;
0122 bool enable_isur ;
0123 int material_debug ;
0124 int solid_debug ;
0125
0126 static U4Tree* Create(
0127 stree* st,
0128 const G4VPhysicalVolume* const top,
0129 U4SensorIdentifier* sid=nullptr
0130 );
0131
0132
0133
0134
0135
0136 private:
0137 U4Tree(
0138 stree* st,
0139 const G4VPhysicalVolume* const top=nullptr,
0140 U4SensorIdentifier* sid=nullptr
0141 );
0142
0143 void init();
0144
0145 void initSid();
0146 static U4PhysicsTable<G4OpRayleigh>* CreateRayleighTable();
0147 void initRayleigh();
0148 void initMaterials();
0149 void initMaterials_NoRINDEX();
0150
0151 void initMaterials_r(const G4VPhysicalVolume* const pv);
0152 void initMaterial(const G4Material* const mt);
0153
0154 void initScint();
0155 void initSurfaces();
0156
0157 void initSolids();
0158 void initSolids_Keys();
0159 void initSolids_Mesh();
0160
0161 void initSolids_r(const G4VPhysicalVolume* const pv);
0162 void initSolid(const G4LogicalVolume* const lv);
0163
0164
0165 void initSolid(const G4VSolid* const so, int lvid );
0166
0167 void initNodes();
0168 int initNodes_r(
0169 const G4VPhysicalVolume* const pv,
0170 const G4VPhysicalVolume* const pv_p,
0171 int depth,
0172 int sibdex,
0173 int parent
0174 );
0175
0176 void initSurfaces_Serialize();
0177 void initStandard();
0178 void initRecorder();
0179
0180 public:
0181 const G4Material* getMaterial(int idx) const ;
0182 const G4LogicalSurface* getSurface(int idx) const ;
0183
0184 std::string desc() const ;
0185 const G4VPhysicalVolume* get_pv_(int nidx) const ;
0186 const G4PVPlacement* get_pv(int nidx) const ;
0187 int get_pv_copyno(int nidx) const ;
0188
0189 int get_nidx(const G4VPhysicalVolume* pv) const ;
0190 int get_prim_for_nidx(int nidx) const ;
0191 const char* get_prname(int globalPrimIdx) const ;
0192
0193
0194 private:
0195
0196 void identifySensitive();
0197 void identifySensitiveInstances();
0198 void identifySensitiveGlobals();
0199
0200 public:
0201 void simtrace_scan(const char* base) const ;
0202 static void SimtraceScan( const G4VPhysicalVolume* const pv, const char* base );
0203 };
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 inline U4Tree* U4Tree::Create(
0218 stree* st,
0219 const G4VPhysicalVolume* const top,
0220 U4SensorIdentifier* sid
0221 )
0222 {
0223 if(st->level > 0) std::cout << "[ U4Tree::Create " << std::endl ;
0224
0225 LOG(LEVEL) << "[new U4Tree" ;
0226 U4Tree* tree = new U4Tree(st, top, sid ) ;
0227 LOG(LEVEL) << "]new U4Tree" ;
0228
0229 LOG(LEVEL) << "[stree::factorize" ;
0230 st->factorize();
0231 LOG(LEVEL) << "]stree::factorize" ;
0232
0233 LOG(LEVEL) << "[U4Tree::identifySensitive" ;
0234 tree->identifySensitive();
0235 LOG(LEVEL) << "]U4Tree::identifySensitive" ;
0236
0237
0238 LOG(LEVEL) << "[stree::add_inst" ;
0239 st->add_inst();
0240 LOG(LEVEL) << "]stree::add_inst" ;
0241
0242 if(st->level > 0) std::cout << "] U4Tree::Create " << std::endl ;
0243
0244
0245 LOG(LEVEL) << "[stree::postcreate" ;
0246 st->postcreate() ;
0247 LOG(LEVEL) << "]stree::postcreate" ;
0248
0249 return tree ;
0250 }
0251
0252 inline U4Tree::U4Tree(
0253 stree* st_,
0254 const G4VPhysicalVolume* const top_,
0255 U4SensorIdentifier* sid_
0256 )
0257 :
0258 st(st_),
0259 top(top_),
0260 sid(sid_ ? sid_ : new U4SensorIdentifierDefault),
0261 level(st->level),
0262 num_surface_standard(-1),
0263 rayleigh_table(CreateRayleighTable()),
0264 scint(nullptr),
0265 enable_osur(!ssys::getenvbool(__DISABLE_OSUR_IMPLICIT)),
0266 enable_isur(!ssys::getenvbool(__DISABLE_ISUR_IMPLICIT)),
0267 material_debug(ssys::getenvint(__MATERIAL_DEBUG,0)),
0268 solid_debug(ssys::getenvint(__SOLID_DEBUG,0))
0269 {
0270 init();
0271 }
0272
0273
0274
0275
0276
0277
0278
0279 inline void U4Tree::init()
0280 {
0281 if(top == nullptr) return ;
0282
0283 LOG(LEVEL) << "-initSid" ;
0284 initSid();
0285 LOG(LEVEL) << "-initRayleigh" ;
0286 initRayleigh();
0287 LOG(LEVEL) << "-initMaterials" ;
0288 initMaterials();
0289 LOG(LEVEL) << "-initMaterials_NoRINDEX" ;
0290 initMaterials_NoRINDEX();
0291
0292 LOG(LEVEL) << "-initScint" ;
0293 initScint();
0294
0295 LOG(LEVEL) << "-initSurfaces" ;
0296 initSurfaces();
0297
0298 LOG(LEVEL) << "-initSolids" ;
0299 initSolids();
0300 LOG(LEVEL) << "-initNodes" ;
0301 initNodes();
0302 LOG(LEVEL) << "-initSurfaces_Serialize" ;
0303 initSurfaces_Serialize();
0304
0305 LOG(LEVEL) << "-initStandard" ;
0306 initStandard();
0307
0308 LOG(LEVEL) << "-initRecorder" ;
0309 initRecorder();
0310
0311 std::cout << "U4Tree::init " << desc() << std::endl;
0312
0313 }
0314
0315 inline void U4Tree::initSid()
0316 {
0317 sid->setLevel(st->level);
0318 }
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342 inline void U4Tree::initMaterials()
0343 {
0344 LOG_IF(info, material_debug > 0 ) << "[" ;
0345
0346 initMaterials_r(top);
0347 st->material = U4Material::MakePropertyFold(materials);
0348
0349 std::map<std::string, G4PhysicsVector*> prop_override ;
0350
0351 G4PhysicsVector* Water_RAYLEIGH = rayleigh_table->find("Water") ;
0352 if(Water_RAYLEIGH) prop_override["Water/RAYLEIGH"] = Water_RAYLEIGH ;
0353
0354 st->standard->mat = U4Material::MakeStandardArray(materials, prop_override) ;
0355
0356 LOG_IF(info, material_debug > 0 ) << "]" ;
0357 }
0358
0359 inline void U4Tree::initMaterials_NoRINDEX()
0360 {
0361 int num_materials = materials.size() ;
0362 for(int i=0 ; i < num_materials ; i++)
0363 {
0364 const G4Material* mt = materials[i] ;
0365 const char* mtn = mt->GetName().c_str();
0366 const G4MaterialPropertyVector* rindex = U4Mat::GetRINDEX( mt ) ;
0367 if(rindex == nullptr) st->mtname_no_rindex.push_back(mtn) ;
0368 }
0369 }
0370
0371
0372
0373
0374
0375
0376
0377
0378 inline void U4Tree::initScint()
0379 {
0380 scint = U4Scint::Create(st->material) ;
0381 if(scint)
0382 {
0383 st->standard->icdf = scint->icdf ;
0384 }
0385 }
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399 inline U4PhysicsTable<G4OpRayleigh>* U4Tree::CreateRayleighTable()
0400 {
0401 G4OpRayleigh* proc = new G4OpRayleigh ;
0402
0403 G4ParticleDefinition* OpticalPhoton = G4OpticalPhoton::Definition() ;
0404 proc->BuildPhysicsTable(*OpticalPhoton);
0405
0406 U4PhysicsTable<G4OpRayleigh>* tab = new U4PhysicsTable<G4OpRayleigh>(proc) ;
0407 return tab ;
0408 }
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420 inline void U4Tree::initRayleigh()
0421 {
0422 if(level > 0) std::cerr
0423 << "U4Tree::initRayleigh"
0424 << " rayleigh_table " << std::endl
0425 << ( rayleigh_table ? rayleigh_table->desc() : "-" )
0426 << std::endl
0427 ;
0428
0429 st->standard->rayleigh = rayleigh_table ? rayleigh_table->tab : nullptr ;
0430 }
0431
0432
0433 inline void U4Tree::initMaterials_r(const G4VPhysicalVolume* const pv)
0434 {
0435 const G4LogicalVolume* lv = pv->GetLogicalVolume() ;
0436 int num_child = int(lv->GetNoDaughters()) ;
0437 for (int i=0 ; i < num_child ;i++ ) initMaterials_r( lv->GetDaughter(i) );
0438
0439
0440 G4Material* mt = lv->GetMaterial() ;
0441
0442 if(mt == nullptr) std::cerr
0443 << "U4Tree::initMaterials_r"
0444 << " pv " << ( pv ? pv->GetName() : "-" )
0445 << " lv " << ( lv ? lv->GetName() : "-" )
0446 << " num_child " << num_child
0447 << " mt " << ( mt ? mt->GetName() : "-" )
0448 << std::endl
0449 ;
0450
0451 assert(mt);
0452
0453 std::vector<const G4Material*>& m = materials ;
0454
0455 bool new_material = std::find(m.begin(), m.end(), mt) == m.end();
0456
0457 if(new_material)
0458 {
0459 LOG_IF(info, material_debug > 0 )
0460 << " pv " << ( pv ? pv->GetName() : "-" )
0461 << " lv " << ( lv ? lv->GetName() : "-" )
0462 << " num_child " << num_child
0463 ;
0464
0465 LOG_IF(info, material_debug > 0 )
0466 << " pv " << ( pv ? pv->GetName() : "-" )
0467 << " lv " << ( lv ? lv->GetName() : "-" )
0468 << " num_child " << num_child
0469 << " mt " << ( mt ? mt->GetName() : "-" )
0470 ;
0471
0472 initMaterial(mt);
0473 }
0474 }
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485 inline void U4Tree::initMaterial(const G4Material* const mt)
0486 {
0487 materials.push_back(mt);
0488 const G4String& _mtname = mt->GetName() ;
0489 unsigned g4index = mt->GetIndex() ;
0490 const char* mtname = _mtname.c_str();
0491 st->add_material( mtname, g4index );
0492 }
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510 inline void U4Tree::initSurfaces()
0511 {
0512 U4Surface::Collect(surfaces);
0513
0514 U4Surface::CollectRawNames(st->suname_raw, surfaces);
0515
0516 sstr::StripTail_Unique( st->suname, st->suname_raw, "0x" );
0517
0518 assert( st->suname.size() == st->suname_raw.size() );
0519
0520
0521 st->surface = U4Surface::MakeFold(surfaces, st->suname );
0522
0523 num_surface_standard = int(surfaces.size()) ;
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539 }
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571 inline void U4Tree::initSurfaces_Serialize()
0572 {
0573 std::vector<U4SurfacePerfect> perfect ;
0574 U4SurfacePerfect::Get(perfect);
0575
0576 int num_perfect = perfect.size();
0577 for(int i=0 ; i < num_perfect ; i++)
0578 {
0579 const U4SurfacePerfect& perf = perfect[i] ;
0580 const char* name = perf.name.c_str() ;
0581 st->add_extra_surface( name );
0582 }
0583
0584
0585 U4SurfaceArray serialize(surfaces, st->implicit, perfect) ;
0586 st->standard->sur = serialize.sur ;
0587
0588 }
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610 inline void U4Tree::initSolids()
0611 {
0612 if(solid_debug > -1) std::cout << "[U4Tree::initSolids" << std::endl ;
0613
0614 initSolids_r(top);
0615 initSolids_Keys();
0616 initSolids_Mesh();
0617
0618 if(solid_debug > 0) std::cout
0619 << "-U4Tree::initSolids\n"
0620 << " [" << __SOLID_DEBUG << "] " << solid_debug << "\n"
0621 << st->desc_solids()
0622 << "\n"
0623 ;
0624
0625 if(solid_debug> -1) std::cout << "]U4Tree::initSolids" << std::endl ;
0626 }
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638 inline void U4Tree::initSolids_Keys()
0639 {
0640 sstr::StripTail_Unique( st->soname, st->soname_raw, "0x" );
0641 assert( st->soname.size() == st->soname_raw.size() );
0642 }
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653 inline void U4Tree::initSolids_Mesh()
0654 {
0655 st->mesh = U4Mesh::MakeFold(solids, st->soname ) ;
0656 }
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667 inline void U4Tree::initSolids_r(const G4VPhysicalVolume* const pv)
0668 {
0669 const G4LogicalVolume* const lv = pv->GetLogicalVolume();
0670 int num_child = int(lv->GetNoDaughters()) ;
0671 for (int i=0 ; i < num_child ;i++ ) initSolids_r( lv->GetDaughter(i) );
0672
0673
0674 if(lvidx.find(lv) == lvidx.end()) initSolid(lv);
0675 }
0676 inline void U4Tree::initSolid(const G4LogicalVolume* const lv)
0677 {
0678 int lvid = lvidx.size() ;
0679 lvidx[lv] = lvid ;
0680 const G4VSolid* const so = lv->GetSolid();
0681 initSolid(so, lvid);
0682 }
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706 inline void U4Tree::initSolid(const G4VSolid* const so, int lvid )
0707 {
0708 G4String _name = so->GetName() ;
0709 const char* name = _name.c_str();
0710
0711 assert( int(solids.size()) == lvid );
0712 int d = 0 ;
0713 sn* root = U4Solid::Convert(so, lvid, d );
0714 assert( root );
0715
0716 solids.push_back(so);
0717 st->soname_raw.push_back(name);
0718 st->solids.push_back(root);
0719
0720 }
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737 inline void U4Tree::initNodes()
0738 {
0739 int nidx = initNodes_r(top, nullptr, 0, -1, -1 );
0740 bool nidx_expect = nidx == 0 ;
0741 assert( nidx_expect );
0742 if(!nidx_expect) std::raise(SIGINT);
0743
0744 }
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800 inline int U4Tree::initNodes_r(
0801 const G4VPhysicalVolume* const pv,
0802 const G4VPhysicalVolume* const pv_p,
0803 int depth,
0804 int sibdex,
0805 int parent )
0806 {
0807
0808 U4TreeBorder border(st, pv, pv_p) ;
0809
0810 int omat = stree::GetPointerIndex<G4Material>( materials, border.omat_);
0811 int osur = stree::GetPointerIndex<G4LogicalSurface>(surfaces, border.osur_);
0812 int isur = stree::GetPointerIndex<G4LogicalSurface>(surfaces, border.isur_);
0813 int imat = stree::GetPointerIndex<G4Material>( materials, border.imat_);
0814
0815 int4 bd = {omat, osur, isur, imat } ;
0816
0817
0818 if(enable_osur && border.has_osur_override(bd)) border.do_osur_override(bd);
0819 if(enable_isur && border.has_isur_override(bd)) border.do_isur_override(bd);
0820
0821 border.check(bd);
0822 int boundary = st->add_boundary(bd) ;
0823 assert( boundary > -1 );
0824
0825
0826 const G4LogicalVolume* const lv = pv->GetLogicalVolume();
0827 int num_child = int(lv->GetNoDaughters()) ;
0828 int lvid = lvidx[lv] ;
0829
0830 const G4PVPlacement* pvp = dynamic_cast<const G4PVPlacement*>(pv) ;
0831 int copyno = pvp ? pvp->GetCopyNo() : -1 ;
0832
0833 glm::tmat4x4<double> tr_m2w(1.) ;
0834 U4Transform::GetObjectTransform(tr_m2w, pv);
0835
0836 glm::tmat4x4<double> tr_w2m(1.) ;
0837 U4Transform::GetFrameTransform(tr_w2m, pv);
0838
0839 std::string dig = stree::Digest(lvid, tr_m2w);
0840
0841 int nidx = st->nds.size() ;
0842
0843 snode nd ;
0844
0845 nd.index = nidx ;
0846 nd.depth = depth ;
0847 nd.sibdex = sibdex ;
0848 nd.parent = parent ;
0849
0850 nd.num_child = num_child ;
0851 nd.first_child = -1 ;
0852 nd.next_sibling = -1 ;
0853 nd.lvid = lvid ;
0854
0855 nd.copyno = copyno ;
0856 nd.boundary = boundary ;
0857
0858 nd.sensor_id = -1 ;
0859 nd.sensor_index = -1 ;
0860 nd.sensor_name = -1 ;
0861
0862
0863 nd.repeat_index = 0 ;
0864 nd.repeat_ordinal = -1 ;
0865
0866
0867 pvs.push_back(pv);
0868
0869 st->nds.push_back(nd);
0870 st->digs.push_back(dig);
0871 st->m2w.push_back(tr_m2w);
0872 st->w2m.push_back(tr_w2m);
0873
0874
0875
0876 glm::tmat4x4<double> tt_gtd(1.) ;
0877 glm::tmat4x4<double> vv_gtd(1.) ;
0878
0879 bool local = false ;
0880 bool reverse = false ;
0881 std::ostream* out = nullptr ;
0882 stree::VTR* t_stack = nullptr ;
0883
0884 st->get_node_product( tt_gtd, vv_gtd, nidx, local, reverse, out, t_stack );
0885
0886
0887
0888 st->gtd.push_back(tt_gtd);
0889
0890
0891 if(sibdex == 0 && nd.parent > -1) st->nds[nd.parent].first_child = nd.index ;
0892
0893
0894 int p_sib = -1 ;
0895 int i_sib = -1 ;
0896 for (int i=0 ; i < num_child ;i++ )
0897 {
0898 p_sib = i_sib ;
0899
0900
0901
0902 i_sib = initNodes_r( lv->GetDaughter(i), pv, depth+1, i, nd.index );
0903
0904 if(p_sib > -1) st->nds[p_sib].next_sibling = i_sib ;
0905
0906
0907 }
0908
0909 return nd.index ;
0910 }
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927 inline void U4Tree::initStandard()
0928 {
0929 st->initStandard();
0930 }
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945 inline void U4Tree::initRecorder()
0946 {
0947 U4Recorder* recorder = U4Recorder::Get();
0948 if(recorder) recorder->setU4Tree(this);
0949 if(!recorder) std::cerr << "U4Tree::initRecorder FAIL no U4Recorder\n" ;
0950 }
0951
0952
0953
0954
0955 inline const G4Material* U4Tree::getMaterial(int idx) const
0956 {
0957 return idx > -1 ? materials[idx] : nullptr ;
0958 }
0959 inline const G4LogicalSurface* U4Tree::getSurface(int idx) const
0960 {
0961 return idx > -1 ? surfaces[idx] : nullptr ;
0962 }
0963
0964 inline std::string U4Tree::desc() const
0965 {
0966 std::stringstream ss ;
0967 ss << "U4Tree::desc" << std::endl
0968 << " st " << ( st ? "Y" : "N" ) << std::endl
0969 << " top " << ( top ? "Y" : "N" ) << std::endl
0970 << " sid " << ( sid ? "Y" : "N" ) << std::endl
0971 << " level " << level << std::endl
0972 << " lvidx " << lvidx.size() << std::endl
0973 << " pvs " << pvs.size() << std::endl
0974 << " materials " << materials.size() << std::endl
0975 << " surfaces " << surfaces.size() << std::endl
0976 << " solids " << solids.size() << std::endl
0977 << " enable_osur " << ( enable_osur ? "YES" : "NO " ) << std::endl
0978 << " enable_isur " << ( enable_isur ? "YES" : "NO " ) << std::endl
0979 ;
0980 std::string str = ss.str();
0981 return str ;
0982 }
0983
0984
0985 inline const G4VPhysicalVolume* U4Tree::get_pv_(int nidx) const
0986 {
0987 return nidx > -1 && nidx < int(pvs.size()) ? pvs[nidx] : nullptr ;
0988 }
0989 inline const G4PVPlacement* U4Tree::get_pv(int nidx) const
0990 {
0991 const G4VPhysicalVolume* pv_ = get_pv_(nidx);
0992 return dynamic_cast<const G4PVPlacement*>(pv_) ;
0993 }
0994 inline int U4Tree::get_pv_copyno(int nidx) const
0995 {
0996 const G4PVPlacement* pv = get_pv(nidx) ;
0997 return pv ? pv->GetCopyNo() : -1 ;
0998 }
0999
1000
1001 inline int U4Tree::get_nidx(const G4VPhysicalVolume* pv) const
1002 {
1003 int nidx = std::distance( pvs.begin(), std::find( pvs.begin(), pvs.end(), pv ) ) ;
1004 return nidx < int(pvs.size()) ? nidx : -1 ;
1005 }
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 inline int U4Tree::get_prim_for_nidx(int nidx) const
1016 {
1017 assert(st);
1018 int globalPrimIdx = st->get_prim_for_nidx(nidx) ;
1019 return globalPrimIdx ;
1020 }
1021
1022 inline const char* U4Tree::get_prname(int globalPrimIdx) const
1023 {
1024 assert(st);
1025 const char* prn = st->get_prname(globalPrimIdx);
1026 return prn ;
1027 }
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060 inline void U4Tree::identifySensitive()
1061 {
1062 if(level > 0) std::cerr
1063 << "[ U4Tree::identifySensitive "
1064 << std::endl
1065 ;
1066
1067 st->sensor_count = 0 ;
1068
1069 identifySensitiveInstances();
1070 identifySensitiveGlobals();
1071
1072 st->reorderSensors();
1073
1074
1075
1076 if(level > 0) std::cerr
1077 << "] U4Tree::identifySensitive"
1078 << " st.sensor_count " << st->sensor_count
1079 << std::endl
1080 ;
1081 }
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106 inline void U4Tree::identifySensitiveInstances()
1107 {
1108 unsigned num_factor = st->get_num_factor();
1109 if(level > 0) std::cerr
1110 << "[ U4Tree::identifySensitiveInstances"
1111 << " num_factor " << num_factor
1112 << " st.sensor_count " << st->sensor_count
1113 << std::endl
1114 ;
1115
1116 for(unsigned i=0 ; i < num_factor ; i++)
1117 {
1118 std::vector<int> outer ;
1119 st->get_factor_nodes(outer, i);
1120
1121
1122 sfactor& fac = st->get_factor_(i);
1123 fac.sensors = 0 ;
1124
1125 for(unsigned j=0 ; j < outer.size() ; j++)
1126 {
1127 int nidx = outer[j] ;
1128 const G4VPhysicalVolume* pv = get_pv_(nidx) ;
1129 const char* pvn = pv->GetName().c_str() ;
1130
1131 int sensor_id = sid->getInstanceIdentity(pv) ;
1132 assert( sensor_id >= -1 );
1133
1134 int sensor_index = sensor_id > -1 ? st->sensor_count : -1 ;
1135 int sensor_name = -1 ;
1136
1137 if(sensor_id > -1 )
1138 {
1139 st->sensor_count += 1 ;
1140 fac.sensors += 1 ;
1141 sensor_name = suniquename::Add(pvn, st->sensor_name ) ;
1142 }
1143
1144 snode& nd = st->nds[nidx] ;
1145 nd.sensor_id = sensor_id ;
1146 nd.sensor_index = sensor_index ;
1147 nd.sensor_name = sensor_name ;
1148
1149 if(level > 1) std::cerr
1150 << "U4Tree::identifySensitiveInstances"
1151 << " i " << std::setw(7) << i
1152 << " sensor_id " << std::setw(7) << sensor_id
1153 << " sensor_index " << std::setw(7) << sensor_index
1154 << std::endl
1155 ;
1156 }
1157
1158 if(level > 0) std::cerr
1159 << "U4Tree::identifySensitiveInstances"
1160 << " factor " << i
1161 << " fac.sensors " << fac.sensors
1162 << std::endl
1163 ;
1164 }
1165
1166 if(level > 0) std::cerr
1167 << "] U4Tree::identifySensitiveInstances"
1168 << " num_factor " << num_factor
1169 << " st.sensor_count " << st->sensor_count
1170 << std::endl
1171 ;
1172 }
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 inline void U4Tree::identifySensitiveGlobals()
1183 {
1184 std::vector<int> remainder ;
1185 st->get_remainder_nidx(remainder) ;
1186
1187 if(level > 0) std::cerr
1188 << "[ U4Tree::identifySensitiveGlobals"
1189 << " st.sensor_count " << st->sensor_count
1190 << " remainder.size " << remainder.size()
1191 << std::endl
1192 ;
1193
1194 for(unsigned i=0 ; i < remainder.size() ; i++)
1195 {
1196 int nidx = remainder[i] ;
1197 snode& nd = st->nds[nidx] ;
1198
1199 const G4VPhysicalVolume* pv = get_pv_(nidx) ;
1200 const G4VPhysicalVolume* ppv = get_pv_(nd.parent) ;
1201
1202 const char* pvn = pv->GetName().c_str() ;
1203 const char* ppvn = ppv ? ppv->GetName().c_str() : nullptr ;
1204
1205 int sensor_id = sid->getGlobalIdentity(pv, ppv ) ;
1206 int sensor_index = sensor_id > -1 ? st->sensor_count : -1 ;
1207 int sensor_name = -1 ;
1208
1209 if(sensor_id > -1 )
1210 {
1211 st->sensor_count += 1 ;
1212 sensor_name = suniquename::Add(pvn, st->sensor_name ) ;
1213 }
1214 nd.sensor_id = sensor_id ;
1215 nd.sensor_index = sensor_index ;
1216 nd.sensor_name = sensor_name ;
1217
1218 if(level > 1) std::cerr
1219 << "U4Tree::identifySensitiveGlobals"
1220 << " i " << std::setw(7) << i
1221 << " nidx " << std::setw(6) << nidx
1222 << " sensor_id " << std::setw(7) << sensor_id
1223 << " sensor_index " << std::setw(7) << sensor_index
1224 << " pvn " << pvn
1225 << " ppvn " << ( ppvn ? ppvn : "-" )
1226 << std::endl
1227 ;
1228 }
1229 if(level > 0) std::cerr
1230 << "] U4Tree::identifySensitiveGlobals "
1231 << " st.sensor_count " << st->sensor_count
1232 << " remainder.size " << remainder.size()
1233 << std::endl
1234 ;
1235 }
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253 inline void U4Tree::simtrace_scan(const char* base) const
1254 {
1255 LOG(info) << "[ " << SEventConfig::RGModeLabel() ;
1256 st->save_trs(base);
1257 assert( st->soname.size() == solids.size() );
1258 for(unsigned i=0 ; i < st->soname.size() ; i++)
1259 {
1260 const char* soname = st->soname[i].c_str();
1261 const G4VSolid* solid = solids[i] ;
1262 G4String name = solid->GetName();
1263
1264 bool soname_expect = strcmp( name.c_str(), soname ) == 0 ;
1265 assert(soname_expect);
1266 if(!soname_expect) std::raise(SIGINT);
1267
1268 LOG(info) << " i " << std::setw(3) << i << " RGMode: " << SEventConfig::RGModeLabel() ;
1269 SSimtrace::Scan(solid) ;
1270 }
1271 LOG(info) << "] " << SEventConfig::RGModeLabel() ;
1272 }
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282 inline void U4Tree::SimtraceScan( const G4VPhysicalVolume* const pv, const char* base )
1283 {
1284 stree st ;
1285 U4Tree ut(&st, pv ) ;
1286 ut.simtrace_scan(base) ;
1287 }
1288
1289