- Hamamatsu PMT Solid breaking Opticks
- CSG tree height 8 : TOO DEEP
- PROFLIGATE : G4ItersectionSolid Z-Cut
- SOLUTION : ZSolid::ApplyZCutTree : Actually Cut the CSG Tree
- Tools for development of solution ZSolid::ApplyZCutTree
- PMTSim::GetSolid PMTSim::GetPV
- X4IntersectTest
- ZSolid::ApplyZCutTree algorithm
- new Opticks pkg : GeoChain
- single executables handle full chain of geometry conversions
ZSolid::Draw [-1] nameprefix _body_solid_ NODE:19 PRIM:10 UNDEFINED:19 EXCLUDE:0 INCLUDE:0 MIXED:0 Order:IN Int
U
17
Uni Pol
U U
15 18
Uni Pol
U U
13 16
Uni Pol
U U
11 14
Uni Ell
U U
9 12
Uni Pol
U U
5 10
Uni Sub
U U
3 7
Uni Ell Pol Tor
U U U U
1 4 6 8
Ell Pol
U U
0 2
0.0 -2.5 -5.0 -179.2 -210.0 -242.5 -275.0 -385.0 -420.0 3.4 zdelta
190.0 0.0 -5.0 -148.4 -130.0 -210.0 -275.0 -350.0 -420.0 190.0 az1
0.0 -5.0 -195.0 -210.0 -290.0 -275.0 -365.0 -420.0 -450.0 -183.2 az0
I 1_2 II 1_3 III 1_4 IV_tub IV IV_tor 1_5 V 1_6 VI 1_8 VIII 1_9 IX cut intubs
Using G4IntersectionSolid to apply Z-cut to PMT
485 // Reduce the size when real surface is enabled.
486 // Tao Lin, 09 Aug 2021
487 if (m_useRealSurface ) {
...
546 const double body_height = m_pmt_h;
547 const double body_half_height = body_height / 2;
548 const G4ThreeVector cut_body_displacement(0., 0., m_z_equator-pmt_half_height);
549 G4VSolid* cut_body_solid = new G4Tubs( GetName() + "_body_solid_intubs",
550 0.,
551 helper_sep_tube_r+1E-9*mm,
552 body_half_height,
553 0., 360.*degree);
554 body_solid = new G4IntersectionSolid( GetName() + "_body_solid_cut",
555 body_solid,
556 cut_body_solid,
557 NULL,
558 cut_body_displacement);
SOLUTION ACTUALLY CUT THE CSG TREE using https://github.com/simoncblyth/j/blob/main/PMTSim/ZSolid.hh
G4VSolid* ZSolid::ApplyZCutTree( const G4VSolid* original, double zcut)
G4VSolid* body_solid = PMTSim::GetSolid("body_solid");
G4VSolid* inner1_solid = PMTSim::GetSolid("inner1_solid");
G4VPhysicalVolume* body_phys = PMTSim::GetPV("body_phys");
G4double X4Intersect::Distance(const G4VSolid* solid,
const G4ThreeVector& pos, const G4ThreeVector& dir)
{
EInside in = solid->Inside(pos) ; G4double t = kInfinity ;
switch( in ) {
case kInside: t = solid->DistanceToOut( pos, dir ) ; break ;
case kSurface: t = solid->DistanceToOut( pos, dir ) ; break ;
case kOutside: t = solid->DistanceToIn( pos, dir ) ; break ; }
return t ;
}
G4VSolid* ZSolid::ApplyZCutTree(const G4VSolid* orig, double zcut)
ZSolid::SetRight
G4BooleanSolid* src = dynamic_cast<G4BooleanSolid*>(node) ; G4String name = src->GetName() ; G4VSolid* left = src->GetConstituentSolid(0) ; G4SolidStore::GetInstance()->DeRegister(src); src1 = new (src) G4UnionSolid(name, left, new_right) assert( src1 == src );
Similar trick used to cut G4Polycone ZSolid::ApplyZCut_G4Polycone
https://github.com/simoncblyth/j/blob/main/PMTSim/ZSolid.hh
Applying Z-cut to G4VSolid CSG Tree
Pruning and Reconnection
ZSolid::apply_cut before prune [ 0] nameprefix maker_body_solid_zcut-183.2246_ NODE:15 PRIM:8 UNDEFINED:0 EXCLUDE:4 INCLUDE:7 MIXED:4 Order:IN
Uni
I : include IE
13
E : exclude
Uni Pol
IE: mixed include/exclude IE E
11 14
X : "crux" node
Uni Pol
S : survivor node IE E
9 12
Uni Ell
IE E
7 10
X
Uni Pol
I E
5 8
S
Uni Pol
I I
3 6
Uni Ell
I I
1 4
Ell Pol
I I
0 2
0.0 -2.5 -5.0 -179.2 -242.5 -275.0 -385.0 -420.0 zdelta
190.0 0.0 -5.0 -162.0 -210.0 -275.0 -350.0 -420.0 az1
0.0 -5.0 -183.2 -183.2 -275.0 -365.0 -420.0 -450.0 az0
I 1_2 II 1_3 III 1_4 IV 1_5 V 1_6 VI 1_8 VIII 1_9 IX
tree::apply_cut after prune and re-classify [ 3] nameprefix maker_body_solid_zcut-183.2246_ NODE:7 PRIM:4 UNDEFINED:0 EXCLUDE:0 INCLUDE:7 MIXED:0 Order:IN
Uni
I
5
S
Uni Pol
I I
3 6
Uni Ell
I I
1 4
Ell Pol
I I
0 2
0.0 -2.5 -5.0 -179.2 zdelta
190.0 0.0 -5.0 -162.0 az1
0.0 -5.0 -183.2 -183.2 az0
I 1_2 II 1_3 III 1_4 IV
G4VPhysicalVolume has no convenient "Distance" methods ... so scan solids individually and present together after applying structure transforms.
Usage of xxv.sh script which runs executable and ipython:
cd ~/opticks/extg4 ./xxv.sh GEOM=body_phys ./xxv.sh
The solid to create is controlled by the name string obtained from envvar GEOM
Subsequently can render this geometry, eg with CSGOptiX/cxs.sh using just the path to the CSGFoundry directory.
DONE
TODO