- ZSolid::ApplyZCutTree applied to both NNVT and Hama PMTs
- Avoid PROFLIGATE : G4ItersectionSolid Z-Cut
- With : ZSolid::ApplyZCutTree : Actually Cut the CSG Tree
- fixed base_steel G4Polycone with multiple R-inner
- improved Opticks G4Polycone translation
- avoids overlap with sStrutBallhead
- ray trace renders and render times following geometry fixes
- timings : no standout bottlenecks remain
- > 100x faster than times from July
- G4Sphere phiCut thetaCut : Opticks translation bug
- LHCb RICH : needs fix for their mirror geometry
- fixing with unbounded primitives : CSG_PHICUT CSG_THETACUT
Using G4IntersectionSolid to apply Z-cut to PMT
344 void NNVTMCPPMTManager::helper_make_solid_profligate_tail_cut() 345 { 346 std::cout << "NNVTMCPPMTManager::helper_make_solid_profligate_tail_cut" << std::endl ; 347 // inner2 348 G4double helper_sep_tube_r = m_pmt_r; 349 const double tail_height = m_pmt_h - m_z_equator; 350 const double tail_half_height = tail_height / 2; 351 const G4ThreeVector cut_tail_displacement(0., 0., -tail_half_height); 352 G4VSolid* cut_tail_solid = new G4Tubs("CutTail_NNVTMCPPMT_Solid", 353 0., 354 helper_sep_tube_r+1E-9*mm, 355 tail_half_height, 356 0., 360.*degree); 357 inner2_solid = new G4IntersectionSolid( GetName() + "_inner2_tail_solid", 358 inner2_solid, 359 cut_tail_solid, 360 NULL, 361 cut_tail_displacement); 362
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)
nnvt_body_solid [-1] nameprefix _body_solid NODE:5 PRIM:3 UNDEFINED:5 EXCLUDE:0 INCLUDE:0 MIXED:0 Order:IN Uni U 3 Uni Tub U U 1 4 Ell Pol U U 0 2 0 -193 -299 zdelta 184 -174 -213 az1 -184 -213 -386 az0 _head _1_2 _neck _tail zcut -200 solid_zcut [-1] nameprefix _body_solid_ NODE:3 PRIM:2 UNDEFINED:3 EXCLUDE:0 INCLUDE:0 MIXED:0 Order:IN Uni U 1 Ell Pol U U 0 2 0 -193 zdelta 184 -174 az1 -184 -200 az0 head 1_2 neck
NNVT : obsolete cylinder-torus neck
opticks/cmake/Modules/FindOpticks.cmake used from offline/cmake/JUNODependencies.cmake:
if(DEFINED ENV{OPTICKS_PREFIX}) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "$ENV{JUNOTOP}/opticks/cmake/Modules") find_package(Opticks QUIET MODULE) message(STATUS "${CMAKE_CURRENT_LIST_FILE} : Opticks_FOUND:${Opticks_FOUND}" ) endif()
Then subsequently packages needing Opticks headers add dependency line:
$<$<BOOL:${Opticks_FOUND}>:${Opticks_TARGET}>
Much easier than integration with CMT Offline : as can use CMake targets
base_steel : G4Polycone with two R_inner
Geant4 Intersect Positions
GEOM=PolyconeWithMultipleRmin ~/opticks/extg4/xxs.sh
Polycone Inner Needed
Prevents overlap with sStrutBallhead
SLA=r7@ ./cxr_solid.sh ## 1:base_steel
cxs.sh OptiX 7, 2D intersect scatter plots
spurious intersects evident
* interfering subtraction-of-subtraction issue
mask tail cutting across PMT bulb ?
Improve cross-section view quality ?
* needs development :
* target gensteps according to 2D histo of intersects
* progressive refinement
Not built by standard Opticks build, need:
cd ~/opticks/CSGOptiX/ b7 ## short for opticks-build7
Using CSGOptiX/tests/CSGOptiXSimulateTest.cc:
cxs.sh ## creates 2D cross section .png scatter plots
Using CSGOptiX/tests/CSGOptiXRenderTest.cc:
cxr_view.sh cxr_solid.sh cxr_overview.sh cxr.sh ## creates 3D render .jpg of geometry
At bottom left of all cxr .jpg is launch time(seconds) for 2M pixels (1920x1080)
MOI=sWorld EYE=0,0.6,0.4 TMIN=0.4 ./cxr_view.sh
MOI Mname:mOrdinal:InstanceIndex
MOI=NNVT:0:1000
MOI defines a center-extent "CE" frame
MOI=NNVT:0:1000 EYE=-2,-2,-2 LOOK=0,0,2,1 TMIN=0.4 ./cxr_view.sh
MOI=NNVT:0:1000 EYE=-2,-2,-2 TMIN=0.4 ./cxr_view.sh
MOI=NNVT:0:1000 EYE=0,1,-2 TMIN=0.4 ./cxr_view.sh
MOI=NNVT:0:1000 EYE=0,2,-4 TMIN=0.4 ./cxr_view.sh
MOI=sWaterTube EYE=0,1,-0.5 LOOK=0,0,-0.5 TMIN=0.4 ./cxr_view.sh
Chimney Coincidence Speckle
Looks like fully coincident cylinders
MOI=sWaterTube EYE=0,1,-0.5 LOOK=0,0,-0.5 TMIN=1 ./cxr_view.sh
MOI=sWaterTube EYE=0,1,-1 LOOK=0,0,-1 TMIN=1 ./cxr_view.sh
MOI=sWaterTube EYE=0,1,-1 LOOK=0,0,0 TMIN=0.4 ./cxr_view.sh
Factorize ~300,000 vol -> 10 comp
"progeny digest" characterizes subtree of every volume-node
ridx | plc | vol | component name | note (3dbec4dc) |
---|---|---|---|---|
0 | 1 | 3084 | 3084:sWorld | non-repeated remainder |
1 | 25600 | 5 | 5:PMT_3inch_pmt_solid | 4 types of PMT |
2 | 12612 | 5 | 5:NNVTMCPPMTsMask | |
3 | 5000 | 5 | 5:HamamatsuR12860sMask | |
4 | 2400 | 4 | 4:mask_PMT_20inch_vetosMask | |
5 | 590 | 1 | 1:sStrutBallhead | 4 parts of Fastener but not instanced together as are sibling volumes that happen to line up rather than parent-child |
6 | 590 | 1 | 1:uni1 | |
7 | 590 | 1 | 1:base_steel | |
8 | 590 | 1 | 1:uni_acrylic1 | |
9 | 504 | 130 | 130:sPanel | repeated parts of TT |
~/opticks/ana/ggeo.sh --mmtrim --mmsmry
cxr_solid.sh renders of single "Solids" in Opticks sense
Actually composite corresponding to "factors" of the geometry
Renders of the 10 auto-factorized JUNO solids follow.
SLA=r0@ ./cxr_solid.sh ## 3084:sWorld
SLA=r1@ ./cxr_solid.sh ## 5:PMT_3inch_pmt_solid
SLA=r2@ ./cxr_solid.sh ## 5:NNVTMCPPMTsMask
SLA=r3@ ./cxr_solid.sh ## 5:HamamatsuR12860sMask
SLA=r4@ ./cxr_solid.sh ## 4:mask_PMT_20inch_vetosMask
SLA=r5@ ./cxr_solid.sh ## 1:sStrutBallhead
SLA=r6@ ./cxr_solid.sh ## 1:uni1
SLA=r7@ ./cxr_solid.sh ## 1:base_steel
SLA=r8@ ./cxr_solid.sh ## 1:uni_acrylic1
SLA=r9@ ./cxr_solid.sh ## 130:sPanel
cxr_view.sh from same position, changing included geometry
cxr_views.sh:
emms=$(seq 0 9) for emm in $emms ; do EMM=$emm, ./cxr_view.sh done
t0 : tilde-zero : ~0 : meaning ALL
3084:sWorld
5:PMT_3inch_pmt_solid
5:NNVTMCPPMTsMask
5:HamamatsuR12860sMask
4:mask_PMT_20inch_vetosMask
1:sStrutBallhead
1:uni1
1:base_steel
1:uni_acrylic1
130:sPanel
idx | -e | time(s) | relative | enabled geometry description 3dbec4dc | |
---|---|---|---|---|---|
0 | 5, | 0.0004 | 0.0004 | ONLY: 1:sStrutBallhead | |
1 | 7, | 0.0004 | 0.0004 | ONLY: 1:base_steel | |
2 | 8, | 0.0005 | 0.0005 | ONLY: 1:uni_acrylic1 | |
3 | 6, | 0.0005 | 0.0005 | ONLY: 1:uni1 | |
4 | 1, | 0.0006 | 0.0006 | ONLY: 5:PMT_3inch_pmt_solid | NOTABLY FAST cf 20inch |
5 | 9, | 0.0006 | 0.0006 | ONLY: 130:sPanel | |
6 | 4, | 0.0011 | 0.0011 | ONLY: 4:mask_PMT_20inch_vetosMask | |
7 | 3, | 0.0022 | 0.0022 | ONLY: 5:HamamatsuR12860sMask | NOTABLY SLOW cf 3inch |
8 | 2, | 0.0031 | 0.0031 | ONLY: 5:NNVTMCPPMTsMask | |
9 | 0, | 0.0035 | 0.0035 | ONLY: 3084:sWorld | |
10 | t0 | 0.0067 | 0.0067 | ALL |
Using cxr_scan.sh to repeateadly invoke cxr_overview.sh with different -e options
ridx | plc | vol | component name | note (3dbec4dc) |
---|---|---|---|---|
0 | 1 | 3084 | 3084:sWorld | non-repeated remainder |
1 | 25600 | 5 | 5:PMT_3inch_pmt_solid | 4 types of PMT |
2 | 12612 | 5 | 5:NNVTMCPPMTsMask | |
3 | 5000 | 5 | 5:HamamatsuR12860sMask | |
4 | 2400 | 4 | 4:mask_PMT_20inch_vetosMask | |
5 | 590 | 1 | 1:sStrutBallhead | 4 parts of Fastener but not instanced together as are sibling volumes that happen to line up rather than parent-child |
6 | 590 | 1 | 1:uni1 | |
7 | 590 | 1 | 1:base_steel | |
8 | 590 | 1 | 1:uni_acrylic1 | |
9 | 504 | 130 | 130:sPanel | repeated parts of TT |
-e t0 : ALL
-e 1,2,3,4 : ONLY PMTs
-e 0, : ONLY 0 : 3084:sWorld
-e 1, : ONLY 1 : 5:PMT_3inch_pmt_solid
-e 2, : ONLY 2 : 5:NNVTMCPPMTsMask
-e 3, : ONLY 3 : 5:HamamatsuR12860sMask
-e 4, : ONLY 4 : 4:mask_PMT_20inch_vetosMask
-e 5, : ONLY 5 : 1:sStrutBallhead
-e 6, : ONLY 6 : 1:uni1
-e 7, : ONLY 7 : 1:base_steel
-e 8, : ONLY 8 : 1:uni_acrylic1
-e 9, : ONLY 9 : 130:sPanel
-e t0, : NOT 0 : 3084:sWorld
-e t1, : NOT 1 : 5:PMT_3inch_pmt_solid
-e t2, : NOT 2 : 5:NNVTMCPPMTsMask
-e t3, : NOT 3 : 5:HamamatsuR12860sMask
-e t4, : NOT 4 : 4:mask_PMT_20inch_vetosMask
-e t5, : NOT 5 : 1:sStrutBallhead
-e t6, : NOT 6 : 1:uni1
-e t7, : NOT 7 : 1:base_steel
-e t8, : NOT 8 : 1:uni_acrylic1
-e t9, : NOT 9 : 130:sPanel
Same viewpoint, vary GPU geometry
Geometry Fixes
Small-ish time range 1:15 (previously 1:600)
ALL PMTs : 0.0097 -> 0.0061 (x1.6 faster)
ALL : 0.6240 -> 0.0054 (x155 faster)
idx | -e | time(s) | relative | enabled geometry description 3dbec4dc |
---|---|---|---|---|
0 | 5, | 0.0004 | 0.0643 | ONLY: 1:sStrutBallhead |
1 | 9, | 0.0004 | 0.0658 | ONLY: 130:sPanel |
2 | 7, | 0.0005 | 0.0782 | ONLY: 1:base_steel |
3 | 8, | 0.0006 | 0.0966 | ONLY: 1:uni_acrylic1 |
4 | 6, | 0.0006 | 0.1009 | ONLY: 1:uni1 |
5 | 1, | 0.0009 | 0.1476 | ONLY: 5:PMT_3inch_pmt_solid FAST cf 20in |
6 | 4, | 0.0015 | 0.2386 | ONLY: 4:mask_PMT_20inch_vetosMask |
7 | 3, | 0.0033 | 0.5373 | ONLY: 5:HamamatsuR12860sMask SLOW cf 3in |
8 | 0, | 0.0040 | 0.6556 | ONLY: 3084:sWorld |
9 | 2, | 0.0040 | 0.6627 | ONLY: 5:NNVTMCPPMTsMask SLOW cf 3in |
10 | t4, | 0.0050 | 0.8307 | EXCL: 4:mask_PMT_20inch_vetosMask |
11 | t2, | 0.0051 | 0.8391 | EXCL: 5:NNVTMCPPMTsMask |
12 | t3, | 0.0052 | 0.8514 | EXCL: 5:HamamatsuR12860sMask |
13 | t6, | 0.0053 | 0.8799 | EXCL: 1:uni1 |
14 | t7, | 0.0054 | 0.8809 | EXCL: 1:base_steel |
15 | t0 | 0.0054 | 0.8843 | ALL |
16 | t5, | 0.0054 | 0.8843 | EXCL: 1:sStrutBallhead |
17 | t9, | 0.0054 | 0.8855 | EXCL: 130:sPanel |
18 | t1, | 0.0054 | 0.8860 | EXCL: 5:PMT_3inch_pmt_solid |
19 | t8, | 0.0055 | 0.9013 | EXCL: 1:uni_acrylic1 |
20 | t0, | 0.0059 | 0.9753 | EXCL: 3084:sWorld |
21 | 1,2,3,4 | 0.0061 | 1.0000 | ONLY PMT |
22 | t8,0 | 0.0062 | 1.0217 | EXCL: 1:uni_acrylic1 3084:sWorld |
Same viewpoint, vary GPU geometry
Very large range of times 1:600
Table identifies slow geometry to fix :
Good performance for ONLY PMTs :
idx | -e | time(s) | relative | enabled geometry description |
---|---|---|---|---|
0 | 9, | 0.0017 | 0.1702 | ONLY: 130:sPanel |
1 | 7, | 0.0017 | 0.1714 | ONLY: 1:base_steel |
2 | 6, | 0.0019 | 0.1923 | ONLY: 1:uni1 |
3 | 5, | 0.0027 | 0.2780 | ONLY: 1:sStrutBallhead |
4 | 4, | 0.0032 | 0.3268 | ONLY: 5:mask_PMT_20inch_vetosMask |
5 | 1, | 0.0032 | 0.3287 | ONLY: 5:PMT_3inch_pmt_solid |
6 | 2, | 0.0055 | 0.5669 | ONLY: 5:NNVTMCPPMTsMask |
7 | 3, | 0.0074 | 0.7582 | ONLY: 5:HamamatsuR12860sMask |
8 | 1,2,3,4 | 0.0097 | 1.0000 | ONLY PMT |
9 | t8,0 | 0.0099 | 1.0179 | EXCL: 1:uni_acrylic3 3084:sWorld |
10 | 0, | 0.1171 | 12.0293 | ONLY: 3084:sWorld |
11 | t8, | 0.1186 | 12.1769 | EXCL: 1:uni_acrylic3 |
12 | t0, | 0.5278 | 54.2066 | EXCL: 3084:sWorld |
13 | 8, | 0.5310 | 54.5298 | ONLY: 1:uni_acrylic3 |
14 | t3, | 0.6017 | 61.7954 | EXCL: 5:HamamatsuR12860sMask |
15 | t2, | 0.6043 | 62.0620 | EXCL: 5:NNVTMCPPMTsMask |
16 | t5, | 0.6171 | 63.3787 | EXCL: 1:sStrutBallhead |
17 | t6, | 0.6196 | 63.6301 | EXCL: 1:uni1 |
18 | t7, | 0.6226 | 63.9458 | EXCL: 1:base_steel |
19 | t0 | 0.6240 | 64.0879 | 3084:sWorld |
20 | t4, | 0.6243 | 64.1169 | EXCL: 5:mask_PMT_20inch_vetosMask |
21 | t9, | 0.6335 | 65.0636 | EXCL: 130:sPanel |
22 | t1, | 0.6391 | 65.6384 | EXCL: 5:PMT_3inch_pmt_solid |
## generate renders and json metadata cx ./cxr_scan.sh # repeating ./cxr_overview.sh ./cxr_grab.sh # from workstation to laptop ## generation of RST table (from metadata) and s5 presentation pages ./cxr_pub.sh cp | sh ./cxr_pub.sh s5 ./cxr_table.sh
LHCb RICH mirror geometry reveals bug
Fixed bug, but approach has problems:
Better approach : New Unbounded Primitives
cosPhi1, sinPhi1, cosPhi2, sinPhi2
Working with LHCb RICH student (Lucas) to implement
CSG_PHICUT : XY cross section : slice of cake shape
need intersects with two half-planes at phi1 and phi2
bool intersect_node_phicut( float4& isect, const quad& q0, const float t_min, const float3& ray_origin, const float3& ray_direction ) { const float cosPhi0 = q0.f.x ; const float sinPhi0 = q0.f.y ; const float cosPhi1 = q0.f.z ; const float sinPhi1 = q0.f.w ; // dot products with normal0 [ sinPhi0, -cosPhi0, 0.f ] float d_n0 = ray_direction.x*sinPhi0 + ray_direction.y*(-cosPhi0) ; float o_n0 = ray_origin.x*sinPhi0 + ray_origin.y*(-cosPhi0) ; float t0 = d_n0 == 0.f ? t_min : -o_n0/d_n0 ; float side0 = ray_origin.x*cosPhi0 + ray_origin.y*sinPhi0 + ( ray_direction.x*cosPhi0 + ray_direction.y*sinPhi0 )*t0 ; if(side0 < 0.f) t0 = t_min ; // Disqualify intersect with other half plane // dot products with normal1 [ -sinPhi1, cosPhi1, 0.f ] float d_n1 = ray_direction.x*(-sinPhi1) + ray_direction.y*cosPhi1 ; float o_n1 = ray_origin.x*(-sinPhi1) + ray_origin.y*cosPhi1 ; float t1 = d_n1 == 0.f ? t_min : -o_n1/d_n1 ; float side1 = ray_origin.x*cosPhi1 + ray_origin.y*sinPhi1 + ( ray_direction.x*cosPhi1 + ray_direction.y*sinPhi1 )*t1 ; if(side1 < 0.f) t1 = t_min ; // Disqualify intersect with other half plane float t_near = fminf(t0,t1); // order the intersects float t_far = fmaxf(t0,t1); float t_cand = t_near > t_min ? t_near : ( t_far > t_min ? t_far : t_min ) ; bool valid_intersect = t_cand > t_min ; if( valid_intersect ) { isect.x = t_cand == t1 ? -sinPhi1 : sinPhi0 ; isect.y = t_cand == t1 ? cosPhi1 : -cosPhi0 ; isect.z = 0.f ; isect.w = t_cand ; } return valid_intersect ; }
opticks/CSG/tests/CSGNodeScanTest.{cc,py,sh}
* CPU test of GPU ray trace code
* isect : intersect normal + distance