diff --git a/.gitignore b/.gitignore index 00336cc60..e4abec999 100644 --- a/.gitignore +++ b/.gitignore @@ -175,4 +175,4 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +.idea/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 01741935c..5bb884755 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,8 +18,6 @@ repos: - id: end-of-file-fixer - id: forbid-new-submodules - id: mixed-line-ending - - id: name-tests-test - args: ["--pytest-test-first"] - id: requirements-txt-fixer - id: trailing-whitespace diff --git a/src/pyg4ometry/fluka/body.py b/src/pyg4ometry/fluka/body.py index 605c0ad1e..1bfb7cd44 100644 --- a/src/pyg4ometry/fluka/body.py +++ b/src/pyg4ometry/fluka/body.py @@ -295,8 +295,8 @@ def __repr__(self): ) def _withLengthSafety(self, safety, reg): - lower = self.lower - [safety, safety, safety] - upper = [*self.upper, safety, safety, safety] + lower = self.lower - Three(safety, safety, safety) + upper = self.upper - Three(safety, safety, safety) return RPP( self.name, lower.x, diff --git a/src/pyg4ometry/fluka/preprocessor.py b/src/pyg4ometry/fluka/preprocessor.py index 12450e591..e7cfdbeb3 100644 --- a/src/pyg4ometry/fluka/preprocessor.py +++ b/src/pyg4ometry/fluka/preprocessor.py @@ -232,7 +232,7 @@ def visit_UnaryOp(self, node): operand = self.visit(node.operand) return op(operand) - def visit_Num(self, node): + def visit_Constant(self, node): return node.n def visit_Name(self, node): diff --git a/src/pyg4ometry/geant4/Registry.py b/src/pyg4ometry/geant4/Registry.py index 9ee2fb726..e6efda658 100644 --- a/src/pyg4ometry/geant4/Registry.py +++ b/src/pyg4ometry/geant4/Registry.py @@ -11,6 +11,13 @@ def solidName(var): return var +def removeprefix(string: str, prefix: str, /) -> str: + if string.startswith(prefix): + return string[len(prefix) :] + else: + return string[:] + + class Registry: """ Object to store geometry for input and output. @@ -713,7 +720,7 @@ def addAndCollapseAssemblyVolumeRecursive( # find the transformations for this assembly in the reference frame of the mother # start with identity transformations and then aggregate the placement # info of the assemblies - mtra = _np.matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) + mtra = _np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) tra = _np.array([0, 0, 0]) for pos, rot, sca in zip(positions, rotations, scales): assembly_mrot = _np.linalg.inv(_transformation.tbxyz2matrix(rot.eval())) @@ -786,8 +793,16 @@ def addAndCollapseAssemblyVolumeRecursive( new_pos = new_tra.tolist() # update the position and rotation information + try: + pos_name = dv_copy.name + dv_copy.position.name.removeprefix( + dv.name + ) + except AttributeError: + pos_name = dv_copy.name + removeprefix( + dv_copy.position.name, dv.name + ) dv_copy.position = _Defines.Position( - dv_copy.name + dv_copy.position.name.removeprefix(dv.name), + pos_name, new_pos[0], new_pos[1], new_pos[2], @@ -795,8 +810,18 @@ def addAndCollapseAssemblyVolumeRecursive( self, True, ) + + try: + rot_name = dv_copy.name + dv_copy.rotation.name.removeprefix( + dv.name + ) + except AttributeError: + rot_name = dv_copy.name + removeprefix( + dv_copy.rotation.name, dv.name + ) + dv_copy.rotation = _Defines.Rotation( - dv_copy.name + dv_copy.rotation.name.removeprefix(dv.name), + rot_name, new_rot[0], new_rot[1], new_rot[2], diff --git a/src/pyg4ometry/visualisation/VisualisationOptions.py b/src/pyg4ometry/visualisation/VisualisationOptions.py index cd74a3af2..a1335acd6 100644 --- a/src/pyg4ometry/visualisation/VisualisationOptions.py +++ b/src/pyg4ometry/visualisation/VisualisationOptions.py @@ -63,14 +63,15 @@ def loadPredefined(): Lods from package resource files. """ - import pkg_resources as _pkg_resources + import importlib_resources config = _configparser.ConfigParser( allow_no_value=True, interpolation=_configparser.ExtendedInterpolation() ) config.optionxform = str - ini = _pkg_resources.resource_filename(__name__, "colours.ini") + ini = importlib_resources.files("pyg4ometry") / "visualisation/colours.ini" + with open(ini) as f: config.read_file(f) diff --git a/tests/compare/ComparisonAssemblyVolume.py b/tests/compare/ComparisonAssemblyVolume.py new file mode 100644 index 000000000..d9e3aa297 --- /dev/null +++ b/tests/compare/ComparisonAssemblyVolume.py @@ -0,0 +1,121 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + r = _g4.Registry() + + # in all of these we force testsAlreadyDone=[] as an argument to reset + # the one 'definition' of it in python. We have to be careful with this + # trick for pass by reference-like arguments + + # we use successive new registries for a mish-mash of bits (not caring about writing out) + # so we can have degenerate names - the comparison doesn't care - it just looks at parameters + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r) + + # predefined materials + comp1 = pyg4ometry.compare.materials(galactic1, galactic2, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # some geometry + a_a_solid = _g4.solid.Box("a_a_solid", 50, 40, 30, r) + a_b_solid = _g4.solid.Tubs("a_b_solid", 0, 12, 30, 0, "2*pi", r) + iron = _g4.MaterialPredefined("G4_Fe") + copper = _g4.MaterialPredefined("G4_Cu") + a_a_lv = _g4.LogicalVolume(a_a_solid, copper, "a_a_lv", r) + a_b_lv = _g4.LogicalVolume(a_b_solid, copper, "a_b_lv", r) + a_ass = _g4.AssemblyVolume("a_assembly", r) + a_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_a_pv1", a_ass, r) + a_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", a_ass, r) + + # with itself + comp2 = pyg4ometry.compare.assemblyVolumes(a_ass, a_ass, tests, testsAlreadyDone=[]) + if printOut: + comp2.print() + assert len(comp2) == 0 + + # missing daughter + r2 = _g4.Registry() + b_ass = _g4.AssemblyVolume("a_assembly", r2) + b_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_a_pv1", b_ass, r2) + comp3 = pyg4ometry.compare.assemblyVolumes(a_ass, b_ass, tests, testsAlreadyDone=[]) + if printOut: + comp3.print() + assert len(comp3) == 2 + + # extra daughter + r3 = _g4.Registry() + c_ass = _g4.AssemblyVolume("a_assembly", r3) + c_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_a_pv1", c_ass, r3) + c_b1_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", c_ass, r3) + c_b2_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], a_b_lv, "a_b_pv2", c_ass, r3) + comp4 = pyg4ometry.compare.assemblyVolumes(a_ass, c_ass, tests, testsAlreadyDone=[]) + if printOut: + comp4.print() + assert len(comp4) == 2 + + # different daughter by name + r4 = _g4.Registry() + d_ass = _g4.AssemblyVolume("a_assembly", r4) + d_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_aaaa_pv1", d_ass, r4) + d_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", d_ass, r4) + comp5 = pyg4ometry.compare.assemblyVolumes(a_ass, d_ass, tests, testsAlreadyDone=[]) + if printOut: + comp5.print() + assert len(comp5) == 2 # both missing and extra + + # different values of pvs + r5 = _g4.Registry() + e_ass = _g4.AssemblyVolume("a_assembly", r5) + e_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, -100], a_a_lv, "a_a_pv1", e_ass, r5) + e_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", e_ass, r5) + comp6 = pyg4ometry.compare.assemblyVolumes(a_ass, e_ass, tests, testsAlreadyDone=[]) + if printOut: + comp6.print() + assert ( + len(comp6) == 3 + ) # 1 pv pos fail, 1x bounding box min fail, 1x bounding box max fail + + # different values of lv material inside pvs inside avs + r6 = _g4.Registry() + f_ass = _g4.AssemblyVolume("a_assembly", r6) + a_b_lv = _g4.LogicalVolume(a_b_solid, iron, "a_b_lv", r6) + f_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_a_pv1", f_ass, r6) + f_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", f_ass, r6) + comp7 = pyg4ometry.compare.assemblyVolumes(a_ass, f_ass, tests, testsAlreadyDone=[]) + if printOut: + comp7.print() + assert len(comp7) == 3 # materialName, materialNameIgnorePointer materialNameNIST + + # mesh volume / area testing + r7 = _g4.Registry() + # should be equivalent to a_a_solid = _g4.solid.Box("a_a_solid", 50, 40, 30, r) + c_a_solidA = _g4.solid.Box("c_a_solidA", 80, 40, 30, r7) + c_a_solidB = _g4.solid.Box("c_a_solidB", 50, 90, 30, r7) + c_a_solid = _g4.solid.Intersection( + "c_a_solid", c_a_solidA, c_a_solidB, [[0, 0, 0], [0, 0, 0]], r7 + ) + c_a_lv = _g4.LogicalVolume(c_a_solid, copper, "c_a_lv", r7) + g_ass = _g4.AssemblyVolume("a_assembly", r7) + a_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], c_a_lv, "a_a_pv1", g_ass, r7) + a_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", g_ass, r7) + testVolumeAreaOnly = pyg4ometry.compare.Tests("shapeVolume", "shapeArea") + assert len(testVolumeAreaOnly) == 2 + comp8 = pyg4ometry.compare.assemblyVolumes( + a_ass, g_ass, testVolumeAreaOnly, testsAlreadyDone=[] + ) + if printOut: + comp8.print() + assert len(comp8) == 0 + + # return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/compare/ComparisonDivisionVolume.py b/tests/compare/ComparisonDivisionVolume.py new file mode 100644 index 000000000..97eabdfad --- /dev/null +++ b/tests/compare/ComparisonDivisionVolume.py @@ -0,0 +1,25 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def test(printOut=False): + r = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r) + + # predefined materials + comp1 = pyg4ometry.compare.materials(galactic1, galactic2, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # TBC + + # return {"teststatus": True} + + +if __name__ == "__main__": + test() diff --git a/tests/compare/ComparisonLogicalVolume.py b/tests/compare/ComparisonLogicalVolume.py new file mode 100644 index 000000000..07c99c698 --- /dev/null +++ b/tests/compare/ComparisonLogicalVolume.py @@ -0,0 +1,167 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + # make 2 copies independently so we can have degenerate names, which we couldn't + # have in just 1 registry + r1 = _g4.Registry() + r2 = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r1) + copper1 = _g4.MaterialPredefined("G4_Cu", r1) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r1) + copper2 = _g4.MaterialPredefined("G4_Cu", r2) + + # ctdeltaphi = pyg4ometry.gdml.Constant("deltaphi","2*pi",r1) + ts1 = _g4.solid.Tubs("ts", 0, 50, 100, 0, "2*pi", r1) + tl1 = _g4.LogicalVolume(ts1, copper1, "tl1_lv", r1) + ts2 = _g4.solid.Tubs("ts", 0, 50, 100, 0, "2*pi", r2) + tl2 = _g4.LogicalVolume(ts2, copper2, "tl1_lv", r2) + tl2b = _g4.LogicalVolume(ts2, galactic2, "tl1b_lv", r2) + + # same lvs + comp1 = pyg4ometry.compare.logicalVolumes(tl1, tl1, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # same lvs, different registry + comp2 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests) + if printOut: + comp2.print() + assert len(comp2) == 0 + + # different material + comp3 = pyg4ometry.compare.logicalVolumes(tl1, tl2b, tests) + if printOut: + comp3.print() + assert len(comp3) > 0 + + miniBox1 = _g4.solid.Box("mb1", 1, 2, 3, r1) + miniBox1LV = _g4.LogicalVolume(miniBox1, galactic1, "mb1_lv", r1) + miniBox2 = _g4.solid.Box("mb2", 1, 2, 3, r1) + miniBox2LV = _g4.LogicalVolume(miniBox1, galactic1, "mb2_lv", r1) + miniBox3 = _g4.solid.Box("mb3", 3, 2, 1, r1) + miniBox3LV = _g4.LogicalVolume(miniBox1, galactic1, "mb3_lv", r1) + miniBox1PV1 = _g4.PhysicalVolume( + [0, 0.1, 0], [-1, 0, -10], miniBox1LV, "mb1_pv1", tl1, r1 + ) + miniBox1PV2 = _g4.PhysicalVolume( + [0, -0.1, 0], [5, 0, 10], miniBox1LV, "mb1_pv2", tl1, r1 + ) + miniBox1PV3 = _g4.PhysicalVolume( + [0.1, -0.1, 3.14159265], + [-5, 0, 30], + miniBox1LV, + "mb1_pv3", + tl1, + r1, + copyNumber=3, + scale=[1, 1, -1], + ) + + # same daughters + comp4 = pyg4ometry.compare.logicalVolumes( + tl1, tl1, tests, recursive=True + ) # recursive = check daughter placements + if printOut: + comp4.print() + assert len(comp4) == 0 + + # make it all again in reg2 (adding "pointer" to end of lv and pv names) + miniBox12 = _g4.solid.Box("mb1", 1, 2, 3, r2) + miniBox12LV = _g4.LogicalVolume(miniBox12, galactic2, "mb1_lv0x1234567", r2) + miniBox22 = _g4.solid.Box("mb2", 1, 2, 3, r2) + miniBox22LV = _g4.LogicalVolume(miniBox12, galactic2, "mb2_lv0x1234567", r2) + miniBox32 = _g4.solid.Box("mb3", 3, 2, 1, r2) + miniBox32LV = _g4.LogicalVolume(miniBox12, galactic2, "mb3_lv0x1234567", r2) + miniBox12PV1 = _g4.PhysicalVolume( + [0, 0.1, 0], [-1, 0, -10], miniBox12LV, "mb1_pv10x1234567", tl2, r2 + ) + miniBox12PV2 = _g4.PhysicalVolume( + [0, -0.1, 0], [5, 0, 10], miniBox12LV, "mb1_pv20x1234567", tl2, r2 + ) + miniBox12PV3 = _g4.PhysicalVolume( + [0.1, -0.1, -3.14159265], + [-5, 0, 30], + miniBox12LV, + "mb1_pv30x1234567", + tl2, + r2, + copyNumber=3, + scale=[1, 1, -1], + ) + # NOTE rotation of -pi vs pi in miniBox1PV3 - it is equivalent so should not result in an error + + # same daughters + tests.names = False # disable exact name matching + comp5 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests, recursive=True) + if printOut: + comp5.print() + assert len(comp5) == 0 + + # extra placement in 2nd one now + miniBox12PV4 = _g4.PhysicalVolume( + [0, 0, 0], [-5, 0, 40], miniBox12LV, "mb1_pv4", tl2, r2 + ) + comp6 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests, recursive=True) + if printOut: + comp6.print() + assert len(comp6) > 0 + + # different copyNumber + miniBox1PV5 = _g4.PhysicalVolume( + [0, 0, 0], [0, 10, 40], miniBox1LV, "mb1_pv5", tl1, r1, copyNumber=2 + ) + miniBox12PV5 = _g4.PhysicalVolume( + [0, 0, 0], [0, 10, 40], miniBox12LV, "mb1_pv5", tl2, r2, copyNumber=3 + ) + comp7 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests, recursive=True) + if printOut: + comp7.print() + assert len(comp7.test["copyNumber"]) > 0 + + # different scale + miniBox1PV6 = _g4.PhysicalVolume( + [0, 0, 0], [0, -10, 40], miniBox1LV, "mb1_pv6", tl1, r1, scale=[1, 1, 1] + ) + miniBox12PV6 = _g4.PhysicalVolume( + [0, 0, 0], [0, -10, 40], miniBox12LV, "mb1_pv6", tl2, r2, scale=[1, 1, -1] + ) + comp8 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests, recursive=True) + if printOut: + comp8.print() + assert len(comp8.test["scale"]) > 0 + + # equivalent volume but different solids + # NOTE solids go with LogicalVolumes in pyg4ometry, not solids + r3 = _g4.Registry() + boxA = _g4.solid.Box("box_a", 10, 20, 50, r3) + boxALV = _g4.LogicalVolume(boxA, copper1, "boxA_lv", r3) + r4 = _g4.Registry() + boxB_A = _g4.solid.Box("box_b_a", 10, 30, 100, r3) + boxB_B = _g4.solid.Box("box_b_b", 10, 20, 50, r3) + boxB = _g4.solid.Intersection("box_b", boxB_A, boxB_B, [[0, 0, 0], [0, 0, 0]], r3) + boxBLV = _g4.LogicalVolume(boxB, copper1, "boxB_lv", r3) + testVolumeAreaOnly = pyg4ometry.compare.Tests("shapeVolume", "shapeArea") + comp9 = pyg4ometry.compare.logicalVolumes(boxALV, boxBLV, testVolumeAreaOnly) + if printOut: + comp9.print() + assert len(comp9) == 0 + + # update the shape of one solid and convince ourselves the area and volume checks work + boxB_B.pY = 12 + boxBLV.reMesh() + comp10 = pyg4ometry.compare.logicalVolumes(boxALV, boxBLV, testVolumeAreaOnly) + if printOut: + comp10.print() + assert len(comp10) == 2 + + # return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/compare/ComparisonParameterisedVolume.py b/tests/compare/ComparisonParameterisedVolume.py new file mode 100644 index 000000000..c63dfbe80 --- /dev/null +++ b/tests/compare/ComparisonParameterisedVolume.py @@ -0,0 +1,26 @@ +import os as _os +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def test(printOut=False): + r = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r) + + # predefined materials + comp1 = pyg4ometry.compare.materials(galactic1, galactic2, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # TBC + + # return {"teststatus": True} + + +if __name__ == "__main__": + test() diff --git a/tests/compare/ComparisonReplicaVolume.py b/tests/compare/ComparisonReplicaVolume.py new file mode 100644 index 000000000..286c7ea28 --- /dev/null +++ b/tests/compare/ComparisonReplicaVolume.py @@ -0,0 +1,48 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def test(printOut=False): + r = _g4.Registry() + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + ws = _g4.solid.Box("ws", 1000, 1000, 1000, r) + bs = _g4.solid.Box("bs", 100, 100, 100, r) + mbs = _g4.solid.Box("mbs", 800, 100, 100, r) + wl = _g4.LogicalVolume(ws, wm, "wl", r) + bl = _g4.LogicalVolume(bs, bm, "bl", r) + ml = _g4.LogicalVolume(mbs, wm, "ml", r) + mbl = _g4.ReplicaVolume("mbl", bl, ml, _g4.ReplicaVolume.Axis.kXAxis, 8, 100, 0, r) + + tests = pyg4ometry.compare.Tests() + + comp1 = pyg4ometry.compare.replicaVolumes(mbl, mbl, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # different number of replicas + r2 = _g4.Registry() + mbl2 = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kXAxis, 7, 100, 0, r2 + ) + comp2 = pyg4ometry.compare.replicaVolumes(mbl, mbl2, tests) + if printOut: + comp2.print() + assert len(comp2) == 1 + + # different axis + r3 = _g4.Registry() + mbl3 = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kYAxis, 8, 100, 0, r3 + ) + comp3 = pyg4ometry.compare.replicaVolumes(mbl, mbl3, tests) + if printOut: + comp3.print() + assert len(comp3) == 1 + + # return {"teststatus": True} + + +if __name__ == "__main__": + test() diff --git a/tests/compare/ComparisonSolid.py b/tests/compare/ComparisonSolid.py new file mode 100644 index 000000000..79753b997 --- /dev/null +++ b/tests/compare/ComparisonSolid.py @@ -0,0 +1,104 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def test(printOut=False): + r = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + box1 = _g4.solid.Box("box1", 100, 80, 60, r) + + # solid with itself + comp1 = pyg4ometry.compare.solids(box1, box1, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + wx = pyg4ometry.gdml.Constant("wx", 10, r) + box2 = _g4.solid.Box("box2", "1*wx", 0.8 * wx, 0.6 * wx, r, lunit="cm") + + # solid with itself - using expressions + comp2 = pyg4ometry.compare.solids(box2, box2, tests) + if printOut: + comp2.print() + assert len(comp2) == 0 + + # box with numbers vs box with expressions but equivalent + # only name should be different + comp3 = pyg4ometry.compare.solids(box1, box2, tests) + if printOut: + comp3.print() + assert len(comp3) == 2 # 2 name tests + + testsNoName = pyg4ometry.compare.Tests() + testsNoName.names = False + comp4 = pyg4ometry.compare.solids( + box1, box2, testsNoName, "maintest", includeAllTestResults=True + ) + if printOut: + comp4.print() + assert len(comp4) > 0 # because we include all tests + + # test a solid where a parameter is potentially a list or not just a number + p1x = pyg4ometry.gdml.Constant("p1x", "-20", r, True) + p1y = pyg4ometry.gdml.Constant("p1y", "-20", r, True) + z1, x1, y1, s1 = -20, 5, 5, 1 + z2, x2, y2, s2 = 0, -5, -5, 1 + z3, x3, y3, s3 = 20, 0, 0, 2 + polygon = [ + [p1x, p1y], + [-20, 20], + [20, 20], + [20, 10], + [-10, 10], + [-10, 10], + [20, -10], + [20, -20], + ] + slices = [[z1, [x1, y1], s1], [z2, [x2, y2], s2], [z3, [x3, y3], s3]] + xs = _g4.solid.ExtrudedSolid("xs", polygon, slices, r) + + # complex solid with other with simple values + comp5 = pyg4ometry.compare.solids(box1, xs, tests) + if printOut: + comp5.print() + assert len(comp5) > 0 + + comp6 = pyg4ometry.compare.solids(xs, xs, tests) + if printOut: + comp6.print() + assert len(comp6) == 0 + + # one number deep inside that's slightly different + polygon2 = [ + [p1x, p1y], + [-20, 20], + [30, 20], + [20, 10], + [-10, 10], + [-10, 10], + [20, -10], + [20, -20], + ] + slices2 = [[z1, [6, y1], s1], [z2, [x2, y2], s2], [z3, [x3, y3], s3]] + xs2 = _g4.solid.ExtrudedSolid("xs2", polygon2, slices2, r) + comp7 = pyg4ometry.compare.solids(xs, xs2, tests) + if printOut: + comp7.print() + assert len(comp7) > 0 + + # different units + polygon3 = [[-2, -2], [-2, 2], [2, 2], [2, 1], [-1, 1], [-1, 1], [2, -1], [2, -2]] + slices3 = [[-2, [0.5, 0.5], 1], [0, [-0.5, -0.5], 1], [2, [0, 0], 2]] + xs3 = _g4.solid.ExtrudedSolid("xs3", polygon3, slices3, r, lunit="cm") + comp8 = pyg4ometry.compare.solids(xs, xs3, tests) + if printOut: + comp8.print() + assert len(comp8) == 2 # 2 name tests + + # return {"teststatus": True} + + +if __name__ == "__main__": + test() diff --git a/tests/compare/test_Comparison.py b/tests/compare/test_Comparison.py new file mode 100644 index 000000000..5c0fd8c11 --- /dev/null +++ b/tests/compare/test_Comparison.py @@ -0,0 +1,10 @@ +import ComparisonLogicalVolume +import ComparisonAssemblyVolume + + +def test_ComparisonAssemblyVolume(): + ComparisonAssemblyVolume.Test() + + +def test_ComparisonLogicalVolume(): + ComparisonLogicalVolume.Test() diff --git a/tests/conftest.py b/tests/conftest.py index f94cdfcc1..c9f04d93e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,12 +3,19 @@ from getpass import getuser from pathlib import Path from tempfile import gettempdir +import sys +import os import pytest from g4edgetestdata import G4EdgeTestData _tmptestdir = Path(gettempdir()) / f"pygama-tests-{getuser()}-{uuid.uuid4()!s}" +sys.path.append(os.path.join(os.path.dirname(__file__), "compare/")) +sys.path.append(os.path.join(os.path.dirname(__file__), "features/")) +sys.path.append(os.path.join(os.path.dirname(__file__), "fluka/")) +sys.path.append(os.path.join(os.path.dirname(__file__), "geant4/")) + pytest_plugins = [ "geant4.test_box", ] @@ -28,5 +35,5 @@ def pytest_sessionfinish(session, exitstatus): @pytest.fixture(scope="session") def testdata(): g4data = G4EdgeTestData() - g4data.checkout("04af6cb") + g4data.checkout("4b0f21f") return g4data diff --git a/tests/convert/Geant42FlukaConversion.py b/tests/convert/Geant42FlukaConversion.py new file mode 100644 index 000000000..96d2a3c51 --- /dev/null +++ b/tests/convert/Geant42FlukaConversion.py @@ -0,0 +1,134 @@ +import unittest as _unittest + +from . import T001_geant4Box2Fluka +from . import T002_geant4Tubs2Fluka +from . import T003_geant4CutTubs2Fluka +from . import T004_geant4Cons2Fluka +from . import T005_geant4Para2Fluka +from . import T006_geant4Trd2Fluka +from . import T007_geant4Trap2Fluka +from . import T008_geant4Sphere2Fluka +from . import T009_geant4Orb2Fluka +from . import T010_geant4Torus2Fluka +from . import T011_geant4Polycone2Fluka +from . import T012_geant4GenericPolycone2Fluka +from . import T013_geant4Polyhedra2Fluka +from . import T014_geant4GenericPolyhedra2Fluka +from . import T015_geant4EllipticalTube2Fluka +from . import T016_geant4Ellipsoid2Fluka +from . import T017_geant4EllipticalCone2Fluka +from . import T018_geant4Paraboloid2Fluka +from . import T019_geant4Hyperboloid2Fluka +from . import T020_geant4Tet2Fluka +from . import T021_geant4ExtrudedSolid2Fluka +from . import T026_geant4GenericTrap2Fluka + +from . import T028_geant4Union2Fluka +from . import T029_geant4Subtraction2Fluka +from . import T030_geant4Intersection2Fluka + +from . import T105_geant4Assembly2Fluka +from . import T106_geant4ReplicaX2Fluka +from . import T107_geant4ReplicaY2Fluka +from . import T108_geant4ReplicaZ2Fluka +from . import T109_geant4ReplicaPhi2Fluka +from . import T110_geant4ReplicaRho2Fluka + + +class Geant42FlukaConversionTests(_unittest.TestCase): + def test_Geant42FlukaConversion_T001_Box(self): + T001_geant4Box2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T002_Tubs(self): + T002_geant4Tubs2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T003_CutTubs(self): + T003_geant4CutTubs2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T004_Cons(self): + T004_geant4Cons2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T005_Para(self): + T005_geant4Para2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T006_Tdr(self): + T006_geant4Trd2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T007_Trap(self): + T007_geant4Trap2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T008_Sphere(self): + T008_geant4Sphere2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T009_Orb(self): + T009_geant4Orb2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T010_Torus(self): + T010_geant4Torus2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T011_Polycone(self): + T011_geant4Polycone2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T012_GenericPolycone(self): + T012_geant4GenericPolycone2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T013_Polyhedra(self): + T013_geant4Polyhedra2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T014_GenericPolyhedra(self): + T014_geant4GenericPolyhedra2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T015_EllipticalTube(self): + T015_geant4EllipticalTube2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T016_Ellipsoid(self): + T016_geant4Ellipsoid2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T017_EllipticalCone(self): + T017_geant4EllipticalCone2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T018_Paraboloid(self): + T018_geant4Paraboloid2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T019_Hyperboloid(self): + T019_geant4Hyperboloid2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T020_Tet(self): + T020_geant4Tet2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T021_ExtrudedSolid(self): + T021_geant4ExtrudedSolid2Fluka.Test(False, False, True) + + # def test_Geant42FlukaConversion_T026_GenericTrap(self): + # T026_geant4GenericTrap2Fluka.Test(False,False,True) + + def test_Geant42FlukaConversion_T028_Union(self): + T028_geant4Union2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T029_Subtraction(self): + T029_geant4Subtraction2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T030_Intersection(self): + T030_geant4Intersection2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T105_Assembly(self): + T105_geant4Assembly2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T106_replica_x(self): + T106_geant4ReplicaX2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T107_replica_y(self): + T107_geant4ReplicaY2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T108_replica_z(self): + T108_geant4ReplicaZ2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T109_replica_phi(self): + T109_geant4ReplicaPhi2Fluka.Test(False, False, True) + + def test_Geant42FlukaConversion_T110_replica_rho(self): + T110_geant4ReplicaRho2Fluka.Test(False, False, True) + + +if __name__ == "__main__": + _unittest.main(verbosity=2) diff --git a/tests/convert/T001_geant4Box2Fluka.py b/tests/convert/T001_geant4Box2Fluka.py new file mode 100644 index 000000000..c0684d27e --- /dev/null +++ b/tests/convert/T001_geant4Box2Fluka.py @@ -0,0 +1,71 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # solids + ws = _g4.solid.Box("ws", 1000, 1000, 1000, reg, "mm") + b1s = _g4.solid.Box("b1s", 50, 75, 100, reg, "mm") + b2s = _g4.solid.Box("b2s", 5, 10, 15, reg, "mm") + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm1 = _g4.nist_material_2geant4Material("G4_Li") + bm2 = _g4.nist_material_2geant4Material("G4_Fe") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + b1l = _g4.LogicalVolume(b1s, bm1, "b1l", reg) + b2l = _g4.LogicalVolume(b2s, bm2, "b2l", reg) + + b2p1 = _g4.PhysicalVolume([0, 0, _np.pi / 4.0], [0, 15, 0], b2l, "b2_pv1", b1l, reg) + b2p2 = _g4.PhysicalVolume([0, 0, 0], [0, -15, 0], b2l, "b2_pv2", b1l, reg) + + b1p1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, -300], b1l, "b1_pv1", wl, reg) + b1p2 = _g4.PhysicalVolume( + [_np.pi / 4.0, 0, 0], [0, 0, -100], b1l, "b1_pv2", wl, reg + ) + b1p3 = _g4.PhysicalVolume([0, _np.pi / 4.0, 0], [0, 0, 100], b1l, "b1_pv3", wl, reg) + b1p4 = _g4.PhysicalVolume([0, 0, _np.pi / 4.0], [0, 0, 300], b1l, "b1_pv4", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T001_geant4Box2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T001_geant4Box2Fluka.inp")) + + # flair output file + f = _fluka.Flair("T001_geant4Box2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T001_geant4Box2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"greg": reg, "freg": freg} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T002_geant4Tubs2Fluka.py b/tests/convert/T002_geant4Tubs2Fluka.py new file mode 100644 index 000000000..f101573fb --- /dev/null +++ b/tests/convert/T002_geant4Tubs2Fluka.py @@ -0,0 +1,69 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + + +def Test(vis=True, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + trmin = _gd.Constant("trmin", "2.5", reg, True) + trmax = _gd.Constant("trmax", "10.0", reg, True) + tz = _gd.Constant("tz", "50", reg, True) + tstartphi = _gd.Constant("startphi", "0", reg, True) + tdeltaphi = _gd.Constant("deltaphi", "1.5*pi", reg, True) + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Tubs("ts", trmin, trmax, tz, tstartphi, tdeltaphi, reg, "mm", "rad") + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0.0, 0.0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T002_geant4Tubs2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T002_geant4Tubs2Fluka.inp")) + + # flair output file + f = _fluka.Flair("T002_geant4Tubs2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T002_geant4Tubs2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.view(interactive=interactive) + + return {"greg": reg, "freg": freg} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T003_geant4CutTubs2Fluka.py b/tests/convert/T003_geant4CutTubs2Fluka.py new file mode 100644 index 000000000..f52970ad0 --- /dev/null +++ b/tests/convert/T003_geant4CutTubs2Fluka.py @@ -0,0 +1,88 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + + +def Test(vis=True, interactive=False, fluka=True): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + trmin = _gd.Constant("trmin", "2.5", reg, True) + trmax = _gd.Constant("trmax", "10.0", reg, True) + tz = _gd.Constant("tz", "50", reg, True) + tstartphi = _gd.Constant("startphi", "0", reg, True) + tdeltaphi = _gd.Constant("deltaphi", "1.3*pi", reg, True) + tlowx = _gd.Constant("ctlowx", "-1", reg, True) + tlowy = _gd.Constant("ctlowy", "-1", reg, True) + tlowz = _gd.Constant("ctlowz", "-1", reg, True) + thighx = _gd.Constant("cthighx", "-1", reg, True) + thighy = _gd.Constant("cthighy", "-1", reg, True) + thighz = _gd.Constant("cthighz", "1", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.CutTubs( + "ts", + trmin, + trmax, + tz, + tstartphi, + tdeltaphi, + [tlowx, tlowy, tlowz], + [thighx, thighy, thighz], + reg, + "mm", + "rad", + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0.0, 0.0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T003_geant4CutTubs2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T003_geant4CutTubs2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T003_geant4CutTubs2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T003_geant4CutTubs2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.view(interactive=interactive) + + return {"greg": reg, "freg": freg} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T004_geant4Cons2Fluka.py b/tests/convert/T004_geant4Cons2Fluka.py new file mode 100644 index 000000000..e5d3eda22 --- /dev/null +++ b/tests/convert/T004_geant4Cons2Fluka.py @@ -0,0 +1,93 @@ +import os as _os +import numpy as _np +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + +normal = 1 +r1min_gt_r1max = 2 +r2min_gt_r2max = 3 +dphi_gt_2pi = 4 +dphi_eq_2pi = 5 +cone_up = 6 +inner_cylinder = 7 + + +def Test(vis=False, interactive=False, fluka=True, type=normal): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + crmin1 = _gd.Constant("crmin1", "6", reg, True) + crmax1 = _gd.Constant("crmax1", "20", reg, True) + crmin2 = _gd.Constant("crmin2", "5", reg, True) + crmax2 = _gd.Constant("crmax2", "10", reg, True) + cz = _gd.Constant("cz", "100", reg, True) + cdp = _gd.Constant("cdp", "1.2*pi", reg, True) + zero = _gd.Constant("zero", "0.0", reg, False) + + if type == r1min_gt_r1max: + crmin1.setExpression(21) + elif type == type == r2min_gt_r2max: + crmin2.setExpression(11) + elif type == dphi_gt_2pi: + cdp.setExpression("3*pi") + elif type == dphi_eq_2pi: + cdp.setExpression(2 * _np.pi) + elif type == cone_up: + crmin1.setExpression(5) + crmax1.setExpression(10) + crmin2.setExpression(6) + crmax2.setExpression(20) + elif type == inner_cylinder: + crmin1.setExpression(5) + crmin2.setExpression(5) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + cm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + cs = _g4.solid.Cons("cs", crmin1, crmax1, crmin2, crmax2, cz, zero, cdp, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + cl = _g4.LogicalVolume(cs, cm, "cl", reg) + cp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], cl, "c_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T004_geant4Cons2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T004_geant4Cons2Fluka.inp")) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T005_geant4Para2Fluka.py b/tests/convert/T005_geant4Para2Fluka.py new file mode 100644 index 000000000..770b080b1 --- /dev/null +++ b/tests/convert/T005_geant4Para2Fluka.py @@ -0,0 +1,107 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, fluka=True): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "200", reg, True) + wy = _gd.Constant("wy", "200", reg, True) + wz = _gd.Constant("wz", "200", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + px = _gd.Constant("px", "2.5", reg, True) + py = _gd.Constant("py", "5", reg, True) + pz = _gd.Constant("pz", "7.5", reg, True) + pAlpha = _gd.Constant("pAlpha", "0.2", reg, True) + pTheta = _gd.Constant("pTheta", "0.4", reg, True) + pPhi = _gd.Constant("pPhi", "0", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + pm = _g4.nist_material_2geant4Material("G4_Fe") + + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + pad = 4.0 + nx = 2 + ny = 2 + nz = 2 + for iAlpha in range(0, nx, 1): + dx = iAlpha * px * pad - (nx - 1) * px * pad / 2.0 + dAlpha = iAlpha * 0.2 + for iTheta in range(0, ny, 1): + dy = iTheta * py * 4 - (ny - 1) * py * pad / 2.0 + dTheta = iTheta * 0.2 + for iPhi in range(0, nz, 1): + dz = iPhi * pz * 4 - (nz - 1) * pz * pad / 2.0 + dPhi = iPhi * 0.2 + # print iAlpha, iTheta, iPhi + + ps = _g4.solid.Para( + "ps_" + str(iAlpha) + "_" + str(iTheta) + "_" + str(iPhi), + px, + py, + pz, + dAlpha, + dTheta, + dPhi, + reg, + "mm", + "rad", + ) + + # structure + pl = _g4.LogicalVolume( + ps, + pm, + "pl_" + str(iAlpha) + "_" + str(iTheta) + "_" + str(iPhi), + reg, + ) + pp = _g4.PhysicalVolume( + [0, 0, 0], + [dx, dy, dz], + pl, + "p_pv1_" + str(iAlpha) + "_" + str(iTheta) + "_" + str(iPhi), + wl, + reg, + ) + + # wl.clipSolid() + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T005_geant4Para2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T005_geant4Para2Fluka.inp")) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T006_geant4Trd2Fluka.py b/tests/convert/T006_geant4Trd2Fluka.py new file mode 100644 index 000000000..1144a3fef --- /dev/null +++ b/tests/convert/T006_geant4Trd2Fluka.py @@ -0,0 +1,64 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + tx1 = _gd.Constant("tx1", "20", reg, True) + ty1 = _gd.Constant("ty1", "25", reg, True) + tx2 = _gd.Constant("tx2", "5", reg, True) + ty2 = _gd.Constant("ty2", "7.5", reg, True) + tz = _gd.Constant("tz", "10.0", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + tm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Trd("ts", tx1, ty1, tx2, ty2, tz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T006_geant4Trd2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T006_geant4Trd2Fluka.inp")) + + # flair output file + f = _fluka.Flair("T006_geant4Trd2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T006_geant4Trd2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T007_geant4Trap2Fluka.py b/tests/convert/T007_geant4Trap2Fluka.py new file mode 100644 index 000000000..22ee1663a --- /dev/null +++ b/tests/convert/T007_geant4Trap2Fluka.py @@ -0,0 +1,75 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + tx1 = _gd.Constant("tx1", "5", reg, True) + tx2 = _gd.Constant("tx2", "5", reg, True) + tx3 = _gd.Constant("tx3", "10", reg, True) + tx4 = _gd.Constant("tx4", "10", reg, True) + + ty1 = _gd.Constant("ty1", "5", reg, True) + ty2 = _gd.Constant("ty2", "7.5", reg, True) + + tz = _gd.Constant("tz", "10.0", reg, True) + + ttheta = _gd.Constant("ttheta", "0.6", reg, True) + tphi = _gd.Constant("tphi", "0.0", reg, True) + talp1 = _gd.Constant("talp1", "0.0", reg, True) + talp2 = _gd.Constant("talp2", "0.0", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + tm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Trap( + "ts", tz, ttheta, tphi, ty1, tx1, tx2, talp1, ty2, tx3, tx4, talp2, reg, "mm" + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T007_geant4Trap2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T007_geant4Trap2Fluka.inp")) + + # flair output file + f = _fluka.Flair("T007_geant4Trap2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T007_geant4Trap2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T008_geant4Sphere2Fluka.py b/tests/convert/T008_geant4Sphere2Fluka.py new file mode 100644 index 000000000..b5b012e29 --- /dev/null +++ b/tests/convert/T008_geant4Sphere2Fluka.py @@ -0,0 +1,81 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka + + +def Test(vis=False, interactive=False, fluka=True, n_slice=10, n_stack=10): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + srmin = _gd.Constant("rmin", "8", reg, True) + srmax = _gd.Constant("rmax", "10", reg, True) + ssphi = _gd.Constant("sphi", "0.1", reg, True) + sdphi = _gd.Constant("dphi", "0.8*pi", reg, True) + sstheta = _gd.Constant("stheta", "0.0*pi", reg, True) + sdtheta = _gd.Constant("dtheta", "1.0*pi", reg, True) + + wm = _g4.nist_material_2geant4Material("G4_Galactic") + sm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ss = _g4.solid.Sphere( + "ss", + srmin, + srmax, + ssphi, + sdphi, + sstheta, + sdtheta, + reg, + "mm", + "rad", + nslice=n_slice, + nstack=n_stack, + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + sl = _g4.LogicalVolume(ss, sm, "sl", reg) + sp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], sl, "s_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T008_geant4Sphere2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T008_geant4Sphere2Fluka.inp") + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T009_geant4Orb2Fluka.py b/tests/convert/T009_geant4Orb2Fluka.py new file mode 100644 index 000000000..8629bdf58 --- /dev/null +++ b/tests/convert/T009_geant4Orb2Fluka.py @@ -0,0 +1,59 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, fluka=True, n_slice=16, n_stack=16): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + ormax = _gd.Constant("rmax", "10", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + om = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + os = _g4.solid.Orb("os", ormax, reg, "mm", nslice=n_slice, nstack=n_stack) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ol = _g4.LogicalVolume(os, om, "ol", reg) + op = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ol, "o_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T009_geant4Orb2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T009_geant4Orb2Fluka.inp")) + + # flair output file + f = _fluka.Flair("T0019_geant4Orb2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T009_geant4Orb2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T010_geant4Torus2Fluka.py b/tests/convert/T010_geant4Torus2Fluka.py new file mode 100644 index 000000000..f99e094cc --- /dev/null +++ b/tests/convert/T010_geant4Torus2Fluka.py @@ -0,0 +1,77 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True, n_slice=30, n_stack=30): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "200", reg, True) + wy = _gd.Constant("wy", "200", reg, True) + wz = _gd.Constant("wz", "200", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + trmin = _gd.Constant("rmin", "8.0", reg, True) + trmax = _gd.Constant("rmax", "10.0", reg, True) + trtor = _gd.Constant("rtor", "40.0", reg, True) + tsphi = _gd.Constant("sphi", "0", reg, True) + tdphi = _gd.Constant("dphi", "1.5*pi", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + tm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Torus( + "ts", + trmin, + trmax, + trtor, + tsphi, + tdphi, + reg, + "mm", + "rad", + nslice=n_slice, + nstack=n_stack, + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T010_geant4Torus2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T010_geant4Torus2Fluka.inp")) + + # flair output file + f = _fluka.Flair("T010_geant4Torus2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T010_geant4Torus2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T011_geant4Polycone2Fluka.py b/tests/convert/T011_geant4Polycone2Fluka.py new file mode 100644 index 000000000..b546fd3b0 --- /dev/null +++ b/tests/convert/T011_geant4Polycone2Fluka.py @@ -0,0 +1,84 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True, n_slice=10): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + psphi = _gd.Constant("sphi", "0", reg, True) + pdphi = _gd.Constant("dphi", "1.5*pi", reg, True) + + prmin1 = _gd.Constant("prmin1", "7", reg, True) + prmax1 = _gd.Constant("prmax1", "9", reg, True) + pz1 = _gd.Constant("z1", "-10", reg, True) + + prmin2 = _gd.Constant("prmin2", "5", reg, True) + prmax2 = _gd.Constant("prmax2", "9", reg, True) + pz2 = _gd.Constant("z2", "0", reg, True) + + prmin3 = _gd.Constant("prmin3", "4", reg, True) + prmax3 = _gd.Constant("prmax3", "5", reg, True) + pz3 = _gd.Constant("z3", "10", reg, True) + + prmin = [prmin1, prmin2, prmin3] + prmax = [prmax1, prmax2, prmax3] + pz = [pz1, pz2, pz3] + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + pm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.Polycone( + "ps", psphi, pdphi, pz, prmin, prmax, reg, "mm", "rad", nslice=n_slice + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T011_geant4Polycone2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T011_geant4Polycone2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T011_geant4Polycone2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T011_geant4Polycone2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T012_geant4GenericPolycone2Fluka.py b/tests/convert/T012_geant4GenericPolycone2Fluka.py new file mode 100644 index 000000000..873333570 --- /dev/null +++ b/tests/convert/T012_geant4GenericPolycone2Fluka.py @@ -0,0 +1,104 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + +normal = 1 +two_planes = 2 + + +def Test(vis=False, interactive=False, fluka=True, type=normal): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + psphi = _gd.Constant("sphi", "1", reg, True) + pdphi = _gd.Constant("dphi", "4", reg, True) + + pr1 = _gd.Constant("pr1", "5", reg, True) + pz1 = _gd.Constant("z1", "-10", reg, True) + + pr2 = _gd.Constant("pr2", "7.5", reg, True) + pz2 = _gd.Constant("z2", "-10", reg, True) + + pr3 = _gd.Constant("pr3", "10", reg, True) + pz3 = _gd.Constant("z3", "0", reg, True) + + pr4 = _gd.Constant("pr4", "20", reg, True) + pz4 = _gd.Constant("z4", "-5", reg, True) + + pr5 = _gd.Constant("pr5", "7.5", reg, True) + pz5 = _gd.Constant("z5", "10", reg, True) + + pr6 = _gd.Constant("pr6", "5", reg, True) + pz6 = _gd.Constant("z6", "10", reg, True) + + pr7 = _gd.Constant("pr7", "2", reg, True) + pz7 = _gd.Constant("z7", "5", reg, True) + + pr = [pr1, pr2, pr3, pr4, pr5, pr6, pr7] + pz = [pz1, pz2, pz3, pz4, pz5, pz6, pz7] + + if type == two_planes: + pr = [pr1, pr2] + pz = [pz1, pz2] + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + pm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.GenericPolycone("ps", psphi, pdphi, pr, pz, reg, "mm", "rad") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T012_geant4GenericPolycone2Fluka.gdml" + ) + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T012_geant4GenericPolycone2Fluka.inp" + ) + ) + + # flair output file + f = _fluka.Flair("T012_geant4GenericPolycone2Fluka.inp", extentBB) + f.write( + _os.path.join( + _os.path.dirname(__file__), "T012_geant4GenericPolycone2Fluka.flair" + ) + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T013_geant4Polyhedra2Fluka.py b/tests/convert/T013_geant4Polyhedra2Fluka.py new file mode 100644 index 000000000..91f1d9122 --- /dev/null +++ b/tests/convert/T013_geant4Polyhedra2Fluka.py @@ -0,0 +1,83 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + psphi = _gd.Constant("sphi", "1", reg, True) + pdphi = _gd.Constant("dphi", "4", reg, True) + pnsid = _gd.Constant("pnsid", "3", reg, True) + + prmin1 = _gd.Constant("prmin1", "1", reg, True) + prmax1 = _gd.Constant("prmax1", "9", reg, True) + pz1 = _gd.Constant("z1", "-10", reg, True) + + prmin2 = _gd.Constant("prmin2", "3", reg, True) + prmax2 = _gd.Constant("prmax2", "5", reg, True) + pz2 = _gd.Constant("z2", "12", reg, True) + + prmin = [prmin1, prmin2] + prmax = [prmax1, prmax2] + pz = [pz1, pz2] + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + pm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.Polyhedra( + "ps", psphi, pdphi, pnsid, len(pz), pz, prmin, prmax, reg, "mm", "rad" + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T013_geant4Polyhedra2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T013_geant4Polyhedra2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T013_geant4Polyhedra2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T013_geant4Polyhedra2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T014_geant4GenericPolyhedra2Fluka.py b/tests/convert/T014_geant4GenericPolyhedra2Fluka.py new file mode 100644 index 000000000..7578a8f14 --- /dev/null +++ b/tests/convert/T014_geant4GenericPolyhedra2Fluka.py @@ -0,0 +1,105 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + +normal = 1 +two_planes = 2 + + +def Test(vis=False, interactive=False, fluka=True, type=normal): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + psphi = _gd.Constant("sphi", "1", reg, True) + pdphi = _gd.Constant("dphi", "4", reg, True) + pnsid = _gd.Constant("pnsid", "4", reg, True) + + pr1 = _gd.Constant("pr1", "5", reg, True) + pz1 = _gd.Constant("z1", "-10", reg, True) + + pr2 = _gd.Constant("pr2", "7", reg, True) + pz2 = _gd.Constant("z2", "-10", reg, True) + + pr3 = _gd.Constant("pr3", "7", reg, True) + pz3 = _gd.Constant("z3", "0", reg, True) + + pr4 = _gd.Constant("pr4", "7", reg, True) + pz4 = _gd.Constant("z4", "5", reg, True) + + pr5 = _gd.Constant("pr5", "7", reg, True) + pz5 = _gd.Constant("z5", "10", reg, True) + + pr6 = _gd.Constant("pr6", "5", reg, True) + pz6 = _gd.Constant("z6", "10", reg, True) + + pr7 = _gd.Constant("pr7", "2", reg, True) + pz7 = _gd.Constant("z7", "5", reg, True) + + pr = [pr1, pr2, pr3, pr4, pr5, pr6, pr7] + pz = [pz1, pz2, pz3, pz4, pz5, pz6, pz7] + + if type == two_planes: + pr = [pr1, pr2] + pz = [pz1, pz2] + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + pm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.GenericPolyhedra("ps", psphi, pdphi, pnsid, pr, pz, reg, "mm", "rad") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T014_geant4GenericPolyhedra2Fluka.gdml" + ) + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T014_geant4GenericPolyhedra2Fluka.inp" + ) + ) + + # flair output file + f = _fluka.Flair("T014_geant4GenericPolyhedra2Fluka.inp", extentBB) + f.write( + _os.path.join( + _os.path.dirname(__file__), "T014_geant4GenericPolyhedra2Fluka.flair" + ) + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T015_geant4EllipticalTube2Fluka.py b/tests/convert/T015_geant4EllipticalTube2Fluka.py new file mode 100644 index 000000000..e6e60bd74 --- /dev/null +++ b/tests/convert/T015_geant4EllipticalTube2Fluka.py @@ -0,0 +1,63 @@ +import os as _os + +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, fluka=True): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + ex = _gd.Constant("ex", "10", reg, True) + ey = _gd.Constant("ey", "25", reg, True) + ez = _gd.Constant("ez", "20", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + em = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + es = _g4.solid.EllipticalTube("es", ex, ey, ez, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + el = _g4.LogicalVolume(es, em, "el", reg) + ep = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], el, "e_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T015_geant4EllipticalTube2Fluka.inp" + ) + ) + + # flair output file + f = _fluka.Flair("T015_geant4EllipticalTube2Fluka.inp", extentBB) + f.write( + _os.path.join( + _os.path.dirname(__file__), "T015_geant4EllipticalTube2Fluka.flair" + ) + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.view(interactive=interactive) diff --git a/tests/convert/T016_geant4Ellipsoid2Fluka.py b/tests/convert/T016_geant4Ellipsoid2Fluka.py new file mode 100644 index 000000000..fce6ba61b --- /dev/null +++ b/tests/convert/T016_geant4Ellipsoid2Fluka.py @@ -0,0 +1,73 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True, n_slice=10, n_stack=10): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + eax = _gd.Constant("eax", "10", reg, True) + eby = _gd.Constant("eby", "15", reg, True) + ecz = _gd.Constant("ecz", "20", reg, True) + ebc = _gd.Constant("ebc", "-15", reg, True) + etc = _gd.Constant("etc", "15", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + em = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + es = _g4.solid.Ellipsoid( + "es", eax, eby, ecz, ebc, etc, reg, nslice=n_slice, nstack=n_stack + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + el = _g4.LogicalVolume(es, em, "el", reg) + ep = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], el, "e_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T016_geant4Ellipsoid2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T016_geant4Ellipsoid2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T016_geant4Ellipsoid2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T016_geant4Ellipsoid2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T017_geant4EllipticalCone2Fluka.py b/tests/convert/T017_geant4EllipticalCone2Fluka.py new file mode 100644 index 000000000..72a2d01dd --- /dev/null +++ b/tests/convert/T017_geant4EllipticalCone2Fluka.py @@ -0,0 +1,84 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + +normal = 1 +zcut_outofrange = 2 + + +def Test(vis=False, interactive=False, fluka=True, type=normal, n_slice=16): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + edx = _gd.Constant("eax", "0.5", reg, True) + edy = _gd.Constant("eby", "1", reg, True) + ezmax = _gd.Constant("ecz", "40", reg, True) + ezcut = _gd.Constant("ebc", "20", reg, True) + + if type == zcut_outofrange: + ezcut.setExpression(30) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + em = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + es = _g4.solid.EllipticalCone( + "es", edx, edy, ezmax, ezcut, reg, "mm", nslice=n_slice + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + el = _g4.LogicalVolume(es, em, "el", reg) + ep = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], el, "e_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T017_geant4EllipticalCone2Fluka.gdml" + ) + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T017_geant4EllipticalCone2Fluka.inp" + ) + ) + + # flair output file + f = _fluka.Flair("T017_geant4EllipticalCone2Fluka.inp", extentBB) + f.write( + _os.path.join( + _os.path.dirname(__file__), "T017_geant4EllipticalCone2Fluka.flair" + ) + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T018_geant4Paraboloid2Fluka.py b/tests/convert/T018_geant4Paraboloid2Fluka.py new file mode 100644 index 000000000..94d34ed33 --- /dev/null +++ b/tests/convert/T018_geant4Paraboloid2Fluka.py @@ -0,0 +1,69 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True, n_slice=16, n_stack=16): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + prlo = _gd.Constant("prlo", "2", reg, True) + prhi = _gd.Constant("prhi", "15", reg, True) + pz = _gd.Constant("pz", "50", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + pm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.Paraboloid("ps", pz, prlo, prhi, reg, nslice=n_slice, nstack=n_stack) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + pp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T018_geant4Paraboloid2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T018_geant4Paraboloid2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T018_geant4Paraboloid2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T001_geant4Paraboloid2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T019_geant4Hyperboloid2Fluka.py b/tests/convert/T019_geant4Hyperboloid2Fluka.py new file mode 100644 index 000000000..0a88112b3 --- /dev/null +++ b/tests/convert/T019_geant4Hyperboloid2Fluka.py @@ -0,0 +1,86 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + +normal = 1 +rmin_eq_zero = 2 +rmin_gt_rmax = 3 + + +def Test(vis=False, interactive=False, fluka=True, type=normal, n_slice=16, n_stack=16): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + pi = _gd.Constant("pi", "3.1415926", reg, True) + hrmin = _gd.Constant("hrmin", "20", reg, True) + hrmax = _gd.Constant("hrmax", "30.0", reg, True) + hz = _gd.Constant("hz", "50.0", reg, True) + hinst = _gd.Constant("hinst", "0.7", reg, True) + houtst = _gd.Constant("houtst", "0.7", reg, True) + + if type == rmin_eq_zero: + hrmin.setExpression(0) + + if type == rmin_gt_rmax: + hrmin.setExpression(2) + hrmax.setExpression(1) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + hm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + hs = _g4.solid.Hype( + "ps", hrmin, hrmax, hinst, houtst, hz, reg, nslice=n_slice, nstack=n_stack + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + hl = _g4.LogicalVolume(hs, hm, "hl", reg) + hp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], hl, "h_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T019_geant4Hyperboloid2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T019_geant4Hyperboloid2Fluka.inp" + ) + ) + + # flair output file + f = _fluka.Flair("T019_geant4Hyperboloid2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T019_geant4Hyperboloid2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T020_geant4Tet2Fluka.py b/tests/convert/T020_geant4Tet2Fluka.py new file mode 100644 index 000000000..05ac50b11 --- /dev/null +++ b/tests/convert/T020_geant4Tet2Fluka.py @@ -0,0 +1,63 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + v1 = _gd.Position("v1", "10", "10", "0", "mm", reg, True) + v2 = _gd.Position("v2", "-10", "10", "0", "mm", reg, True) + v3 = _gd.Position("v3", "-10", "-10", "0", "mm", reg, True) + v4 = _gd.Position("v4", "0", "0", "10", "mm", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + tm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Tet("ts", v1, v2, v3, v4, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T020_geant4Tet2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T020_geant4Tet2Fluka.inp")) + + # flair output file + f = _fluka.Flair("T020_geant4Tet2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T020_geant4Tet2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T021_geant4ExtrudedSolid2Fluka.py b/tests/convert/T021_geant4ExtrudedSolid2Fluka.py new file mode 100644 index 000000000..e5dc375d6 --- /dev/null +++ b/tests/convert/T021_geant4ExtrudedSolid2Fluka.py @@ -0,0 +1,118 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, fluka=True): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "150", reg, True) + wy = _gd.Constant("wy", "150", reg, True) + wz = _gd.Constant("wz", "150", reg, True) + + p1x = _gd.Constant("p1x", "-20", reg, True) + p1y = _gd.Constant("p1y", "-20", reg, True) + + p2x = _gd.Constant("p2x", "-20", reg, True) + p2y = _gd.Constant("p2y", "20", reg, True) + + p3x = _gd.Constant("p3x", "20", reg, True) + p3y = _gd.Constant("p3y", "20", reg, True) + + p4x = _gd.Constant("p4x", "20", reg, True) + p4y = _gd.Constant("p4y", "10", reg, True) + + p5x = _gd.Constant("p5x", "-10", reg, True) + p5y = _gd.Constant("p5y", "10", reg, True) + + p6x = _gd.Constant("p6x", "-10", reg, True) + p6y = _gd.Constant("p6y", "-10", reg, True) + + p7x = _gd.Constant("p7x", "20", reg, True) + p7y = _gd.Constant("p7y", "-10", reg, True) + + p8x = _gd.Constant("p8x", "20", reg, True) + p8y = _gd.Constant("p8y", "-20", reg, True) + + z1 = _gd.Constant("z1", "-20", reg, True) + x1 = _gd.Constant("x1", "5", reg, True) + y1 = _gd.Constant("y1", "5", reg, True) + s1 = _gd.Constant("s1", "1", reg, True) + + z2 = _gd.Constant("z2", "0", reg, True) + x2 = _gd.Constant("x2", "-5", reg, True) + y2 = _gd.Constant("y2", "-5", reg, True) + s2 = _gd.Constant("s2", "1", reg, True) + + z3 = _gd.Constant("z3", "20", reg, True) + x3 = _gd.Constant("x3", "0", reg, True) + y3 = _gd.Constant("y3", "0", reg, True) + s3 = _gd.Constant("s3", "2", reg, True) + + polygon = [ + [p1x, p1y], + [p2x, p2y], + [p3x, p3y], + [p4x, p4y], + [p5x, p5y], + [p6x, p6y], + [p7x, p7y], + [p8x, p8y], + ] + slices = [[z1, [x1, y1], s1], [z2, [x2, y2], s2], [z3, [x3, y3], s3]] + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + xm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + xs = _g4.solid.ExtrudedSolid("xs", polygon, slices, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + xl = _g4.LogicalVolume(xs, xm, "xl", reg) + xp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], xl, "x_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T021_geant4ExtrudedSolid2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T021_geant4ExtrudedSolid2Fluka.inp" + ) + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T022_geant4TwistedBox2Fluka.py b/tests/convert/T022_geant4TwistedBox2Fluka.py new file mode 100644 index 000000000..1f1af7c68 --- /dev/null +++ b/tests/convert/T022_geant4TwistedBox2Fluka.py @@ -0,0 +1,68 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + tbx = _gd.Constant("bx", "10", reg, True) + tby = _gd.Constant("by", "20", reg, True) + tbz = _gd.Constant("bz", "30", reg, True) + tbphit = _gd.Constant("bt", "1.0", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + tm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.TwistedBox("ts", tbphit, tbx, tby, tbz, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T022_geant4TwistedBox2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T022_geant4TwistedBox2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T022_geant4TwistedBox2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T022_geant4TwistedBox2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T023_geantt4TwistedTrap2Fluka.py b/tests/convert/T023_geantt4TwistedTrap2Fluka.py new file mode 100644 index 000000000..b9b174a12 --- /dev/null +++ b/tests/convert/T023_geantt4TwistedTrap2Fluka.py @@ -0,0 +1,82 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + ttwist = _gd.Constant("tptwist", "1.0", reg, True) + + tx1 = _gd.Constant("tx1", "5", reg, True) + tx2 = _gd.Constant("tx2", "5", reg, True) + tx3 = _gd.Constant("tx3", "10", reg, True) + tx4 = _gd.Constant("tx4", "10", reg, True) + + ty1 = _gd.Constant("ty1", "5", reg, True) + ty2 = _gd.Constant("ty2", "7.5", reg, True) + + tz = _gd.Constant("tz", "10.0", reg, True) + + ttheta = _gd.Constant("ttheta", "0.6", reg, True) + tphi = _gd.Constant("tphi", "0.0", reg, True) + talp = _gd.Constant("talp", "0.0", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + tm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.TwistedTrap( + "ts", ttwist, tz, ttheta, tphi, ty1, tx1, tx2, ty2, tx3, tx4, talp, reg + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T023_geant4TwistedTrap2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T023_geant4TwistedTrap2Fluka.inp" + ) + ) + + # flair output file + f = _fluka.Flair("T001_geant4Box2Fluka.inp", extentBB) + f.write(_os.path.join(_os.path.dirname(__file__), "T001_geant4Box2Fluka.flair")) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T024_geant4TwistedTrd2Fluka.py b/tests/convert/T024_geant4TwistedTrd2Fluka.py new file mode 100644 index 000000000..d0168ff92 --- /dev/null +++ b/tests/convert/T024_geant4TwistedTrd2Fluka.py @@ -0,0 +1,72 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + ttwist = _gd.Constant("tptwist", "1.0", reg, True) + + tx1 = _gd.Constant("tx1", "20", reg, True) + ty1 = _gd.Constant("ty1", "25", reg, True) + tx2 = _gd.Constant("tx2", "5", reg, True) + ty2 = _gd.Constant("ty2", "7.5", reg, True) + tz = _gd.Constant("tz", "10.0", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + tm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.TwistedTrd("ts", ttwist, tx1, ty1, tx2, ty2, tz, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T023_geant4TwistedTrd2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T023_geantTwistedTrd2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T024_geant4TwistedTrd2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T024_geant4TwistedTrd2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T025_geant4TwistedTubs2Fluka.py b/tests/convert/T025_geant4TwistedTubs2Fluka.py new file mode 100644 index 000000000..f39d2f9b2 --- /dev/null +++ b/tests/convert/T025_geant4TwistedTubs2Fluka.py @@ -0,0 +1,74 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + + ttwist = _gd.Constant("tptwist", "1.0", reg, True) + trmin = _gd.Constant("trmin", "2.5", reg, True) + trmax = _gd.Constant("trmax", "10.0", reg, True) + tz = _gd.Constant("tz", "50", reg, True) + tphi = _gd.Constant("phi", "1.5*pi", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.TwistedTubs("ts", trmin, trmax, tz, tphi, ttwist, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T025_geant4TwistedTubs2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T025_geant4TwistedTubs2Fluka.inp" + ) + ) + + # flair output file + f = _fluka.Flair("T025_geant4TwiistedTubs2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T025_geant4TwistedTubs2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T026_geant4GenericTrap2Fluka.py b/tests/convert/T026_geant4GenericTrap2Fluka.py new file mode 100644 index 000000000..09b9a904f --- /dev/null +++ b/tests/convert/T026_geant4GenericTrap2Fluka.py @@ -0,0 +1,117 @@ +import os as _os +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import numpy as _np + +normal = 1 +zero_area_quad = 2 + + +def Test(vis=False, interactive=False, fluka=True): + # registry + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + + tv1x = _gd.Constant("v1x", "10", reg, True) + tv1y = _gd.Constant("v1y", "10", reg, True) + + tv2x = _gd.Constant("v2x", "20", reg, True) + tv2y = _gd.Constant("v2y", "30", reg, True) + + tv3x = _gd.Constant("v3x", "30", reg, True) + tv3y = _gd.Constant("v3y", "30", reg, True) + + tv4x = _gd.Constant("v4x", "40", reg, True) + tv4y = _gd.Constant("v4y", "10", reg, True) + + tv5x = _gd.Constant("v5x", "20", reg, True) + tv5y = _gd.Constant("v5y", "20", reg, True) + + tv6x = _gd.Constant("v6x", "20", reg, True) + tv6y = _gd.Constant("v6y", "40", reg, True) + + tv7x = _gd.Constant("v7x", "40", reg, True) + tv7y = _gd.Constant("v7y", "40", reg, True) + + tv8x = _gd.Constant("v8x", "40", reg, True) + tv8y = _gd.Constant("v8y", "20", reg, True) + + tz = _gd.Constant("z", "30", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + tm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.GenericTrap( + "ts", + tv1x, + tv1y, + tv2x, + tv2y, + tv3x, + tv3y, + tv4x, + tv4y, + tv5x, + tv5y, + tv6x, + tv6y, + tv7x, + tv7y, + tv8x, + tv8y, + tz, + reg, + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T026_geant4GenericTrap2Fluka.gdml") + ) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T026_geant4GenericTrap2Fluka.inp" + ) + ) + + # flair output file + f = _fluka.Flair("T026_geant4GenericTrap2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T026_geant4GenericTrap2Fluka.flair") + ) + + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) diff --git a/tests/convert/T028_geant4Union2Fluka.py b/tests/convert/T028_geant4Union2Fluka.py new file mode 100644 index 000000000..1ba9e5f4e --- /dev/null +++ b/tests/convert/T028_geant4Union2Fluka.py @@ -0,0 +1,76 @@ +import numpy as _np +import pyg4ometry.gdml as _gd +import pyg4ometry.convert as _convert +import pyg4ometry.geant4 as _g4 +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import os as _os + + +def Test(vis=False, interactive=False, fluka=True, disjoint=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "5", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "15", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + if not disjoint: + us1 = _g4.solid.Union( + "us1", + bs, + bs, + [[0.0, _np.pi / 4, _np.pi / 4], [bx / 2, by / 2, bz / 2]], + reg, + ) + us2 = _g4.solid.Union( + "us2", + bs, + us1, + [[0.0, _np.pi / 4, _np.pi / 4], [bx / 2, by / 2, bz / 2]], + reg, + ) + else: + us = _g4.solid.Union( + "us", bs, bs, [[0.0, 0.0, 0.0], [bx * 2, by * 2, bz * 2]], reg + ) + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ul = _g4.LogicalVolume(us2, bm, "ul", reg) + up = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ul, "u_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write(_os.path.join(_os.path.dirname(__file__), "T028_geant4Union2Fluka.inp")) + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T029_geant4Subtraction2Fluka.py b/tests/convert/T029_geant4Subtraction2Fluka.py new file mode 100644 index 000000000..fc3f67aff --- /dev/null +++ b/tests/convert/T029_geant4Subtraction2Fluka.py @@ -0,0 +1,73 @@ +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import os as _os + + +def Test(vis=False, interactive=False, fluka=True, nullMesh=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + bs1 = _g4.solid.Box("bs1", 2 * bx, 2 * by, 2 * bz, reg, "mm") + + if not nullMesh: + ss = _g4.solid.Subtraction( + "us", bs, bs, [[0.1, 0.2, 0.3], [bx / 2, by / 2, bz / 2]], reg + ) + else: + ss = _g4.solid.Subtraction("us", bs, bs1, [[0, 0, 0], [0, 0, 0]], reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + sl = _g4.LogicalVolume(ss, bm, "ul", reg) + + sp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], sl, "s_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test __repr__ + str(ss) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T029_geant4Subtraction2Fluka.inp" + ) + ) + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T030_geant4Intersection2Fluka.py b/tests/convert/T030_geant4Intersection2Fluka.py new file mode 100644 index 000000000..77209992d --- /dev/null +++ b/tests/convert/T030_geant4Intersection2Fluka.py @@ -0,0 +1,72 @@ +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka +import os as _os + +normal = 1 +non_intersecting = 2 + + +def Test(vis=False, interactive=False, fluka=True, type=normal): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + if type == normal: + ns = _g4.solid.Intersection( + "ns", bs, bs, [[0.1, 0.2, 0.3], [bx / 2, by / 2, bz / 2]], reg + ) + elif type == non_intersecting: + ns = _g4.solid.Intersection( + "ns", bs, bs, [[0.1, 0.2, 0.3], [bx * 2, by * 2, bz * 22]], reg + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + nl = _g4.LogicalVolume(ns, bm, "nl", reg) + np = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], nl, "i_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T030_geant4Intersection2Fluka.inp" + ) + ) + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T105_geant4Assembly2Fluka.py b/tests/convert/T105_geant4Assembly2Fluka.py new file mode 100644 index 000000000..de79a2d20 --- /dev/null +++ b/tests/convert/T105_geant4Assembly2Fluka.py @@ -0,0 +1,80 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.fluka as _fluka +import pyg4ometry.convert as _convert + + +def Test(vis=False, interactive=False, fluka=True): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "2", reg, True) + wy = _gd.Constant("wy", "2", reg, True) + wz = _gd.Constant("wz", "2", reg, True) + + halfPi = _gd.Constant("HALPPI", "pi/2.", reg, True) + twoPi = _gd.Constant("TWOPI", "2*pi", reg, True) + centre = _gd.Position("centre", 0, 0, 0, "m", reg, True) + indentity = _gd.Rotation("identity", 0, 0, 0, "rad", reg, True) + alignSurfX = _gd.Rotation("alignSurfX", 0, halfPi, 0, "rad", reg, True) + alignSurfY = _gd.Rotation("alignSurfY", halfPi, 0, 0, "rad", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "m") + ts = _g4.solid.Tubs("ts", 0.1075, 0.1875, 0.1875, 0, twoPi, reg, "m", "rad") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + wa = _g4.AssemblyVolume("wa", reg, True) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + + tp1 = _g4.PhysicalVolume(alignSurfX, [0, 0, 500], tl, "t_pv1", wa, reg) + tp2 = _g4.PhysicalVolume(alignSurfY, [0, 0, -500], tl, "t_pv2", wa, reg) + + a_pv1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], wa, "a_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T105_geant4Assembly2Fluka.gdml")) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T105_geant4Assembly2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T105_geant4Assembly2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T105_geant4Assembly2Fluka.flair") + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T106_geant4ReplicaX2Fluka.py b/tests/convert/T106_geant4ReplicaX2Fluka.py new file mode 100644 index 000000000..97fbc6c46 --- /dev/null +++ b/tests/convert/T106_geant4ReplicaX2Fluka.py @@ -0,0 +1,86 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka + + +def Test(vis=False, interactive=False, fluka=True): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "100", reg, True) + by = _gd.Constant("by", "100", reg, True) + bz = _gd.Constant("bz", "100", reg, True) + + mbx = _gd.Constant("mbx", "800", reg, True) + mby = _gd.Constant("mby", "100", reg, True) + mbz = _gd.Constant("mbz", "100", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + mbs = _g4.solid.Box("mbs", mbx, mby, mbz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + ml = _g4.LogicalVolume(mbs, wm, "ml", reg) + mbl = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kXAxis, 8, 100, 0, reg, True, "mm", "mm" + ) + + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T106_geant4ReplicaX2Fluka.gdml")) + + # test __repr__ + str(mbl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T106_geant4ReplicaX2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T106_geant4ReplicaX2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T106_geant4ReplicaX2Fluka.flair") + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T107_geant4ReplicaY2Fluka.py b/tests/convert/T107_geant4ReplicaY2Fluka.py new file mode 100644 index 000000000..8d7ba6c11 --- /dev/null +++ b/tests/convert/T107_geant4ReplicaY2Fluka.py @@ -0,0 +1,86 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka + + +def Test(vis=False, interactive=False, fluka=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "100", reg, True) + by = _gd.Constant("by", "100", reg, True) + bz = _gd.Constant("bz", "100", reg, True) + + mbx = _gd.Constant("mbx", "100", reg, True) + mby = _gd.Constant("mby", "800", reg, True) + mbz = _gd.Constant("mbz", "100", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + mbs = _g4.solid.Box("mbs", mbx, mby, mbz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + ml = _g4.LogicalVolume(mbs, wm, "ml", reg) + mbl = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kYAxis, 8, 100, 0, reg, True, "mm", "mm" + ) + + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T107_geant4ReplicaY2Fluka.gdml")) + + # test __repr__ + str(mbl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T107_geant4ReplicaY2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T107_geant4ReplicaY2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T107_geant4ReplicaY2Fluka.flair") + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T108_geant4ReplicaZ2Fluka.py b/tests/convert/T108_geant4ReplicaZ2Fluka.py new file mode 100644 index 000000000..38a17e7b3 --- /dev/null +++ b/tests/convert/T108_geant4ReplicaZ2Fluka.py @@ -0,0 +1,86 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka + + +def Test(vis=False, interactive=False, fluka=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "100", reg, True) + by = _gd.Constant("by", "100", reg, True) + bz = _gd.Constant("bz", "100", reg, True) + + mbx = _gd.Constant("mbx", "100", reg, True) + mby = _gd.Constant("mby", "100", reg, True) + mbz = _gd.Constant("mbz", "800", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + mbs = _g4.solid.Box("mbs", mbx, mby, mbz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + ml = _g4.LogicalVolume(mbs, wm, "ml", reg) + mbl = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kZAxis, 8, 100, 0, reg, True, "mm", "mm" + ) + + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T108_geant4ReplicaY2Fluka.gdml")) + + # test __repr__ + str(mbl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T108_geant4ReplicaZ2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T108_geant4ReplicaZ2Fluka.inp", extentBB) + f.write( + _os.path.join(_os.path.dirname(__file__), "T108_geant4ReplicaZ2Fluka.flair") + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T109_geant4ReplicaPhi2Fluka.py b/tests/convert/T109_geant4ReplicaPhi2Fluka.py new file mode 100644 index 000000000..b48f55d41 --- /dev/null +++ b/tests/convert/T109_geant4ReplicaPhi2Fluka.py @@ -0,0 +1,92 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _convert + + +def Test(vis=False, interactive=False, fluka=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", 1000, reg, True) + wy = _gd.Constant("wy", 1000, reg, True) + wz = _gd.Constant("wz", 1000, reg, True) + + bx = _gd.Constant("bx", 100, reg, True) + by = _gd.Constant("by", 100, reg, True) + bz = _gd.Constant("bz", 100, reg, True) + + trmin = _gd.Constant("rmin", 100, reg, True) + trmax = _gd.Constant("rmax", 200, reg, True) + tz = _gd.Constant("z", 800, reg, True) + mtdphi = _gd.Constant("mtdphi", "2*pi", reg, True) + tdphi = _gd.Constant("tdphi", "2*pi/8.0", reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Tubs("ts", trmin, trmax, tz, 0, tdphi, reg, "mm", "rad", 16, True) + mts = _g4.solid.Tubs("mts", trmin, trmax, tz, 0, mtdphi, reg, "mm", "rad", 16, True) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + ml = _g4.LogicalVolume(mts, wm, "ml", reg) + mtl = _g4.ReplicaVolume( + "mtl", tl, ml, _g4.ReplicaVolume.Axis.kPhi, 8, tdphi, 0, reg, True, "mm", "mm" + ) + + mtp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T109_geant4ReplicaPhi2Fluka.gdml") + ) + + # test __repr__ + str(mtl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T109_geant4ReplicaPhi2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T109_geant4ReplicaPhi2Fluka.inp", extentBB) + f.write( + _os.path.join( + _os.path.dirname(__file__), "T109_geant4ReplicaPhi2Fluka.flair" + ) + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/T110_geant4ReplicaRho2Fluka.py b/tests/convert/T110_geant4ReplicaRho2Fluka.py new file mode 100644 index 000000000..487f89d8d --- /dev/null +++ b/tests/convert/T110_geant4ReplicaRho2Fluka.py @@ -0,0 +1,104 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _convert +import pyg4ometry.fluka as _fluka + + +def Test(vis=False, interactive=False, fluka=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", 1000, reg, True) + wy = _gd.Constant("wy", 1000, reg, True) + wz = _gd.Constant("wz", 1000, reg, True) + + bx = _gd.Constant("bx", 100, reg, True) + by = _gd.Constant("by", 100, reg, True) + bz = _gd.Constant("bz", 100, reg, True) + + trmin = _gd.Constant("rmin", 100, reg, True) + trmax = _gd.Constant("rmax", 200, reg, True) + tz = _gd.Constant("z", 800, reg, True) + mtdphi = _gd.Constant("mtdphi", "2*pi", reg, True) + tdphi = _gd.Constant("tdphi", "2*pi", reg, True) + nreplicas = _gd.Constant("nreplicas", 8, reg, True) + tdR = _gd.Constant("tdR", trmax / nreplicas, reg, True) + + # materials + wm = _g4.nist_material_2geant4Material("G4_Galactic") + bm = _g4.nist_material_2geant4Material("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Tubs("ts", 0, trmax, tz, 0, tdphi, reg, "mm", "rad", 16, True) + mts = _g4.solid.Tubs("mts", 0, trmax, tz, 0, mtdphi, reg, "mm", "rad", 16, True) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + ml = _g4.LogicalVolume(mts, wm, "ml", reg) + mtl = _g4.ReplicaVolume( + "mtl", + tl, + ml, + _g4.ReplicaVolume.Axis.kRho, + nreplicas, + tdR, + 0, + reg, + True, + "mm", + "mm", + ) + + mtp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T110_geant4ReplicaRho2Fluka.gdml") + ) + + # test __repr__ + str(mtl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # fluka conversion + if fluka: + freg = _convert.geant4Reg2FlukaReg(reg) + w = _fluka.Writer() + w.addDetector(freg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T110_geant4ReplicaRho2Fluka.inp") + ) + + # flair output file + f = _fluka.Flair("T110_geant4ReplicaRho2Fluka.inp", extentBB) + f.write( + _os.path.join( + _os.path.dirname(__file__), "T110_geant4ReplicaRho2Fluka.flair" + ) + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/convert/__init__.py b/tests/convert/__init__.py new file mode 100644 index 000000000..ae56a22cc --- /dev/null +++ b/tests/convert/__init__.py @@ -0,0 +1 @@ +from .Geant42FlukaConversion import * diff --git a/tests/convert/test_geant42Fluka.py b/tests/convert/test_geant42Fluka.py new file mode 100644 index 000000000..a101b03a0 --- /dev/null +++ b/tests/convert/test_geant42Fluka.py @@ -0,0 +1,157 @@ +from . import T001_geant4Box2Fluka +from . import T002_geant4Tubs2Fluka +from . import T003_geant4CutTubs2Fluka +from . import T004_geant4Cons2Fluka +from . import T005_geant4Para2Fluka +from . import T006_geant4Trd2Fluka +from . import T007_geant4Trap2Fluka +from . import T008_geant4Sphere2Fluka +from . import T009_geant4Orb2Fluka +from . import T010_geant4Torus2Fluka +from . import T011_geant4Polycone2Fluka +from . import T012_geant4GenericPolycone2Fluka +from . import T013_geant4Polyhedra2Fluka +from . import T014_geant4GenericPolyhedra2Fluka +from . import T015_geant4EllipticalTube2Fluka +from . import T016_geant4Ellipsoid2Fluka +from . import T017_geant4EllipticalCone2Fluka +from . import T018_geant4Paraboloid2Fluka +from . import T019_geant4Hyperboloid2Fluka +from . import T020_geant4Tet2Fluka +from . import T021_geant4ExtrudedSolid2Fluka +from . import T026_geant4GenericTrap2Fluka + +from . import T028_geant4Union2Fluka +from . import T029_geant4Subtraction2Fluka +from . import T030_geant4Intersection2Fluka + +from . import T105_geant4Assembly2Fluka +from . import T106_geant4ReplicaX2Fluka +from . import T107_geant4ReplicaY2Fluka +from . import T108_geant4ReplicaZ2Fluka +from . import T109_geant4ReplicaPhi2Fluka +from . import T110_geant4ReplicaRho2Fluka + + +def test_Geant42FlukaConversion_T001_Box(): + T001_geant4Box2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T002_Tubs(): + T002_geant4Tubs2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T003_CutTubs(): + T003_geant4CutTubs2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T004_Cons(): + T004_geant4Cons2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T005_Para(): + T005_geant4Para2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T006_Tdr(): + T006_geant4Trd2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T007_Trap(): + T007_geant4Trap2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T008_Sphere(): + T008_geant4Sphere2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T009_Orb(): + T009_geant4Orb2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T010_Torus(): + T010_geant4Torus2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T011_Polycone(): + T011_geant4Polycone2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T012_GenericPolycone(): + T012_geant4GenericPolycone2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T013_Polyhedra(): + T013_geant4Polyhedra2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T014_GenericPolyhedra(): + T014_geant4GenericPolyhedra2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T015_EllipticalTube(): + T015_geant4EllipticalTube2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T016_Ellipsoid(): + T016_geant4Ellipsoid2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T017_EllipticalCone(): + T017_geant4EllipticalCone2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T018_Paraboloid(): + T018_geant4Paraboloid2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T019_Hyperboloid(): + T019_geant4Hyperboloid2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T020_Tet(): + T020_geant4Tet2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T021_ExtrudedSolid(): + T021_geant4ExtrudedSolid2Fluka.Test(False, False, True) + + +# def test_Geant42FlukaConversion_T026_GenericTrap(): +# T026_geant4GenericTrap2Fluka.Test(False,False,True) + + +def test_Geant42FlukaConversion_T028_Union(): + T028_geant4Union2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T029_Subtraction(): + T029_geant4Subtraction2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T030_Intersection(): + T030_geant4Intersection2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T105_Assembly(): + T105_geant4Assembly2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T106_replica_x(): + T106_geant4ReplicaX2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T107_replica_y(): + T107_geant4ReplicaY2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T108_replica_z(): + T108_geant4ReplicaZ2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T109_replica_phi(): + T109_geant4ReplicaPhi2Fluka.Test(False, False, True) + + +def test_Geant42FlukaConversion_T110_replica_rho(): + T110_geant4ReplicaRho2Fluka.Test(False, False, True) diff --git a/tests/features/T720_featureExtract.py b/tests/features/T720_featureExtract.py new file mode 100644 index 000000000..d5fddaef2 --- /dev/null +++ b/tests/features/T720_featureExtract.py @@ -0,0 +1,21 @@ +import pyg4ometry as _pyg4 +import os as _os + + +def Test(testdata, tmptestdir, vis=False, interactive=False): + pathToStl = testdata["stl/ST0372507_01_a.stl"] + cs1 = _pyg4.features.algos.CoordinateSystem([0, 0, 0], [1, 0, 0], [0, 1, 0]) + cs2 = _pyg4.features.algos.CoordinateSystem([0, 0, 20], [1, 0, 0], [0, 1, 0]) + r = _pyg4.features.extract( + pathToStl, + planes=[], + outputFileName=tmptestdir / "T720_featureExtract.dat", + bViewer=vis, + bViewerInteractive=interactive, + ) + + return True + + +if __name__ == "__main__": + Test() diff --git a/tests/features/T721_featureExtract_cutTubs.py b/tests/features/T721_featureExtract_cutTubs.py new file mode 100644 index 000000000..c3e948ee6 --- /dev/null +++ b/tests/features/T721_featureExtract_cutTubs.py @@ -0,0 +1,83 @@ +import pyg4ometry as _pyg4 +import os as _os +import numpy as _np + + +def Test(testdata, tmptestdir, vis=False, interactive=False): + reg = _pyg4.geant4.Registry() + radius1 = 7 + radius2 = 9 + theta = 0.1 + rho = 500 + + s = theta * rho + d = _np.sin(theta / 2.0) * rho * 2 + + n1 = [_np.cos(_np.pi / 2 - theta / 2.0), 0, -_np.sin(_np.pi / 2 - theta / 2.0)] + n2 = [_np.cos(_np.pi / 2 - theta / 2.0), 0, _np.sin(_np.pi / 2 - theta / 2.0)] + + t = _pyg4.geant4.solid.CutTubs( + "t1", radius1, radius2, d, 0, 2 * _np.pi, n1, n2, reg + ) + + stlFileName = testdata["stl/ST0372507_01_a.stl"] + # _os.path.join( + # _os.path.dirname(__file__), "T721_featureExtract_cutTubs.stl" + # ) + datFileName = tmptestdir / "ST0372507_01_a.dat" + _pyg4.convert.pycsgMeshToStl(t.mesh(), stlFileName) + + p1 = _pyg4.features.algos.Plane([0, 0, 0], [0, 0, 1]) + v = _pyg4.features.extract( + stlFileName, + angle=46, + circumference=2 * _np.pi * 8, + planes=[], + outputFileName=datFileName, + bViewer=vis, + bViewerInteractive=interactive, + ) + + fd = _pyg4.features.algos.FeatureData() + fd.readFile(datFileName) + + p1 = fd.features[2]["plane"] + p2 = fd.features[3]["plane"] + + pp1 = _pyg4.features.Plane(p1[0:3], p1[3:]) + pp2 = _pyg4.features.Plane(p2[0:3], p2[3:]) + pp3 = _pyg4.features.Plane([0, 0, 0], [0, 1, 0]) + + cs = _pyg4.features.CoordinateSystem() + cs.makeFromPlanes(pp1, pp2, pp3) + + cs1 = cs.coordinateSystem(0, 0.01, 0) + cs2 = cs.coordinateSystem(0, 0.02, 0) + cs3 = cs.coordinateSystem(0, 0.03, 0) + cs4 = cs.coordinateSystem(0, 0.04, 0) + + if v is None: + return True + + v.addPlane(cs.origin, cs.e1, cs.e2, cs.dist) + v.addPlane(cs.origin, cs1.e1, cs1.e2, cs.dist) + v.addAxis( + cs.origin, [cs.dist, cs.dist, cs.dist], cs.rot, label=True, disableCone=True + ) + v.view(interactive=interactive) + + v = _pyg4.features.extract( + stlFileName, + angle=46, + circumference=2 * _np.pi * 8, + planes=[cs1, cs2, cs3, cs4], + outputFileName=datFileName, + bViewer=vis, + bViewerInteractive=interactive, + ) + + return True + + +if __name__ == "__main__": + Test() diff --git a/tests/features/T721_featureExtract_cutTubs.stl b/tests/features/T721_featureExtract_cutTubs.stl new file mode 100644 index 000000000..2a739c5d1 --- /dev/null +++ b/tests/features/T721_featureExtract_cutTubs.stl @@ -0,0 +1,898 @@ +solid Visualization Toolkit generated SLA File + facet normal 0.049978661533971465 -2.333139111010282e-07 -0.99875028580282177 + outer loop + vertex 6.4671568870544434 2.6787841320037842 -24.665956497192383 + vertex 9 0 -24.539209365844727 + vertex 7 0 -24.639291763305664 + endloop + endfacet + facet normal 0.049978661533971465 -2.333139111010282e-07 0.99875028580282177 + outer loop + vertex 9 0 24.539209365844727 + vertex 6.4671568870544434 2.6787841320037842 24.665956497192383 + vertex 7 0 24.639291763305664 + endloop + endfacet + facet normal 0.98078527337889565 0.19509035732984101 0 + outer loop + vertex 8.314915657043457 3.4441509246826172 -24.573492050170898 + vertex 9 0 24.539209365844727 + vertex 9 0 -24.539209365844727 + endloop + endfacet + facet normal -0.98078529304487616 -0.19509025846227224 0 + outer loop + vertex 7 0 24.639291763305664 + vertex 6.4671568870544434 2.6787841320037842 -24.665956497192383 + vertex 7 0 -24.639291763305664 + endloop + endfacet + facet normal 0.049978983691036066 -2.7964576111001245e-07 -0.99875026968163216 + outer loop + vertex 6.4671568870544434 2.6787841320037842 -24.665956497192383 + vertex 6.3639612197875977 6.3639612197875977 -24.671121597290039 + vertex 8.314915657043457 3.4441509246826172 -24.573492050170898 + endloop + endfacet + facet normal 0.049978537107365488 -2.9218272378077363e-07 0.99875029202925503 + outer loop + vertex 6.4671568870544434 2.6787841320037842 24.665956497192383 + vertex 6.3639612197875977 6.3639612197875977 24.671121597290039 + vertex 4.9497475624084473 4.9497475624084473 24.741889953613281 + endloop + endfacet + facet normal 0.83146966869757644 0.55557014861846432 0 + outer loop + vertex 6.3639612197875977 6.3639612197875977 -24.671121597290039 + vertex 8.314915657043457 3.4441509246826172 24.573492050170898 + vertex 8.314915657043457 3.4441509246826172 -24.573492050170898 + endloop + endfacet + facet normal -0.83146959996386427 -0.55557025148574279 0 + outer loop + vertex 6.4671568870544434 2.6787841320037842 24.665956497192383 + vertex 4.9497475624084473 4.9497475624084473 -24.741889953613281 + vertex 6.4671568870544434 2.6787841320037842 -24.665956497192383 + endloop + endfacet + facet normal 0.049978998270547373 -7.5450071928608675e-07 -0.99875026895180519 + outer loop + vertex 2.6787841320037842 6.4671568870544434 -24.855533599853516 + vertex 6.3639612197875977 6.3639612197875977 -24.671121597290039 + vertex 4.9497475624084473 4.9497475624084473 -24.741889953613281 + endloop + endfacet + facet normal 0.049978998270547373 -7.5450071928608675e-07 0.99875026895180519 + outer loop + vertex 6.3639612197875977 6.3639612197875977 24.671121597290039 + vertex 2.6787841320037842 6.4671568870544434 24.855533599853516 + vertex 4.9497475624084473 4.9497475624084473 24.741889953613281 + endloop + endfacet + facet normal 0.55557014861846432 0.83146966869757644 0 + outer loop + vertex 3.4441509246826172 8.314915657043457 -24.817234039306641 + vertex 6.3639612197875977 6.3639612197875977 24.671121597290039 + vertex 6.3639612197875977 6.3639612197875977 -24.671121597290039 + endloop + endfacet + facet normal -0.55557025148574279 -0.83146959996386427 0 + outer loop + vertex 4.9497475624084473 4.9497475624084473 24.741889953613281 + vertex 2.6787841320037842 6.4671568870544434 -24.855533599853516 + vertex 4.9497475624084473 4.9497475624084473 -24.741889953613281 + endloop + endfacet + facet normal 0.049978761358725358 -2.096768260745424e-07 -0.99875028080747175 + outer loop + vertex 2.6787841320037842 6.4671568870544434 -24.855533599853516 + vertex 5.5109107042843573e-16 9 -24.989583969116211 + vertex 3.4441509246826172 8.314915657043457 -24.817234039306641 + endloop + endfacet + facet normal 0.049978959117075887 -3.0603287489104884e-18 0.99875027091138935 + outer loop + vertex 2.6787841320037842 6.4671568870544434 24.855533599853516 + vertex 5.5109107042843573e-16 9 24.989583969116211 + vertex 4.2862638516991895e-16 7 24.989583969116211 + endloop + endfacet + facet normal 0.19509035732984104 0.98078527337889565 0 + outer loop + vertex 5.5109107042843573e-16 9 -24.989583969116211 + vertex 3.4441509246826172 8.314915657043457 24.817234039306641 + vertex 3.4441509246826172 8.314915657043457 -24.817234039306641 + endloop + endfacet + facet normal -0.19509025846227229 -0.98078529304487627 0 + outer loop + vertex 2.6787841320037842 6.4671568870544434 24.855533599853516 + vertex 4.2862638516991895e-16 7 -24.989583969116211 + vertex 2.6787841320037842 6.4671568870544434 -24.855533599853516 + endloop + endfacet + facet normal 0.04997966847115734 -3.0603721843226492e-18 -0.99875023541399643 + outer loop + vertex -2.6787841320037842 6.4671568870544434 -25.123636245727539 + vertex 5.5109107042843573e-16 9 -24.989583969116211 + vertex 4.2862638516991895e-16 7 -24.989583969116211 + endloop + endfacet + facet normal 0.04997966847115734 0 0.99875023541399643 + outer loop + vertex 5.5109107042843573e-16 9 24.989583969116211 + vertex -2.6787841320037842 6.4671568870544434 25.123636245727539 + vertex 4.2862638516991895e-16 7 24.989583969116211 + endloop + endfacet + facet normal -0.19509035732984095 0.98078527337889565 0 + outer loop + vertex -3.4441509246826172 8.314915657043457 -25.161935806274414 + vertex 5.5109107042843573e-16 9 24.989583969116211 + vertex 5.5109107042843573e-16 9 -24.989583969116211 + endloop + endfacet + facet normal 0.19509025846227221 -0.98078529304487627 0 + outer loop + vertex 4.2862638516991895e-16 7 24.989583969116211 + vertex -2.6787841320037842 6.4671568870544434 -25.123636245727539 + vertex 4.2862638516991895e-16 7 -24.989583969116211 + endloop + endfacet + facet normal 0.049979010598128128 3.1317369474917703e-07 -0.9987502683351499 + outer loop + vertex -2.6787841320037842 6.4671568870544434 -25.123636245727539 + vertex -6.3639612197875977 6.3639612197875977 -25.308048248291016 + vertex -3.4441509246826172 8.314915657043457 -25.161935806274414 + endloop + endfacet + facet normal 0.049979034871687859 -5.5582004134037765e-07 0.99875026712035753 + outer loop + vertex -2.6787841320037842 6.4671568870544434 25.123636245727539 + vertex -6.3639612197875977 6.3639612197875977 25.308048248291016 + vertex -4.9497475624084473 4.9497475624084473 25.237277984619141 + endloop + endfacet + facet normal -0.55557014861846421 0.83146966869757644 0 + outer loop + vertex -6.3639612197875977 6.3639612197875977 -25.308048248291016 + vertex -3.4441509246826172 8.314915657043457 25.161935806274414 + vertex -3.4441509246826172 8.314915657043457 -25.161935806274414 + endloop + endfacet + facet normal 0.55557025148574279 -0.83146959996386427 0 + outer loop + vertex -2.6787841320037842 6.4671568870544434 25.123636245727539 + vertex -4.9497475624084473 4.9497475624084473 -25.237277984619141 + vertex -2.6787841320037842 6.4671568870544434 -25.123636245727539 + endloop + endfacet + facet normal 0.049979342565966589 -2.4735524245280037e-07 -0.9987502517229282 + outer loop + vertex -6.4671568870544434 2.6787841320037842 -25.313211441040039 + vertex -6.3639612197875977 6.3639612197875977 -25.308048248291016 + vertex -4.9497475624084473 4.9497475624084473 -25.237277984619141 + endloop + endfacet + facet normal 0.049979342565966589 -2.4735524245280037e-07 0.9987502517229282 + outer loop + vertex -6.3639612197875977 6.3639612197875977 25.308048248291016 + vertex -6.4671568870544434 2.6787841320037842 25.313211441040039 + vertex -4.9497475624084473 4.9497475624084473 25.237277984619141 + endloop + endfacet + facet normal -0.83146966869757655 0.55557014861846432 0 + outer loop + vertex -8.314915657043457 3.4441509246826172 -25.405677795410156 + vertex -6.3639612197875977 6.3639612197875977 25.308048248291016 + vertex -6.3639612197875977 6.3639612197875977 -25.308048248291016 + endloop + endfacet + facet normal 0.83146959996386427 -0.55557025148574279 0 + outer loop + vertex -4.9497475624084473 4.9497475624084473 25.237277984619141 + vertex -6.4671568870544434 2.6787841320037842 -25.313211441040039 + vertex -4.9497475624084473 4.9497475624084473 -25.237277984619141 + endloop + endfacet + facet normal 0.04997982937480043 -1.6253729404357035e-07 -0.99875022736199637 + outer loop + vertex -6.4671568870544434 2.6787841320037842 -25.313211441040039 + vertex -9 1.1021821408568715e-15 -25.439960479736328 + vertex -8.314915657043457 3.4441509246826172 -25.405677795410156 + endloop + endfacet + facet normal 0.049979611637226792 4.3853424993623902e-08 0.9987502382580894 + outer loop + vertex -6.4671568870544434 2.6787841320037842 25.313211441040039 + vertex -9 1.1021821408568715e-15 25.439960479736328 + vertex -7 8.572527703398379e-16 25.339876174926758 + endloop + endfacet + facet normal -0.98078527337889543 0.19509035732984104 0 + outer loop + vertex -9 1.1021821408568715e-15 -25.439960479736328 + vertex -8.314915657043457 3.4441509246826172 25.405677795410156 + vertex -8.314915657043457 3.4441509246826172 -25.405677795410156 + endloop + endfacet + facet normal 0.98078529304487627 -0.19509025846227232 0 + outer loop + vertex -6.4671568870544434 2.6787841320037842 25.313211441040039 + vertex -7 8.572527703398379e-16 -25.339876174926758 + vertex -6.4671568870544434 2.6787841320037842 -25.313211441040039 + endloop + endfacet + facet normal 0.049979611637226494 1.1911813118906345e-07 -0.99875023825808329 + outer loop + vertex -7 8.572527703398379e-16 -25.339876174926758 + vertex -8.314915657043457 -3.4441509246826172 -25.405677795410156 + vertex -9 1.1021821408568715e-15 -25.439960479736328 + endloop + endfacet + facet normal 0.049979891585538207 1.1971186246587229e-08 0.99875022424883475 + outer loop + vertex -7 8.572527703398379e-16 25.339876174926758 + vertex -8.314915657043457 -3.4441509246826172 25.405677795410156 + vertex -6.4671568870544434 -2.6787841320037842 25.313211441040039 + endloop + endfacet + facet normal -0.98078527337889554 -0.19509035732984092 -0 + outer loop + vertex -8.314915657043457 -3.4441509246826172 -25.405677795410156 + vertex -9 1.1021821408568715e-15 25.439960479736328 + vertex -9 1.1021821408568715e-15 -25.439960479736328 + endloop + endfacet + facet normal 0.98078529304487627 0.19509025846227215 0 + outer loop + vertex -7 8.572527703398379e-16 25.339876174926758 + vertex -6.4671568870544434 -2.6787841320037842 -25.313211441040039 + vertex -7 8.572527703398379e-16 -25.339876174926758 + endloop + endfacet + facet normal 0.049979789149807906 2.5989219886582566e-07 -0.99875022937492886 + outer loop + vertex -6.4671568870544434 -2.6787841320037842 -25.313211441040039 + vertex -6.3639612197875977 -6.3639612197875977 -25.308048248291016 + vertex -8.314915657043457 -3.4441509246826172 -25.405677795410156 + endloop + endfacet + facet normal 0.049979342565966589 2.4735524245280037e-07 0.9987502517229282 + outer loop + vertex -6.4671568870544434 -2.6787841320037842 25.313211441040039 + vertex -6.3639612197875977 -6.3639612197875977 25.308048248291016 + vertex -4.9497475624084473 -4.9497475624084473 25.237277984619141 + endloop + endfacet + facet normal -0.83146966869757633 -0.55557014861846421 -0 + outer loop + vertex -6.3639612197875977 -6.3639612197875977 -25.308048248291016 + vertex -8.314915657043457 -3.4441509246826172 25.405677795410156 + vertex -8.314915657043457 -3.4441509246826172 -25.405677795410156 + endloop + endfacet + facet normal 0.83146959996386427 0.55557025148574279 0 + outer loop + vertex -6.4671568870544434 -2.6787841320037842 25.313211441040039 + vertex -4.9497475624084473 -4.9497475624084473 -25.237277984619141 + vertex -6.4671568870544434 -2.6787841320037842 -25.313211441040039 + endloop + endfacet + facet normal 0.049979034871687859 5.5582004134037765e-07 -0.99875026712035753 + outer loop + vertex -2.6787841320037842 -6.4671568870544434 -25.123636245727539 + vertex -6.3639612197875977 -6.3639612197875977 -25.308048248291016 + vertex -4.9497475624084473 -4.9497475624084473 -25.237277984619141 + endloop + endfacet + facet normal 0.049979034871687859 5.5582004134037765e-07 0.99875026712035753 + outer loop + vertex -6.3639612197875977 -6.3639612197875977 25.308048248291016 + vertex -2.6787841320037842 -6.4671568870544434 25.123636245727539 + vertex -4.9497475624084473 -4.9497475624084473 25.237277984619141 + endloop + endfacet + facet normal -0.55557014861846432 -0.83146966869757655 -0 + outer loop + vertex -3.4441509246826172 -8.314915657043457 -25.161935806274414 + vertex -6.3639612197875977 -6.3639612197875977 25.308048248291016 + vertex -6.3639612197875977 -6.3639612197875977 -25.308048248291016 + endloop + endfacet + facet normal 0.55557025148574279 0.83146959996386427 0 + outer loop + vertex -4.9497475624084473 -4.9497475624084473 25.237277984619141 + vertex -2.6787841320037842 -6.4671568870544434 -25.123636245727539 + vertex -4.9497475624084473 -4.9497475624084473 -25.237277984619141 + endloop + endfacet + facet normal 0.04997927108141903 -4.213395989069661e-07 -0.99875025530008876 + outer loop + vertex -2.6787841320037842 -6.4671568870544434 -25.123636245727539 + vertex -1.6532732112853072e-15 -9 -24.989583969116211 + vertex -3.4441509246826172 -8.314915657043457 -25.161935806274414 + endloop + endfacet + facet normal 0.049979668471157368 -9.1811172144433574e-18 0.99875023541399643 + outer loop + vertex -2.6787841320037842 -6.4671568870544434 25.123636245727539 + vertex -1.6532732112853072e-15 -9 24.989583969116211 + vertex -1.2858791290399772e-15 -7 24.989583969116211 + endloop + endfacet + facet normal -0.19509035732984109 -0.98078527337889554 -0 + outer loop + vertex -1.6532732112853072e-15 -9 -24.989583969116211 + vertex -3.4441509246826172 -8.314915657043457 25.161935806274414 + vertex -3.4441509246826172 -8.314915657043457 -25.161935806274414 + endloop + endfacet + facet normal 0.19509025846227232 0.98078529304487627 0 + outer loop + vertex -2.6787841320037842 -6.4671568870544434 25.123636245727539 + vertex -1.2858791290399772e-15 -7 -24.989583969116211 + vertex -2.6787841320037842 -6.4671568870544434 -25.123636245727539 + endloop + endfacet + facet normal 0.049978802961868254 -1.6097371740382619e-17 -0.9987502787256175 + outer loop + vertex -1.2858791290399772e-15 -7 -24.989583969116211 + vertex 3.4441509246826172 -8.314915657043457 -24.817234039306641 + vertex -1.6532732112853072e-15 -9 -24.989583969116211 + endloop + endfacet + facet normal 0.049978905627349079 2.6958449152136063e-07 0.99875027358805757 + outer loop + vertex -1.2858791290399772e-15 -7 24.989583969116211 + vertex 3.4441509246826172 -8.314915657043457 24.817234039306641 + vertex 2.6787841320037842 -6.4671568870544434 24.855533599853516 + endloop + endfacet + facet normal 0.1950903573298409 -0.98078527337889565 0 + outer loop + vertex 3.4441509246826172 -8.314915657043457 -24.817234039306641 + vertex -1.6532732112853072e-15 -9 24.989583969116211 + vertex -1.6532732112853072e-15 -9 -24.989583969116211 + endloop + endfacet + facet normal -0.19509025846227218 0.98078529304487627 0 + outer loop + vertex -1.2858791290399772e-15 -7 24.989583969116211 + vertex 2.6787841320037842 -6.4671568870544434 -24.855533599853516 + vertex -1.2858791290399772e-15 -7 -24.989583969116211 + endloop + endfacet + facet normal 0.049979231328113952 4.048320056528683e-07 -0.99875025728942224 + outer loop + vertex 4.9497475624084473 -4.9497475624084473 -24.741889953613281 + vertex 3.4441509246826172 -8.314915657043457 -24.817234039306641 + vertex 2.6787841320037842 -6.4671568870544434 -24.855533599853516 + endloop + endfacet + facet normal 0.049979231328113952 4.048320056528683e-07 0.99875025728942224 + outer loop + vertex 3.4441509246826172 -8.314915657043457 24.817234039306641 + vertex 4.9497475624084473 -4.9497475624084473 24.741889953613281 + vertex 2.6787841320037842 -6.4671568870544434 24.855533599853516 + endloop + endfacet + facet normal 0.55557014861846421 -0.83146966869757633 0 + outer loop + vertex 6.3639612197875977 -6.3639612197875977 -24.671121597290039 + vertex 3.4441509246826172 -8.314915657043457 24.817234039306641 + vertex 3.4441509246826172 -8.314915657043457 -24.817234039306641 + endloop + endfacet + facet normal -0.55557025148574279 0.83146959996386427 0 + outer loop + vertex 2.6787841320037842 -6.4671568870544434 24.855533599853516 + vertex 4.9497475624084473 -4.9497475624084473 -24.741889953613281 + vertex 2.6787841320037842 -6.4671568870544434 -24.855533599853516 + endloop + endfacet + facet normal 0.049978537107365488 2.9218272378077363e-07 -0.99875029202925503 + outer loop + vertex 6.4671568870544434 -2.6787841320037842 -24.665956497192383 + vertex 6.3639612197875977 -6.3639612197875977 -24.671121597290039 + vertex 4.9497475624084473 -4.9497475624084473 -24.741889953613281 + endloop + endfacet + facet normal 0.049978537107365488 2.9218272378077363e-07 0.99875029202925503 + outer loop + vertex 6.3639612197875977 -6.3639612197875977 24.671121597290039 + vertex 6.4671568870544434 -2.6787841320037842 24.665956497192383 + vertex 4.9497475624084473 -4.9497475624084473 24.741889953613281 + endloop + endfacet + facet normal 0.83146966869757644 -0.55557014861846432 0 + outer loop + vertex 8.314915657043457 -3.4441509246826172 -24.573492050170898 + vertex 6.3639612197875977 -6.3639612197875977 24.671121597290039 + vertex 6.3639612197875977 -6.3639612197875977 -24.671121597290039 + endloop + endfacet + facet normal -0.83146959996386427 0.55557025148574279 0 + outer loop + vertex 4.9497475624084473 -4.9497475624084473 24.741889953613281 + vertex 6.4671568870544434 -2.6787841320037842 -24.665956497192383 + vertex 4.9497475624084473 -4.9497475624084473 -24.741889953613281 + endloop + endfacet + facet normal 0.049978879271444815 2.692330657772008e-08 -0.99875027490698076 + outer loop + vertex 6.4671568870544434 -2.6787841320037842 -24.665956497192383 + vertex 9 0 -24.539209365844727 + vertex 8.314915657043457 -3.4441509246826172 -24.573492050170898 + endloop + endfacet + facet normal 0.049978661533971465 2.333139111010282e-07 0.99875028580282177 + outer loop + vertex 6.4671568870544434 -2.6787841320037842 24.665956497192383 + vertex 9 0 24.539209365844727 + vertex 7 0 24.639291763305664 + endloop + endfacet + facet normal 0.98078527337889554 -0.19509035732984098 0 + outer loop + vertex 9 0 -24.539209365844727 + vertex 8.314915657043457 -3.4441509246826172 24.573492050170898 + vertex 8.314915657043457 -3.4441509246826172 -24.573492050170898 + endloop + endfacet + facet normal -0.98078529304487616 0.19509025846227224 0 + outer loop + vertex 6.4671568870544434 -2.6787841320037842 24.665956497192383 + vertex 7 0 -24.639291763305664 + vertex 6.4671568870544434 -2.6787841320037842 -24.665956497192383 + endloop + endfacet + facet normal 0.049978879271444815 -2.692330657772008e-08 -0.99875027490698076 + outer loop + vertex 9 0 -24.539209365844727 + vertex 6.4671568870544434 2.6787841320037842 -24.665956497192383 + vertex 8.314915657043457 3.4441509246826172 -24.573492050170898 + endloop + endfacet + facet normal 0.049978879271444815 -2.692330657772008e-08 0.99875027490698076 + outer loop + vertex 6.4671568870544434 2.6787841320037842 24.665956497192383 + vertex 9 0 24.539209365844727 + vertex 8.314915657043457 3.4441509246826172 24.573492050170898 + endloop + endfacet + facet normal 0.98078527337889554 0.19509035732984098 -0 + outer loop + vertex 9 0 24.539209365844727 + vertex 8.314915657043457 3.4441509246826172 -24.573492050170898 + vertex 8.314915657043457 3.4441509246826172 24.573492050170898 + endloop + endfacet + facet normal -0.98078529304487616 -0.19509025846227224 0 + outer loop + vertex 6.4671568870544434 2.6787841320037842 -24.665956497192383 + vertex 7 0 24.639291763305664 + vertex 6.4671568870544434 2.6787841320037842 24.665956497192383 + endloop + endfacet + facet normal 0.049978537107365488 -2.9218272378077363e-07 -0.99875029202925503 + outer loop + vertex 6.3639612197875977 6.3639612197875977 -24.671121597290039 + vertex 6.4671568870544434 2.6787841320037842 -24.665956497192383 + vertex 4.9497475624084473 4.9497475624084473 -24.741889953613281 + endloop + endfacet + facet normal 0.049978983691036066 -2.7964576111001245e-07 0.99875026968163216 + outer loop + vertex 6.3639612197875977 6.3639612197875977 24.671121597290039 + vertex 6.4671568870544434 2.6787841320037842 24.665956497192383 + vertex 8.314915657043457 3.4441509246826172 24.573492050170898 + endloop + endfacet + facet normal 0.83146966869757644 0.55557014861846432 -0 + outer loop + vertex 8.314915657043457 3.4441509246826172 24.573492050170898 + vertex 6.3639612197875977 6.3639612197875977 -24.671121597290039 + vertex 6.3639612197875977 6.3639612197875977 24.671121597290039 + endloop + endfacet + facet normal -0.83146959996386427 -0.55557025148574279 0 + outer loop + vertex 4.9497475624084473 4.9497475624084473 -24.741889953613281 + vertex 6.4671568870544434 2.6787841320037842 24.665956497192383 + vertex 4.9497475624084473 4.9497475624084473 24.741889953613281 + endloop + endfacet + facet normal 0.049979010598128128 -3.1317369474917703e-07 -0.9987502683351499 + outer loop + vertex 6.3639612197875977 6.3639612197875977 -24.671121597290039 + vertex 2.6787841320037842 6.4671568870544434 -24.855533599853516 + vertex 3.4441509246826172 8.314915657043457 -24.817234039306641 + endloop + endfacet + facet normal 0.049979010598128128 -3.1317369474917703e-07 0.9987502683351499 + outer loop + vertex 2.6787841320037842 6.4671568870544434 24.855533599853516 + vertex 6.3639612197875977 6.3639612197875977 24.671121597290039 + vertex 3.4441509246826172 8.314915657043457 24.817234039306641 + endloop + endfacet + facet normal 0.55557014861846421 0.83146966869757633 -0 + outer loop + vertex 6.3639612197875977 6.3639612197875977 24.671121597290039 + vertex 3.4441509246826172 8.314915657043457 -24.817234039306641 + vertex 3.4441509246826172 8.314915657043457 24.817234039306641 + endloop + endfacet + facet normal -0.55557025148574279 -0.83146959996386427 0 + outer loop + vertex 2.6787841320037842 6.4671568870544434 -24.855533599853516 + vertex 4.9497475624084473 4.9497475624084473 24.741889953613281 + vertex 2.6787841320037842 6.4671568870544434 24.855533599853516 + endloop + endfacet + facet normal 0.049978959117075887 0 -0.99875027091138935 + outer loop + vertex 5.5109107042843573e-16 9 -24.989583969116211 + vertex 2.6787841320037842 6.4671568870544434 -24.855533599853516 + vertex 4.2862638516991895e-16 7 -24.989583969116211 + endloop + endfacet + facet normal 0.049978761358725352 -2.0967682607655456e-07 0.99875028080747175 + outer loop + vertex 5.5109107042843573e-16 9 24.989583969116211 + vertex 2.6787841320037842 6.4671568870544434 24.855533599853516 + vertex 3.4441509246826172 8.314915657043457 24.817234039306641 + endloop + endfacet + facet normal 0.19509035732984104 0.98078527337889565 -0 + outer loop + vertex 3.4441509246826172 8.314915657043457 24.817234039306641 + vertex 5.5109107042843573e-16 9 -24.989583969116211 + vertex 5.5109107042843573e-16 9 24.989583969116211 + endloop + endfacet + facet normal -0.19509025846227229 -0.98078529304487627 0 + outer loop + vertex 4.2862638516991895e-16 7 -24.989583969116211 + vertex 2.6787841320037842 6.4671568870544434 24.855533599853516 + vertex 4.2862638516991895e-16 7 24.989583969116211 + endloop + endfacet + facet normal 0.049979271081418988 4.2133959888885622e-07 -0.99875025530008865 + outer loop + vertex 5.5109107042843573e-16 9 -24.989583969116211 + vertex -2.6787841320037842 6.4671568870544434 -25.123636245727539 + vertex -3.4441509246826172 8.314915657043457 -25.161935806274414 + endloop + endfacet + facet normal 0.049979271081418988 4.213395988908684e-07 0.99875025530008876 + outer loop + vertex -2.6787841320037842 6.4671568870544434 25.123636245727539 + vertex 5.5109107042843573e-16 9 24.989583969116211 + vertex -3.4441509246826172 8.314915657043457 25.161935806274414 + endloop + endfacet + facet normal -0.19509035732984095 0.98078527337889554 0 + outer loop + vertex 5.5109107042843573e-16 9 24.989583969116211 + vertex -3.4441509246826172 8.314915657043457 -25.161935806274414 + vertex -3.4441509246826172 8.314915657043457 25.161935806274414 + endloop + endfacet + facet normal 0.19509025846227221 -0.98078529304487627 0 + outer loop + vertex -2.6787841320037842 6.4671568870544434 -25.123636245727539 + vertex 4.2862638516991895e-16 7 24.989583969116211 + vertex -2.6787841320037842 6.4671568870544434 25.123636245727539 + endloop + endfacet + facet normal 0.049979034871687859 -5.5582004134037765e-07 -0.99875026712035753 + outer loop + vertex -6.3639612197875977 6.3639612197875977 -25.308048248291016 + vertex -2.6787841320037842 6.4671568870544434 -25.123636245727539 + vertex -4.9497475624084473 4.9497475624084473 -25.237277984619141 + endloop + endfacet + facet normal 0.049979010598128128 3.1317369474917703e-07 0.9987502683351499 + outer loop + vertex -6.3639612197875977 6.3639612197875977 25.308048248291016 + vertex -2.6787841320037842 6.4671568870544434 25.123636245727539 + vertex -3.4441509246826172 8.314915657043457 25.161935806274414 + endloop + endfacet + facet normal -0.55557014861846432 0.83146966869757655 0 + outer loop + vertex -3.4441509246826172 8.314915657043457 25.161935806274414 + vertex -6.3639612197875977 6.3639612197875977 -25.308048248291016 + vertex -6.3639612197875977 6.3639612197875977 25.308048248291016 + endloop + endfacet + facet normal 0.55557025148574279 -0.83146959996386427 0 + outer loop + vertex -4.9497475624084473 4.9497475624084473 -25.237277984619141 + vertex -2.6787841320037842 6.4671568870544434 25.123636245727539 + vertex -4.9497475624084473 4.9497475624084473 25.237277984619141 + endloop + endfacet + facet normal 0.049979789149807906 -2.5989219886582566e-07 -0.99875022937492886 + outer loop + vertex -6.3639612197875977 6.3639612197875977 -25.308048248291016 + vertex -6.4671568870544434 2.6787841320037842 -25.313211441040039 + vertex -8.314915657043457 3.4441509246826172 -25.405677795410156 + endloop + endfacet + facet normal 0.049979789149807906 -2.5989219886582566e-07 0.99875022937492886 + outer loop + vertex -6.4671568870544434 2.6787841320037842 25.313211441040039 + vertex -6.3639612197875977 6.3639612197875977 25.308048248291016 + vertex -8.314915657043457 3.4441509246826172 25.405677795410156 + endloop + endfacet + facet normal -0.83146966869757633 0.55557014861846421 0 + outer loop + vertex -6.3639612197875977 6.3639612197875977 25.308048248291016 + vertex -8.314915657043457 3.4441509246826172 -25.405677795410156 + vertex -8.314915657043457 3.4441509246826172 25.405677795410156 + endloop + endfacet + facet normal 0.83146959996386427 -0.55557025148574279 0 + outer loop + vertex -6.4671568870544434 2.6787841320037842 -25.313211441040039 + vertex -4.9497475624084473 4.9497475624084473 25.237277984619141 + vertex -6.4671568870544434 2.6787841320037842 25.313211441040039 + endloop + endfacet + facet normal 0.049979611637226778 4.3853424993623902e-08 -0.99875023825808917 + outer loop + vertex -9 1.1021821408568715e-15 -25.439960479736328 + vertex -6.4671568870544434 2.6787841320037842 -25.313211441040039 + vertex -7 8.572527703398379e-16 -25.339876174926758 + endloop + endfacet + facet normal 0.049979829374800437 -1.6253729404357037e-07 0.99875022736199637 + outer loop + vertex -9 1.1021821408568715e-15 25.439960479736328 + vertex -6.4671568870544434 2.6787841320037842 25.313211441040039 + vertex -8.314915657043457 3.4441509246826172 25.405677795410156 + endloop + endfacet + facet normal -0.98078527337889554 0.19509035732984106 0 + outer loop + vertex -8.314915657043457 3.4441509246826172 25.405677795410156 + vertex -9 1.1021821408568715e-15 -25.439960479736328 + vertex -9 1.1021821408568715e-15 25.439960479736328 + endloop + endfacet + facet normal 0.98078529304487627 -0.19509025846227232 0 + outer loop + vertex -7 8.572527703398379e-16 -25.339876174926758 + vertex -6.4671568870544434 2.6787841320037842 25.313211441040039 + vertex -7 8.572527703398379e-16 25.339876174926758 + endloop + endfacet + facet normal 0.049979891585538214 1.1971186246587229e-08 -0.99875022424883475 + outer loop + vertex -8.314915657043457 -3.4441509246826172 -25.405677795410156 + vertex -7 8.572527703398379e-16 -25.339876174926758 + vertex -6.4671568870544434 -2.6787841320037842 -25.313211441040039 + endloop + endfacet + facet normal 0.049979611637226494 1.1911813118906345e-07 0.99875023825808329 + outer loop + vertex -8.314915657043457 -3.4441509246826172 25.405677795410156 + vertex -7 8.572527703398379e-16 25.339876174926758 + vertex -9 1.1021821408568715e-15 25.439960479736328 + endloop + endfacet + facet normal -0.98078527337889565 -0.19509035732984095 0 + outer loop + vertex -9 1.1021821408568715e-15 25.439960479736328 + vertex -8.314915657043457 -3.4441509246826172 -25.405677795410156 + vertex -8.314915657043457 -3.4441509246826172 25.405677795410156 + endloop + endfacet + facet normal 0.98078529304487627 0.19509025846227215 0 + outer loop + vertex -6.4671568870544434 -2.6787841320037842 -25.313211441040039 + vertex -7 8.572527703398379e-16 25.339876174926758 + vertex -6.4671568870544434 -2.6787841320037842 25.313211441040039 + endloop + endfacet + facet normal 0.049979342565966589 2.4735524245280037e-07 -0.9987502517229282 + outer loop + vertex -6.3639612197875977 -6.3639612197875977 -25.308048248291016 + vertex -6.4671568870544434 -2.6787841320037842 -25.313211441040039 + vertex -4.9497475624084473 -4.9497475624084473 -25.237277984619141 + endloop + endfacet + facet normal 0.049979789149807906 2.5989219886582566e-07 0.99875022937492886 + outer loop + vertex -6.3639612197875977 -6.3639612197875977 25.308048248291016 + vertex -6.4671568870544434 -2.6787841320037842 25.313211441040039 + vertex -8.314915657043457 -3.4441509246826172 25.405677795410156 + endloop + endfacet + facet normal -0.83146966869757655 -0.55557014861846432 0 + outer loop + vertex -8.314915657043457 -3.4441509246826172 25.405677795410156 + vertex -6.3639612197875977 -6.3639612197875977 -25.308048248291016 + vertex -6.3639612197875977 -6.3639612197875977 25.308048248291016 + endloop + endfacet + facet normal 0.83146959996386427 0.55557025148574279 0 + outer loop + vertex -4.9497475624084473 -4.9497475624084473 -25.237277984619141 + vertex -6.4671568870544434 -2.6787841320037842 25.313211441040039 + vertex -4.9497475624084473 -4.9497475624084473 25.237277984619141 + endloop + endfacet + facet normal 0.049979010598128128 -3.1317369474917703e-07 -0.9987502683351499 + outer loop + vertex -6.3639612197875977 -6.3639612197875977 -25.308048248291016 + vertex -2.6787841320037842 -6.4671568870544434 -25.123636245727539 + vertex -3.4441509246826172 -8.314915657043457 -25.161935806274414 + endloop + endfacet + facet normal 0.049979010598128128 -3.1317369474917703e-07 0.9987502683351499 + outer loop + vertex -2.6787841320037842 -6.4671568870544434 25.123636245727539 + vertex -6.3639612197875977 -6.3639612197875977 25.308048248291016 + vertex -3.4441509246826172 -8.314915657043457 25.161935806274414 + endloop + endfacet + facet normal -0.55557014861846421 -0.83146966869757644 0 + outer loop + vertex -6.3639612197875977 -6.3639612197875977 25.308048248291016 + vertex -3.4441509246826172 -8.314915657043457 -25.161935806274414 + vertex -3.4441509246826172 -8.314915657043457 25.161935806274414 + endloop + endfacet + facet normal 0.55557025148574279 0.83146959996386427 0 + outer loop + vertex -2.6787841320037842 -6.4671568870544434 -25.123636245727539 + vertex -4.9497475624084473 -4.9497475624084473 25.237277984619141 + vertex -2.6787841320037842 -6.4671568870544434 25.123636245727539 + endloop + endfacet + facet normal 0.049979668471157368 -1.034830964876016e-17 -0.99875023541399643 + outer loop + vertex -1.6532732112853072e-15 -9 -24.989583969116211 + vertex -2.6787841320037842 -6.4671568870544434 -25.123636245727539 + vertex -1.2858791290399772e-15 -7 -24.989583969116211 + endloop + endfacet + facet normal 0.049979271081419023 -4.2133959890092956e-07 0.99875025530008876 + outer loop + vertex -1.6532732112853072e-15 -9 24.989583969116211 + vertex -2.6787841320037842 -6.4671568870544434 25.123636245727539 + vertex -3.4441509246826172 -8.314915657043457 25.161935806274414 + endloop + endfacet + facet normal -0.19509035732984109 -0.98078527337889565 0 + outer loop + vertex -3.4441509246826172 -8.314915657043457 25.161935806274414 + vertex -1.6532732112853072e-15 -9 -24.989583969116211 + vertex -1.6532732112853072e-15 -9 24.989583969116211 + endloop + endfacet + facet normal 0.19509025846227235 0.98078529304487627 0 + outer loop + vertex -1.2858791290399772e-15 -7 -24.989583969116211 + vertex -2.6787841320037842 -6.4671568870544434 25.123636245727539 + vertex -1.2858791290399772e-15 -7 24.989583969116211 + endloop + endfacet + facet normal 0.049978905627349079 2.6958449152136063e-07 -0.99875027358805757 + outer loop + vertex 3.4441509246826172 -8.314915657043457 -24.817234039306641 + vertex -1.2858791290399772e-15 -7 -24.989583969116211 + vertex 2.6787841320037842 -6.4671568870544434 -24.855533599853516 + endloop + endfacet + facet normal 0.049978802961868254 -9.1809582229478825e-18 0.9987502787256175 + outer loop + vertex 3.4441509246826172 -8.314915657043457 24.817234039306641 + vertex -1.2858791290399772e-15 -7 24.989583969116211 + vertex -1.6532732112853072e-15 -9 24.989583969116211 + endloop + endfacet + facet normal 0.1950903573298409 -0.98078527337889565 0 + outer loop + vertex -1.6532732112853072e-15 -9 24.989583969116211 + vertex 3.4441509246826172 -8.314915657043457 -24.817234039306641 + vertex 3.4441509246826172 -8.314915657043457 24.817234039306641 + endloop + endfacet + facet normal -0.19509025846227215 0.98078529304487627 0 + outer loop + vertex 2.6787841320037842 -6.4671568870544434 -24.855533599853516 + vertex -1.2858791290399772e-15 -7 24.989583969116211 + vertex 2.6787841320037842 -6.4671568870544434 24.855533599853516 + endloop + endfacet + facet normal 0.049978829331157527 5.8513828036852865e-07 -0.99875027740589117 + outer loop + vertex 3.4441509246826172 -8.314915657043457 -24.817234039306641 + vertex 4.9497475624084473 -4.9497475624084473 -24.741889953613281 + vertex 6.3639612197875977 -6.3639612197875977 -24.671121597290039 + endloop + endfacet + facet normal 0.049978829331157527 5.8513828036852865e-07 0.99875027740589117 + outer loop + vertex 4.9497475624084473 -4.9497475624084473 24.741889953613281 + vertex 3.4441509246826172 -8.314915657043457 24.817234039306641 + vertex 6.3639612197875977 -6.3639612197875977 24.671121597290039 + endloop + endfacet + facet normal 0.55557014861846432 -0.83146966869757644 0 + outer loop + vertex 3.4441509246826172 -8.314915657043457 24.817234039306641 + vertex 6.3639612197875977 -6.3639612197875977 -24.671121597290039 + vertex 6.3639612197875977 -6.3639612197875977 24.671121597290039 + endloop + endfacet + facet normal -0.55557025148574279 0.83146959996386427 0 + outer loop + vertex 4.9497475624084473 -4.9497475624084473 -24.741889953613281 + vertex 2.6787841320037842 -6.4671568870544434 24.855533599853516 + vertex 4.9497475624084473 -4.9497475624084473 24.741889953613281 + endloop + endfacet + facet normal 0.049978983691036066 2.7964576111001245e-07 -0.99875026968163216 + outer loop + vertex 6.3639612197875977 -6.3639612197875977 -24.671121597290039 + vertex 6.4671568870544434 -2.6787841320037842 -24.665956497192383 + vertex 8.314915657043457 -3.4441509246826172 -24.573492050170898 + endloop + endfacet + facet normal 0.049978983691036066 2.7964576111001245e-07 0.99875026968163216 + outer loop + vertex 6.4671568870544434 -2.6787841320037842 24.665956497192383 + vertex 6.3639612197875977 -6.3639612197875977 24.671121597290039 + vertex 8.314915657043457 -3.4441509246826172 24.573492050170898 + endloop + endfacet + facet normal 0.83146966869757644 -0.55557014861846432 0 + outer loop + vertex 6.3639612197875977 -6.3639612197875977 24.671121597290039 + vertex 8.314915657043457 -3.4441509246826172 -24.573492050170898 + vertex 8.314915657043457 -3.4441509246826172 24.573492050170898 + endloop + endfacet + facet normal -0.83146959996386427 0.55557025148574279 0 + outer loop + vertex 6.4671568870544434 -2.6787841320037842 -24.665956497192383 + vertex 4.9497475624084473 -4.9497475624084473 24.741889953613281 + vertex 6.4671568870544434 -2.6787841320037842 24.665956497192383 + endloop + endfacet + facet normal 0.049978661533971465 2.333139111010282e-07 -0.99875028580282177 + outer loop + vertex 9 0 -24.539209365844727 + vertex 6.4671568870544434 -2.6787841320037842 -24.665956497192383 + vertex 7 0 -24.639291763305664 + endloop + endfacet + facet normal 0.049978879271444815 2.692330657772008e-08 0.99875027490698076 + outer loop + vertex 9 0 24.539209365844727 + vertex 6.4671568870544434 -2.6787841320037842 24.665956497192383 + vertex 8.314915657043457 -3.4441509246826172 24.573492050170898 + endloop + endfacet + facet normal 0.98078527337889565 -0.19509035732984101 0 + outer loop + vertex 8.314915657043457 -3.4441509246826172 24.573492050170898 + vertex 9 0 -24.539209365844727 + vertex 9 0 24.539209365844727 + endloop + endfacet + facet normal -0.98078529304487616 0.19509025846227224 0 + outer loop + vertex 7 0 -24.639291763305664 + vertex 6.4671568870544434 -2.6787841320037842 24.665956497192383 + vertex 7 0 24.639291763305664 + endloop + endfacet +endsolid diff --git a/tests/features/test_Feature.py b/tests/features/test_Feature.py new file mode 100644 index 000000000..36db40c88 --- /dev/null +++ b/tests/features/test_Feature.py @@ -0,0 +1,10 @@ +import T720_featureExtract +import T721_featureExtract_cutTubs + + +def test_PythonFeature_T720_featureExtract(testdata, tmptestdir): + T720_featureExtract.Test(testdata, tmptestdir, False, False) + + +def test_PythonFeature_T721_featureExtract_cutTubs(testdata, tmptestdir): + T721_featureExtract_cutTubs.Test(testdata, tmptestdir, False, False) diff --git a/tests/fluka/T001_RPP.py b/tests/fluka/T001_RPP.py new file mode 100644 index 000000000..39fc412a8 --- /dev/null +++ b/tests/fluka/T001_RPP.py @@ -0,0 +1,32 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + z = Zone() + z.addIntersection(rpp) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + greg.getWorldVolume().clipSolid() + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/fluka/T002_BOX.py b/tests/fluka/T002_BOX.py new file mode 100644 index 000000000..2e67319e2 --- /dev/null +++ b/tests/fluka/T002_BOX.py @@ -0,0 +1,34 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import BOX, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # box with corner at the origin and sides of length 20 extending + # along the axes + box = BOX( + "BOX_BODY", [0, 0, 0], [20, 0, 0], [0, 20, 0], [0, 0, 20], flukaregistry=freg + ) + z = Zone() + z.addIntersection(box) + region = Region("BOX_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T003_SPH.py b/tests/fluka/T003_SPH.py new file mode 100644 index 000000000..500a76d87 --- /dev/null +++ b/tests/fluka/T003_SPH.py @@ -0,0 +1,30 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import SPH, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + sph = SPH("SPH_BODY", [10, 10, 10], 10, flukaregistry=freg) + z = Zone() + z.addIntersection(sph) + region = Region("SPH_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T004_RCC.py b/tests/fluka/T004_RCC.py new file mode 100644 index 000000000..be6d3034a --- /dev/null +++ b/tests/fluka/T004_RCC.py @@ -0,0 +1,30 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RCC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rcc = RCC("RCC_BODY", [0, 0, 0], [5, 5, 5], 2.5, flukaregistry=freg) + z = Zone() + z.addIntersection(rcc) + region = Region("RCC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T005_REC.py b/tests/fluka/T005_REC.py new file mode 100644 index 000000000..674abc7b5 --- /dev/null +++ b/tests/fluka/T005_REC.py @@ -0,0 +1,43 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import REC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + face = [0, 0, 0] # one face is situated at (0, 0, 0). + direction = [3, 3, 3] # length pointing from above face in the + # i+j+k direction. + semiminor = [0.5, -1, 0.5] # one axis line intercepts the y-axis, length= ~1.22 + semiminor_length = np.linalg.norm(semiminor) + semimajor = np.cross(direction, semiminor) + semimajor = 2 * ( + semiminor_length * semimajor / np.linalg.norm(semimajor) + ) # Twice the length of semiminor + + rec = REC("REC_BODY", face, direction, semiminor, semimajor, flukaregistry=freg) + + z = Zone() + z.addIntersection(rec) + region = Region("REC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T006_TRC.py b/tests/fluka/T006_TRC.py new file mode 100644 index 000000000..8a63c2168 --- /dev/null +++ b/tests/fluka/T006_TRC.py @@ -0,0 +1,31 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import TRC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # big face (r=5) is at the origin, smaller face (r=2) is at [5, 5, 5]. + trc = TRC("TRC_BODY", [0, 0, 0], [5, 5, 5], 5, 2, flukaregistry=freg) + z = Zone() + z.addIntersection(trc) + region = Region("TRC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T007_ELL.py b/tests/fluka/T007_ELL.py new file mode 100644 index 000000000..7bf283890 --- /dev/null +++ b/tests/fluka/T007_ELL.py @@ -0,0 +1,37 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ELL, Region, Zone, FlukaRegistry, Three + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # ellipsoid with major axes poining in the y direction, total + # legnth=20, offset in x. + focus1 = Three([20, 5, 0]) + focus2 = Three([20, 15, 0]) + length = 20 + + ell = ELL("ELL_BODY", focus1, focus2, length, flukaregistry=freg) + + z = Zone() + z.addIntersection(ell) + region = Region("ELL_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T008_RAW.py b/tests/fluka/T008_RAW.py new file mode 100644 index 000000000..0287d6131 --- /dev/null +++ b/tests/fluka/T008_RAW.py @@ -0,0 +1,58 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RAW, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # What I expect to see in the visualiser is a cube formed by the + # union of two wedeges. with sides equal to 20cm. The mesh shows + # the two wedges. + + raw1 = RAW( + "RAW1_BODY", + [20, 20, 20], # vertex position + [-20, 0, 0], # one transverse side. + [0, 0, -20], # the other transverse side. + [0, -20, 0], # length vector. + flukaregistry=freg, + ) + + raw2 = RAW( + "RAW2_BODY", + [0, 0, 0], + [20, 0, 0], # one transverse side. + [0, 0, 20], # the other transverse side. + [0, 20, 0], # length vector. + flukaregistry=freg, + ) + + # better test please...? + + z1 = Zone() + z1.addIntersection(raw1) + + z2 = Zone() + z2.addIntersection(raw2) + + region = Region("RAW_REG") + region.addZone(z1) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T008_WED.py b/tests/fluka/T008_WED.py new file mode 100644 index 000000000..9fb55c540 --- /dev/null +++ b/tests/fluka/T008_WED.py @@ -0,0 +1,56 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import WED, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # What I expect to see in the visualiser is a cube formed by the + # union of two wedeges. with sides equal to 20cm. The mesh shows + # the two wedges. + + wed1 = WED( + "WED1_BODY", + [20, 20, 20], # vertex position + [-20, 0, 0], # one transverse side. + [0, 0, -20], # length vector. + [0, -20, 0], # the other transverse side. + flukaregistry=freg, + ) + + wed2 = WED( + "WED2_BODY", + [0, 0, 0], + [20, 0, 0], # one transverse side. + [0, 0, 20], # length vector. + [0, 20, 0], # the other transverse side. + flukaregistry=freg, + ) + + z1 = Zone() + z1.addIntersection(wed1) + + z2 = Zone() + z2.addIntersection(wed2) + + region = Region("WED_REG") + region.addZone(z1) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T009_ARB.py b/tests/fluka/T009_ARB.py new file mode 100644 index 000000000..1e80b2d34 --- /dev/null +++ b/tests/fluka/T009_ARB.py @@ -0,0 +1,68 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ARB, Region, Zone, FlukaRegistry, Three + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # In FLUKA we can choose: either all of the face numbers must + # refer to vertices in clockwise or anticlockwise direction. Here + # we ensure all are clockwise looking out from the centre of the + # tesselated solid. This is the right hand corkscrew rule. + + # Rear face: + vertex1 = Three([0.0, 0.0, 0.0]) # lower left corner + vertex2 = Three([20.0, 0.0, 0.0]) # lower right corner + vertex3 = Three([10.0, 20.0, 0.0]) # upper right corner + vertex4 = Three([0.0, 20.0, 0.0]) # Upper left corner + face1 = 4321 # clockwise in direction of normal + # face1 = 1234 # anticlockwise in direction of normal + + # Front face: + vertex5 = Three([0.0, 0.0, 20.0]) # lower left corner + vertex6 = Three([20.0, 0.0, 20.0]) # lower right corner + vertex7 = Three([10.0, 20.0, 20.0]) # upper right corner + vertex8 = Three([0.0, 20.0, 20.0]) # Upper left corner + + face2 = 5678 # clockwise in direction of normal + # face2 = 8765 # anticlockwise in direction of normal + + face3 = 2376 # right face + face4 = 1584 # left face + face5 = 3487 # top face + face6 = 1265 # bottom face + + # anticlockwise in direction of noraml + # face3 = 6732 # right face + # face4 = 4851 # left face + # face5 = 7843 # top face + # face6 = 5621 # bottom face + + vertices = [vertex1, vertex2, vertex3, vertex4, vertex5, vertex6, vertex7, vertex8] + facenumbers = [face1, face2, face3, face4, face5, face6] + + arb = ARB("ARB_BODY", vertices, facenumbers, flukaregistry=freg) + + z = Zone() + z.addIntersection(arb) + + region = Region("ARB_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T010_XYP.py b/tests/fluka/T010_XYP.py new file mode 100644 index 000000000..034c54513 --- /dev/null +++ b/tests/fluka/T010_XYP.py @@ -0,0 +1,34 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XYP, Region, Zone, FlukaRegistry, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + xyp = XYP("XYP_BODY", 20.0, flukaregistry=freg) + + z = Zone() + z.addIntersection(xyp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T010_XZP.py b/tests/fluka/T010_XZP.py new file mode 100644 index 000000000..6d2963b6a --- /dev/null +++ b/tests/fluka/T010_XZP.py @@ -0,0 +1,34 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XZP, Region, Zone, FlukaRegistry, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + xzp = XZP("XZP_BODY", 20.0, flukaregistry=freg) + + z = Zone() + z.addIntersection(xzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T010_YZP.py b/tests/fluka/T010_YZP.py new file mode 100644 index 000000000..134a34427 --- /dev/null +++ b/tests/fluka/T010_YZP.py @@ -0,0 +1,34 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YZP, Region, Zone, FlukaRegistry, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + yzp = YZP("YZP_BODY", 20.0, flukaregistry=freg) + + z = Zone() + z.addIntersection(yzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T011_PLA.py b/tests/fluka/T011_PLA.py new file mode 100644 index 000000000..aed434a51 --- /dev/null +++ b/tests/fluka/T011_PLA.py @@ -0,0 +1,34 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import PLA, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + pla1 = PLA("PLA1_BODY", [1, 1, 1], [0, 0.0, 0], flukaregistry=freg) + + z1 = Zone() + + z1.addIntersection(pla1) + + region = Region("REG_INF") + region.addZone(z1) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T012_XCC.py b/tests/fluka/T012_XCC.py new file mode 100644 index 000000000..8f8890942 --- /dev/null +++ b/tests/fluka/T012_XCC.py @@ -0,0 +1,41 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XCC, YZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + xcc = XCC("XCC_BODY", 0, 0, 20, flukaregistry=freg) + + yzp_hi = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xcc) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T012_YCC.py b/tests/fluka/T012_YCC.py new file mode 100644 index 000000000..7a01a56cc --- /dev/null +++ b/tests/fluka/T012_YCC.py @@ -0,0 +1,41 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YCC, XZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + ycc = YCC("YCC_BODY", 0, 0, 20, flukaregistry=freg) + + xzp_hi = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(ycc) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T012_ZCC.py b/tests/fluka/T012_ZCC.py new file mode 100644 index 000000000..a38f06ab6 --- /dev/null +++ b/tests/fluka/T012_ZCC.py @@ -0,0 +1,41 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZCC, XYP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + zcc = ZCC("ZCC_BODY", 0, 0, 20, flukaregistry=freg) + + xyp_hi = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zcc) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T013_XEC.py b/tests/fluka/T013_XEC.py new file mode 100644 index 000000000..74f4776a8 --- /dev/null +++ b/tests/fluka/T013_XEC.py @@ -0,0 +1,43 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XEC, YZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + # Bigger semi axis is y, smaller is z + xec = XEC("XEC_BODY", 0, 0, 20, 10, flukaregistry=freg) + + yzp_hi = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xec) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T013_YEC.py b/tests/fluka/T013_YEC.py new file mode 100644 index 000000000..617c8b976 --- /dev/null +++ b/tests/fluka/T013_YEC.py @@ -0,0 +1,43 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YEC, XZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + # Bigger semi axis is z, smaller is x + yec = YEC("YEC_BODY", 0, 0, 20, 10, flukaregistry=freg) + + xzp_hi = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(yec) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T013_ZEC.py b/tests/fluka/T013_ZEC.py new file mode 100644 index 000000000..1eda61393 --- /dev/null +++ b/tests/fluka/T013_ZEC.py @@ -0,0 +1,43 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZEC, XYP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + # Bigger semi axis is x, smaller is y + zec = ZEC("ZEC_BODY", 0, 0, 20, 10, flukaregistry=freg) + + xyp_hi = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zec) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T014_QUA.py b/tests/fluka/T014_QUA.py new file mode 100644 index 000000000..79eae1861 --- /dev/null +++ b/tests/fluka/T014_QUA.py @@ -0,0 +1,44 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import QUA, Region, Zone, FlukaRegistry, AABB, XYP, XZP + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + parabolicCylinder = QUA( + "parab", 0.006, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -200, flukaregistry=freg + ) + + # 1 metre long parabolic cylinder 10cm tall from base to tip. + end1 = XYP("end1", 1000, flukaregistry=freg) + end2 = XYP("end2", 0, flukaregistry=freg) + end3 = XZP("end3", 100, flukaregistry=freg) + + z = Zone() + z.addIntersection(parabolicCylinder) + z.addIntersection(end1) + z.addSubtraction(end2) + z.addSubtraction(end3) + + region = Region("QUA_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + quaAABB = {"QUA_REG": AABB([-150.0, 100.0, 0], [150.0, 200.0, 1000.0])} + + greg = convert.fluka2Geant4(freg, quadricRegionAABBs=quaAABB) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(origin=[0, 100, 0], length=100) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T051_expansion.py b/tests/fluka/T051_expansion.py new file mode 100644 index 000000000..3e2dda97f --- /dev/null +++ b/tests/fluka/T051_expansion.py @@ -0,0 +1,32 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + transform = Transform(expansion=2.0) + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, flukaregistry=freg, transform=transform) + z = Zone() + z.addIntersection(rpp) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T052_translation.py b/tests/fluka/T052_translation.py new file mode 100644 index 000000000..c404ac903 --- /dev/null +++ b/tests/fluka/T052_translation.py @@ -0,0 +1,40 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp = RPP( + "RPP_BODY", + 10, + 20, + 10, + 20, + 10, + 20, + flukaregistry=freg, + transform=Transform(translation=[-10, -10, -10]), + ) + z = Zone() + z.addIntersection(rpp) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T090_lattice.py b/tests/fluka/T090_lattice.py new file mode 100644 index 000000000..eccd188ff --- /dev/null +++ b/tests/fluka/T090_lattice.py @@ -0,0 +1,88 @@ +import os.path + +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ( + RCC, + Region, + Zone, + FlukaRegistry, + RotoTranslation, + RecursiveRotoTranslation, + Transform, + Lattice, +) +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 +from pyg4ometry.gdml import Writer + + +def Test(vis=False, interactive=False, write=False): + freg = FlukaRegistry() + + # This is simply test/flairFluka/701_LATTICE.inp in pure python form. + + rtrans = RecursiveRotoTranslation( + "rtrans", + [ + RotoTranslation("rtrans", translation=[0, -20, -300]), + RotoTranslation("rtrans", axis="x", azimuth=-45), + ], + ) + + target = RCC( + "target", [0.0, 0.0, -50.0], [0.0, 0.0, 100.0], 50.0, flukaregistry=freg + ) + ztarget = Zone() + ztarget.addIntersection(target) + + targRepl = RCC( + "targRepl", + [0.0, 0.0, -50.0], + [0.0, 0.0, 100.0], + 50.0, + transform=Transform(rotoTranslation=rtrans, invertRotoTranslation=True), + ) + zrepl = Zone() + zrepl.addIntersection(targRepl) + + targetRegion = Region("TARGET") + targetRegion.addZone(ztarget) + replicaRegion = Region("REPLICA") + replicaRegion.addZone(zrepl) + + lattice = Lattice(replicaRegion, rotoTranslation=rtrans, flukaregistry=freg) + + freg.addRegion(targetRegion) + + freg.assignma("COPPER", targetRegion) + + greg = convert.fluka2Geant4(freg, worldDimensions=[100, 100, 100]) + + assert len(greg.logicalVolumeDict) == 2 + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + if write: + w = Writer() + w.addDetector(greg) + dirname = os.path.dirname(os.path.abspath(__file__)) + filename = os.path.basename(__file__) + name, _ = os.path.splitext(__file__) + + gdml_name = f"{name}.gdml" + gmad_name = f"{name}.gmad" + w.write(os.path.join(dirname, gdml_name)) + w.writeGMADTesterNoBeamline(os.path.join(dirname, gmad_name), gdml_name) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True, True) diff --git a/tests/fluka/T101_region_one_body.py b/tests/fluka/T101_region_one_body.py new file mode 100644 index 000000000..2ffb11d94 --- /dev/null +++ b/tests/fluka/T101_region_one_body.py @@ -0,0 +1,30 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + z = Zone() + z.addIntersection(rpp) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/fluka/T102_region_intersection_two_bodies.py b/tests/fluka/T102_region_intersection_two_bodies.py new file mode 100644 index 000000000..15fc825bd --- /dev/null +++ b/tests/fluka/T102_region_intersection_two_bodies.py @@ -0,0 +1,33 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp1 = RPP("RPP_BODY1", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + rpp2 = RPP("RPP_BODY2", 5, 15, 0, 10, 0, 10, flukaregistry=freg) + + z = Zone() + z.addIntersection(rpp1) + z.addIntersection(rpp2) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T103_region_subtraction_two_bodies.py b/tests/fluka/T103_region_subtraction_two_bodies.py new file mode 100644 index 000000000..fba08a2d1 --- /dev/null +++ b/tests/fluka/T103_region_subtraction_two_bodies.py @@ -0,0 +1,33 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp1 = RPP("RPP_BODY1", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + rpp2 = RPP("RPP_BODY2", 5, 15, 0, 10, 0, 10, flukaregistry=freg) + + z = Zone() + z.addIntersection(rpp1) + z.addSubtraction(rpp2) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T103_region_subtraction_two_bodies_RCC.py b/tests/fluka/T103_region_subtraction_two_bodies_RCC.py new file mode 100644 index 000000000..826fd91d7 --- /dev/null +++ b/tests/fluka/T103_region_subtraction_two_bodies_RCC.py @@ -0,0 +1,34 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RCC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rcc1 = RCC("RCC1_BODY", [0, 0, 0], [5, 5, 5], 2.5, flukaregistry=freg) + rcc2 = RCC("RCC2_BODY", [-1, -1, -1], [6, 6, 6], 1.25, flukaregistry=freg) + + z = Zone() + + z.addIntersection(rcc1) + z.addSubtraction(rcc2) + region = Region("RCC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T104_region_union_two_zones.py b/tests/fluka/T104_region_union_two_zones.py new file mode 100644 index 000000000..785fd964d --- /dev/null +++ b/tests/fluka/T104_region_union_two_zones.py @@ -0,0 +1,37 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp1 = RPP("RPP_BODY1", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + rpp2 = RPP("RPP_BODY2", 5, 15, 0, 10, 0, 10, flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + + z1.addIntersection(rpp1) + z2.addIntersection(rpp2) + + region = Region("RPP_REG") + region.addZone(z1) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T104_region_union_two_zones_2.py b/tests/fluka/T104_region_union_two_zones_2.py new file mode 100644 index 000000000..a033539f6 --- /dev/null +++ b/tests/fluka/T104_region_union_two_zones_2.py @@ -0,0 +1,39 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import TRC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # big face (r=5) is at the origin, smaller face (r=2) is at [5, 5, 5]. + trc = TRC("TRC_BODY", [0, 0, 0], [5, 5, 5], 5, 2, flukaregistry=freg) + # big face (r=5) is at the [4, 4, 4] , smaller face (r=2) is at + # [9, 9, 9]. + trc2 = TRC("TRC2_BODY", [4, 4, 4], [5, 5, 5], 5, 2, flukaregistry=freg) + + z = Zone() + z2 = Zone() + z.addIntersection(trc) + z2.addIntersection(trc2) + + region = Region("TRC_REG") + region.addZone(z) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T105_region_subzone_subtraction.py b/tests/fluka/T105_region_subzone_subtraction.py new file mode 100644 index 000000000..e15c8b7ec --- /dev/null +++ b/tests/fluka/T105_region_subzone_subtraction.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, ZCC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp = RPP("RPP_BODY", -20, 20, -20, 20, -20, 20, flukaregistry=freg) + rppsub = RPP("RPP2_BODY", -10, 10, -10, 10, -30, 30, flukaregistry=freg) + + zcc = ZCC("ZCC_BODY", 0, 0, 10, flukaregistry=freg) + + # +rpp -(+rppsub -zcc): + + z = Zone() + z.addIntersection(rpp) + + z2 = Zone() + z2.addIntersection(rppsub) + z2.addSubtraction(zcc) + + # Adding zone2 as a subtraction to the first zone. + z.addSubtraction(z2) + + region = Region("RPP_REG") + + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T106_region_subzone_subtraction_with_union.py b/tests/fluka/T106_region_subzone_subtraction_with_union.py new file mode 100644 index 000000000..ab6d6991d --- /dev/null +++ b/tests/fluka/T106_region_subzone_subtraction_with_union.py @@ -0,0 +1,55 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, ZCC, Region, Zone, FlukaRegistry + +# This is same as T105_REGION_SUBZONE_SUBTRACTION.py but with a union +# as well. + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp = RPP("RPP_BODY1", -20, 20, -20, 20, -20, 20, flukaregistry=freg) + rppsub = RPP("RPP2_BODY2", -10, 10, -10, 10, -30, 30, flukaregistry=freg) + + rppunion = RPP("RPP_BODY3", 0, 20, -20, 20, -20, 20, flukaregistry=freg) + + zcc = ZCC("ZCC_BODY", 0, 0, 10, flukaregistry=freg) + + # +rpp -(+rppsub -zcc) | +rpp3 + + z = Zone() + z.addIntersection(rpp) + + z2 = Zone() + z2.addIntersection(rppsub) + z2.addSubtraction(zcc) + + # Adding zone2 as a subtraction to the first zone. + z.addSubtraction(z2) + + z3 = Zone() + z3.addIntersection(rppunion) + + region = Region("RPP_REG") + + region.addZone(z) + region.addZone(z3) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T107_region_union_with_reused_bodies.py b/tests/fluka/T107_region_union_with_reused_bodies.py new file mode 100644 index 000000000..79a89234c --- /dev/null +++ b/tests/fluka/T107_region_union_with_reused_bodies.py @@ -0,0 +1,40 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, RCC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting cube is of the correct length is trivial. + rpp = RPP("RPP_BODY", 0, 20.0, 0, 20.0, 0.0, 20.0, flukaregistry=freg) + rcc = RCC("RCC_BODY", [0.0, 0.0, 20.0], [0.0, 20.0, 0.0], 10.0, flukaregistry=freg) + + # RPP is used in the definitions of both zone1 and zone2. + + z1 = Zone() + z1.addIntersection(rpp) + z2 = Zone() + z2.addIntersection(rcc) + z2.addSubtraction(rpp) + + region = Region("REG_INF") + region.addZone(z1) + region.addZone(z2) + + freg.addRegion(region) + freg.assignma("COPPER", region) + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T201_RPP_coplanar.py b/tests/fluka/T201_RPP_coplanar.py new file mode 100644 index 000000000..2c403fdef --- /dev/null +++ b/tests/fluka/T201_RPP_coplanar.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp1 = RPP("RPP_BODY1", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + rpp2 = RPP("RPP_BODY2", 2, 8, 2, 8, 2, 8, flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + + z1.addIntersection(rpp1) + z1.addSubtraction(rpp2) + + z2.addIntersection(rpp2) + + region1 = Region("RPP_REG1") + region2 = Region("RPP_REG2") + + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T202_BOX_coplanar.py b/tests/fluka/T202_BOX_coplanar.py new file mode 100644 index 000000000..e58525975 --- /dev/null +++ b/tests/fluka/T202_BOX_coplanar.py @@ -0,0 +1,52 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import BOX, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # trivially coplanar: + box1 = BOX( + "BOX1_BODY", [0, 0, 0], [0, 0, 10], [0, 10, 0], [10, 0, 0], flukaregistry=freg + ) + + box2 = BOX( + "BOX2_BODY", [2, 2, 2], [0, 0, 6], [0, 6, 0], [6, 0, 0], flukaregistry=freg + ) + + z1 = Zone() + z2 = Zone() + + z1.addIntersection(box1) + z1.addSubtraction(box2) + z2.addIntersection(box2) + + region1 = Region("BOX_REG1") + region2 = Region("BOX_REG2") + + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + # default is True, but to be explicit: + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wv = greg.getWorldVolume() + wv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T203_SPH_coplanar.py b/tests/fluka/T203_SPH_coplanar.py new file mode 100644 index 000000000..9f5aa62d2 --- /dev/null +++ b/tests/fluka/T203_SPH_coplanar.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import SPH, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + sph1 = SPH("SPH_BODY1", [0, 0, 0], 10, flukaregistry=freg) + sph2 = SPH("SPH_BODY2", [0, 0, 0], 5, flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + + z1.addIntersection(sph1) + z1.addSubtraction(sph2) + + z2.addIntersection(sph2) + + region1 = Region("SPH_REG1") + region2 = Region("SPH_REG2") + + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T204_RCC_coplanar.py b/tests/fluka/T204_RCC_coplanar.py new file mode 100644 index 000000000..448c72628 --- /dev/null +++ b/tests/fluka/T204_RCC_coplanar.py @@ -0,0 +1,48 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RCC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # trivially coplanar: + rcc1 = RCC("RCC_BODY1", [0, 0, 0], [20, 0, 0], 10, flukaregistry=freg) + rcc2 = RCC("RCC_BODY2", [5, 0, 0], [10, 0, 0], 5, flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + + z1.addIntersection(rcc1) + z1.addSubtraction(rcc2) + + z2.addIntersection(rcc2) + + region1 = Region("RCC_REG1") + region2 = Region("RCC_REG2") + + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + # default is True, but to be explicit: + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wv = greg.getWorldVolume() + wv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T205_REC_coplanar.py b/tests/fluka/T205_REC_coplanar.py new file mode 100644 index 000000000..609c158a6 --- /dev/null +++ b/tests/fluka/T205_REC_coplanar.py @@ -0,0 +1,53 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import REC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # trivially coplanar: + rec1 = REC( + "REC_BODY1", [0, 0, 0], [20, 0, 0], [0, 0, 5], [0, 10, 0], flukaregistry=freg + ) + + rec2 = REC( + "REC_BODY2", [5, 0, 0], [10, 0, 0], [0, 0, 2.5], [0, 5, 0], flukaregistry=freg + ) + + z1 = Zone() + z2 = Zone() + + z1.addIntersection(rec1) + z1.addSubtraction(rec2) + + z2.addIntersection(rec2) + + region1 = Region("REC_REG1") + region2 = Region("REC_REG2") + + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + # default is True, but to be explicit: + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wv = greg.getWorldVolume() + wv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T206_TRC_coplanar.py b/tests/fluka/T206_TRC_coplanar.py new file mode 100644 index 000000000..113895dbe --- /dev/null +++ b/tests/fluka/T206_TRC_coplanar.py @@ -0,0 +1,52 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import TRC, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # trivially coplanar: + trc1 = TRC("TRC_BODY1", [0, 0, 0], [5, 5, 5], 5, 2, flukaregistry=freg) + trc2 = TRC("TRC_BODY2", [10, 10, 10], [-5, -5, -5], 5, 2, flukaregistry=freg) + trc3 = TRC("TRC_BODY3", [10, 10, 10], [5, 5, 5], 5, 2, flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + z3 = Zone() + + z1.addIntersection(trc1) + z2.addIntersection(trc2) + z3.addIntersection(trc3) + + region1 = Region("TRC_REG1") + region2 = Region("TRC_REG2") + region3 = Region("TRC_REG3") + + region1.addZone(z1) + region2.addZone(z2) + region3.addZone(z3) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2, region3) + freg.addRegion(region3) + + # default is True, but to be explicit: + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wv = greg.getWorldVolume() + wv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T207_ELL_coplanar.py b/tests/fluka/T207_ELL_coplanar.py new file mode 100644 index 000000000..814e212b1 --- /dev/null +++ b/tests/fluka/T207_ELL_coplanar.py @@ -0,0 +1,56 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ELL, Region, Zone, FlukaRegistry, Three + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # ellipsoid with major axes poining in the y direction, total + # legnth=20, offset in x. + + ell1 = ELL( + "ELL1_BODY", + [20, 5, 0], # focus1 + [20, 15, 0], # focus2 + 20, # length + flukaregistry=freg, + ) + + ell2 = ELL( + "ELL2_BODY", + [20, 7.5, 0], # focus1 + [20, 12.5, 0], # focus2 + 15, # length + flukaregistry=freg, + ) + + z1 = Zone() + z1.addIntersection(ell1) + z1.addSubtraction(ell2) + + z2 = Zone() + z2.addIntersection(ell2) + + region = Region("ELL_REG") + region.addZone(z1) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T208_RAW_coplanar.py b/tests/fluka/T208_RAW_coplanar.py new file mode 100644 index 000000000..f3574892c --- /dev/null +++ b/tests/fluka/T208_RAW_coplanar.py @@ -0,0 +1,66 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RAW, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # What I expect to see in the visualiser is a cube formed by the + # union of two wedeges. with sides equal to 20cm. The mesh shows + # the two wedges. + + raw1 = RAW( + "RAW1_BODY", + [0, 0, 0], # vertex position + [20, 0, 0], # one transverse side. + [0, 0, 20], # length vector. + [0, 20, 0], # the other transverse side. + flukaregistry=freg, + ) + + raw2 = RAW( + "RAW2_BODY", + [5, 5, 5], # vertex position + [5, 0, 0], # one transverse side. + [0, 0, 5], # length vector. + [0, 5, 0], # the other transverse side. + flukaregistry=freg, + ) + + z1 = Zone() + z1.addIntersection(raw1) + z1.addSubtraction(raw2) + + z2 = Zone() + z2.addIntersection(raw2) + + region1 = Region("RAW_REG1") + region1.addZone(z1) + + region2 = Region("RAW_REG2") + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + # default is True, but to be explicit: + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(wlv) + v.setRandomColours() + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T208_WED_coplanar.py b/tests/fluka/T208_WED_coplanar.py new file mode 100644 index 000000000..955364a9d --- /dev/null +++ b/tests/fluka/T208_WED_coplanar.py @@ -0,0 +1,68 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import WED, Region, Zone, FlukaRegistry + +import numpy as np + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # What I expect to see in the visualiser is a cube formed by the + # union of two wedeges. with sides equal to 20cm. The mesh shows + # the two wedges. + + wed1 = WED( + "WED1_BODY", + [0, 0, 0], # vertex position + [20, 0, 0], # one transverse side. + [0, 0, 20], # length vector. + [0, 20, 0], # the other transverse side. + flukaregistry=freg, + ) + + wed2 = WED( + "WED2_BODY", + [5, 5, 5], # vertex position + [5, 0, 0], # one transverse side. + [0, 0, 5], # length vector. + [0, 5, 0], # the other transverse side. + flukaregistry=freg, + ) + + z1 = Zone() + z1.addIntersection(wed1) + z1.addSubtraction(wed2) + + z2 = Zone() + z2.addIntersection(wed2) + + region1 = Region("WED_REG1") + region1.addZone(z1) + + region2 = Region("WED_REG2") + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + # default is True, but to be explicit: + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(wlv) + v.setRandomColours() + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T209_ARB_coplanar.py b/tests/fluka/T209_ARB_coplanar.py new file mode 100644 index 000000000..23fde1200 --- /dev/null +++ b/tests/fluka/T209_ARB_coplanar.py @@ -0,0 +1,59 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ARB, Region, Zone, FlukaRegistry, Three, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + vertices = [ + [0, 0, 0], + [20, 0, 0], + [10, 20, 0], + [0, 20, 0], + [0, 0, 20], + [20, 0, 20], + [10, 20, 20], + [0, 20, 20], + ] + facenumbers = [4321, 5678, 2376, 1584, 3487, 1265] + + arb = ARB("ARB_BODY", vertices, facenumbers, flukaregistry=freg) + + trans = Transform(expansion=0.5, translation=[5, 5, 5]) + + arbInner = ARB("ARB_BODY2", vertices, facenumbers, transform=trans) + + z1 = Zone() + z1.addIntersection(arb) + z1.addSubtraction(arbInner) + + z2 = Zone() + z2.addIntersection(arbInner) + + region1 = Region("ARB_REG") + region2 = Region("ARB_REG2") + + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg) + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T210_PLA_coplanar.py b/tests/fluka/T210_PLA_coplanar.py new file mode 100644 index 000000000..65786584b --- /dev/null +++ b/tests/fluka/T210_PLA_coplanar.py @@ -0,0 +1,73 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import PLA, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # Bigger cube. + pla_a1 = PLA("PLA_A1_BODY", [0, 0, 20], [0, 0, 20], flukaregistry=freg) + pla_a2 = PLA("PLA_A2_BODY", [0, 0, 20], [0, 0, 0], flukaregistry=freg) + pla_b1 = PLA("PLA_B1_BODY", [0, 20, 0], [0, 20, 0], flukaregistry=freg) + pla_b2 = PLA("PLA_B2_BODY", [0, 20, 0], [0, 0, 0], flukaregistry=freg) + pla_c1 = PLA("PLA_C1_BODY", [20, 0, 0], [20, 0, 0], flukaregistry=freg) + pla_c2 = PLA("PLA_C2_BODY", [20, 0, 0], [0, 0, 0], flukaregistry=freg) + + # smaller cube. + pla_d1 = PLA("PLA_D1_BODY", [0, 0, 20], [0, 0, 15], flukaregistry=freg) + pla_d2 = PLA("PLA_D2_BODY", [0, 0, 20], [0, 0, 5.0], flukaregistry=freg) + pla_e1 = PLA("PLA_e1_BODY", [0, 20, 0], [0, 15, 0], flukaregistry=freg) + pla_e2 = PLA("PLA_e2_BODY", [0, 20, 0], [0, 5.0, 0], flukaregistry=freg) + pla_f1 = PLA("PLA_f1_BODY", [20, 0, 0], [15, 0, 0], flukaregistry=freg) + pla_f2 = PLA("PLA_f2_BODY", [20, 0, 0], [5, 0, 0], flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + + # Box1: + z1.addIntersection(pla_a1) + z1.addSubtraction(pla_a2) + z1.addIntersection(pla_b1) + z1.addSubtraction(pla_b2) + z1.addIntersection(pla_c1) + z1.addSubtraction(pla_c2) + + # box 2 + z2.addIntersection(pla_d1) + z2.addSubtraction(pla_d2) + z2.addIntersection(pla_e1) + z2.addSubtraction(pla_e2) + z2.addIntersection(pla_f1) + z2.addSubtraction(pla_f2) + # make hole in box1 with box2 + z1.addSubtraction(z2) + + region1 = Region("REG_INF1") + region1.addZone(z1) + + # # fill hole with box. + region2 = Region("REG_INF2") + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T210_XYP_coplanar.py b/tests/fluka/T210_XYP_coplanar.py new file mode 100644 index 000000000..7a8147307 --- /dev/null +++ b/tests/fluka/T210_XYP_coplanar.py @@ -0,0 +1,74 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XYP, XZP, YZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # the first box.. + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting cube is of the correct length is trivial. + xyp_lo1 = XYP("XYP1_BODY1", 0, flukaregistry=freg) + xyp_hi1 = XYP("XYP2_BODY1", 20.0, flukaregistry=freg) + xzp_lo1 = XZP("XZP1_BODY1", 0, flukaregistry=freg) + xzp_hi1 = XZP("XZP2_BODY1", 20.0, flukaregistry=freg) + yzp_lo1 = YZP("YZP1_BODY1", 0, flukaregistry=freg) + yzp_hi1 = YZP("YZP2_BODY1", 20.0, flukaregistry=freg) + + # the second box... + xyp_lo2 = XYP("XYP1_BODY2", 5, flukaregistry=freg) + xyp_hi2 = XYP("XYP2_BODY2", 15.0, flukaregistry=freg) + xzp_lo2 = XZP("XZP1_BODY2", 5, flukaregistry=freg) + xzp_hi2 = XZP("XZP2_BODY2", 15.0, flukaregistry=freg) + yzp_lo2 = YZP("YZP1_BODY2", 5, flukaregistry=freg) + yzp_hi2 = YZP("YZP2_BODY2", 15.0, flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + z3 = Zone() + + z1.addIntersection(xyp_hi1) + z1.addSubtraction(xyp_lo1) + z1.addIntersection(xzp_hi1) + z1.addSubtraction(xzp_lo1) + z1.addIntersection(yzp_hi1) + z1.addSubtraction(yzp_lo1) + + z2.addIntersection(xyp_hi2) + z2.addSubtraction(xyp_lo2) + z2.addIntersection(xzp_hi2) + z2.addSubtraction(xzp_lo2) + z2.addIntersection(yzp_hi2) + z2.addSubtraction(yzp_lo2) + + z1.addSubtraction(z2) + z3.addIntersection(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z3) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True) + + wlv = greg.getWorldVolume() + + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T210_XZP_coplanar.py b/tests/fluka/T210_XZP_coplanar.py new file mode 100644 index 000000000..7a8147307 --- /dev/null +++ b/tests/fluka/T210_XZP_coplanar.py @@ -0,0 +1,74 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XYP, XZP, YZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # the first box.. + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting cube is of the correct length is trivial. + xyp_lo1 = XYP("XYP1_BODY1", 0, flukaregistry=freg) + xyp_hi1 = XYP("XYP2_BODY1", 20.0, flukaregistry=freg) + xzp_lo1 = XZP("XZP1_BODY1", 0, flukaregistry=freg) + xzp_hi1 = XZP("XZP2_BODY1", 20.0, flukaregistry=freg) + yzp_lo1 = YZP("YZP1_BODY1", 0, flukaregistry=freg) + yzp_hi1 = YZP("YZP2_BODY1", 20.0, flukaregistry=freg) + + # the second box... + xyp_lo2 = XYP("XYP1_BODY2", 5, flukaregistry=freg) + xyp_hi2 = XYP("XYP2_BODY2", 15.0, flukaregistry=freg) + xzp_lo2 = XZP("XZP1_BODY2", 5, flukaregistry=freg) + xzp_hi2 = XZP("XZP2_BODY2", 15.0, flukaregistry=freg) + yzp_lo2 = YZP("YZP1_BODY2", 5, flukaregistry=freg) + yzp_hi2 = YZP("YZP2_BODY2", 15.0, flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + z3 = Zone() + + z1.addIntersection(xyp_hi1) + z1.addSubtraction(xyp_lo1) + z1.addIntersection(xzp_hi1) + z1.addSubtraction(xzp_lo1) + z1.addIntersection(yzp_hi1) + z1.addSubtraction(yzp_lo1) + + z2.addIntersection(xyp_hi2) + z2.addSubtraction(xyp_lo2) + z2.addIntersection(xzp_hi2) + z2.addSubtraction(xzp_lo2) + z2.addIntersection(yzp_hi2) + z2.addSubtraction(yzp_lo2) + + z1.addSubtraction(z2) + z3.addIntersection(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z3) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True) + + wlv = greg.getWorldVolume() + + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T210_YZP_coplanar.py b/tests/fluka/T210_YZP_coplanar.py new file mode 100644 index 000000000..7a8147307 --- /dev/null +++ b/tests/fluka/T210_YZP_coplanar.py @@ -0,0 +1,74 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XYP, XZP, YZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # the first box.. + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting cube is of the correct length is trivial. + xyp_lo1 = XYP("XYP1_BODY1", 0, flukaregistry=freg) + xyp_hi1 = XYP("XYP2_BODY1", 20.0, flukaregistry=freg) + xzp_lo1 = XZP("XZP1_BODY1", 0, flukaregistry=freg) + xzp_hi1 = XZP("XZP2_BODY1", 20.0, flukaregistry=freg) + yzp_lo1 = YZP("YZP1_BODY1", 0, flukaregistry=freg) + yzp_hi1 = YZP("YZP2_BODY1", 20.0, flukaregistry=freg) + + # the second box... + xyp_lo2 = XYP("XYP1_BODY2", 5, flukaregistry=freg) + xyp_hi2 = XYP("XYP2_BODY2", 15.0, flukaregistry=freg) + xzp_lo2 = XZP("XZP1_BODY2", 5, flukaregistry=freg) + xzp_hi2 = XZP("XZP2_BODY2", 15.0, flukaregistry=freg) + yzp_lo2 = YZP("YZP1_BODY2", 5, flukaregistry=freg) + yzp_hi2 = YZP("YZP2_BODY2", 15.0, flukaregistry=freg) + + z1 = Zone() + z2 = Zone() + z3 = Zone() + + z1.addIntersection(xyp_hi1) + z1.addSubtraction(xyp_lo1) + z1.addIntersection(xzp_hi1) + z1.addSubtraction(xzp_lo1) + z1.addIntersection(yzp_hi1) + z1.addSubtraction(yzp_lo1) + + z2.addIntersection(xyp_hi2) + z2.addSubtraction(xyp_lo2) + z2.addIntersection(xzp_hi2) + z2.addSubtraction(xzp_lo2) + z2.addIntersection(yzp_hi2) + z2.addSubtraction(yzp_lo2) + + z1.addSubtraction(z2) + z3.addIntersection(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z3) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True) + + wlv = greg.getWorldVolume() + + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T212_XCC_coplanar.py b/tests/fluka/T212_XCC_coplanar.py new file mode 100644 index 000000000..491c52fd9 --- /dev/null +++ b/tests/fluka/T212_XCC_coplanar.py @@ -0,0 +1,57 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XCC, YZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + xcc1 = XCC("XCC_BODY1", 0, 0, 20, flukaregistry=freg) + xcc2 = XCC("XCC_BODY2", 0, 0, 10, flukaregistry=freg) + + yzp1 = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp2 = YZP("YZP2_BODY", 0, flukaregistry=freg) + + yzp3 = YZP("YZP3_BODY", 15, flukaregistry=freg) + yzp4 = YZP("YZP4_BODY", 5, flukaregistry=freg) + + z1 = Zone() + z1.addIntersection(xcc1) + z1.addIntersection(yzp1) + z1.addSubtraction(yzp2) + + z2 = Zone() + z2.addIntersection(xcc2) + z2.addIntersection(yzp3) + z2.addSubtraction(yzp4) + + z1.addSubtraction(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T212_YCC_coplanar.py b/tests/fluka/T212_YCC_coplanar.py new file mode 100644 index 000000000..671c55df2 --- /dev/null +++ b/tests/fluka/T212_YCC_coplanar.py @@ -0,0 +1,57 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YCC, XZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + ycc1 = YCC("YCC_BODY1", 0, 0, 20, flukaregistry=freg) + ycc2 = YCC("YCC_BODY2", 0, 0, 10, flukaregistry=freg) + + xzp1 = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp2 = XZP("XZP2_BODY", 0, flukaregistry=freg) + + xzp3 = XZP("XZP3_BODY", 15, flukaregistry=freg) + xzp4 = XZP("XZP4_BODY", 5, flukaregistry=freg) + + z1 = Zone() + z1.addIntersection(ycc1) + z1.addIntersection(xzp1) + z1.addSubtraction(xzp2) + + z2 = Zone() + z2.addIntersection(ycc2) + z2.addIntersection(xzp3) + z2.addSubtraction(xzp4) + + z1.addSubtraction(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T212_ZCC_coplanar.py b/tests/fluka/T212_ZCC_coplanar.py new file mode 100644 index 000000000..26601d39d --- /dev/null +++ b/tests/fluka/T212_ZCC_coplanar.py @@ -0,0 +1,57 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZCC, XYP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + zcc1 = ZCC("ZCC_BODY1", 0, 0, 20, flukaregistry=freg) + zcc2 = ZCC("ZCC_BODY2", 0, 0, 10, flukaregistry=freg) + + xyp1 = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp2 = XYP("XYP2_BODY", 0, flukaregistry=freg) + + xyp3 = XYP("XYP3_BODY", 15, flukaregistry=freg) + xyp4 = XYP("XYP4_BODY", 5, flukaregistry=freg) + + z1 = Zone() + z1.addIntersection(zcc1) + z1.addIntersection(xyp1) + z1.addSubtraction(xyp2) + + z2 = Zone() + z2.addIntersection(zcc2) + z2.addIntersection(xyp3) + z2.addSubtraction(xyp4) + + z1.addSubtraction(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T213_XEC_coplanar.py b/tests/fluka/T213_XEC_coplanar.py new file mode 100644 index 000000000..f48807392 --- /dev/null +++ b/tests/fluka/T213_XEC_coplanar.py @@ -0,0 +1,60 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XEC, YZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + xec1 = XEC("XEC_BODY1", 0, 0, 20, 10, flukaregistry=freg) + xec2 = XEC("XEC_BODY2", 0, 0, 10, 5, flukaregistry=freg) + + yzp1 = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp2 = YZP("YZP2_BODY", 0, flukaregistry=freg) + + yzp3 = YZP("YZP3_BODY", 15, flukaregistry=freg) + yzp4 = YZP("YZP4_BODY", 5, flukaregistry=freg) + + z = Zone() + + z1 = Zone() + z1.addIntersection(xec1) + z1.addIntersection(yzp1) + z1.addSubtraction(yzp2) + + z2 = Zone() + z2.addIntersection(xec2) + z2.addIntersection(yzp3) + z2.addSubtraction(yzp4) + + z1.addSubtraction(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T213_YEC_coplanar.py b/tests/fluka/T213_YEC_coplanar.py new file mode 100644 index 000000000..762ae17d0 --- /dev/null +++ b/tests/fluka/T213_YEC_coplanar.py @@ -0,0 +1,60 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YEC, XZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + yec1 = YEC("YEC_BODY1", 0, 0, 20, 10, flukaregistry=freg) + yec2 = YEC("YEC_BODY2", 0, 0, 10, 5, flukaregistry=freg) + + xzp1 = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp2 = XZP("XZP2_BODY", 0, flukaregistry=freg) + + xzp3 = XZP("XZP3_BODY", 15, flukaregistry=freg) + xzp4 = XZP("XZP4_BODY", 5, flukaregistry=freg) + + z = Zone() + + z1 = Zone() + z1.addIntersection(yec1) + z1.addIntersection(xzp1) + z1.addSubtraction(xzp2) + + z2 = Zone() + z2.addIntersection(yec2) + z2.addIntersection(xzp3) + z2.addSubtraction(xzp4) + + z1.addSubtraction(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T213_ZEC_coplanar.py b/tests/fluka/T213_ZEC_coplanar.py new file mode 100644 index 000000000..dd4d22035 --- /dev/null +++ b/tests/fluka/T213_ZEC_coplanar.py @@ -0,0 +1,60 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZEC, XYP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + zec1 = ZEC("ZEC_BODY1", 0, 0, 20, 10, flukaregistry=freg) + zec2 = ZEC("ZEC_BODY2", 0, 0, 10, 5, flukaregistry=freg) + + xyp1 = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp2 = XYP("XYP2_BODY", 0, flukaregistry=freg) + + xyp3 = XYP("XYP3_BODY", 15, flukaregistry=freg) + xyp4 = XYP("XYP4_BODY", 5, flukaregistry=freg) + + z = Zone() + + z1 = Zone() + z1.addIntersection(zec1) + z1.addIntersection(xyp1) + z1.addSubtraction(xyp2) + + z2 = Zone() + z2.addIntersection(zec2) + z2.addIntersection(xyp3) + z2.addSubtraction(xyp4) + + z1.addSubtraction(z2) + + region1 = Region("REG_INF1") + region2 = Region("REG_INF2") + region1.addZone(z1) + region2.addZone(z2) + + freg.addRegion(region1) + freg.addRegion(region2) + freg.assignma("COPPER", region1, region2) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps(recursive=False, coplanar=True, debugIO=False) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T214_QUA_coplanar.py b/tests/fluka/T214_QUA_coplanar.py new file mode 100644 index 000000000..696d77cbf --- /dev/null +++ b/tests/fluka/T214_QUA_coplanar.py @@ -0,0 +1,93 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import QUA, Region, Zone, FlukaRegistry, AABB, XYP, XZP + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + parabolicCylinderOuter = QUA( + "parabo", + 0.006, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + -200, + flukaregistry=freg, + ) + + parabolicCylinderInner = QUA( + "parabi", + 0.012, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + -150, + flukaregistry=freg, + ) + + # 1 metre long parabolic cylinder 10cm tall from base to tip. + end1outer = XYP("end1o", 1000, flukaregistry=freg) + end2outer = XYP("end2o", 0, flukaregistry=freg) + end3outer = XZP("end3o", 0, flukaregistry=freg) + + end1inner = XYP("end1i", 750, flukaregistry=freg) + end2inner = XYP("end2i", 250, flukaregistry=freg) + end3inner = XZP("end3i", 50, flukaregistry=freg) + + # Outer parabolic cylinder + z1 = Zone() + z1.addIntersection(parabolicCylinderOuter) + z1.addIntersection(end1outer) + z1.addSubtraction(end2outer) + z1.addSubtraction(end3outer) + + # Inner parabolic cylinder + z2 = Zone() + z2.addIntersection(parabolicCylinderInner) + z2.addIntersection(end1inner) + z2.addSubtraction(end2inner) + z2.addSubtraction(end3inner) + + z1.addSubtraction(z2) + + r1 = Region("OUTER") + r1.addZone(z1) + + r2 = Region("INNER") + r2.addZone(z2) + + freg.addRegion(r1) + freg.addRegion(r2) + + freg.assignma("IRON", r1, r2) + + quaAABB = { + "OUTER": AABB([-200.0, 0.0, 0.0], [200, 200, 1100]), + "INNER": AABB([-100.0, 50.0, 250], [100.0, 150.0, 850.0]), + } + + greg = convert.fluka2Geant4(freg, quadricRegionAABBs=quaAABB) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(origin=[0, 100, 0], length=100) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T401_RPP_expansion.py b/tests/fluka/T401_RPP_expansion.py new file mode 100644 index 000000000..10f46c8d1 --- /dev/null +++ b/tests/fluka/T401_RPP_expansion.py @@ -0,0 +1,40 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp = RPP( + "RPP_BODY", + 0, + 10, + 0, + 10, + 0, + 10, + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(rpp) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T402_BOX_expansion.py b/tests/fluka/T402_BOX_expansion.py new file mode 100644 index 000000000..6fc043d2a --- /dev/null +++ b/tests/fluka/T402_BOX_expansion.py @@ -0,0 +1,38 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import BOX, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + box = BOX( + "BOX_BODY", + [5, 0, 0], + [5, 0, 0], + [0, 10, 0], + [0, 0, 10], + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(box) + region = Region("BOX_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T403_SPH_expansion.py b/tests/fluka/T403_SPH_expansion.py new file mode 100644 index 000000000..09fcdd17f --- /dev/null +++ b/tests/fluka/T403_SPH_expansion.py @@ -0,0 +1,33 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import SPH, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + sph = SPH( + "SPH_BODY", [5, 5, 5], 5, transform=Transform(expansion=2.0), flukaregistry=freg + ) + + z = Zone() + z.addIntersection(sph) + region = Region("SPH_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T404_RCC_expansion.py b/tests/fluka/T404_RCC_expansion.py new file mode 100644 index 000000000..f6717c1f0 --- /dev/null +++ b/tests/fluka/T404_RCC_expansion.py @@ -0,0 +1,39 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RCC, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rcc = RCC( + "RCC_BODY", + [5, 5, 5], + [5, 0, 0], + 5, + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(rcc) + region = Region("RCC_REG") + freg.assignma("COPPER", region) + + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T405_REC_expansion.py b/tests/fluka/T405_REC_expansion.py new file mode 100644 index 000000000..2a2242187 --- /dev/null +++ b/tests/fluka/T405_REC_expansion.py @@ -0,0 +1,46 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import REC, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + face = [0, 0, 0] + direction = [0, 0, 10] + semiminor = [10, 0, 0] + semimajor = [0, 5, 0] + + rec = REC( + "REC_BODY", + face, + direction, + semiminor, + semimajor, + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(rec) + region = Region("REC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T406_TRC_expansion.py b/tests/fluka/T406_TRC_expansion.py new file mode 100644 index 000000000..5be944efe --- /dev/null +++ b/tests/fluka/T406_TRC_expansion.py @@ -0,0 +1,38 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import TRC, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + trc = TRC( + "TRC_BODY", + [5, 0, 0], + [5, 0, 0], + 10, + 5, + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(trc) + region = Region("TRC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T407_ELL_expansion.py b/tests/fluka/T407_ELL_expansion.py new file mode 100644 index 000000000..1a956d8ec --- /dev/null +++ b/tests/fluka/T407_ELL_expansion.py @@ -0,0 +1,44 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ELL, Region, Zone, FlukaRegistry, Transform, Three + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # ellipsoid with major axes poining in the y direction, total + # legnth=20, offset in x. + focus1 = Three([20, 5, 0]) + focus2 = Three([20, 15, 0]) + length = 20 + + ell = ELL( + "ELL_BODY", + focus1, + focus2, + length, + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(ell) + region = Region("ELL_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T408_RAW_expansion.py b/tests/fluka/T408_RAW_expansion.py new file mode 100644 index 000000000..166e7d633 --- /dev/null +++ b/tests/fluka/T408_RAW_expansion.py @@ -0,0 +1,40 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RAW, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + raw = RAW( + "RAW_BODY", + [5, 0, 0], # vertex position + [5, 0, 0], # one transverse side. + [0, 0, 10], # length vector. + [0, 10, 0], # the other transverse side. + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(raw) + + region = Region("RAW_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T408_WED_expansion.py b/tests/fluka/T408_WED_expansion.py new file mode 100644 index 000000000..690db34e9 --- /dev/null +++ b/tests/fluka/T408_WED_expansion.py @@ -0,0 +1,40 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import WED, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + wed = WED( + "WED_BODY", + [5, 0, 0], # vertex position + [5, 0, 0], # one transverse side. + [0, 0, 10], # length vector. + [0, 10, 0], # the other transverse side. + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(wed) + + region = Region("WED_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T409_ARB_expansion.py b/tests/fluka/T409_ARB_expansion.py new file mode 100644 index 000000000..7b3429e5d --- /dev/null +++ b/tests/fluka/T409_ARB_expansion.py @@ -0,0 +1,74 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ARB, Region, Zone, FlukaRegistry, Transform, Three + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # In FLUKA we can choose: either all of the face numbers must + # refer to vertices in clockwise or anticlockwise direction. Here + # we ensure all are clockwise looking out from the centre of the + # tesselated solid. This is the right hand corkscrew rule. + + # Rear face: + vertex1 = Three([0.0, 0.0, 0.0]) # lower left corner + vertex2 = Three([20.0, 0.0, 0.0]) # lower right corner + vertex3 = Three([10.0, 20.0, 0.0]) # upper right corner + vertex4 = Three([0.0, 20.0, 0.0]) # Upper left corner + face1 = 4321 # clockwise in direction of normal + # face1 = 1234 # anticlockwise in direction of normal + + # Front face: + vertex5 = Three([0.0, 0.0, 20.0]) # lower left corner + vertex6 = Three([20.0, 0.0, 20.0]) # lower right corner + vertex7 = Three([10.0, 20.0, 20.0]) # upper right corner + vertex8 = Three([0.0, 20.0, 20.0]) # Upper left corner + + face2 = 5678 # clockwise in direction of normal + # face2 = 8765 # anticlockwise in direction of normal + + face3 = 2376 # right face + face4 = 1584 # left face + face5 = 3487 # top face + face6 = 1265 # bottom face + + # anticlockwise in direction of noraml + # face3 = 6732 # right face + # face4 = 4851 # left face + # face5 = 7843 # top face + # face6 = 5621 # bottom face + + vertices = [vertex1, vertex2, vertex3, vertex4, vertex5, vertex6, vertex7, vertex8] + facenumbers = [face1, face2, face3, face4, face5, face6] + + arb = ARB( + "ARB_BODY", + vertices, + facenumbers, + transform=Transform(expansion=0.5), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(arb) + + region = Region("ARB_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T410_XYP_expansion.py b/tests/fluka/T410_XYP_expansion.py new file mode 100644 index 000000000..65fdece7a --- /dev/null +++ b/tests/fluka/T410_XYP_expansion.py @@ -0,0 +1,36 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XYP, Region, Zone, FlukaRegistry, Transform, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + xyp = XYP( + "XYP_BODY", 10.0, transform=Transform(expansion=2.0), flukaregistry=freg + ) + + z = Zone() + z.addIntersection(xyp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T410_XZP_expansion.py b/tests/fluka/T410_XZP_expansion.py new file mode 100644 index 000000000..babec21e5 --- /dev/null +++ b/tests/fluka/T410_XZP_expansion.py @@ -0,0 +1,36 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XZP, Region, Zone, FlukaRegistry, Transform, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + xzp = XZP( + "XZP_BODY", 10.0, transform=Transform(expansion=2.0), flukaregistry=freg + ) + + z = Zone() + z.addIntersection(xzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T410_YZP_expansion.py b/tests/fluka/T410_YZP_expansion.py new file mode 100644 index 000000000..acecedc77 --- /dev/null +++ b/tests/fluka/T410_YZP_expansion.py @@ -0,0 +1,36 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YZP, Region, Zone, FlukaRegistry, Transform, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + yzp = YZP( + "YZP_BODY", 10.0, transform=Transform(expansion=2.0), flukaregistry=freg + ) + + z = Zone() + z.addIntersection(yzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T411_PLA_expansion.py b/tests/fluka/T411_PLA_expansion.py new file mode 100644 index 000000000..462fb7e3f --- /dev/null +++ b/tests/fluka/T411_PLA_expansion.py @@ -0,0 +1,41 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import PLA, Region, Zone, FlukaRegistry, Transform, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + pla1 = PLA( + "PLA1_BODY", + [0, 0, 10], + [0, 0, 10], + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + + z1 = Zone() + + z1.addIntersection(pla1) + + region = Region("REG_INF") + region.addZone(z1) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T412_XCC_expansion.py b/tests/fluka/T412_XCC_expansion.py new file mode 100644 index 000000000..de5f98da9 --- /dev/null +++ b/tests/fluka/T412_XCC_expansion.py @@ -0,0 +1,41 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XCC, YZP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + xcc = XCC( + "XCC_BODY", 5, 5, 5, transform=Transform(expansion=2.0), flukaregistry=freg + ) + + yzp_hi = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xcc) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T412_YCC_expansion.py b/tests/fluka/T412_YCC_expansion.py new file mode 100644 index 000000000..2ebb554c6 --- /dev/null +++ b/tests/fluka/T412_YCC_expansion.py @@ -0,0 +1,41 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YCC, XZP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + ycc = YCC( + "YCC_BODY", 5, 5, 5, transform=Transform(expansion=2.0), flukaregistry=freg + ) + + xzp_hi = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(ycc) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T412_ZCC_expansion.py b/tests/fluka/T412_ZCC_expansion.py new file mode 100644 index 000000000..446c5398e --- /dev/null +++ b/tests/fluka/T412_ZCC_expansion.py @@ -0,0 +1,41 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZCC, XYP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + zcc = ZCC( + "ZCC_BODY", 5, 5, 5, transform=Transform(expansion=2.0), flukaregistry=freg + ) + + xyp_hi = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zcc) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T413_XEC_expansion.py b/tests/fluka/T413_XEC_expansion.py new file mode 100644 index 000000000..0463f2214 --- /dev/null +++ b/tests/fluka/T413_XEC_expansion.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XEC, YZP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + xec = XEC( + "XEC_BODY", + 2.5, + 5, + 2.5, + 5, + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + + yzp_hi = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xec) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T413_YEC_expansion.py b/tests/fluka/T413_YEC_expansion.py new file mode 100644 index 000000000..844d5ceb1 --- /dev/null +++ b/tests/fluka/T413_YEC_expansion.py @@ -0,0 +1,51 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YEC, XZP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + # Bigger semi axis is z, smaller is x + yec = YEC( + "YEC_BODY", + 2.5, + 5, + 2.5, + 5, + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + + xzp_hi = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(yec) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T413_ZEC_expansion.py b/tests/fluka/T413_ZEC_expansion.py new file mode 100644 index 000000000..7593b5c43 --- /dev/null +++ b/tests/fluka/T413_ZEC_expansion.py @@ -0,0 +1,47 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZEC, XYP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + zec = ZEC( + "ZEC_BODY", + 2.5, + 5, + 2.5, + 5, + transform=Transform(expansion=2.0), + flukaregistry=freg, + ) + + xyp_hi = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zec) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T414_QUA_expansion.py b/tests/fluka/T414_QUA_expansion.py new file mode 100644 index 000000000..a2b09557a --- /dev/null +++ b/tests/fluka/T414_QUA_expansion.py @@ -0,0 +1,58 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import QUA, Region, Zone, FlukaRegistry, AABB, XYP, XZP, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + expansion = Transform(expansion=0.5) + + parabolicCylinder = QUA( + "parab", + 0.006, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + -200, + transform=expansion, + flukaregistry=freg, + ) + + # 1 metre long parabolic cylinder 10cm tall from base to tip. + end1 = XYP("end1", 1000, transform=expansion, flukaregistry=freg) + end2 = XYP("end2", 0, transform=expansion, flukaregistry=freg) + end3 = XZP("end3", 100, transform=expansion, flukaregistry=freg) + + z = Zone() + z.addIntersection(parabolicCylinder) + z.addIntersection(end1) + z.addSubtraction(end2) + z.addSubtraction(end3) + + region = Region("QUA_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + quaAABB = {"QUA_REG": AABB([-70.0, 50.0, 0], [70.0, 100.0, 500.0])} + + greg = convert.fluka2Geant4(freg, quadricRegionAABBs=quaAABB) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(origin=[0, 0, 0], length=500) # XYP end1's position in z. + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T501_RPP_translation.py b/tests/fluka/T501_RPP_translation.py new file mode 100644 index 000000000..be016266b --- /dev/null +++ b/tests/fluka/T501_RPP_translation.py @@ -0,0 +1,42 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp = RPP( + "RPP_BODY", + -20, + 20, + -20, + 20, + -20, + 20, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(rpp) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addAxes(length=20, origin=(-20, -20, -20)) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T502_BOX_translation.py b/tests/fluka/T502_BOX_translation.py new file mode 100644 index 000000000..df7246570 --- /dev/null +++ b/tests/fluka/T502_BOX_translation.py @@ -0,0 +1,40 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import BOX, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # box with corner at the origin and sides of length 20 extending + # along the axes + box = BOX( + "BOX_BODY", + [20, 20, 20], + [20, 0, 0], + [0, 20, 0], + [0, 0, 20], + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(box) + region = Region("BOX_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T503_SPH_translation.py b/tests/fluka/T503_SPH_translation.py new file mode 100644 index 000000000..a134aa4c3 --- /dev/null +++ b/tests/fluka/T503_SPH_translation.py @@ -0,0 +1,36 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import SPH, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + sph = SPH( + "SPH_BODY", + [20, 20, 20], + 20, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(sph) + region = Region("SPH_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T504_RCC_translation.py b/tests/fluka/T504_RCC_translation.py new file mode 100644 index 000000000..79d4595f3 --- /dev/null +++ b/tests/fluka/T504_RCC_translation.py @@ -0,0 +1,37 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RCC, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rcc = RCC( + "RCC_BODY", + [20, 20, 20], + [5, 5, 5], + 2.5, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(rcc) + region = Region("RCC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T505_REC_translation.py b/tests/fluka/T505_REC_translation.py new file mode 100644 index 000000000..bc48bdfec --- /dev/null +++ b/tests/fluka/T505_REC_translation.py @@ -0,0 +1,51 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import REC, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + face = [20, 20, 20] # one face is situated at (0, 0, 0). + direction = [3, 3, 3] # length pointing from above face in the + # i+j+k direction. + semiminor = [0.5, -1, 0.5] # one axis line intercepts the y-axis, length= ~1.22 + semiminor_length = np.linalg.norm(semiminor) + semimajor = np.cross(direction, semiminor) + semimajor = 2 * ( + semiminor_length * semimajor / np.linalg.norm(semimajor) + ) # Twice the length of semiminor + + rec = REC( + "REC_BODY", + face, + direction, + semiminor, + semimajor, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(rec) + region = Region("REC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T506_TRC_translation.py b/tests/fluka/T506_TRC_translation.py new file mode 100644 index 000000000..943cd7930 --- /dev/null +++ b/tests/fluka/T506_TRC_translation.py @@ -0,0 +1,39 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import TRC, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # big face (r=5) is at the origin, smaller face (r=2) is at [5, 5, 5]. + trc = TRC( + "TRC_BODY", + [20, 20, 20], + [5, 5, 5], + 5, + 2, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(trc) + region = Region("TRC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T507_ELL_translation.py b/tests/fluka/T507_ELL_translation.py new file mode 100644 index 000000000..46e28ee2b --- /dev/null +++ b/tests/fluka/T507_ELL_translation.py @@ -0,0 +1,45 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ELL, Region, Zone, FlukaRegistry, Transform, Three + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # ellipsoid with major axes poining in the y direction, total + # legnth=20, offset in x. + focus1 = Three([20, 5, 0]) + focus2 = Three([20, 15, 0]) + length = 20 + + ell = ELL( + "ELL_BODY", + focus1, + focus2, + length, + transform=Transform(translation=[-20, -20, 20]), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(ell) + region = Region("ELL_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(20, [0, 0, 0]) + + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T508_RAW_translation.py b/tests/fluka/T508_RAW_translation.py new file mode 100644 index 000000000..130e2f1ba --- /dev/null +++ b/tests/fluka/T508_RAW_translation.py @@ -0,0 +1,60 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RAW, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # What I expect to see in the visualiser is a cube formed by the + # union of two wedeges. with sides equal to 20cm. The mesh shows + # the two wedges. + + transform = Transform(translation=[-20, -20, -20]) + + raw1 = RAW( + "RAW1_BODY", + [40, 40, 40], # vertex position + [-20, 0, 0], # one transverse side. + [0, 0, -20], # length vector. + [0, -20, 0], # the other transverse side. + transform=transform, + flukaregistry=freg, + ) + + raw2 = RAW( + "RAW2_BODY", + [20, 20, 20], + [20, 0, 0], # one transverse side. + [0, 0, 20], # length vector. + [0, 20, 0], # the other transverse side. + transform=transform, + flukaregistry=freg, + ) + + z1 = Zone() + z1.addIntersection(raw1) + + z2 = Zone() + z2.addIntersection(raw2) + + region = Region("RAW_REG") + region.addZone(z1) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T508_WED_translation.py b/tests/fluka/T508_WED_translation.py new file mode 100644 index 000000000..570efd12d --- /dev/null +++ b/tests/fluka/T508_WED_translation.py @@ -0,0 +1,60 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import WED, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # What I expect to see in the visualiser is a cube formed by the + # union of two wedeges. with sides equal to 20cm. The mesh shows + # the two wedges. + + transform = Transform(translation=[-20, -20, -20]) + + wed1 = WED( + "WED1_BODY", + [40, 40, 40], # vertex position + [-20, 0, 0], # one transverse side. + [0, 0, -20], # length vector. + [0, -20, 0], # the other transverse side. + transform=transform, + flukaregistry=freg, + ) + + wed2 = WED( + "WED2_BODY", + [20, 20, 20], + [20, 0, 0], # one transverse side. + [0, 0, 20], # length vector. + [0, 20, 0], # the other transverse side. + transform=transform, + flukaregistry=freg, + ) + + z1 = Zone() + z1.addIntersection(wed1) + + z2 = Zone() + z2.addIntersection(wed2) + + region = Region("WED_REG") + region.addZone(z1) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T509_ARB_translation.py b/tests/fluka/T509_ARB_translation.py new file mode 100644 index 000000000..6b85565fa --- /dev/null +++ b/tests/fluka/T509_ARB_translation.py @@ -0,0 +1,74 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ARB, Region, Zone, FlukaRegistry, Transform, Three + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # In FLUKA we can choose: either all of the face numbers must + # refer to vertices in clockwise or anticlockwise direction. Here + # we ensure all are clockwise looking out from the centre of the + # tesselated solid. This is the right hand corkscrew rule. + + # Rear face: + vertex1 = Three([0.0, 0.0, 0.0]) # lower left corner + vertex2 = Three([20.0, 0.0, 0.0]) # lower right corner + vertex3 = Three([10.0, 20.0, 0.0]) # upper right corner + vertex4 = Three([0.0, 20.0, 0.0]) # Upper left corner + face1 = 4321 # clockwise in direction of normal + # face1 = 1234 # anticlockwise in direction of normal + + # Front face: + vertex5 = Three([0.0, 0.0, 20.0]) # lower left corner + vertex6 = Three([20.0, 0.0, 20.0]) # lower right corner + vertex7 = Three([10.0, 20.0, 20.0]) # upper right corner + vertex8 = Three([0.0, 20.0, 20.0]) # Upper left corner + + face2 = 5678 # clockwise in direction of normal + # face2 = 8765 # anticlockwise in direction of normal + + face3 = 2376 # right face + face4 = 1584 # left face + face5 = 3487 # top face + face6 = 1265 # bottom face + + # anticlockwise in direction of noraml + # face3 = 6732 # right face + # face4 = 4851 # left face + # face5 = 7843 # top face + # face6 = 5621 # bottom face + + vertices = [vertex1, vertex2, vertex3, vertex4, vertex5, vertex6, vertex7, vertex8] + facenumbers = [face1, face2, face3, face4, face5, face6] + + arb = ARB( + "ARB_BODY", + vertices, + facenumbers, + transform=Transform(translation=[10, 10, 10]), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(arb) + + region = Region("ARB_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T510_XYP_translation.py b/tests/fluka/T510_XYP_translation.py new file mode 100644 index 000000000..65a2cd18b --- /dev/null +++ b/tests/fluka/T510_XYP_translation.py @@ -0,0 +1,39 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XZP, Region, Zone, FlukaRegistry, Transform, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + xzp = XZP( + "XZP_BODY", + 20.0, + transform=Transform(translation=[0, -20, 0]), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(xzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T510_XZP_translation.py b/tests/fluka/T510_XZP_translation.py new file mode 100644 index 000000000..65a2cd18b --- /dev/null +++ b/tests/fluka/T510_XZP_translation.py @@ -0,0 +1,39 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XZP, Region, Zone, FlukaRegistry, Transform, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + xzp = XZP( + "XZP_BODY", + 20.0, + transform=Transform(translation=[0, -20, 0]), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(xzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T510_YZP_translation.py b/tests/fluka/T510_YZP_translation.py new file mode 100644 index 000000000..9ab6bbb78 --- /dev/null +++ b/tests/fluka/T510_YZP_translation.py @@ -0,0 +1,39 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YZP, Region, Zone, FlukaRegistry, Transform, infinity + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + yzp = YZP( + "YZP_BODY", + 20.0, + transform=Transform(translation=[-20, 0, 0]), + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(yzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T511_PLA_translation.py b/tests/fluka/T511_PLA_translation.py new file mode 100644 index 000000000..e37ed126b --- /dev/null +++ b/tests/fluka/T511_PLA_translation.py @@ -0,0 +1,42 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import PLA, Region, Zone, FlukaRegistry, Transform, infinity +import pyg4ometry.fluka.body + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + with infinity(30): + pla1 = PLA( + "PLA1_BODY", + [1, 1, 1], + [20, 20.0, 20], + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + z1 = Zone() + + z1.addIntersection(pla1) + + region = Region("REG_INF") + region.addZone(z1) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T512_XCC_translation.py b/tests/fluka/T512_XCC_translation.py new file mode 100644 index 000000000..47632c9a6 --- /dev/null +++ b/tests/fluka/T512_XCC_translation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XCC, YZP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + xcc = XCC( + "XCC_BODY", + 20, + 20, + 20, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + yzp_hi = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xcc) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T512_YCC_translation.py b/tests/fluka/T512_YCC_translation.py new file mode 100644 index 000000000..a949acc09 --- /dev/null +++ b/tests/fluka/T512_YCC_translation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YCC, XZP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + ycc = YCC( + "YCC_BODY", + 20, + 20, + 20, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + xzp_hi = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(ycc) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T512_ZCC_translation.py b/tests/fluka/T512_ZCC_translation.py new file mode 100644 index 000000000..e86129329 --- /dev/null +++ b/tests/fluka/T512_ZCC_translation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZCC, XYP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + zcc = ZCC( + "ZCC_BODY", + 20, + 20, + 20, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + xyp_hi = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zcc) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T513_XEC_translation.py b/tests/fluka/T513_XEC_translation.py new file mode 100644 index 000000000..1413ab364 --- /dev/null +++ b/tests/fluka/T513_XEC_translation.py @@ -0,0 +1,47 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XEC, YZP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + xec = XEC( + "XEC_BODY", + 20, + 20, + 20, + 10, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + yzp_hi = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xec) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T513_YEC_translation.py b/tests/fluka/T513_YEC_translation.py new file mode 100644 index 000000000..11076bb55 --- /dev/null +++ b/tests/fluka/T513_YEC_translation.py @@ -0,0 +1,47 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YEC, XZP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + yec = YEC( + "YEC_BODY", + 20, + 20, + 20, + 10, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + xzp_hi = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(yec) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T513_ZEC_translation.py b/tests/fluka/T513_ZEC_translation.py new file mode 100644 index 000000000..8a74e0264 --- /dev/null +++ b/tests/fluka/T513_ZEC_translation.py @@ -0,0 +1,47 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZEC, XYP, Region, Zone, FlukaRegistry, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + zec = ZEC( + "ZEC_BODY", + 20, + 20, + 20, + 10, + transform=Transform(translation=[-20, -20, -20]), + flukaregistry=freg, + ) + + xyp_hi = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zec) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T514_QUA_translation.py b/tests/fluka/T514_QUA_translation.py new file mode 100644 index 000000000..39698f58f --- /dev/null +++ b/tests/fluka/T514_QUA_translation.py @@ -0,0 +1,59 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import QUA, Region, Zone, FlukaRegistry, AABB, XYP, XZP, Transform + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + translation = Transform(translation=[0, 0, -1000]) + + parabolicCylinder = QUA( + "parab", + 0.006, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + -200, + transform=translation, + flukaregistry=freg, + ) + + # 1 metre long parabolic cylinder 10cm tall from base to tip. + end1 = XYP("end1", 1000, transform=translation, flukaregistry=freg) + end2 = XYP("end2", 0, transform=translation, flukaregistry=freg) + end3 = XZP("end3", 100, transform=translation, flukaregistry=freg) + + z = Zone() + z.addIntersection(parabolicCylinder) + z.addIntersection(end1) + z.addSubtraction(end2) + z.addSubtraction(end3) + + region = Region("QUA_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + quaAABB = {"QUA_REG": AABB([-150.0, 100.0, -1000.0], [150.0, 200.0, 0.0])} + + greg = convert.fluka2Geant4(freg, quadricRegionAABBs=quaAABB) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(origin=[0, 0, 0], length=500) + v.addAxes(origin=[0, 0, -1000], length=1000) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T601_RPP_rototranslation.py b/tests/fluka/T601_RPP_rototranslation.py new file mode 100644 index 000000000..c73a9ee85 --- /dev/null +++ b/tests/fluka/T601_RPP_rototranslation.py @@ -0,0 +1,54 @@ +import os.path + +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 +from pyg4ometry.gdml import Writer + + +def Test(vis=False, interactive=False, write=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "rppTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, transform=transform, flukaregistry=freg) + + z = Zone() + z.addIntersection(rpp) + region = Region("RPP_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg, worldDimensions=[100, 100, 100]) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + if write: + w = Writer() + w.addDetector(greg) + dirname = os.path.dirname(os.path.abspath(__file__)) + filename = os.path.basename(__file__) + name, _ = os.path.splitext(__file__) + + gdml_name = f"{name}.gdml" + gmad_name = f"{name}.gmad" + w.write(os.path.join(dirname, gdml_name)) + w.writeGMADTesterNoBeamline(os.path.join(dirname, gmad_name), gdml_name) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True, True) diff --git a/tests/fluka/T602_BOX_rototranslation.py b/tests/fluka/T602_BOX_rototranslation.py new file mode 100644 index 000000000..1f141cd97 --- /dev/null +++ b/tests/fluka/T602_BOX_rototranslation.py @@ -0,0 +1,48 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import BOX, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "boxTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + # box with corner at the origin and sides of length 20 extending + # along the axes + box = BOX( + "BOX_BODY", + [0, 0, 0], + [20, 0, 0], + [0, 20, 0], + [0, 0, 20], + transform=transform, + flukaregistry=freg, + ) + z = Zone() + z.addIntersection(box) + region = Region("BOX_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T603_SPH_rototranslation.py b/tests/fluka/T603_SPH_rototranslation.py new file mode 100644 index 000000000..c113eedac --- /dev/null +++ b/tests/fluka/T603_SPH_rototranslation.py @@ -0,0 +1,38 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import SPH, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "sphTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + sph = SPH("SPH_BODY", [10, 10, 10], 10, transform=transform, flukaregistry=freg) + z = Zone() + z.addIntersection(sph) + region = Region("SPH_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T604_RCC_rototranslation.py b/tests/fluka/T604_RCC_rototranslation.py new file mode 100644 index 000000000..ffa7e52e4 --- /dev/null +++ b/tests/fluka/T604_RCC_rototranslation.py @@ -0,0 +1,40 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RCC, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "rccTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + rcc = RCC( + "RCC_BODY", [0, 0, 0], [5, 5, 5], 2.5, transform=transform, flukaregistry=freg + ) + z = Zone() + z.addIntersection(rcc) + region = Region("RCC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T605_REC_rototranslation.py b/tests/fluka/T605_REC_rototranslation.py new file mode 100644 index 000000000..bd6c62810 --- /dev/null +++ b/tests/fluka/T605_REC_rototranslation.py @@ -0,0 +1,57 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import REC, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "recTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + face = [0, 0, 0] # one face is situated at (0, 0, 0). + direction = [3, 3, 3] # length pointing from above face in the + # i+j+k direction. + semiminor = [0.5, -1, 0.5] # one axis line intercepts the y-axis, length= ~1.22 + semiminor_length = np.linalg.norm(semiminor) + semimajor = np.cross(direction, semiminor) + semimajor = 2 * ( + semiminor_length * semimajor / np.linalg.norm(semimajor) + ) # Twice the length of semiminor + + rec = REC( + "REC_BODY", + face, + direction, + semiminor, + semimajor, + transform=transform, + flukaregistry=freg, + ) + + z = Zone() + z.addIntersection(rec) + region = Region("REC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T606_TRC_rototranslation.py b/tests/fluka/T606_TRC_rototranslation.py new file mode 100644 index 000000000..fdfbe4b29 --- /dev/null +++ b/tests/fluka/T606_TRC_rototranslation.py @@ -0,0 +1,41 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import TRC, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "trcTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + # big face (r=5) is at the origin, smaller face (r=2) is at [5, 5, 5]. + trc = TRC( + "TRC_BODY", [0, 0, 0], [5, 5, 5], 5, 2, transform=transform, flukaregistry=freg + ) + z = Zone() + z.addIntersection(trc) + region = Region("TRC_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T607_ELL_rototranslation.py b/tests/fluka/T607_ELL_rototranslation.py new file mode 100644 index 000000000..a40aeaf5a --- /dev/null +++ b/tests/fluka/T607_ELL_rototranslation.py @@ -0,0 +1,47 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ELL, Region, Zone, FlukaRegistry, Transform, Three +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "ellTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + # ellipsoid with major axes poining in the y direction, total + # legnth=20, offset in x. + focus1 = Three([20, 5, 0]) + focus2 = Three([20, 15, 0]) + length = 20 + + ell = ELL( + "ELL_BODY", focus1, focus2, length, transform=transform, flukaregistry=freg + ) + + z = Zone() + z.addIntersection(ell) + region = Region("ELL_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T608_RAW_rototranslation.py b/tests/fluka/T608_RAW_rototranslation.py new file mode 100644 index 000000000..9f7e3ff9a --- /dev/null +++ b/tests/fluka/T608_RAW_rototranslation.py @@ -0,0 +1,68 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RAW, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "rawTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + # What I expect to see in the visualiser is a cube formed by the + # union of two wedeges. with sides equal to 20cm. The mesh shows + # the two wedges. + + raw1 = RAW( + "RAW1_BODY", + [20, 20, 20], # vertex position + [-20, 0, 0], # one transverse side. + [0, 0, -20], # the other transverse side. + [0, -20, 0], # length vector. + transform=transform, + flukaregistry=freg, + ) + + raw2 = RAW( + "RAW2_BODY", + [0, 0, 0], + [20, 0, 0], # one transverse side. + [0, 0, 20], # the other transverse side. + [0, 20, 0], # length vector. + transform=transform, + flukaregistry=freg, + ) + + # better test please...? + + z1 = Zone() + z1.addIntersection(raw1) + + z2 = Zone() + z2.addIntersection(raw2) + + region = Region("RAW_REG") + region.addZone(z1) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T608_WED_rototranslation.py b/tests/fluka/T608_WED_rototranslation.py new file mode 100644 index 000000000..82f6af84f --- /dev/null +++ b/tests/fluka/T608_WED_rototranslation.py @@ -0,0 +1,68 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RAW, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "wedTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + # What I expect to see in the visualiser is a cube formed by the + # union of two wedeges. with sides equal to 20cm. The mesh shows + # the two wedges. + + raw1 = RAW( + "RAW1_BODY", + [20, 20, 20], # vertex position + [-20, 0, 0], # one transverse side. + [0, 0, -20], # the other transverse side. + [0, -20, 0], # length vector. + transform=transform, + flukaregistry=freg, + ) + + raw2 = RAW( + "RAW2_BODY", + [0, 0, 0], + [20, 0, 0], # one transverse side. + [0, 0, 20], # the other transverse side. + [0, 20, 0], # length vector. + transform=transform, + flukaregistry=freg, + ) + + # better test please...? + + z1 = Zone() + z1.addIntersection(raw1) + + z2 = Zone() + z2.addIntersection(raw2) + + region = Region("RAW_REG") + region.addZone(z1) + region.addZone(z2) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes() + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T609_ARB_rototranslation.py b/tests/fluka/T609_ARB_rototranslation.py new file mode 100644 index 000000000..8d82a4f5a --- /dev/null +++ b/tests/fluka/T609_ARB_rototranslation.py @@ -0,0 +1,78 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ARB, Region, Zone, FlukaRegistry, Transform, Three +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # In FLUKA we can choose: either all of the face numbers must + # refer to vertices in clockwise or anticlockwise direction. Here + # we ensure all are clockwise looking out from the centre of the + # tesselated solid. This is the right hand corkscrew rule. + + # Rear face: + vertex1 = Three([0.0, 0.0, 0.0]) # lower left corner + vertex2 = Three([20.0, 0.0, 0.0]) # lower right corner + vertex3 = Three([10.0, 20.0, 0.0]) # upper right corner + vertex4 = Three([0.0, 20.0, 0.0]) # Upper left corner + face1 = 4321 # clockwise in direction of normal + # face1 = 1234 # anticlockwise in direction of normal + + # Front face: + vertex5 = Three([0.0, 0.0, 20.0]) # lower left corner + vertex6 = Three([20.0, 0.0, 20.0]) # lower right corner + vertex7 = Three([10.0, 20.0, 20.0]) # upper right corner + vertex8 = Three([0.0, 20.0, 20.0]) # Upper left corner + + face2 = 5678 # clockwise in direction of normal + # face2 = 8765 # anticlockwise in direction of normal + + face3 = 2376 # right face + face4 = 1584 # left face + face5 = 3487 # top face + face6 = 1265 # bottom face + + # anticlockwise in direction of noraml + # face3 = 6732 # right face + # face4 = 4851 # left face + # face5 = 7843 # top face + # face6 = 5621 # bottom face + + vertices = [vertex1, vertex2, vertex3, vertex4, vertex5, vertex6, vertex7, vertex8] + facenumbers = [face1, face2, face3, face4, face5, face6] + + rtrans = rotoTranslationFromTra2( + "rppTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + arb = ARB( + "ARB_BODY", vertices, facenumbers, transform=transform, flukaregistry=freg + ) + + z = Zone() + z.addIntersection(arb) + + region = Region("ARB_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T610_XYP_rototranslation.py b/tests/fluka/T610_XYP_rototranslation.py new file mode 100644 index 000000000..9ef348011 --- /dev/null +++ b/tests/fluka/T610_XYP_rototranslation.py @@ -0,0 +1,44 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XYP, Region, Zone, FlukaRegistry, Transform, infinity + +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + +import pyg4ometry.fluka.body + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "rppTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + with infinity(30): + xyp = XYP("XYP_BODY", 20.0, transform=transform, flukaregistry=freg) + + z = Zone() + z.addIntersection(xyp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T610_XZP_rototranslation.py b/tests/fluka/T610_XZP_rototranslation.py new file mode 100644 index 000000000..5a6379b12 --- /dev/null +++ b/tests/fluka/T610_XZP_rototranslation.py @@ -0,0 +1,42 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XZP, Region, Zone, FlukaRegistry, Transform, infinity +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "rppTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + with infinity(30): + xzp = XZP("XZP_BODY", 20.0, transform=transform, flukaregistry=freg) + + z = Zone() + z.addIntersection(xzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T610_YZP_rototranslation.py b/tests/fluka/T610_YZP_rototranslation.py new file mode 100644 index 000000000..619756a54 --- /dev/null +++ b/tests/fluka/T610_YZP_rototranslation.py @@ -0,0 +1,42 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YZP, Region, Zone, FlukaRegistry, Transform, infinity +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "rppTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + with infinity(30): + yzp = YZP("YZP_BODY", 20.0, transform=transform, flukaregistry=freg) + + z = Zone() + z.addIntersection(yzp) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T611_PLA_rototranslation.py b/tests/fluka/T611_PLA_rototranslation.py new file mode 100644 index 000000000..3292e267e --- /dev/null +++ b/tests/fluka/T611_PLA_rototranslation.py @@ -0,0 +1,46 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import PLA, Region, Zone, FlukaRegistry, Transform, infinity +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2( + "plaTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + + transform = Transform(rotoTranslation=rtrans) + + with infinity(30): + pla1 = PLA( + "PLA1_BODY", [1, 1, 1], [0, 0.0, 0], transform=transform, flukaregistry=freg + ) + + z1 = Zone() + + z1.addIntersection(pla1) + + region = Region("REG_INF") + region.addZone(z1) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T612_XCC_rototranslation.py b/tests/fluka/T612_XCC_rototranslation.py new file mode 100644 index 000000000..57fa521d3 --- /dev/null +++ b/tests/fluka/T612_XCC_rototranslation.py @@ -0,0 +1,50 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XCC, YZP, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + rtrans = rotoTranslationFromTra2( + "xccTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + xcc = XCC("XCC_BODY", 0, 0, 20, transform=transform, flukaregistry=freg) + + yzp_hi = YZP("YZP1_BODY", 20, transform=transform, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, transform=transform, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xcc) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T612_YCC_rototranslation.py b/tests/fluka/T612_YCC_rototranslation.py new file mode 100644 index 000000000..d156c25b7 --- /dev/null +++ b/tests/fluka/T612_YCC_rototranslation.py @@ -0,0 +1,50 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YCC, XZP, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + rtrans = rotoTranslationFromTra2( + "yccTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + ycc = YCC("YCC_BODY", 0, 0, 20, transform=transform, flukaregistry=freg) + + xzp_hi = XZP("XZP1_BODY", 20, transform=transform, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, transform=transform, flukaregistry=freg) + + z = Zone() + + z.addIntersection(ycc) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T612_ZCC_rototranslation.py b/tests/fluka/T612_ZCC_rototranslation.py new file mode 100644 index 000000000..dd182729c --- /dev/null +++ b/tests/fluka/T612_ZCC_rototranslation.py @@ -0,0 +1,50 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZCC, XYP, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + rtrans = rotoTranslationFromTra2( + "zccTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + zcc = ZCC("ZCC_BODY", 0, 0, 20, transform=transform, flukaregistry=freg) + + xyp_hi = XYP("XYP1_BODY", 20, transform=transform, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, transform=transform, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zcc) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T613_XEC_rototranslation.py b/tests/fluka/T613_XEC_rototranslation.py new file mode 100644 index 000000000..bab6cd39e --- /dev/null +++ b/tests/fluka/T613_XEC_rototranslation.py @@ -0,0 +1,51 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XEC, YZP, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + rtrans = rotoTranslationFromTra2( + "xecTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + # Bigger semi axis is y, smaller is z + xec = XEC("XEC_BODY", 0, 0, 20, 10, transform=transform, flukaregistry=freg) + + yzp_hi = YZP("YZP1_BODY", 20, transform=transform, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, transform=transform, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xec) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T613_YEC_rototranslation.py b/tests/fluka/T613_YEC_rototranslation.py new file mode 100644 index 000000000..f5aa7154a --- /dev/null +++ b/tests/fluka/T613_YEC_rototranslation.py @@ -0,0 +1,51 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YEC, XZP, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + rtrans = rotoTranslationFromTra2( + "yecTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + # Bigger semi axis is y, smaller is z + yec = YEC("YEC_BODY", 0, 0, 20, 10, transform=transform, flukaregistry=freg) + + xzp_hi = XZP("XZP1_BODY", 20, transform=transform, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, transform=transform, flukaregistry=freg) + + z = Zone() + + z.addIntersection(yec) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T613_ZEC_rototranslation.py b/tests/fluka/T613_ZEC_rototranslation.py new file mode 100644 index 000000000..0d8ae8d46 --- /dev/null +++ b/tests/fluka/T613_ZEC_rototranslation.py @@ -0,0 +1,51 @@ +import numpy as np + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZEC, XYP, Region, Zone, FlukaRegistry, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + + rtrans = rotoTranslationFromTra2( + "zecTRF", [[np.pi / 4, np.pi / 4, np.pi / 4], [0, 0, 20]] + ) + transform = Transform(rotoTranslation=rtrans) + + # Bigger semi axis is y, smaller is z + zec = ZEC("ZEC_BODY", 0, 0, 20, 10, transform=transform, flukaregistry=freg) + + xyp_hi = XYP("XYP1_BODY", 20, transform=transform, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, transform=transform, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zec) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T614_QUA_rototranslation.py b/tests/fluka/T614_QUA_rototranslation.py new file mode 100644 index 000000000..e3ad7751d --- /dev/null +++ b/tests/fluka/T614_QUA_rototranslation.py @@ -0,0 +1,61 @@ +import numpy as np +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import QUA, Region, Zone, FlukaRegistry, AABB, XYP, XZP, Transform +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rtrans = rotoTranslationFromTra2("quaTRF", [[0, 0, np.pi / 4], [0, 0, 0]]) + transform = Transform(rotoTranslation=rtrans) + + parabolicCylinder = QUA( + "parab", + 0.006, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + -200, + transform=transform, + flukaregistry=freg, + ) + + # 1 metre long parabolic cylinder 10cm tall from base to tip. + end1 = XYP("end1", 1000, flukaregistry=freg, transform=transform) + end2 = XYP("end2", 0, flukaregistry=freg, transform=transform) + end3 = XZP("end3", 100, flukaregistry=freg, transform=transform) + + z = Zone() + z.addIntersection(parabolicCylinder) + z.addIntersection(end1) + z.addSubtraction(end2) + z.addSubtraction(end3) + + region = Region("QUA_REG") + region.addZone(z) + freg.addRegion(region) + freg.assignma("COPPER", region) + + quaAABB = {"QUA_REG": AABB([-190.0, 40.0, 0], [50.0, 200.0, 1000.0])} + + greg = convert.fluka2Geant4(freg, quadricRegionAABBs=quaAABB) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(origin=[0, 100, 0], length=100) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T710_XYP_XZP_YZP_minimisation.py b/tests/fluka/T710_XYP_XZP_YZP_minimisation.py new file mode 100644 index 000000000..0c2d2b0c8 --- /dev/null +++ b/tests/fluka/T710_XYP_XZP_YZP_minimisation.py @@ -0,0 +1,66 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XYP, YZP, XZP, Region, Zone, FlukaRegistry +from pyg4ometry.fluka.body import INFINITY + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting cube is of the correct length is trivial. + xyp_lo = XYP("XYP1_BODY", 0, flukaregistry=freg) + xyp_hi = XYP("XYP2_BODY", 20.0, flukaregistry=freg) + + xzp_lo = XZP("XZP1_BODY", 0, flukaregistry=freg) + xzp_hi = XZP("XZP2_BODY", 20.0, flukaregistry=freg) + + yzp_lo = YZP("YZP1_BODY", 0, flukaregistry=freg) + yzp_hi = YZP("YZP2_BODY", 20.0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True, minimiseSolids=True) + + names = [ + "XYP1_BODY_e", + "XYP2_BODY_s", + "XZP1_BODY_e", + "XZP2_BODY_s", + "YZP1_BODY_e", + "YZP2_BODY_s", + ] + + for name in names: + # Subtract 10 because we expect some of them to be strictly + # smaller than INFINITY anyway because of automatic length safety. + assert greg.solidDict[name].pX < INFINITY - 10 + assert greg.solidDict[name].pY < INFINITY - 10 + assert greg.solidDict[name].pZ < INFINITY - 10 + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T711_PLA_minimisation.py b/tests/fluka/T711_PLA_minimisation.py new file mode 100644 index 000000000..248e24909 --- /dev/null +++ b/tests/fluka/T711_PLA_minimisation.py @@ -0,0 +1,66 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import PLA, Region, Zone, FlukaRegistry +from pyg4ometry.fluka.body import INFINITY + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # Bigger cube. + pla_a1 = PLA("PLA_A1_BODY", [0, 0, 20], [0, 0, 20], flukaregistry=freg) + pla_a2 = PLA("PLA_A2_BODY", [0, 0, 20], [0, 0, 0], flukaregistry=freg) + pla_b1 = PLA("PLA_B1_BODY", [0, 20, 0], [0, 20, 0], flukaregistry=freg) + pla_b2 = PLA("PLA_B2_BODY", [0, 20, 0], [0, 0, 0], flukaregistry=freg) + pla_c1 = PLA("PLA_C1_BODY", [20, 0, 0], [20, 0, 0], flukaregistry=freg) + pla_c2 = PLA("PLA_C2_BODY", [20, 0, 0], [0, 0, 0], flukaregistry=freg) + + z1 = Zone() + + # Box1: + z1.addIntersection(pla_a1) + z1.addSubtraction(pla_a2) + z1.addIntersection(pla_b1) + z1.addSubtraction(pla_b2) + z1.addIntersection(pla_c1) + z1.addSubtraction(pla_c2) + + region1 = Region("REG_INF1") + region1.addZone(z1) + + freg.addRegion(region1) + + freg.assignma("IRON", region1) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True, minimiseSolids=True) + names = [ + "PLA_A1_BODY_s", + "PLA_A2_BODY_e", + "PLA_B1_BODY_s", + "PLA_B2_BODY_e", + "PLA_C1_BODY_s", + "PLA_C2_BODY_e", + ] + + for name in names: + # Subtract 10 because we expect some of them to be strictly + # smaller than INFINITY anyway because of automatic length safety. + assert greg.solidDict[name].pX < INFINITY - 10 + assert greg.solidDict[name].pY < INFINITY - 10 + assert greg.solidDict[name].pZ < INFINITY - 10 + + wlv = greg.getWorldVolume() + wlv.checkOverlaps() + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T712_XCC_minimisation.py b/tests/fluka/T712_XCC_minimisation.py new file mode 100644 index 000000000..bfb28529e --- /dev/null +++ b/tests/fluka/T712_XCC_minimisation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XCC, YZP, Region, Zone, FlukaRegistry +from pyg4ometry.fluka.body import INFINITY + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + xcc = XCC("XCC_BODY", 0, 0, 20, flukaregistry=freg) + + yzp_hi = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xcc) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4( + freg, withLengthSafety=True, splitDisjointUnions=False, minimiseSolids=True + ) + + assert greg.solidDict["XCC_BODY_s"].pDz < INFINITY + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T712_YCC_minimisation.py b/tests/fluka/T712_YCC_minimisation.py new file mode 100644 index 000000000..dfe8e8fc1 --- /dev/null +++ b/tests/fluka/T712_YCC_minimisation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YCC, XZP, Region, Zone, FlukaRegistry +from pyg4ometry.fluka.body import INFINITY + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + ycc = YCC("YCC_BODY", 0, 0, 20, flukaregistry=freg) + + xzp_hi = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(ycc) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4( + freg, withLengthSafety=True, splitDisjointUnions=False, minimiseSolids=True + ) + + assert greg.solidDict["YCC_BODY_s"].pDz < INFINITY + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T712_ZCC_minimisation.py b/tests/fluka/T712_ZCC_minimisation.py new file mode 100644 index 000000000..de5aaf6d8 --- /dev/null +++ b/tests/fluka/T712_ZCC_minimisation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZCC, XYP, Region, Zone, FlukaRegistry +from pyg4ometry.fluka.body import INFINITY + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + zcc = ZCC("ZCC_BODY", 0, 0, 20, flukaregistry=freg) + + xyp_hi = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zcc) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4( + freg, withLengthSafety=True, splitDisjointUnions=False, minimiseSolids=True + ) + + assert greg.solidDict["ZCC_BODY_s"].pDz < INFINITY + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T713_XEC_minimisation.py b/tests/fluka/T713_XEC_minimisation.py new file mode 100644 index 000000000..54345847b --- /dev/null +++ b/tests/fluka/T713_XEC_minimisation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XEC, YZP, Region, Zone, FlukaRegistry +from pyg4ometry.fluka.body import INFINITY + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + xec = XEC("XEC_BODY", 0, 0, 20, 10, flukaregistry=freg) + + yzp_hi = YZP("YZP1_BODY", 20, flukaregistry=freg) + yzp_lo = YZP("YZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xec) + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4( + freg, withLengthSafety=True, splitDisjointUnions=False, minimiseSolids=True + ) + + assert greg.solidDict["XEC_BODY_s"].pDz < INFINITY + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T713_YEC_minimisation.py b/tests/fluka/T713_YEC_minimisation.py new file mode 100644 index 000000000..52fc5d39c --- /dev/null +++ b/tests/fluka/T713_YEC_minimisation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import YEC, XZP, Region, Zone, FlukaRegistry +from pyg4ometry.fluka.body import INFINITY + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + yec = YEC("YEC_BODY", 0, 0, 20, 10, flukaregistry=freg) + + xzp_hi = XZP("XZP1_BODY", 20, flukaregistry=freg) + xzp_lo = XZP("XZP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(yec) + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4( + freg, withLengthSafety=True, splitDisjointUnions=False, minimiseSolids=True + ) + + assert greg.solidDict["YEC_BODY_s"].pDz < INFINITY + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T713_ZEC_minimisation.py b/tests/fluka/T713_ZEC_minimisation.py new file mode 100644 index 000000000..90876bb86 --- /dev/null +++ b/tests/fluka/T713_ZEC_minimisation.py @@ -0,0 +1,46 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import ZEC, XYP, Region, Zone, FlukaRegistry +from pyg4ometry.fluka.body import INFINITY + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting body is of the correct length and radius + # is trivial. + zec = ZEC("ZEC_BODY", 0, 0, 20, 10, flukaregistry=freg) + + xyp_hi = XYP("XYP1_BODY", 20, flukaregistry=freg) + xyp_lo = XYP("XYP2_BODY", 0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(zec) + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4( + freg, withLengthSafety=True, splitDisjointUnions=False, minimiseSolids=True + ) + + assert greg.solidDict["ZEC_BODY_s"].pDz < INFINITY + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T801_filter_redundant_halfspaces.py b/tests/fluka/T801_filter_redundant_halfspaces.py new file mode 100644 index 000000000..428cb0985 --- /dev/null +++ b/tests/fluka/T801_filter_redundant_halfspaces.py @@ -0,0 +1,72 @@ +import logging + +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XZP, YZP, XYP, PLA, RPP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + + # logging.getLogger("pyg4ometry.convert.fluka2Geant4").setLevel(logging.DEBUG) + + faraway = 10000 + + xzp = XZP("XZP", faraway, flukaregistry=freg) + xzpsub = XZP("XZPsub", -faraway, flukaregistry=freg) + yzp = YZP("YZP", faraway, flukaregistry=freg) + yzpsub = YZP("YZPsub", -faraway, flukaregistry=freg) + xyp = XYP("XYP", faraway, flukaregistry=freg) + xypsub = XYP("XYPsub", -faraway, flukaregistry=freg) + + pla = PLA("PLA", [1, 1, 1], [faraway, faraway, faraway], flukaregistry=freg) + plasub = PLA( + "PLAsub", [1, 1, 1], [-faraway, -faraway, -faraway], flukaregistry=freg + ) + + plaDoesIntersect = PLA("PLAint", [1, 1, 1], [3, 3, 3], flukaregistry=freg) + + z = Zone() + z.addIntersection(rpp) + z.addIntersection(xyp) + z.addIntersection(xzp) + z.addIntersection(yzp) + z.addIntersection(pla) + + z.addIntersection(plaDoesIntersect) + + z.addSubtraction(xzpsub) + z.addSubtraction(yzpsub) + z.addSubtraction(xypsub) + z.addSubtraction(plasub) + + region = Region("RPP_REG") + region.addZone(z) + + assert len(region.bodies()) == 10 + + freg.addRegion(region) + freg.assignma("COPPER", region) + + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + assert len(greg.solidDict) == 4 # world, rpp, plaDoesInt, and rpp+plaDoesInt + + greg.getWorldVolume().clipSolid() + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T803_material_element.py b/tests/fluka/T803_material_element.py new file mode 100644 index 000000000..4776f2850 --- /dev/null +++ b/tests/fluka/T803_material_element.py @@ -0,0 +1,49 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Material + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + density = 2.48 + z = 87 + massNumber = None # i.e. determine it automatically given z. + fr = Material("FRANCIUM", z, density, massNumber=massNumber, flukaregistry=freg) + card = fr.toCards()[0] + assert card.keyword == "MATERIAL" + assert card.what1 == z + assert card.what3 == density + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + zone = Zone() + zone.addIntersection(rpp) + region = Region("RPP_REG") # should this be string or + + # material instance or maybe either? + region.addZone(zone) + freg.addRegion(region) + + freg.addMaterialAssignments(fr, region) + + greg = convert.fluka2Geant4(freg) + + lvmat = greg.logicalVolumeDict["RPP_REG_lv"].material + assert lvmat.name == "FRANCIUM" + assert lvmat.density == density + assert lvmat.atomic_number == z + assert lvmat.atomic_weight == 223 + greg.getWorldVolume().clipSolid() + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T804_material_mass_fraction.py b/tests/fluka/T804_material_mass_fraction.py new file mode 100644 index 000000000..c95c16b1c --- /dev/null +++ b/tests/fluka/T804_material_mass_fraction.py @@ -0,0 +1,58 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Material, Compound + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + fr = Material("FRANCIUM", 87, 2.48, flukaregistry=freg) + es = Material("EINSTEIN", 99, 8.84, flukaregistry=freg) + + fr2es3 = Compound( + "Fr2Es3", 7.5, [(fr, 2.0), (es, 3.0)], fractionType="mass", flukaregistry=freg + ) + + card = fr2es3.toCards() + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + zone = Zone() + zone.addIntersection(rpp) + region = Region("RPP_REG") # should this be string or + + # material instance or maybe either? + region.addZone(zone) + freg.addRegion(region) + freg.assignma("COPPER", region) + + freg.addMaterialAssignments(fr2es3, region) + + greg = convert.fluka2Geant4(freg) + + lvmat = greg.logicalVolumeDict["RPP_REG_lv"].material + comp = lvmat.components + first = comp[0] + second = comp[1] + + assert first[0].name == "FRANCIUM" + assert first[1] == 0.4 + assert first[2] == "massfraction" + + assert second[0].name == "EINSTEIN" + assert second[1] == 0.6 + assert second[2] == "massfraction" + + greg.getWorldVolume().clipSolid() + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T805_material_volume_fraction.py b/tests/fluka/T805_material_volume_fraction.py new file mode 100644 index 000000000..427517502 --- /dev/null +++ b/tests/fluka/T805_material_volume_fraction.py @@ -0,0 +1,57 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Material, Compound + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + fr = Material("FRANCIUM", 87, 2, flukaregistry=freg) + es = Material("EINSTEIN", 99, 8, flukaregistry=freg) + + fr2es3 = Compound( + "Fr2Es3", 7.5, [(fr, 1.0), (es, 1.0)], fractionType="volume", flukaregistry=freg + ) + + card = fr2es3.toCards() + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + zone = Zone() + zone.addIntersection(rpp) + region = Region("RPP_REG") # should this be string or + + # material instance or maybe either? + region.addZone(zone) + freg.addRegion(region) + + freg.addMaterialAssignments(fr2es3, region) + + greg = convert.fluka2Geant4(freg) + + lvmat = greg.logicalVolumeDict["RPP_REG_lv"].material + comp = lvmat.components + first = comp[0] + second = comp[1] + + assert first[0].name == "FRANCIUM" + assert first[1] == 0.2 + assert first[2] == "massfraction" + + assert second[0].name == "EINSTEIN" + assert second[1] == 0.8 + assert second[2] == "massfraction" + + greg.getWorldVolume().clipSolid() + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T806_material_atomic_fraction.py b/tests/fluka/T806_material_atomic_fraction.py new file mode 100644 index 000000000..179c7ba3a --- /dev/null +++ b/tests/fluka/T806_material_atomic_fraction.py @@ -0,0 +1,71 @@ +import os +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry import gdml +from pyg4ometry.fluka import RPP, Region, Zone, FlukaRegistry, Material, Compound + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + fr = Material("FRANCIUM", 50, 2, flukaregistry=freg) + es = Material("EINSTEIN", 100, 8, flukaregistry=freg) + + frFrac = 0.5 + frEs = 0.5 + + fr2es3 = Compound( + "Fr2Es3", + 7.5, + [(fr, frFrac), (es, frEs)], + fractionType="atomic", + flukaregistry=freg, + ) + + card = fr2es3.toCards() + + rpp = RPP("RPP_BODY", 0, 10, 0, 10, 0, 10, flukaregistry=freg) + zone = Zone() + zone.addIntersection(rpp) + region = Region("RPP_REG") # should this be string or + + # material instance or maybe either? + region.addZone(zone) + freg.addRegion(region) + + freg.addMaterialAssignments(fr2es3, region) + + greg = convert.fluka2Geant4(freg) + + lvmat = greg.logicalVolumeDict["RPP_REG_lv"].material + comp = lvmat.components + first = comp[0] + second = comp[1] + + assert first[0].name == "FRANCIUM" + assert first[2] == "massfraction" + + assert second[0].name == "EINSTEIN" + assert second[2] == "massfraction" + + greg.getWorldVolume().clipSolid() + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + w = gdml.Writer() + w.addDetector(greg) + gdml_name = "atom.inp".rstrip(".inp") + ".gdml" + gmad_name = "atom.inp".rstrip(".inp") + ".gmad" + w.write(os.path.join(os.path.dirname(__file__), gdml_name)) + w.writeGmadTester(gmad_name, gdml_name) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T901_cube_from_XYP_XZP_YZP.py b/tests/fluka/T901_cube_from_XYP_XZP_YZP.py new file mode 100644 index 000000000..152f5c17b --- /dev/null +++ b/tests/fluka/T901_cube_from_XYP_XZP_YZP.py @@ -0,0 +1,49 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import XYP, YZP, XZP, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + # I pick 20 because that's the length of the axes added below, so + # verifying the resulting cube is of the correct length is trivial. + xyp_lo = XYP("XYP1_BODY", 0, flukaregistry=freg) + xyp_hi = XYP("XYP2_BODY", 20.0, flukaregistry=freg) + + xzp_lo = XZP("XZP1_BODY", 0, flukaregistry=freg) + xzp_hi = XZP("XZP2_BODY", 20.0, flukaregistry=freg) + + yzp_lo = YZP("YZP1_BODY", 0, flukaregistry=freg) + yzp_hi = YZP("YZP2_BODY", 20.0, flukaregistry=freg) + + z = Zone() + + z.addIntersection(xyp_hi) + z.addSubtraction(xyp_lo) + + z.addIntersection(xzp_hi) + z.addSubtraction(xzp_lo) + + z.addIntersection(yzp_hi) + z.addSubtraction(yzp_lo) + + region = Region("REG_INF") + region.addZone(z) + + freg.addRegion(region) + freg.assignma("COPPER", region) + + greg = convert.fluka2Geant4(freg) + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(greg.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/T902_cube_from_six_PLAs.py b/tests/fluka/T902_cube_from_six_PLAs.py new file mode 100644 index 000000000..95961b076 --- /dev/null +++ b/tests/fluka/T902_cube_from_six_PLAs.py @@ -0,0 +1,50 @@ +import pyg4ometry.convert as convert +import pyg4ometry.visualisation as vi +from pyg4ometry.fluka import PLA, Region, Zone, FlukaRegistry + + +def Test(vis=False, interactive=False): + freg = FlukaRegistry() + + # Bigger cube. + pla_a1 = PLA("PLA_A1_BODY", [0, 0, 20], [0, 0, 20], flukaregistry=freg) + pla_a2 = PLA("PLA_A2_BODY", [0, 0, 20], [0, 0, 0], flukaregistry=freg) + pla_b1 = PLA("PLA_B1_BODY", [0, 20, 0], [0, 20, 0], flukaregistry=freg) + pla_b2 = PLA("PLA_B2_BODY", [0, 20, 0], [0, 0, 0], flukaregistry=freg) + pla_c1 = PLA("PLA_C1_BODY", [20, 0, 0], [20, 0, 0], flukaregistry=freg) + pla_c2 = PLA("PLA_C2_BODY", [20, 0, 0], [0, 0, 0], flukaregistry=freg) + + z1 = Zone() + + # Box1: + z1.addIntersection(pla_a1) + z1.addSubtraction(pla_a2) + z1.addIntersection(pla_b1) + z1.addSubtraction(pla_b2) + z1.addIntersection(pla_c1) + z1.addSubtraction(pla_c2) + + region1 = Region("REG_INF1") + region1.addZone(z1) + + freg.addRegion(region1) + + freg.assignma("IRON", region1) + + greg = convert.fluka2Geant4(freg, withLengthSafety=True, splitDisjointUnions=False) + + wlv = greg.getWorldVolume() + wlv.checkOverlaps() + + v = None + if vis: + v = vi.VtkViewer() + v.addAxes(length=20) + v.addLogicalVolume(wlv) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": greg.getWorldVolume(), "vtkViewer": v} + + +if __name__ == "__main__": + Test(True, True) diff --git a/tests/fluka/test_Fluka.py b/tests/fluka/test_Fluka.py new file mode 100644 index 000000000..f2354f4d2 --- /dev/null +++ b/tests/fluka/test_Fluka.py @@ -0,0 +1,762 @@ +from random import random +import numpy as np +import pytest + +from pyg4ometry.fluka.fluka_registry import RotoTranslationStore, FlukaRegistry +from pyg4ometry.fluka.directive import rotoTranslationFromTra2 + +import T001_RPP +import T002_BOX +import T003_SPH +import T004_RCC +import T005_REC +import T006_TRC +import T007_ELL +import T008_RAW +import T008_WED +import T009_ARB +import T010_XYP +import T010_XZP +import T010_YZP +import T011_PLA +import T012_XCC +import T012_YCC +import T012_ZCC +import T013_XEC +import T013_YEC +import T013_ZEC +import T014_QUA + +import T051_expansion +import T052_translation +import T090_lattice + +import T101_region_one_body +import T102_region_intersection_two_bodies +import T103_region_subtraction_two_bodies +import T103_region_subtraction_two_bodies_RCC +import T104_region_union_two_zones +import T104_region_union_two_zones_2 +import T105_region_subzone_subtraction +import T106_region_subzone_subtraction_with_union +import T107_region_union_with_reused_bodies + +import T201_RPP_coplanar +import T202_BOX_coplanar +import T203_SPH_coplanar +import T204_RCC_coplanar +import T205_REC_coplanar +import T206_TRC_coplanar +import T207_ELL_coplanar +import T208_RAW_coplanar +import T208_WED_coplanar +import T209_ARB_coplanar +import T210_PLA_coplanar +import T210_XYP_coplanar +import T210_XZP_coplanar +import T210_YZP_coplanar +import T212_XCC_coplanar +import T212_YCC_coplanar +import T212_ZCC_coplanar +import T213_XEC_coplanar +import T213_YEC_coplanar +import T213_ZEC_coplanar +import T214_QUA_coplanar + +import T401_RPP_expansion +import T402_BOX_expansion +import T403_SPH_expansion +import T404_RCC_expansion +import T405_REC_expansion +import T406_TRC_expansion +import T407_ELL_expansion +import T408_RAW_expansion +import T408_WED_expansion +import T409_ARB_expansion +import T410_XYP_expansion +import T410_XZP_expansion +import T410_YZP_expansion +import T411_PLA_expansion +import T412_XCC_expansion +import T412_YCC_expansion +import T412_ZCC_expansion +import T413_XEC_expansion +import T413_YEC_expansion +import T413_ZEC_expansion +import T414_QUA_expansion +import T501_RPP_translation +import T502_BOX_translation +import T503_SPH_translation +import T504_RCC_translation +import T505_REC_translation +import T506_TRC_translation +import T507_ELL_translation +import T508_RAW_translation +import T508_WED_translation +import T509_ARB_translation +import T510_XYP_translation +import T510_XZP_translation +import T510_YZP_translation +import T511_PLA_translation +import T512_XCC_translation +import T512_YCC_translation +import T512_ZCC_translation +import T513_XEC_translation +import T513_YEC_translation +import T513_ZEC_translation +import T514_QUA_translation + +import T601_RPP_rototranslation +import T602_BOX_rototranslation +import T603_SPH_rototranslation +import T604_RCC_rototranslation +import T605_REC_rototranslation +import T606_TRC_rototranslation +import T607_ELL_rototranslation +import T608_RAW_rototranslation +import T608_WED_rototranslation +import T609_ARB_rototranslation +import T610_XYP_rototranslation +import T610_XZP_rototranslation +import T610_YZP_rototranslation +import T611_PLA_rototranslation +import T612_XCC_rototranslation +import T612_YCC_rototranslation +import T612_ZCC_rototranslation +import T613_XEC_rototranslation +import T613_YEC_rototranslation +import T613_ZEC_rototranslation +import T614_QUA_rototranslation + +import T710_XYP_XZP_YZP_minimisation +import T711_PLA_minimisation +import T712_XCC_minimisation +import T712_YCC_minimisation +import T712_ZCC_minimisation +import T713_XEC_minimisation +import T713_YEC_minimisation +import T713_ZEC_minimisation + +import T801_filter_redundant_halfspaces +import T803_material_element + +import T901_cube_from_XYP_XZP_YZP +import T902_cube_from_six_PLAs + + +def test_PythonFluka_T001_RPP(): + T001_RPP.Test(False, False) + + +def test_PythonFluka_T002_BOX(): + T002_BOX.Test(False, False) + + +def test_PythonFluka_T003_SPH(): + T003_SPH.Test(False, False) + + +def test_PythonFluka_T004_RCC(): + T004_RCC.Test(False, False) + + +def test_PythonFluka_T005_REC(): + T005_REC.Test(False, False) + + +def test_PythonFluka_T006_TRC(): + T006_TRC.Test(False, False) + + +def test_PythonFluka_T007_ELL(): + T007_ELL.Test(False, False) + + +def test_PythonFluka_T008_RAW(): + T008_RAW.Test(False, False) + + +def test_PythonFluka_T008_WED(): + T008_WED.Test(False, False) + + +def test_PythonFluka_T009_ARB(): + T009_ARB.Test(False, False) + + +def test_PythonFluka_T010_XYP(): + T010_XYP.Test(False, False) + + +def test_PythonFluka_T010_XZP(): + T010_XZP.Test(False, False) + + +def test_PythonFluka_T010_YZP(): + T010_YZP.Test(False, False) + + +def test_PythonFluka_T011_PLA(): + T011_PLA.Test(False, False) + + +def test_PythonFluka_T012_XCC(): + T012_XCC.Test(False, False) + + +def test_PythonFluka_T012_YCC(): + T012_YCC.Test(False, False) + + +def test_PythonFluka_T012_ZCC(): + T012_ZCC.Test(False, False) + + +def test_PythonFluka_T013_XEC(): + T013_XEC.Test(False, False) + + +def test_PythonFluka_T013_YEC(): + T013_YEC.Test(False, False) + + +def test_PythonFluka_T013_ZEC(): + T013_ZEC.Test(False, False) + + +def test_PythonFluka_T014_QUA(): + T014_QUA.Test(False, False) + + +def test_PythonFluka_T051_expansion(): + T051_expansion.Test(False, False) + + +def test_PythonFluka_T052_translation(): + T052_translation.Test(False, False) + + +def test_PythonFluka_T090_lattice(): + T090_lattice.Test(False, False) + + +# 1111111111 +def test_PythonFluka_T101_region_one_body(): + T101_region_one_body.Test(False, False) + + +def test_PythonFluka_T102_region_intersection_two_bodies(): + T102_region_intersection_two_bodies.Test(False, False) + + +def test_PythonFluka_T103_region_subtraction_two_bodies(): + T103_region_subtraction_two_bodies.Test(False, False) + + +def test_PythonFluka_T103_region_subtraction_two_bodies_RCC(): + T103_region_subtraction_two_bodies_RCC.Test(False, False) + + +def test_PythonFluka_T104_region_union_two_zones(): + T104_region_union_two_zones.Test(False, False) + + +def test_PythonFluka_T104_region_union_two_zones_2(): + T104_region_union_two_zones_2.Test(False, False) + + +def test_PythonFluka_T105_region_subzone_subtraction(): + T105_region_subzone_subtraction.Test(False, False) + + +def test_PythonFluka_T106_region_subzone_subtraction_with_union(): + T106_region_subzone_subtraction_with_union.Test(False, False) + + +def test_PythonFluka_T107_region_union_with_reused_bodies(): + T107_region_union_with_reused_bodies.Test(False, False) + + +# 2222222222 +def test_PythonFluka_T201_RPP_coplanar(): + T201_RPP_coplanar.Test(False, False) + + +def test_PythonFluka_T202_BOX_coplanar(): + T202_BOX_coplanar.Test(False, False) + + +def test_PythonFluka_T203_SPH_coplanar(): + T203_SPH_coplanar.Test(False, False) + + +def test_PythonFluka_T204_RCC_coplanar(): + T204_RCC_coplanar.Test(False, False) + + +def test_PythonFluka_T205_REC_coplanar(): + T205_REC_coplanar.Test(False, False) + + +def test_PythonFluka_T206_TRC_coplanar(): + T206_TRC_coplanar.Test(False, False) + + +def test_PythonFluka_T207_ELL_coplanar(): + T207_ELL_coplanar.Test(False, False) + + +def test_PythonFluka_T208_RAW_coplanar(): + T208_RAW_coplanar.Test(False, False) + + +def test_PythonFluka_T208_WED_coplanar(): + T208_WED_coplanar.Test(False, False) + + +def test_PythonFluka_T209_ARB_coplanar(): + T209_ARB_coplanar.Test(False, False) + + +def test_PythonFluka_T210_PLA_coplanar(): + T210_PLA_coplanar.Test(False, False) + + +def test_PythonFluka_T210_XYP_coplanar(): + T210_XYP_coplanar.Test(False, False) + + +def test_PythonFluka_T210_XZP_coplanar(): + T210_XZP_coplanar.Test(False, False) + + +def test_PythonFluka_T210_YZP_coplanar(): + T210_YZP_coplanar.Test(False, False) + + +def test_PythonFluka_T212_XCC_coplanar(): + T212_XCC_coplanar.Test(False, False) + + +def test_PythonFluka_T212_YCC_coplanar(): + T212_YCC_coplanar.Test(False, False) + + +def test_PythonFluka_T212_ZCC_coplanar(): + T212_ZCC_coplanar.Test(False, False) + + +def test_PythonFluka_T213_XEC_coplanar(): + T213_XEC_coplanar.Test(False, False) + + +def test_PythonFluka_T213_YEC_coplanar(): + T213_YEC_coplanar.Test(False, False) + + +def test_PythonFluka_T213_ZEC_coplanar(): + T213_ZEC_coplanar.Test(False, False) + + +def test_PythonFluka_T214_QUA_coplanar(): + T214_QUA_coplanar.Test(False, False) + + +# 4444444444 +def test_PythonFluka_T401_RPP_expansion(): + T401_RPP_expansion.Test(False, False) + + +def test_PythonFluka_T402_BOX_expansion(): + T402_BOX_expansion.Test(False, False) + + +def test_PythonFluka_T403_SPH_expansion(): + T403_SPH_expansion.Test(False, False) + + +def test_PythonFluka_T404_RCC_expansion(): + T404_RCC_expansion.Test(False, False) + + +def test_PythonFluka_T405_REC_expansion(): + T405_REC_expansion.Test(False, False) + + +def test_PythonFluka_T406_TRC_expansion(): + T406_TRC_expansion.Test(False, False) + + +def test_PythonFluka_T407_ELL_expansion(): + T407_ELL_expansion.Test(False, False) + + +def test_PythonFluka_T408_RAW_expansion(): + T408_RAW_expansion.Test(False, False) + + +def test_PythonFluka_T408_WED_expansion(): + T408_WED_expansion.Test(False, False) + + +def test_PythonFluka_T409_ARB_expansion(): + T409_ARB_expansion.Test(False, False) + + +def test_PythonFluka_T410_XYP_expansion(): + T410_XYP_expansion.Test(False, False) + + +def test_PythonFluka_T410_XZP_expansion(): + T410_XZP_expansion.Test(False, False) + + +def test_PythonFluka_T410_YZP_expansion(): + T410_YZP_expansion.Test(False, False) + + +def test_PythonFluka_T411_PLA_expansion(): + T411_PLA_expansion.Test(False, False) + + +def test_PythonFluka_T412_XCC_expansion(): + T412_XCC_expansion.Test(False, False) + + +def test_PythonFluka_T412_YCC_expansion(): + T412_YCC_expansion.Test(False, False) + + +def test_PythonFluka_T412_ZCC_expansion(): + T412_ZCC_expansion.Test(False, False) + + +def test_PythonFluka_T413_XEC_expansion(): + T413_XEC_expansion.Test(False, False) + + +def test_PythonFluka_T413_YEC_expansion(): + T413_YEC_expansion.Test(False, False) + + +def test_PythonFluka_T413_ZEC_expansion(): + T413_ZEC_expansion.Test(False, False) + + +def test_PythonFluka_T414_QUA_expansion(): + T414_QUA_expansion.Test(False, False) + + +def test_PythonFluka_T501_RPP_translation(): + T501_RPP_translation.Test(False, False) + + +def test_PythonFluka_T502_BOX_translation(): + T502_BOX_translation.Test(False, False) + + +def test_PythonFluka_T503_SPH_translation(): + T503_SPH_translation.Test(False, False) + + +def test_PythonFluka_T504_RCC_translation(): + T504_RCC_translation.Test(False, False) + + +def test_PythonFluka_T505_REC_translation(): + T505_REC_translation.Test(False, False) + + +def test_PythonFluka_T506_TRC_translation(): + T506_TRC_translation.Test(False, False) + + +def test_PythonFluka_T507_ELL_translation(): + T507_ELL_translation.Test(False, False) + + +def test_PythonFluka_T508_RAW_translation(): + T508_RAW_translation.Test(False, False) + + +def test_PythonFluka_T508_WED_translation(): + T508_WED_translation.Test(False, False) + + +def test_PythonFluka_T509_ARB_translation(): + T509_ARB_translation.Test(False, False) + + +def test_PythonFluka_T510_XYP_translation(): + T510_XYP_translation.Test(False, False) + + +def test_PythonFluka_T510_XZP_translation(): + T510_XZP_translation.Test(False, False) + + +def test_PythonFluka_T510_YZP_translation(): + T510_YZP_translation.Test(False, False) + + +def test_PythonFluka_T511_PLA_translation(): + T511_PLA_translation.Test(False, False) + + +def test_PythonFluka_T512_XCC_translation(): + T512_XCC_translation.Test(False, False) + + +def test_PythonFluka_T512_YCC_translation(): + T512_YCC_translation.Test(False, False) + + +def test_PythonFluka_T512_ZCC_translation(): + T512_ZCC_translation.Test(False, False) + + +def test_PythonFluka_T513_XEC_translation(): + T513_XEC_translation.Test(False, False) + + +def test_PythonFluka_T513_YEC_translation(): + T513_YEC_translation.Test(False, False) + + +def test_PythonFluka_T513_ZEC_translation(): + T513_ZEC_translation.Test(False, False) + + +def test_PythonFluka_T514_QUA_translation(): + T514_QUA_translation.Test(False, False) + + +# 6666666666 +def test_PythonFluka_T601_RPP_rototranslation(): + T601_RPP_rototranslation.Test(False, False) + + +def test_PythonFluka_T602_BOX_rototranslation(): + T602_BOX_rototranslation.Test(False, False) + + +def test_PythonFluka_T603_SPH_rototranslation(): + T603_SPH_rototranslation.Test(False, False) + + +def test_PythonFluka_T604_RCC_rototranslation(): + T604_RCC_rototranslation.Test(False, False) + + +def test_PythonFluka_T605_REC_rototranslation(): + T605_REC_rototranslation.Test(False, False) + + +def test_PythonFluka_T606_TRC_rototranslation(): + T606_TRC_rototranslation.Test(False, False) + + +def test_PythonFluka_T607_ELL_rototranslation(): + T607_ELL_rototranslation.Test(False, False) + + +def test_PythonFluka_T608_RAW_rototranslation(): + T608_RAW_rototranslation.Test(False, False) + + +def test_PythonFluka_T608_WED_rototranslation(): + T608_WED_rototranslation.Test(False, False) + + +def test_PythonFluka_T609_ARB_rototranslation(): + T609_ARB_rototranslation.Test(False, False) + + +def test_PythonFluka_T610_XYP_rototranslation(): + T610_XYP_rototranslation.Test(False, False) + + +def test_PythonFluka_T610_XZP_rototranslation(): + T610_XZP_rototranslation.Test(False, False) + + +def test_PythonFluka_T610_YZP_rototranslation(): + T610_YZP_rototranslation.Test(False, False) + + +def test_PythonFluka_T611_PLA_rototranslation(): + T611_PLA_rototranslation.Test(False, False) + + +def test_PythonFluka_T612_XCC_rototranslation(): + T612_XCC_rototranslation.Test(False, False) + + +def test_PythonFluka_T612_YCC_rototranslation(): + T612_YCC_rototranslation.Test(False, False) + + +def test_PythonFluka_T612_ZCC_rototranslation(): + T612_ZCC_rototranslation.Test(False, False) + + +def test_PythonFluka_T613_XEC_rototranslation(): + T613_XEC_rototranslation.Test(False, False) + + +def test_PythonFluka_T613_YEC_rototranslation(): + T613_YEC_rototranslation.Test(False, False) + + +def test_PythonFluka_T613_ZEC_rototranslation(): + T613_ZEC_rototranslation.Test(False, False) + + +def test_PythonFluka_T614_QUA_rototranslation(): + T614_QUA_rototranslation.Test(False, False) + + +# 7777777777 +def test_PythonFluka_T710_XYP_XZP_YZP_minimisation(): + T710_XYP_XZP_YZP_minimisation.Test(False, False) + + +def test_PythonFluka_T711_PLA_minimisation(): + T711_PLA_minimisation.Test(False, False) + + +def test_PythonFluka_T712_XCC_minimisation(): + T712_XCC_minimisation.Test(False, False) + + +def test_PythonFluka_T712_YCC_minimisation(): + T712_YCC_minimisation.Test(False, False) + + +def test_PythonFluka_T712_ZCC_minimisation(): + T712_ZCC_minimisation.Test(False, False) + + +def test_PythonFluka_T713_XEC_minimisation(): + T713_XEC_minimisation.Test(False, False) + + +def test_PythonFluka_T713_YEC_minimisation(): + T713_YEC_minimisation.Test(False, False) + + +def test_PythonFluka_T713_ZEC_minimisation(): + T713_ZEC_minimisation.Test(False, False) + + +# 8888888888 +def test_PythonFluka_T801_filter_redundant_halfspaces(): + T801_filter_redundant_halfspaces.Test(False, False) + + +def test_PythonFluka_T803_material_element(): + T803_material_element.Test(False, False) + + +# 9999999999 +def test_PythonFluka_T901_cube_from_XYP_XZP_YZP(): + T901_cube_from_XYP_XZP_YZP.Test(False, False) + + +def test_PythonFluka_T902_cube_from_six_PLAs(): + T902_cube_from_six_PLAs.Test(False, False) + + +def test_PythonFluka_empyRegistry(): + import pyg4ometry.convert as convert + from pyg4ometry.fluka import FlukaRegistry + + freg = FlukaRegistry() + try: + greg = convert.fluka2Geant4(freg) + except ValueError: + pass + + +def _makeRotoTranslation(name="rppTRF"): + angle = random() * np.pi + rtrans = rotoTranslationFromTra2(name, [[angle, angle, angle], [0, 0, 20]]) + return name, rtrans + + +def _makeStore(): + return RotoTranslationStore() + + +def test_storeInit(): + _makeStore() + + +def test_gettingRotoTranslation(): + name, rtrans = _makeRotoTranslation() + store = _makeStore() + store[name] = rtrans + r = store[name] + + +def test_RotoTranslation_fails_setting_with_wrong_name(): + name, rtrans = _makeRotoTranslation() + store = _makeStore() + # TODO + # with pytest.raises(ValueError): + # store["asdasd"] = rtrans + + +def test_RotoTranslation_fails_without_rotoTranslation(): + name, rtrans = _makeRotoTranslation() + store = _makeStore() + # TODO check this test + # with pytest.raises(TypeError): + # store[name] = "something" + + +def test_store_len(): + name, rtrans = _makeRotoTranslation() + store = _makeStore() + # assert(len(store), 0) + store[name] = rtrans + # assert(len(store), 1) + + +def test_store_del(): + name, rtrans = _makeRotoTranslation() + store = _makeStore() + # assert(len(store), 0) + store[name] = rtrans + # assert(len(store), 1) + del store[name] + # assert(len(store), 0) + + +def test_addRotoTranslation(): + name1, rtrans1 = _makeRotoTranslation(name="rtrans1") + name2, rtrans2 = _makeRotoTranslation(name="rtrans2") + name3, rtrans3 = _makeRotoTranslation(name="rtrans3") + name4, rtrans4 = _makeRotoTranslation(name="rtrans4") + name5, rtrans5 = _makeRotoTranslation(name="rtrans5") + + store = _makeStore() + + store.addRotoTranslation(rtrans1) + store.addRotoTranslation(rtrans2) + # assert(rtrans1.transformationIndex, 2000) + # assert(rtrans2.transformationIndex, 3000) + del store[name1] + store.addRotoTranslation(rtrans3) + # assert(rtrans3.transformationIndex, 4000) + + # assert(store.allTransformationIndices(), [3000, 4000]) + + rtrans4.transformationIndex = 9000 + store.addRotoTranslation(rtrans4) + # assert(rtrans4.transformationIndex, 9000) + + rtrans5.transformationIndex = 9000 + # TODO check + # with pytest.raises(KeyError): + # store.addRotoTranslation(rtrans5) diff --git a/tests/fluka/test_FlukaLoad.py b/tests/fluka/test_FlukaLoad.py new file mode 100644 index 000000000..a73fec662 --- /dev/null +++ b/tests/fluka/test_FlukaLoad.py @@ -0,0 +1,438 @@ +import os as _os + +import pyg4ometry.fluka as _fluka +import pyg4ometry.visualisation as _vi +import pyg4ometry.gdml as _gdml +from pyg4ometry.convert import fluka2Geant4 as _fluka2Geant4 +import pyg4ometry.geant4.solid + + +def _pj(filename): + """ + Append the absolute path to *this* directory to the filename so the tests + can be ran from anywhere + """ + return _os.path.join(_os.path.dirname(__file__), filename) + + +def flairLoadWriteTest(fileName, vis=True, interactive=False, quadricRegionAABBs=None): + r = _fluka.Reader(_pj(fileName)) + + greg = _fluka2Geant4(r.flukaregistry, quadricRegionAABBs=quadricRegionAABBs) + + wlv = greg.getWorldVolume() + + if vis: + v = _vi.VtkViewer() + v.addAxes(length=20) + wlv.checkOverlaps() + v.addLogicalVolume(wlv) + v.view(interactive) + + w = _gdml.Writer() + w.addDetector(greg) + + # TODO write to temporary directory + # gdmlFileName = fileName.replace(".inp", ".gdml") + # gmadFileName = fileName.replace(".inp", ".gmad") + # w.write(_os.path.join(_os.path.dirname(__file__), gdmlFileName)) + # w.writeGmadTester(_os.path.join(_os.path.dirname(__file__),gmadFileName),gdmlFileName) + + return r.flukaregistry, greg + + +def test_FlairLoad_T001_RPP(testdata): + flairLoadWriteTest(testdata["fluka/001_RPP.inp"], False, False) + + +def test_FlairLoad_T002_BOX(testdata): + flairLoadWriteTest(testdata["fluka/002_BOX.inp"], False, False) + + +def test_FlairLoad_T003_SPH(testdata): + flairLoadWriteTest(testdata["fluka/003_SPH.inp"], False, False) + + +def test_FlairLoad_T004_RCC(testdata): + flairLoadWriteTest(testdata["fluka/004_RCC.inp"], False, False) + + +def test_FlairLoad_T005_REC(testdata): + flairLoadWriteTest(testdata["fluka/005_REC.inp"], False, False) + + +def test_FlairLoad_T006_TRC(testdata): + flairLoadWriteTest(testdata["fluka/006_TRC.inp"], False, False) + + +def test_FlairLoad_T007_ELL(testdata): + flairLoadWriteTest(testdata["fluka/007_ELL.inp"], False, False) + + +def test_FlairLoad_T009_ARB(testdata): + flairLoadWriteTest(testdata["fluka/009_ARB.inp"], False, False) + + +def test_FlairLoad_T009_ARB_cube_anticlockwise(testdata): + flairLoadWriteTest(testdata["fluka/009_ARB_cube_anticlockwise.inp"], False, False) + + +def test_FlairLoad_T009_ARB_cube_clockwise(testdata): + flairLoadWriteTest(testdata["fluka/009_ARB_cube_clockwise.inp"], False, False) + + +def test_FlairLoad_T011_XYP(testdata): + flairLoadWriteTest(testdata["fluka/011_XYP.inp"], False, False) + + +def test_FlairLoad_T012_XZP(testdata): + flairLoadWriteTest(testdata["fluka/012_XZP.inp"], False, False) + + +def test_FlairLoad_T013_YZP(testdata): + flairLoadWriteTest(testdata["fluka/013_YZP.inp"], False, False) + + +def test_FlairLoad_T014_PLA(testdata): + flairLoadWriteTest(testdata["fluka/014_PLA.inp"], False, False) + + +def test_FlairLoad_T015_XCC(testdata): + flairLoadWriteTest(testdata["fluka/015_XCC.inp"], False, False) + + +def test_FlairLoad_T016_YCC(testdata): + flairLoadWriteTest(testdata["fluka/016_YCC.inp"], False, False) + + +def test_FlairLoad_T017_ZCC(testdata): + flairLoadWriteTest(testdata["fluka/017_ZCC.inp"], False, False) + + +def test_FlairLoad_T018_XEC(testdata): + flairLoadWriteTest(testdata["fluka/018_XEC.inp"], False, False) + + +def test_FlairLoad_T019_YEC(testdata): + flairLoadWriteTest(testdata["fluka/019_YEC.inp"], False, False) + + +def test_FlairLoad_T020_ZEC(testdata): + flairLoadWriteTest(testdata["fluka/020_ZEC.inp"], False, False) + + +def test_FlairLoad_T021_QUA(testdata): + quaAABB = {"QUA_REG": _fluka.AABB([-150.0, 100.0, 0], [150.0, 200.0, 1000.0])} + flairLoadWriteTest( + testdata["fluka/021_QUA.inp"], False, False, quadricRegionAABBs=quaAABB + ) + + +def test_FlairLoad_T050_RPP_Translate(testdata): + flairLoadWriteTest(testdata["fluka/050_RPP_Translate.inp"], False, False) + + +def test_FlairLoad_T051_RPP_Expansion(testdata): + flairLoadWriteTest(testdata["fluka/051_RPP_Expansion.inp"], False, False) + + +def test_FlairLoad_T052_RPP_RotDefi(testdata): + flairLoadWriteTest(testdata["fluka/052_RPP_RotDefi.inp"], False, False) + + +def test_FlairLoad_T053_RPP_RotDefi2(testdata): + flairLoadWriteTest(testdata["fluka/053_RPP_RotDefi2.inp"], False, False) + + +def test_FlairLoad_T054_RPP_TranslateExpansionRotDefi(testdata): + flairLoadWriteTest( + testdata["fluka/054_RPP_TranslateExpansionRotDefi.inp"], False, False + ) + + +def test_FlairLoad_T100_Multiple(testdata): + flairLoadWriteTest(testdata["fluka/100_Multiple.inp"], False, False) + + +def test_FlairLoad_T101_Intersection(testdata): + flairLoadWriteTest(testdata["fluka/101_Intersection.inp"], False, False) + + +def test_FlairLoad_T102_Difference(testdata): + flairLoadWriteTest(testdata["fluka/102_Difference.inp"], False, False) + + +def test_FlairLoad_T103_Union(testdata): + flairLoadWriteTest(testdata["fluka/103_Union.inp"], False, False) + + +def test_FlairLoad_T104_Union(testdata): + flairLoadWriteTest(testdata["fluka/104_shift_cylinders.inp"], False, False) + + +def test_FlairLoad_T301_RPP_transform(testdata): + flairLoadWriteTest(testdata["fluka/301_RPP_transform.inp"], False, False) + + +def test_FlairLoad_T302_BOX_transform(testdata): + flairLoadWriteTest(testdata["fluka/302_BOX_transform.inp"], False, False) + + +def test_FlairLoad_T303_SPH_transform(testdata): + flairLoadWriteTest(testdata["fluka/303_SPH_transform.inp"], False, False) + + +def test_FlairLoad_T304_RCC_transform(testdata): + flairLoadWriteTest(testdata["fluka/304_RCC_transform.inp"], False, False) + + +def test_FlairLoad_T305_REC_transform(testdata): + flairLoadWriteTest(testdata["fluka/305_REC_transform.inp"], False, False) + + +def test_FlairLoad_T306_TRC_transform(testdata): + flairLoadWriteTest(testdata["fluka/306_TRC_transform.inp"], False, False) + + +def test_FlairLoad_T307_ELL_transform(testdata): + flairLoadWriteTest(testdata["fluka/307_ELL_transform.inp"], False, False) + + +def test_FlairLoad_T308_RAW_transform(testdata): + flairLoadWriteTest(testdata["fluka/308_RAW_transform.inp"], False, False) + + +def test_FlairLoad_T308_WED_transform(testdata): + flairLoadWriteTest(testdata["fluka/308_WED_transform.inp"], False, False) + + +def test_FlairLoad_T309_ARB_transform(testdata): + flairLoadWriteTest(testdata["fluka/309_ARB_transform.inp"], False, False) + + +def test_FlairLoad_T310_XYP_transform(testdata): + flairLoadWriteTest(testdata["fluka/310_XYP_transform.inp"], False, False) + + +def test_FlairLoad_T310_XZP_transform(testdata): + flairLoadWriteTest(testdata["fluka/310_XZP_transform.inp"], False, False) + + +def test_FlairLoad_T310_YZP_transform(testdata): + flairLoadWriteTest(testdata["fluka/310_YZP_transform.inp"], False, False) + + +def test_FlairLoad_T311_PLA_transform(testdata): + flairLoadWriteTest(testdata["fluka/311_PLA_transform.inp"], False, False) + + +def test_FlairLoad_T312_XCC_transform(testdata): + flairLoadWriteTest(testdata["fluka/312_XCC_transform.inp"], False, False) + + +def test_FlairLoad_T312_YCC_transform(testdata): + flairLoadWriteTest(testdata["fluka/312_YCC_transform.inp"], False, False) + + +def test_FlairLoad_T312_ZCC_transform(testdata): + flairLoadWriteTest(testdata["fluka/312_ZCC_transform.inp"], False, False) + + +def test_FlairLoad_T313_XEC_transform(testdata): + flairLoadWriteTest(testdata["fluka/313_XEC_transform.inp"], False, False) + + +def test_FlairLoad_T313_YEC_transform(testdata): + flairLoadWriteTest(testdata["fluka/313_YEC_transform.inp"], False, False) + + +def test_FlairLoad_T313_ZEC_transform(testdata): + flairLoadWriteTest(testdata["fluka/313_ZEC_transform.inp"], False, False) + + +def test_FlairLoad_T314_QUA_transform(testdata): + quaAABB = {"QUA_REG": _fluka.AABB([-190.0, 40.0, 0], [50.0, 200.0, 1000.0])} + flairLoadWriteTest( + testdata["fluka/314_QUA_transform.inp"], + False, + False, + quadricRegionAABBs=quaAABB, + ) + + +def test_FlairLoad_T320_cube_from_halfspaces_transform(testdata): + flairLoadWriteTest( + testdata["fluka/320_cube_from_halfspaces_transform.inp"], False, False + ) + + +def test_FlairLoad_T321_cube_from_plas_transform(testdata): + flairLoadWriteTest(testdata["fluka/321_cube_from_plas_transform.inp"], False, False) + + +def test_FlairLoad_T514_QUA_expansion(testdata): + quaAABB = {"QUA_REG": _fluka.AABB([-70.0, 50.0, 0], [70.0, 100.0, 500.0])} + flairLoadWriteTest( + testdata["fluka/514_QUA_expansion.inp"], + False, + False, + quadricRegionAABBs=quaAABB, + ) + + +def test_FlairLoad_T514_QUA_translation(testdata): + quaAABB = {"QUA_REG": _fluka.AABB([-150.0, 100.0, -1000.0], [150.0, 200.0, 0.0])} + flairLoadWriteTest( + testdata["fluka/514_QUA_translation.inp"], + False, + False, + quadricRegionAABBs=quaAABB, + ) + + +def test_FlairLoad_T514_QUA_rototranslation(testdata): + quaAABB = {"QUA_REG": _fluka.AABB([-190.0, 40.0, 0], [50.0, 200.0, 1000.0])} + flairLoadWriteTest( + testdata["fluka/514_QUA_rototranslation.inp"], + False, + False, + quadricRegionAABBs=quaAABB, + ) + + +def test_FlairLoad_T514_QUA_coplanar(testdata): + quaAABB = { + "OUTER": _fluka.AABB([-200.0, 0.0, 0.0], [200, 200, 1100]), + "INNER": _fluka.AABB([-100.0, 50.0, 250], [100.0, 150.0, 850.0]), + } + flairLoadWriteTest( + testdata["fluka/514_QUA_coplanar.inp"], False, False, quadricRegionAABBs=quaAABB + ) + + +def test_FlairLoad_T601_filter_redundant_halfspaces(testdata): + flairLoadWriteTest( + testdata["fluka/601_filter_redundant_halfspaces.inp"], False, False + ) + + +def test_FlairLoad_T701_LATTICE(testdata): + flairLoadWriteTest(testdata["fluka/701_LATTICE.inp"], False, False) + + +def test_FlairLoad_T702_LATTICE(testdata): + flairLoadWriteTest(testdata["fluka/702_LATTICE.inp"], False, False) + + +def test_FlairLoad_T703_LATTICE(testdata): + flairLoadWriteTest(testdata["fluka/703_LATTICE.inp"], False, False) + + +def test_FlairLoad_T801_nested_expansion(testdata): + flairLoadWriteTest(testdata["fluka/801_nested_expansion.inp"], False, False) + + +def test_FlairLoad_T802_nested_translation(testdata): + flairLoadWriteTest(testdata["fluka/802_nested_translation.inp"], False, False) + + +def test_FlairLoad_T803_nested_transform(testdata): + flairLoadWriteTest(testdata["fluka/803_nested_transform.inp"], False, False) + + +def test_FlairLoad_T804_recursive_transform(testdata): + flairLoadWriteTest(testdata["fluka/804_recursive_transform.inp"], False, False) + + +def test_FlairLoad_T805_inverse_transform(testdata): + flairLoadWriteTest(testdata["fluka/805_inverse_transform.inp"], False, False) + + +def test_FlairLoad_T806_combined_translat_transform(testdata): + flairLoadWriteTest( + testdata["fluka/806_combined_translat_transform.inp"], False, False + ) + + +def test_FlairLoad_T901_preprocessor_if(testdata): + freg, greg = flairLoadWriteTest( + testdata["fluka/901_preprocessor_if.inp"], False, False + ) + solids = greg.solidDict + assert isinstance(solids["bb1_s"], pyg4ometry.geant4.solid.Cons) + + +def test_FlairLoad_T902_preprocessor_elif(testdata): + freg, greg = flairLoadWriteTest( + testdata["fluka/902_preprocessor_elif.inp"], False, False + ) + solids = greg.solidDict + assert isinstance(solids["bb1_s"], pyg4ometry.geant4.solid.Box) + + +def test_FlairLoad_T903_preprocessor_else(testdata): + freg, greg = flairLoadWriteTest( + testdata["fluka/903_preprocessor_else.inp"], False, False + ) + solids = greg.solidDict + assert isinstance(solids["bb1_s"], pyg4ometry.geant4.solid.Tubs) + + +def test_FlairLoad_T904_preprocessor_include(testdata): + flairLoadWriteTest(testdata["fluka/904_preprocessor_include.inp"], False, False) + + +def test_FlairLoad_T905_preprocessor_nested_if(testdata): + freg, greg = flairLoadWriteTest( + testdata["fluka/905_preprocessor_nested_if.inp"], False, False + ) + solids = greg.solidDict + assert isinstance(solids["bb1_s"], pyg4ometry.geant4.solid.Cons) + + +def test_FlairLoad_T906_preprocessor_nested_elif(testdata): + freg, greg = flairLoadWriteTest( + testdata["fluka/906_preprocessor_nested_elif.inp"], False, False + ) + solids = greg.solidDict + assert isinstance(solids["bb1_s"], pyg4ometry.geant4.solid.Box) + + +def test_FlairLoad_T907_preprocessor_nested_else(testdata): + freg, greg = flairLoadWriteTest( + testdata["fluka/907_preprocessor_nested_else.inp"], False, False + ) + solids = greg.solidDict + assert isinstance(solids["bb1_s"], pyg4ometry.geant4.solid.Box) + + +def test_FlairLoad_T908_preprocessor_define(testdata): + flairLoadWriteTest(testdata["fluka/908_preprocessor_define.inp"], False, False) + + +def test_FlairLoad_Tex_geometry(testdata): + flairLoadWriteTest(testdata["fluka/ex-geometry.inp"], False, False) + + +def test_FlairLoad_Tex_Scoring(testdata): + flairLoadWriteTest(testdata["fluka/ex_Scoring.inp"], False, False) + + +def test_FlairLoad_Texample_running(testdata): + flairLoadWriteTest(testdata["fluka/example_running.inp"], False, False) + + +def test_FlairLoad_Texample_score(testdata): + flairLoadWriteTest(testdata["fluka/example_score.inp"], False, False) + + +def test_FlairLoad_TmanualSimpleFileFixed(testdata): + flairLoadWriteTest(testdata["fluka/manualSimpleFileFixed.inp"], False, False) + + +def test_FlairLoad_TmanualSimpleFileFree(testdata): + flairLoadWriteTest(testdata["fluka/manualSimpleFileFree.inp"], False, False) + + +# def test_FlairLoad_TcorrectorDipole(): +# flairLoadWriteTest("corrector-dipole.inp", False, False) diff --git a/tests/gdml/test_Define.py b/tests/gdml/test_Define.py new file mode 100644 index 000000000..c783d5e21 --- /dev/null +++ b/tests/gdml/test_Define.py @@ -0,0 +1,644 @@ +import pyg4ometry + + +# ############################# +# Define upgrades +# ############################# +def test_GdmlDefine_UpgradeToStringExpression(): + r = pyg4ometry.geant4.Registry() + + # number to expression string + assert pyg4ometry.gdml.upgradeToStringExpression(r, 10) == "10.000000000000000" + + # string to expression string (evaluatable) + assert pyg4ometry.gdml.upgradeToStringExpression(r, "10+10") == "10+10" + + # string to expression string (unevaluatable) + + x = pyg4ometry.gdml.Constant("x", 1, r) + + try: + assert pyg4ometry.gdml.upgradeToStringExpression(r, "10*x+10") == "10*x+10" + except AttributeError: + pass + + # string but in define dict + c = pyg4ometry.gdml.Defines.Constant("c", "10", r, True) + assert pyg4ometry.gdml.upgradeToStringExpression(r, "c") == "c" + + # expression that cannot be evaluated + try: + pyg4ometry.gdml.upgradeToStringExpression(r, "z") + except Exception: + pass + + +def test_GdmlDefine_UpgradeToVector(): + r = pyg4ometry.geant4.Registry() + + v = pyg4ometry.gdml.Defines.Position("v", 0, 0, 0, "mm", r, False) + + # vector + p = pyg4ometry.gdml.Defines.upgradeToVector( + v, r, "position", unit="", addRegistry=False + ) + assert p.eval() == [0, 0, 0] + + # list to position + p = pyg4ometry.gdml.Defines.upgradeToVector( + [0, 0, 0], r, "position", addRegistry=False + ) + assert p.eval() == [0, 0, 0] + + # list to rotation + p = pyg4ometry.gdml.Defines.upgradeToVector( + [0, 0, 0], r, "rotation", addRegistry=False + ) + assert p.eval() == [0, 0, 0] + + # list to scale + p = pyg4ometry.gdml.Defines.upgradeToVector( + [0, 0, 0], r, "scale", addRegistry=False + ) + assert p.eval() == [0, 0, 0] + + # list to undefined + p = pyg4ometry.gdml.Defines.upgradeToVector( + [0, 0, 0], r, "undefined", addRegistry=False + ) + assert p is None + + +# ############################# +# ANTLR expressions +# ############################# + + +def test_GdmlDefine_ExpressionInt(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", 1, r) + assert xc.eval() == 1 + + +def test_GdmlDefine_ExpressionFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", 1.2345, r) + assert xc.eval() == 1.2345 + + +def test_GdmlDefine_ExpressionScientific1(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", 1e3, r) + assert xc.eval() == 1000 + + +def test_GdmlDefine_ExpressionScientific2(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", 1.2345e3, r) + assert xc.eval() == 1234.5 + + +def test_GdmlDefine_ExpressionStringInt(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + assert xc.eval() == 1 + + +def test_GdmlDefine_ExpressionStringFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1.2345", r) + assert xc.eval() == 1.2345 + + +def test_GdmlDefine_ExpressionStringScientific1(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1E3", r) + assert xc.eval() == 1000 + + +def test_GdmlDefine_ExpressionStringScientific2(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1.2345E3", r) + assert xc.eval() == 1234.5 + + +def test_GdmlDefine_ExpressionOperatorAddIntInt(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1+2", r) + assert xc.eval() == 3 + + +def test_GdmlDefine_ExpressionOperatorAddIntFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "2.3456+1", r) + assert xc.eval() == 3.3456 + + +def test_GdmlDefine_ExpressionOperatorAddFloatFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1.2345+2.3456", r) + assert xc.eval() == 3.5801 + + +def test_GdmlDefine_ExpressionOperatorAddFloatInt(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1+2.3456", r) + assert xc.eval() == 3.3456 + + +def test_GdmlDefine_ExpressionOperatorSubIntInt(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1-2", r) + assert xc.eval() == -1 + + +def test_GdmlDefine_ExpressionOperatorSubIntFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1-2.3456", r) + assert xc.eval() == -1.3456000000000001 + + +def test_GdmlDefine_ExpressionOperatorSubFloatInt(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "2.3456-1", r) + assert xc.eval() == 1.3456000000000001 + + +def test_GdmlDefine_FuncAbs(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "abs(-1)", r) + assert xc.eval() == 1.0 + + +# ############################# +# Constants +# ############################# +def test_GdmlDefine_ConstantSetName(): + r = pyg4ometry.geant4.Registry() + c = pyg4ometry.gdml.Constant("xc", "1", r) + c.setName("testName") + assert c.name == "testName" + assert c.expression.name == "expr_testName" + + +def test_GdmlDefine_ConstantOperatorAddExpressionExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + yc = pyg4ometry.gdml.Constant("yc", "2", r) + assert (xc + yc).eval() == 3 + + +def test_GdmlDefine_ConstantOperatorAddExpressionFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + assert (xc + 10).eval() == 11 + + +def test_GdmlDefine_ConstantOperatorAddFloatExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + assert (10 + xc).eval() == 11 + + +def test_GdmlDefine_ConstantOperatorSubExpressionExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + yc = pyg4ometry.gdml.Constant("yc", "2", r) + assert (xc - yc).eval() == -1 + + +def test_GdmlDefine_ConstantOperatorSubExpressionFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + assert (xc - 10).eval() == -9 + + +def test_GdmlDefine_ConstantOperatorSubExpressionFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + assert (10 - xc).eval() == 9 + + +def test_GdmlDefine_ConstantOperatorMulExpressionExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + yc = pyg4ometry.gdml.Constant("yc", "5", r) + assert (xc * yc).eval() == 25 + + +def test_GdmlDefine_ConstantOperatorMulExpressionFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + assert (xc * 5).eval() == 25 + + +def test_GdmlDefine_ConstantOperatorMulFloatExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + assert (5 * xc).eval() == 25 + + +def test_GdmlDefine_ConstantOperatorDivExpressionExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + yc = pyg4ometry.gdml.Constant("yc", "10", r) + assert (xc / yc).eval() == 0.5 + + +def test_GdmlDefine_ConstantOperatorDivExpressionFloat(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + assert (xc / 10).eval() == 0.5 + + +def test_GdmlDefine_ConstantOperatorDivFloatExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + assert (10.0 / xc).eval() == 2 + + +def test_GdmlDefine_ConstantOperationNegExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + assert (-xc).eval() == -5 + + +def test_GdmlDefine_ConstantOperatorEqual(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + yc = pyg4ometry.gdml.Constant("yc", "5", r) + zc = pyg4ometry.gdml.Constant("zc", "10", r) + assert xc == yc + assert xc != zc + + +def test_GdmlDefine_ConstantOperatorNotEqual(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + yc = pyg4ometry.gdml.Constant("yc", "5", r) + zc = pyg4ometry.gdml.Constant("zc", "10", r) + assert xc == yc + assert xc != zc + + +def test_GdmlDefine_ConstantOperatorLessThan(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + yc = pyg4ometry.gdml.Constant("yc", "10", r) + assert xc < yc + assert yc > xc + + +def test_GdmlDefine_ConstantOperatorGreaterThan(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "10", r) + yc = pyg4ometry.gdml.Constant("yc", "5", r) + assert xc > yc + assert yc < xc + + +def test_GdmlDefine_ConstantOperatorLessThanOrEqual(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "5", r) + yc = pyg4ometry.gdml.Constant("yc", "10", r) + zc = pyg4ometry.gdml.Constant("zc", "5", r) + assert xc <= yc + assert xc <= zc + assert yc >= xc + + +def test_GdmlDefine_ConstantOperatorGreaterThanOrEqual(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "10", r) + yc = pyg4ometry.gdml.Constant("yc", "5", r) + zc = pyg4ometry.gdml.Constant("zc", "10", r) + assert xc >= yc + assert xc >= zc + assert yc <= xc + + +def test_GdmlDefine_ConstantSinExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.sin(xc).eval() - 0.09983341664682815) < 1e-14 + + +def test_GdmlDefine_ConstantCosExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.cos(xc).eval() - 0.9950041652780257) < 1e-14 + + +def test_GdmlDefine_ConstantTanExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.tan(xc).eval() - 0.10033467208545055) < 1e-14 + + +def test_GdmlDefine_ConstantExpExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.exp(xc).eval() - 1.1051709180756477) < 1e-14 + + +def test_GdmlDefine_ConstantLogExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.log(xc).eval() - (-2.3025850929940455)) < 1e-14 + + +def test_GdmlDefine_ConstantLog10Expression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert pyg4ometry.gdml.log10(xc).eval() == -1.0 + + +def test_GdmlDefine_ConstantSqrtExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.sqrt(xc).eval() - 0.31622776601683794) < 1e-14 + + +def test_GdmlDefine_ConstantArcSinExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.asin(xc).eval() - 0.1001674211615598) < 1e-14 + + +def test_GdmlDefine_ConstantArcCosExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.acos(xc).eval() - 1.4706289056333368) < 1e-14 + + +def test_GdmlDefine_ConstantArcTanExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "0.1", r) + assert abs(pyg4ometry.gdml.atan(xc).eval() - 0.09966865249116204) < 1e-14 + + +def test_GdmlDefine_PowExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "2", r) + assert pyg4ometry.gdml.pow(xc, 2).eval() == 4 + + +def test_GdmlDefine_AbsExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "-2", r) + assert (pyg4ometry.gdml.abs(xc)).eval() == 2 + + +def test_GdmlDefine_PowerOperator(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "-2", r) + assert (xc**2).eval() == 4 + + +# ############################# +# Quantity +# ############################# +def test_GdmlDefine_Quantity(): + r = pyg4ometry.geant4.Registry() + xq = pyg4ometry.gdml.Quantity("xq", "0.1", "mass", "kg", r) + assert xq.eval() == 0.1 + assert float(xq) == 0.1 + str(xq) + + +# ############################# +# Variable +# ############################# +def test_GdmlDefine_Variable(): + r = pyg4ometry.geant4.Registry() + xv = pyg4ometry.gdml.Variable("xv", "0.1", r) + assert xv.eval() == 0.1 + assert float(xv) == 0.1 + str(xv) + + +# ############################# +# Expression +# ############################# +def test_GdmlDefine_Expression(): + r = pyg4ometry.geant4.Registry() + xe = pyg4ometry.gdml.Expression("xe", "0.1", r, True) + assert xe.eval() == 0.1 + assert float(xe) == 0.1 + str(xe) + + +# ############################# +# Position +# ############################# +def test_GdmlDefine_PositionSetName(): + r = pyg4ometry.geant4.Registry() + v = pyg4ometry.gdml.Position("p", "1", "2", "3", "mm", r) + v.setName("newName") + assert v.name == "newName" + + +def test_GdmlDefine_PositionGetItem(): + r = pyg4ometry.geant4.Registry() + v = pyg4ometry.gdml.Position("p", "1", "2", "3", "mm", r) + + assert v[0].eval() == 1 + assert v[1].eval() == 2 + assert v[2].eval() == 3 + + try: + v[3] + except IndexError: + pass + + +def test_GdmlDefine_PositionConstructorStrStrStr(): + r = pyg4ometry.geant4.Registry() + v = pyg4ometry.gdml.Position("p", "1", "2", "3", "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorStrStrFloat(): + r = pyg4ometry.geant4.Registry() + v = pyg4ometry.gdml.Position("p", "1", "2", 3, "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorStrFloatStr(): + r = pyg4ometry.geant4.Registry() + v = pyg4ometry.gdml.Position("p", "1", 2, "3", "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorFloatStrStr(): + r = pyg4ometry.geant4.Registry() + v = pyg4ometry.gdml.Position("p", 1, "2", "3", "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorStrStrExpression(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "3", r) + v = pyg4ometry.gdml.Position("p", "1", "2", xc, "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorStrExpressionStr(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "2", r) + v = pyg4ometry.gdml.Position("p", "1", xc, "3", "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorExpressionStrStr(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + v = pyg4ometry.gdml.Position("p", xc, "2", "3", "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorStrStrExprstr(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "3", r) + v = pyg4ometry.gdml.Position("p", "1", "2", "xc", "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorStrExprstrStr(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "2", r) + v = pyg4ometry.gdml.Position("p", "1", "xc", "3", "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorExprstrStrStr(): + r = pyg4ometry.geant4.Registry() + xc = pyg4ometry.gdml.Constant("xc", "1", r) + v = pyg4ometry.gdml.Position("p", "xc", "2", "3", "mm", r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionConstructorUnitNone(): + r = pyg4ometry.geant4.Registry() + v = pyg4ometry.gdml.Position("p", "1", "2", "3", None, r) + assert v.eval() == [1, 2, 3] + + +def test_GdmlDefine_PositionOperatorAdd(): + r = pyg4ometry.geant4.Registry() + v1 = pyg4ometry.gdml.Position("v1", "1", "2", "3", "mm", r) + v2 = pyg4ometry.gdml.Position("v2", "11", "12", "13", "mm", r) + assert (v1 + v2).eval() == [12, 14, 16] + + +def test_GdmlDefine_PositionOperatorSub(): + r = pyg4ometry.geant4.Registry() + v1 = pyg4ometry.gdml.Position("v1", "1", "2", "3", "mm", r) + v2 = pyg4ometry.gdml.Position("v2", "11", "12", "13", "mm", r) + assert (v2 - v1).eval() == [10, 10, 10] + + +def test_GdmlDefine_PositionOperatorMulFloatPosition(): + r = pyg4ometry.geant4.Registry() + v1 = pyg4ometry.gdml.Position("v1", "1", "2", "3", "mm", r) + assert (10.0 * v1).eval() == [10, 20, 30] + + +def test_GdmlDefine_PositionOperatorMulPositionFloat(): + r = pyg4ometry.geant4.Registry() + v1 = pyg4ometry.gdml.Position("v1", "1", "2", "3", "mm", r) + assert (v1 * 10.0).eval() == [10, 20, 30] + + +def test_GdmlDefine_PositionOperatorMulExpressionPosition(): + r = pyg4ometry.geant4.Registry() + x = pyg4ometry.gdml.Constant("x", "1.5", r) + v1 = pyg4ometry.gdml.Position("v1", "1", "2", "3", "mm", r) + assert (x * v1).eval() == [1.5, 3.0, 4.5] + + +def test_GdmlDefine_PositionOperatorMulPositionExpression(): + r = pyg4ometry.geant4.Registry() + x = pyg4ometry.gdml.Constant("x", "1.5", r) + v1 = pyg4ometry.gdml.Position("v1", "1", "2", "3", "mm", r) + assert (v1 * x).eval() == [1.5, 3.0, 4.5] + + +def test_GdmlDefine_PositionOperatorDivPositionFloat(): + r = pyg4ometry.geant4.Registry() + v1 = pyg4ometry.gdml.Position("v1", "1", "2", "3", "mm", r) + assert (v1 / 10).eval() == [0.1, 0.2, 0.3] + + +def test_GdmlDefine_PositionOperatorDivPositionExpression(): + r = pyg4ometry.geant4.Registry() + x = pyg4ometry.gdml.Constant("x", "10.0", r) + v1 = pyg4ometry.gdml.Position("v1", "1", "2", "3", "mm", r) + assert (v1 / x).eval() == [0.1, 0.2, 0.3] + + +# ############################# +# Rotations +# ############################# +def test_GdmlDefine_Rotation(): + r = pyg4ometry.geant4.Registry() + r1 = pyg4ometry.gdml.Rotation("r1", 1, 2, 3, "rad", r, True) + r2 = pyg4ometry.gdml.Rotation("r2", 1, 2, 3, "deg", r, True) + r3 = pyg4ometry.gdml.Rotation("r3", 1, 2, 3, None, r, True) + r4 = pyg4ometry.gdml.Rotation("r4", 1, 2, 3, None, r, False) + str(r1) + + +# ############################# +# Scale +# ############################# +def test_GdmlDefine_Scale(): + r = pyg4ometry.geant4.Registry() + s1 = pyg4ometry.gdml.Scale("s1", 1, 2, 3, None, r, True) + s2 = pyg4ometry.gdml.Scale("s2", 1, 2, 3, None, r, False) + str(s1) + + +# ############################# +# Matrix +# ############################# +def test_GdmlDefine_MatrixConstructor1x10(): + r = pyg4ometry.geant4.Registry() + mat = pyg4ometry.gdml.Matrix("mat", 1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], r, False) + assert (mat.eval() == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).all() + + +def test_GdmlDefine_MatrixConstructor1x10(): + r = pyg4ometry.geant4.Registry() + mat = pyg4ometry.gdml.Matrix("mat", 2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], r, False) + + +def test_GdmlDefine_Matrix1x10Index(): + r = pyg4ometry.geant4.Registry() + mat = pyg4ometry.gdml.Matrix("mat", 1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], r, False) + assert mat[9].eval() == 10 + + +def test_GdmlDefine_Matrix2x5Index(): + r = pyg4ometry.geant4.Registry() + mat = pyg4ometry.gdml.Matrix("mat", 2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], r, False) + assert mat[0][2].eval() == 3 + + +def test_GdmlDefine_MatrixConstructor1x10AddRegistry(): + r = pyg4ometry.geant4.Registry() + mat = pyg4ometry.gdml.Matrix("mat", 1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], r, True) + assert (mat.eval() == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).all() + + +def test_GdmlDefine_MatrixRepr(): + r = pyg4ometry.geant4.Registry() + mat = pyg4ometry.gdml.Matrix("mat", 2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], r, True) + str(mat) + + +def test_GdmlDefine_MatrixGetItemInRegistry(): + r = pyg4ometry.geant4.Registry() + mat = pyg4ometry.gdml.Matrix("mat", 2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], r, True) + v = mat[0, 0] + assert v.expression.expressionString == "mat[1,1]" diff --git a/tests/gdml/test_Reader.py b/tests/gdml/test_Reader.py new file mode 100644 index 000000000..17d6007fe --- /dev/null +++ b/tests/gdml/test_Reader.py @@ -0,0 +1,1050 @@ +import pyg4ometry + +import pytest +import os as _os +import git as _git + +from subprocess import Popen as _Popen, PIPE as _PIPE +from hashlib import md5 as _md5 +from collections import OrderedDict as _OrderedDict + +# logger = _log.getLogger() +# logger.disabled = True + + +def _pj(filename): + """ + Append the absolute path to *this* directory to the filename so the tests + can be ran from anywhere + """ + return _os.path.join(_os.path.dirname(__file__), filename) + + +def pyg4ometryLoadWriteTest(filename, vis=False, interactive=False): + filepath = _pj(filename) + + # Loading + reader = pyg4ometry.gdml.Reader(filepath) + registry = reader.getRegistry() + + # World logical + worldLogical = registry.getWorldVolume() + + # test extent of physical volume + extentBB = worldLogical.extent(includeBoundingSolid=True) + + # Visualisation + if vis: + v = pyg4ometry.visualisation.VtkViewer() + v.addLogicalVolume(registry.getWorldVolume()) + v.addAxes(pyg4ometry.visualisation.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + # Writing + newFilename = filepath.replace(".gdml", "_processed.gdml") + + writer = pyg4ometry.gdml.Writer() + writer.addDetector(registry) + writer.write(newFilename) + + return registry, newFilename + + +def geant4LoadTest(filename, visualiser=False, physics=False, verbose=True): + # check if GDML file has updated + # if not checkIfGdmlFileUpdated(filename) : + # return True + + print("geant4LoadTest> running G4") + script_path = _pj("simple_G4_loader/build/simple_loader") + if not _os.path.isfile(script_path): + print(f"Geant4 test executable not found in {script_path}, skip test.") + return True + + proc = _Popen( + [script_path, _pj(filename), str(int(visualiser)), str(int(physics))], + stdout=_PIPE, + stderr=_PIPE, + ) + outs, errs = proc.communicate() + + status = proc.returncode + if status: + if verbose: + print( + "\nError! Geant4 load failed: \nOutput>>> {} \nErrors>>> {}".format( + outs, errs + ) + ) + return False + + return True + + +def checkIfGdmlFileUpdated(filename): + filename = _os.path.basename(filename) + repo = _git.Repo(_os.path.join(_os.path.dirname(__file__), "../../../../")) + head_commit = repo.head.commit + diffs = head_commit.diff(None) + + for d in diffs: + if _os.path.basename(d.a_path).find(filename) != -1: + return True + + return False + + +# solid name : (nslice , nstack) +# nslice is normally used for granularity of curvature in radius +# nstack is normally used for granularity of curvature in Z +# solids not listed here do not have discretised curves +curved_solids = { + "Tubs": (16, None), + "CutTubs": (16, None), + "Cons": (16, None), + "Sphere": (6, 6), + "Orb": (16, 8), + "Torus": (6, 6), + "Polycone": (16, None), + "GenericPolycone": (16, None), + "EllipticalTube": (6, 6), + "Ellipsoid": (8, 8), + "EllipticalCone": (16, 16), + "Paraboloid": (16, 8), + "Hype": (6, 6), + "TwistedBox": (None, 20), + "TwistedTrap": (None, 20), + "TwistedTrd": (None, 20), + "TwistedTubs": (16, 16), + "GenericTrap": (None, 20), +} + + +def computeGDMLFileChecksum(filename): + with open(_pj(filename)) as gdml_file: + contents = gdml_file.read() + checksum = int(_md5(contents.encode()).hexdigest(), 16) + + return checksum + + +def loadChecksumTable(): + checksum_filepath = _pj("processed_file_checksums.dat") + checksum_table = _OrderedDict() + + if _os.path.exists(checksum_filepath): + with open(checksum_filepath) as checksum_file: + for line in checksum_file: + sline = line.split() + checksum_table[sline[0]] = int(sline[1]) + + return checksum_table + + +def writeChecksumTable(checksum_table): + checksum_filepath = _pj("processed_file_checksums.dat") + with open(checksum_filepath, "w") as checksum_file: + for filename, checksum in checksum_table.items(): + checksum_file.write(f"{filename}\t{checksum}\n") + + +def validateProcessedFile(filename): + checksum_table = loadChecksumTable() + checksum = computeGDMLFileChecksum(filename) + checksum = computeGDMLFileChecksum(filename) + + isValid = False + # Handle missing cases by using get + if checksum_table.get(filename, -1) == checksum: + isValid = True + else: + isValid = geant4LoadTest(filename) + if isValid: + checksum_table[filename] = checksum + writeChecksumTable(checksum_table) + + return isValid + + +def getSolidChecksum(solid): + if solid.type in curved_solids: + mesh_density = curved_solids[solid.type] + if mesh_density[0]: + setattr(solid, "nslice", mesh_density[0]) + if mesh_density[1]: + setattr(solid, "nstack", mesh_density[1]) + + checksum = hash(solid.pycsgmesh()) + return checksum + + +def test_GdmlLoad_001_BoxLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/001_box.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["box1"]), -1) + + +def test_GdmlLoad_002_TubeLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/002_tubs.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["tube1"]), -1) + + +def test_GdmlLoad_003_CutTubeLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/003_cut_tubs.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["cuttube1"]), -1) + + +def test_GdmlLoad_004_ConeLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/004_cons.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["cone1"]), -1) + + +def test_GdmlLoad_005_ParaLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/005_para.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["para1"]), -1) + + +def test_GdmlLoad_006_TrdLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/006_trd.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["trd1"]), -1) + + +def test_GdmlLoad_007_TrapLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/007_trap.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["trap1"]), -1) + + +def test_GdmlLoad_008_SphereLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/008_sphere.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["sphere1"]), -1) + + +def test_GdmlLoad_009_OrbLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/009_orb.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["orb1"]), -1) + + +def test_GdmlLoad_010_TorusLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/010_torus.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["torus1"]), -1) + + +def test_GdmlLoad_011_PolyconeLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/011_polycone.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["polycone1"]), -1) + + +def test_GdmlLoad_012_GenericPolyconeLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/012_generic_polycone.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["genpoly1"]), -1) + + +def test_GdmlLoad_013_PolyhedraLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/013_polyhedra.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["polyhedra1"]), -1) + + +def test_GdmlLoad_014_GenericPolyhedraLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/014_generic_polyhedra.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["genpolyhedra1"]), -1) + + +def test_GdmlLoad_015_EltubeLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/015_eltube.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["eltube1"]), -1) + + +def test_GdmlLoad_016_EllipsoidLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/016_ellipsoid.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["ellipsoid"]), -1) + + +def test_GdmlLoad_017_ElconeLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/017_elcone.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["elcone1"]), -1) + + +def test_GdmlLoad_018_ParaboloidLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/018_paraboloid.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["paraboloid1"]), -1) + + +def test_GdmlLoad_019_HypeLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/019_hype.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["hype1"]), -1) + + +def test_GdmlLoad_020_TetLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/020_tet.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["tet1"]), -1) + + +def test_GdmlLoad_021_ExtrudedSolid(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/021_xtru.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["xtru1"]), -1) + + +def test_GdmlLoad_022_TwistedBox(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/022_twisted_box.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["twistbox1"]), -1) + + +def test_GdmlLoad_023_TwistedTrap(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/023_twisted_trap.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["twisttrap1"]), -1) + + +def test_GdmlLoad_024_TwistedTrd(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/024_twisted_trd.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["twisttrd1"]), -1) + + +def test_GdmlLoad_025_TwistedTubs(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/025_twisted_tube.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["twisttube1"]), -1) + + +def test_GdmlLoad_026_GenericTrap(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/026_generic_trap.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["arb81"]), -1) + + +def test_GdmlLoad_027_TessellatedSolid(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/027_tesselated.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["tessellated"]), -1) + + +def test_GdmlLoad_028_UnionLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/028_union.gdml"]) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["union1"]), -1) + + +def test_GdmlLoad_029_SubtractionLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/029_subtraction.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["subtraction1"]), -1) + + +def test_GdmlLoad_030_IntersetionLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/030_intersection.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["intersection1"]), -1) + + +def test_GdmlLoad_031_MultiUnionLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/031_multiUnion.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["multiunion1"]), -1) + + +def test_GdmlLoad_032_ScaledLoad(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/032_scaled.gdml"] + ) + assert geant4LoadTest(writtenFilename) + # self.assertEqual(getSolidChecksum(registry.solidDict["box1Scaled"]), -1) + + +def test_GdmlLoad_106_ReplicaVolume_x(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/106_replica_x.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "replica": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_107_ReplicaVolume_y(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/107_replica_y.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "replica": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_108_ReplicaVolume_z(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/108_replica_z.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "replica": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_109_ReplicaVolume_phi(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/109_replica_phi.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "replica": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_110_ReplicaVolume_rho(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/110_replica_rho.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "replica": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_111_ParameterisedVolume_box(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/111_parameterised_box.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_112_ParameterisedVolume_tube(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/112_parameterised_tube.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_113_ParameterisedVolume_cone(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/113_parameterised_cone.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_114_ParameterisedVolume_orb(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/114_parameterised_orb.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_115_ParameterisedVolume_sphere(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/115_parameterised_sphere.gdml"] + ) + assert geant4LoadTest(writtenFilename) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_116_ParameterisedVolume_torus(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/116_parameterised_torus.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_117_ParameterisedVolume_hype(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/117_parameterised_hype.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_118_ParameterisedVolume_para(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/118_parameterised_para.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_119_ParameterisedVolume_trd(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/119_parameterised_trd.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_120_ParameterisedVolume_trap(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/120_parameterised_trap.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_121_ParameterisedVolume_polycone(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/121_parameterised_polycone.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_122_ParameterisedVolume_polyhedron(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/122_parameterised_polyhedron.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_123_ParameterisedVolume_ellipsoid(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/123_parameterised_ellipsoid.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "parametrised": + solid = volume.meshes[0].solid + + +def test_GdmlLoad_124_DivisionVolume_box_x(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/124_division_box_x.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_125_DivisionVolume_box_y(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/125_division_box_y.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_126_DivisionVolume_box_z(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/126_division_box_z.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_127_DivisionVolume_tubs_rho(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/127_division_tubs_rho.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_128_DivisionVolume_tubs_phi(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/128_division_tubs_phi.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_129_DivisionVolume_tubs_z(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/129_division_tubs_z.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_130_DivisionVolume_cons_rho(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/130_division_cons_rho.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_131_DivisionVolume_cons_phi(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/131_division_cons_phi.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_132_DivisionVolume_cons_z(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/132_division_cons_z.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_133_DivisionVolume_trd_x(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/133_division_trd_x.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_134_DivisionVolume_trd_y(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/134_division_trd_y.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_135_DivisionVolume_trd_z(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/135_division_trd_z.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_136_DivisionVolume_para_x(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/136_division_para_x.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_137_DivisionVolume_para_y(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/137_division_para_y.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_138_DivisionVolume_para_z(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/138_division_para_z.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_139_DivisionVolume_polycone_rho(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/139_division_polycone_rho.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_140_DivisionVolume_polycone_phi(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/140_division_polycone_phi.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty gdml + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_141_DivisionVolume_polycone_z(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/141_division_polycone_z.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_142_DivisionVolume_polyhedra_rho(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/142_division_polyhedra_rho.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_143_DivisionVolume_polyhedra_phi(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/143_division_polyhedra_phi.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_144_DivisionVolume_polyhedra_z(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/144_division_polyhedra_z.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Faulty in Geant4 + + for volname, volume in registry.physicalVolumeDict.items(): + if volume.type == "division": + solid = volume.meshes[0].solid + # self.assertEqual(getSolidChecksum(solid), -1) + + +def test_GdmlLoad_150_OpticalSurfaces(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/150_opticalsurfaces.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_201_Materials(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/201_materials.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_Auxiliary(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/202_auxiliary.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_Entity(testdata): + # Need to process the GDML file to inject the absolute path to the entity file + with open(testdata["gdml/203_entity.gdml"]) as infile: + contents = infile.read() + + contents_replaced = contents.replace( + "203_materials.xml", _pj("203_materials.xml") + ) + with open(_pj("203_temp.gdml"), "w") as tempfile: + tempfile.write(contents_replaced) + + # TODO write in tmp dir + # registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/203_temp.gdml"]) + + +def test_GdmlLoad_300_MalformedGdml(testdata): + import xml.parsers.expat as _expat + + # TODO reinstate + # with pytest.raises(_expat.ExpatError): + # r = pyg4ometry.gdml.Reader(testdata["gdml/300_malformed.gdml"]) + + +def test_GdmlLoad_301_Quantity(testdata): + assert pyg4ometryLoadWriteTest(testdata["gdml/301_quantity.gdml"]) + + +def test_GdmlLoad_302_Variable(testdata): + assert pyg4ometryLoadWriteTest(testdata["gdml/302_variable.gdml"]) + + +def test_GdmlLoad_303_Matrix(testdata): + assert pyg4ometryLoadWriteTest(testdata["gdml/303_matrix.gdml"]) + + +def test_GdmlLoad_304_Scale(testdata): + assert pyg4ometryLoadWriteTest(testdata["gdml/304_scale.gdml"]) + + +def test_GdmlLoad_305_UnrecognisedDefine(testdata): + assert pyg4ometryLoadWriteTest(testdata["gdml/305_unrecognised_define.gdml"]) + + +def test_GdmlLoad_306_Tubs_Bad_Pi(testdata): + pass + # TODO check it raises an exception + # with pytest.raises(ValueError): + # pyg4ometryLoadWriteTest(testdata["gdml/306_tubs_hand_written_bad_pi.gdml"]) + + +def test_GdmlLoad_ChargeExhangeMC(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/ChargeExchangeMC/lht.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Overlaps in the original file + + +def test_GdmlLoad_G01assembly(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/G01/assembly.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Overlaps in the original file + + +def test_GdmlLoad_G01auxiliary(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/G01/auxiliary.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01axes(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/G01/axes.gdml"]) + # assert(geant4LoadTest(writtenFilename)) # Overlaps in the original file + + +def test_GdmlLoad_G01divisionvol(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml//G01/divisionvol.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01mat_nist(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/G01/mat_nist.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01multiUnion(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/G01/multiUnion.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01pTube(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/G01/pTube.gdml"]) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01parameterized(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/G01/parameterized.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01replicated(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml//G01/replicated.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01scale(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/G01/scale.gdml"]) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01solids(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/G01/solids.gdml"] + ) + assert geant4LoadTest(writtenFilename) + + +def test_GdmlLoad_G01tess(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/G01/tess.gdml"]) + # assert(geant4LoadTest(writtenFilename)) + + +def test_GdmlLoad_G02test(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest(testdata["gdml/G02/test.gdml"]) + # assert(geant4LoadTest(writtenFilename)) + + +def test_GdmlLoad_G04auxiliary(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/G04/auxiliary.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) + + +def test_GdmlLoad_Par02FullDetector(testdata): + registry, writtenFilename = pyg4ometryLoadWriteTest( + testdata["gdml/Par02/Par02FullDetector.gdml"] + ) + # assert(geant4LoadTest(writtenFilename)) # Overlaps in the orignal file diff --git a/tests/geant4/ECamelAssembly.py b/tests/geant4/ECamelAssembly.py new file mode 100644 index 000000000..335bacfd6 --- /dev/null +++ b/tests/geant4/ECamelAssembly.py @@ -0,0 +1,64 @@ +import pyg4ometry.geant4 as _g4 + + +def MakeECamelAssembly(reg, margin=1, separation=1): + iron = _g4.MaterialPredefined("G4_Fe") + + # solids + # E shape - go from bottom left around outside edge clockwise + dx = 30 # width + dy = 60 # height + tt = 10 # thickness of each bit + polygon = [ + [-dx, 0], + [-dx, dy], + [0, dy], + [0, dy - tt], + [-dx + tt, dy - tt], + [-dx + tt, 0.5 * (dy + tt)], + [0, 0.5 * (dy + tt)], + [0, 0.5 * dy - 0.5 * tt], + [-dx + tt, 0.5 * dy - 0.5 * tt], + [-dx + tt, tt], + [0, tt], + [0, 0], + ] + slices = [[-5, [0, 0], 1.0], [5, [0, 0], 1.0]] + + eSolid = _g4.solid.ExtrudedSolid("e_solid", polygon, slices, reg) + + # now for a camel-like two hump solid to fit 'into' the E tightly but not touching + # start bottom left corner then go clockwise (so beside bottom right corner of E) + hx = dx - tt + ma = margin + hy = 0.5 * (dy - 3 * tt) + polygon2 = [ + [0, 0], + [0, tt + ma], + [-hx, tt + ma], + [-hx, tt + hy - ma], + [0, tt + hy - ma], + [0, tt + hy + tt + ma], + [-hx, tt + hy + tt + ma], + [-hx, dy - tt - ma], + [0, dy - tt - ma], + [0, dy], + [tt, dy], + [tt, 0], + ] + slices2 = [[-5, [0, 0], 1.0], [5, [0, 0], 1.0]] + camelSolid = _g4.solid.ExtrudedSolid("camel_solid", polygon2, slices2, reg) + + # logicals + eLV = _g4.LogicalVolume(eSolid, iron, "e_lv", reg) + camelLV = _g4.LogicalVolume(camelSolid, iron, "camel_lv", reg) + + # structure + assembly = _g4.AssemblyVolume("assembly1", reg) + xo = (dx + tt) * 0.5 - tt + epv = _g4.PhysicalVolume([0, 0, 0], [xo, 0, 0], eLV, "e_pv", assembly, reg) + cpv = _g4.PhysicalVolume( + [0, 0, 0], [xo + separation, 0, 0], camelLV, "camel_pv", assembly, reg + ) + + return assembly diff --git a/tests/geant4/T000_SolidBase.py b/tests/geant4/T000_SolidBase.py new file mode 100644 index 000000000..c5f205957 --- /dev/null +++ b/tests/geant4/T000_SolidBase.py @@ -0,0 +1,25 @@ +import pyg4ometry + + +def Test(): + s = pyg4ometry.geant4.solid.SolidBase("oldname", "type", None) + + # get name + name = s.name + + # set name + s.name = "newname" + + # set name special char + try: + s.name = "newname!" + except ValueError: + pass + + # set name first char number + try: + s.name = "1newname" + except ValueError: + pass + + return {"testStatus": True} diff --git a/tests/geant4/T001_Box.py b/tests/geant4/T001_Box.py new file mode 100644 index 000000000..084057c2c --- /dev/null +++ b/tests/geant4/T001_Box.py @@ -0,0 +1,75 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.convert as _conv +import pyg4ometry.fluka as _flu + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Au", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Au") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + assert bs.evaluateParameterWithUnits("pX") == bx + assert bs.evaluateParameterWithUnits("pY") == by + assert bs.evaluateParameterWithUnits("pZ") == bz + bs2 = _g4.solid.Box("bs2", bx, by, bz, reg, "cm") + assert bs2.evaluateParameterWithUnits("pX") == 10 * bx + assert bs2.evaluateParameterWithUnits("pY") == 10 * by + assert bs2.evaluateParameterWithUnits("pZ") == 10 * bz + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T001_Box.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T001_Box.gmad"), "T001_Box.gdml" + ) + + # test __repr__ + str(bs) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.PubViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v, "registry": reg} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T002_Tubs.py b/tests/geant4/T002_Tubs.py new file mode 100644 index 000000000..920742f22 --- /dev/null +++ b/tests/geant4/T002_Tubs.py @@ -0,0 +1,109 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, n_slice=16, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + trmin = _gd.Constant("trmin", "2.5", reg, True) + trmax = _gd.Constant("trmax", "10.0", reg, True) + tz = _gd.Constant("tz", "50", reg, True) + tstartphi = _gd.Constant("startphi", "0", reg, True) + tdeltaphi = _gd.Constant("deltaphi", "1.5*pi", reg, True) + + tstartphi_deg = _gd.Constant("startphi_deg", "0", reg, True) + tdeltaphi_deg = _gd.Constant("deltaphi_deg", "270", reg, True) + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Au", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Au") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Tubs( + "ts", trmin, trmax, tz, tstartphi, tdeltaphi, reg, "mm", "rad", nslice=n_slice + ) + + assert ts.evaluateParameterWithUnits("pRMin") == trmin + assert ts.evaluateParameterWithUnits("pRMax") == trmax + assert ts.evaluateParameterWithUnits("pDz") == tz + assert ts.evaluateParameterWithUnits("pSPhi") == tstartphi + assert ts.evaluateParameterWithUnits("pDPhi") == tdeltaphi + assert ts.evaluateParameterWithUnits("nslice") == n_slice + ts2 = _g4.solid.Tubs( + "ts2", + trmin, + trmax, + tz, + tstartphi_deg, + tdeltaphi_deg, + reg, + "cm", + "deg", + nslice=n_slice, + ) + assert ts2.evaluateParameterWithUnits("pRMin") == 10 * trmin + assert ts2.evaluateParameterWithUnits("pRMax") == 10 * trmax + assert ts2.evaluateParameterWithUnits("pDz") == 10 * tz + assert ts2.evaluateParameterWithUnits("pSPhi") == tstartphi + assert ts2.evaluateParameterWithUnits("pDPhi") == tdeltaphi + assert ts2.evaluateParameterWithUnits("nslice") == n_slice + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # test __repr__ + str(ts) + + # test extent of physical volume + wlextent = wl.extent(True) + wlextent_daughters = wl.extent(False) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T002_Tubs.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T002_Tubs.gmad"), "T002_Tubs.gdml" + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T0031_CutTubs_number.py b/tests/geant4/T0031_CutTubs_number.py new file mode 100644 index 000000000..c83255d5c --- /dev/null +++ b/tests/geant4/T0031_CutTubs_number.py @@ -0,0 +1,90 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +flat_ends = 2 + + +def Test(vis=False, interactive=False, type=normal): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True).eval() + wy = _gd.Constant("wy", "100", reg, True).eval() + wz = _gd.Constant("wz", "100", reg, True).eval() + + pi = _gd.Constant("pi", "3.1415926", reg, False).eval() + ctrmin = _gd.Constant("trmin", "2.5", reg, False).eval() + ctrmax = _gd.Constant("trmax", "10.0", reg, False).eval() + ctz = _gd.Constant("tz", "50", reg, False).eval() + ctstartphi = _gd.Constant("startphi", "0", reg, False).eval() + ctdeltaphi = _gd.Constant("deltaphi", "1.5*pi", reg, False).eval() + ctlowx = _gd.Constant("ctlowx", "-1", reg, False).eval() + ctlowy = _gd.Constant("ctlowy", "-1", reg, False).eval() + ctlowz = _gd.Constant("ctlowz", "-1", reg, False).eval() + cthighx = _gd.Constant("cthighx", "1", reg, False).eval() + cthighy = _gd.Constant("cthighy", "1", reg, False).eval() + cthighz = _gd.Constant("cthighz", "1", reg, False).eval() + + if type == flat_ends: + ctlowx.setExpression(0) + ctlowy.setExpression(0) + ctlowz.setExpression(-1) + cthighx.setExpression(0) + cthighy.setExpression(0) + cthighz.setExpression(1) + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + cts = _g4.solid.CutTubs( + "ts", + ctrmin, + ctrmax, + ctz, + ctstartphi, + ctdeltaphi, + [ctlowx, ctlowy, ctlowz], + [cthighx, cthighy, cthighz], + reg, + "mm", + "rad", + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ctl = _g4.LogicalVolume(cts, bm, "ctl", reg) + ctp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ctl, "ct_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T0031_CutTubs_numbers.gdml")) + + # test __repr__ + str(cts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T0032_CutTubs_string.py b/tests/geant4/T0032_CutTubs_string.py new file mode 100644 index 000000000..66c4140fb --- /dev/null +++ b/tests/geant4/T0032_CutTubs_string.py @@ -0,0 +1,90 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +flat_ends = 2 + + +def Test(vis=False, interactive=False, type=normal): + reg = _g4.Registry() + + # defines + wx = str(_gd.Constant("wx", "100", reg, True).eval()) + wy = str(_gd.Constant("wy", "100", reg, True).eval()) + wz = str(_gd.Constant("wz", "100", reg, True).eval()) + + pi = str(_gd.Constant("pi", "3.1415926", reg, False).eval()) + ctrmin = str(_gd.Constant("trmin", "2.5", reg, False).eval()) + ctrmax = str(_gd.Constant("trmax", "10.0", reg, False).eval()) + ctz = str(_gd.Constant("tz", "50", reg, False).eval()) + ctstartphi = str(_gd.Constant("startphi", "0", reg, False).eval()) + ctdeltaphi = str(_gd.Constant("deltaphi", "1.5*pi", reg, False).eval()) + ctlowx = str(_gd.Constant("ctlowx", "-1", reg, False).eval()) + ctlowy = str(_gd.Constant("ctlowy", "-1", reg, False).eval()) + ctlowz = str(_gd.Constant("ctlowz", "-1", reg, False).eval()) + cthighx = str(_gd.Constant("cthighx", "1", reg, False).eval()) + cthighy = str(_gd.Constant("cthighy", "1", reg, False).eval()) + cthighz = str(_gd.Constant("cthighz", "1", reg, False).eval()) + + if type == flat_ends: + ctlowx.setExpression(0) + ctlowy.setExpression(0) + ctlowz.setExpression(-1) + cthighx.setExpression(0) + cthighy.setExpression(0) + cthighz.setExpression(1) + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + cts = _g4.solid.CutTubs( + "ts", + ctrmin, + ctrmax, + ctz, + ctstartphi, + ctdeltaphi, + [ctlowx, ctlowy, ctlowz], + [cthighx, cthighy, cthighz], + reg, + "mm", + "rad", + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ctl = _g4.LogicalVolume(cts, bm, "ctl", reg) + ctp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ctl, "ct_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T0032_CutTubs_string.gdml")) + + # test __repr__ + str(cts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T0033_CutTubs_expression.py b/tests/geant4/T0033_CutTubs_expression.py new file mode 100644 index 000000000..cee8d779f --- /dev/null +++ b/tests/geant4/T0033_CutTubs_expression.py @@ -0,0 +1,93 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +flat_ends = 2 + + +def Test(vis=False, interactive=False, type=normal): + reg = _g4.Registry() + + # defines + + cc = _gd.Constant("cc", "1", reg, True) + + wx = str(_gd.Constant("wx", "100", reg, False).eval()) + "*cc" + wy = str(_gd.Constant("wy", "100", reg, False).eval()) + "*cc" + wz = str(_gd.Constant("wz", "100", reg, False).eval()) + "*cc" + + pi = str(_gd.Constant("pi", "3.1415926", reg, False).eval()) + "*cc" + ctrmin = str(_gd.Constant("trmin", "2.5", reg, False).eval()) + "*cc" + ctrmax = str(_gd.Constant("trmax", "10.0", reg, False).eval()) + "*cc" + ctz = str(_gd.Constant("tz", "50", reg, False).eval()) + "*cc" + ctstartphi = str(_gd.Constant("startphi", "0", reg, False).eval()) + "*cc" + ctdeltaphi = str(_gd.Constant("deltaphi", "1.5*pi", reg, False).eval()) + "*cc" + ctlowx = str(_gd.Constant("ctlowx", "-1", reg, False).eval()) + "*cc" + ctlowy = str(_gd.Constant("ctlowy", "-1", reg, False).eval()) + "*cc" + ctlowz = str(_gd.Constant("ctlowz", "-1", reg, False).eval()) + "*cc" + cthighx = str(_gd.Constant("cthighx", "1", reg, False).eval()) + "*cc" + cthighy = str(_gd.Constant("cthighy", "1", reg, False).eval()) + "*cc" + cthighz = str(_gd.Constant("cthighz", "1", reg, False).eval()) + "*cc" + + if type == flat_ends: + ctlowx.setExpression(0) + ctlowy.setExpression(0) + ctlowz.setExpression(-1) + cthighx.setExpression(0) + cthighy.setExpression(0) + cthighz.setExpression(1) + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + cts = _g4.solid.CutTubs( + "ts", + ctrmin, + ctrmax, + ctz, + ctstartphi, + ctdeltaphi, + [ctlowx, ctlowy, ctlowz], + [cthighx, cthighy, cthighz], + reg, + "mm", + "rad", + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ctl = _g4.LogicalVolume(cts, bm, "ctl", reg) + ctp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ctl, "ct_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T0033_CutTubs_expression.gdml")) + + # test __repr__ + str(cts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T0034_CutTubs_DefineTree.py b/tests/geant4/T0034_CutTubs_DefineTree.py new file mode 100644 index 000000000..39b1841be --- /dev/null +++ b/tests/geant4/T0034_CutTubs_DefineTree.py @@ -0,0 +1,105 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +flat_ends = 2 + + +def Test(vis=False, interactive=False, type=normal): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + ctrmin = _gd.Constant("trmin", "2.5", reg, True) + ctrmax = _gd.Constant("trmax", "10.0", reg, True) + ctz = _gd.Constant("tz", "50", reg, True) + ctstartphi = _gd.Constant("startphi", "0", reg, True) + ctdeltaphi = _gd.Constant("deltaphi", "1.5*pi", reg, True) + + ctlowtheta = _gd.Constant("ctlowtheta", "30/360*pi", reg, True) + ctlowphi = _gd.Constant("ctlowphi", "40/360*pi", reg, True) + + ctlowx = _gd.sin(ctlowtheta) * _gd.cos(ctlowphi) + ctlowy = _gd.sin(ctlowtheta) * _gd.sin(ctlowphi) + ctlowz = -_gd.cos(ctlowtheta) + + cthightheta = _gd.Constant("cthightheta", "50/360*pi", reg, True) + cthighphi = _gd.Constant("cthighphi", "60/360*pi", reg, True) + + cthighx = _gd.sin(cthightheta) * _gd.cos(cthighphi) + cthighy = _gd.sin(cthightheta) * _gd.sin(cthighphi) + cthighz = _gd.cos(cthightheta) + + ctlowx.setName("ctlowx") + ctlowy.setName("ctlowy") + ctlowz.setName("ctlowz") + + cthighx.setName("cthighx") + cthighy.setName("cthighy") + cthighz.setName("cthighz") + + if type == flat_ends: + ctlowx.setExpression(0) + ctlowy.setExpression(0) + ctlowz.setExpression(-1) + cthighx.setExpression(0) + cthighy.setExpression(0) + cthighz.setExpression(1) + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + cts = _g4.solid.CutTubs( + "ts", + ctrmin, + ctrmax, + ctz, + ctstartphi, + ctdeltaphi, + [ctlowx, ctlowy, ctlowz], + [cthighx, cthighy, cthighz], + reg, + "mm", + "rad", + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ctl = _g4.LogicalVolume(cts, bm, "ctl", reg) + ctp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ctl, "ct_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T0034_CutTubs_DefineTree.gdml")) + + # test __repr__ + str(cts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T003_CutTubs.py b/tests/geant4/T003_CutTubs.py new file mode 100644 index 000000000..e97e28702 --- /dev/null +++ b/tests/geant4/T003_CutTubs.py @@ -0,0 +1,141 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +flat_ends = 2 + + +def Test( + vis=False, interactive=False, type=normal, n_slice=16, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + ctrmin = _gd.Constant("trmin", "2.5", reg, True) + ctrmax = _gd.Constant("trmax", "10.0", reg, True) + ctz = _gd.Constant("tz", "50", reg, True) + ctstartphi = _gd.Constant("startphi", "0", reg, True) + ctdeltaphi = _gd.Constant("deltaphi", "1.5*pi", reg, True) + ctlowx = _gd.Constant("ctlowx", "-1", reg, True) + ctlowy = _gd.Constant("ctlowy", "-1", reg, True) + ctlowz = _gd.Constant("ctlowz", "-1", reg, True) + cthighx = _gd.Constant("cthighx", "1", reg, True) + cthighy = _gd.Constant("cthighy", "1", reg, True) + cthighz = _gd.Constant("cthighz", "1", reg, True) + + ctstartphi_deg = _gd.Constant("startphi_deg", "0", reg, True) + ctdeltaphi_deg = _gd.Constant("deltaphi_deg", "270", reg, True) + + expected_low = [-1, -1, -1] + expected_high = [1, 1, 1] + if type == flat_ends: + ctlowx.setExpression(0) + ctlowy.setExpression(0) + ctlowz.setExpression(-1) + cthighx.setExpression(0) + cthighy.setExpression(0) + cthighz.setExpression(1) + expected_low = [0, 0, -1] + expected_high = [0, 0, 1] + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Au", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Au") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + cts = _g4.solid.CutTubs( + "ts", + ctrmin, + ctrmax, + ctz, + ctstartphi, + ctdeltaphi, + [ctlowx, ctlowy, ctlowz], + [cthighx, cthighy, cthighz], + reg, + "mm", + "rad", + nslice=n_slice, + ) + assert cts.evaluateParameterWithUnits("pRMin") == ctrmin + assert cts.evaluateParameterWithUnits("pRMax") == ctrmax + assert cts.evaluateParameterWithUnits("pDz") == ctz + assert cts.evaluateParameterWithUnits("pSPhi") == ctstartphi + assert cts.evaluateParameterWithUnits("pDPhi") == ctdeltaphi + assert cts.evaluateParameterWithUnits("pLowNorm") == expected_low + assert cts.evaluateParameterWithUnits("pHighNorm") == expected_high + assert cts.evaluateParameterWithUnits("nslice") == n_slice + cts2 = _g4.solid.CutTubs( + "ts2", + ctrmin, + ctrmax, + ctz, + ctstartphi_deg, + ctdeltaphi_deg, + [ctlowx, ctlowy, ctlowz], + [cthighx, cthighy, cthighz], + reg, + "cm", + "deg", + nslice=n_slice, + ) + assert cts2.evaluateParameterWithUnits("pRMin") == 10 * ctrmin + assert cts2.evaluateParameterWithUnits("pRMax") == 10 * ctrmax + assert cts2.evaluateParameterWithUnits("pDz") == 10 * ctz + assert cts2.evaluateParameterWithUnits("pSPhi") == ctstartphi + assert cts2.evaluateParameterWithUnits("pDPhi") == ctdeltaphi + assert cts2.evaluateParameterWithUnits("pLowNorm") == [10 * i for i in expected_low] + assert cts2.evaluateParameterWithUnits("pHighNorm") == [ + 10 * i for i in expected_high + ] + assert cts2.evaluateParameterWithUnits("nslice") == n_slice + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ctl = _g4.LogicalVolume(cts, bm, "ctl", reg) + ctp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ctl, "ct_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T003_CutTubs.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T003_CutTubs.gmad"), + "T003_CutTubs.gdml", + ) + + # test __repr__ + str(cts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T004_Cons.py b/tests/geant4/T004_Cons.py new file mode 100644 index 000000000..4b7944df0 --- /dev/null +++ b/tests/geant4/T004_Cons.py @@ -0,0 +1,146 @@ +import os as _os +import numpy as _np +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +r1min_gt_r1max = 2 +r2min_gt_r2max = 3 +dphi_gt_2pi = 4 +dphi_eq_2pi = 5 +cone_up = 6 +inner_cylinder = 7 + + +def Test( + vis=False, interactive=False, type=normal, n_slice=10, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + crmin1 = _gd.Constant("crmin1", "6", reg, True) + crmax1 = _gd.Constant("crmax1", "20", reg, True) + crmin2 = _gd.Constant("crmin2", "5", reg, True) + crmax2 = _gd.Constant("crmax2", "10", reg, True) + cz = _gd.Constant("cz", "100", reg, True) + cdp = _gd.Constant("cdp", "1.5*pi", reg, True) + zero = _gd.Constant("zero", "0.0", reg, False) + + cdp_deg = _gd.Constant("cdp_deg", "270", reg, True) + + if type == r1min_gt_r1max: + crmin1.setExpression(21) + elif type == type == r2min_gt_r2max: + crmin2.setExpression(11) + elif type == dphi_gt_2pi: + cdp.setExpression("3*pi") + cdp_deg.setExpression("540") + elif type == dphi_eq_2pi: + cdp.setExpression(2 * _np.pi) + cdp_deg.setExpression("360") + elif type == cone_up: + crmin1.setExpression(5) + crmax1.setExpression(10) + crmin2.setExpression(6) + crmax2.setExpression(20) + elif type == inner_cylinder: + crmin1.setExpression(5) + crmin2.setExpression(5) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + cm = _g4.nist_material_2geant4Material("G4_Au", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + cm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + cs = _g4.solid.Cons( + "cs", + crmin1, + crmax1, + crmin2, + crmax2, + cz, + zero, + cdp, + reg, + "mm", + "rad", + nslice=n_slice, + ) + assert cs.evaluateParameterWithUnits("pRmin1") == crmin1 + assert cs.evaluateParameterWithUnits("pRmin2") == crmin2 + assert cs.evaluateParameterWithUnits("pRmax1") == crmax1 + assert cs.evaluateParameterWithUnits("pRmax2") == crmax2 + assert cs.evaluateParameterWithUnits("pDz") == cz + assert cs.evaluateParameterWithUnits("pSPhi") == zero + assert cs.evaluateParameterWithUnits("pDPhi") == cdp + assert cs.evaluateParameterWithUnits("nslice") == n_slice + cs2 = _g4.solid.Cons( + "cs2", + crmin1, + crmax1, + crmin2, + crmax2, + cz, + zero, + cdp_deg, + reg, + "cm", + "deg", + nslice=n_slice, + ) + assert cs2.evaluateParameterWithUnits("pRmin1") == 10 * crmin1 + assert cs2.evaluateParameterWithUnits("pRmin2") == 10 * crmin2 + assert cs2.evaluateParameterWithUnits("pRmax1") == 10 * crmax1 + assert cs2.evaluateParameterWithUnits("pRmax2") == 10 * crmax2 + assert cs2.evaluateParameterWithUnits("pDz") == 10 * cz + assert cs2.evaluateParameterWithUnits("pSPhi") == zero + assert cs2.evaluateParameterWithUnits("pDPhi") == cdp + assert cs2.evaluateParameterWithUnits("nslice") == n_slice + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + cl = _g4.LogicalVolume(cs, cm, "cl", reg) + cp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], cl, "c_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T004_Cons.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T004_Cons.gmad"), "T004_Cons.gdml" + ) + + # test __repr__ + str(cs) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T005_Para.py b/tests/geant4/T005_Para.py new file mode 100644 index 000000000..0848d291f --- /dev/null +++ b/tests/geant4/T005_Para.py @@ -0,0 +1,91 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + px = _gd.Constant("px", "10", reg, True) + py = _gd.Constant("py", "20", reg, True) + pz = _gd.Constant("pz", "30", reg, True) + pAlpha = _gd.Constant("pAlpha", "0.2", reg, True) + pTheta = _gd.Constant("pTheta", "0.3", reg, True) + pPhi = _gd.Constant("pPhi", "0.4", reg, True) + + pAlpha_deg = _gd.Constant("pAlpha_deg", "0.2/pi*180", reg, True) + pTheta_deg = _gd.Constant("pTheta_deg", "0.3/pi*180", reg, True) + pPhi_deg = _gd.Constant("pPhi_deg", "0.4/pi*180", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + pm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.Para("ps", px, py, pz, pAlpha, pTheta, pPhi, reg, "mm", "rad") + assert ps.evaluateParameterWithUnits("pX") == px + assert ps.evaluateParameterWithUnits("pY") == py + assert ps.evaluateParameterWithUnits("pZ") == pz + assert ps.evaluateParameterWithUnits("pAlpha") == pAlpha + assert ps.evaluateParameterWithUnits("pPhi") == pPhi + assert ps.evaluateParameterWithUnits("pTheta") == pTheta + ps2 = _g4.solid.Para( + "ps2", px, py, pz, pAlpha_deg, pTheta_deg, pPhi_deg, reg, "cm", "deg" + ) + assert ps2.evaluateParameterWithUnits("pX") == 10 * px + assert ps2.evaluateParameterWithUnits("pY") == 10 * py + assert ps2.evaluateParameterWithUnits("pZ") == 10 * pz + assert ps2.evaluateParameterWithUnits("pAlpha") == pAlpha + assert ps2.evaluateParameterWithUnits("pPhi") == pPhi + assert ps2.evaluateParameterWithUnits("pTheta") == pTheta + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + pp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T005_Para.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T005_Para.gmad"), "T005_Para.gdml" + ) + + # test __repr__ + str(ps) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T006_Trd.py b/tests/geant4/T006_Trd.py new file mode 100644 index 000000000..95cff53af --- /dev/null +++ b/tests/geant4/T006_Trd.py @@ -0,0 +1,79 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + tx1 = _gd.Constant("tx1", "20", reg, True) + ty1 = _gd.Constant("ty1", "25", reg, True) + tx2 = _gd.Constant("tx2", "5", reg, True) + ty2 = _gd.Constant("ty2", "7.5", reg, True) + tz = _gd.Constant("tz", "10.0", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + tm = _g4.nist_material_2geant4Material("G4_Au", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Trd("ts", tx1, tx2, ty1, ty2, tz, reg, "mm") + assert ts.evaluateParameterWithUnits("pX1") == tx1 + assert ts.evaluateParameterWithUnits("pX2") == tx2 + assert ts.evaluateParameterWithUnits("pY1") == ty1 + assert ts.evaluateParameterWithUnits("pY2") == ty2 + assert ts.evaluateParameterWithUnits("pZ") == tz + ts2 = _g4.solid.Trd("ts2", tx1, tx2, ty1, ty2, tz, reg, "cm") + assert ts2.evaluateParameterWithUnits("pX1") == 10 * tx1 + assert ts2.evaluateParameterWithUnits("pX2") == 10 * tx2 + assert ts2.evaluateParameterWithUnits("pY1") == 10 * ty1 + assert ts2.evaluateParameterWithUnits("pY2") == 10 * ty2 + assert ts2.evaluateParameterWithUnits("pZ") == 10 * tz + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T006_Trd.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T006_Trd.gmad"), "T002_Trd.gdml" + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T007_Trap.py b/tests/geant4/T007_Trap.py new file mode 100644 index 000000000..856716b1f --- /dev/null +++ b/tests/geant4/T007_Trap.py @@ -0,0 +1,140 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + tx1 = _gd.Constant("tx1", "5", reg, True) + tx2 = _gd.Constant("tx2", "5", reg, True) + tx3 = _gd.Constant("tx3", "10", reg, True) + tx4 = _gd.Constant("tx4", "10", reg, True) + + ty1 = _gd.Constant("ty1", "5", reg, True) + ty2 = _gd.Constant("ty2", "7.5", reg, True) + + tz = _gd.Constant("tz", "10.0", reg, True) + + ttheta = _gd.Constant("ttheta", "0.6", reg, True) + tphi = _gd.Constant("tphi", "0.0", reg, True) + talp1 = _gd.Constant("talp1", "0.0", reg, True) + talp2 = _gd.Constant("talp2", "0.0", reg, True) + + ttheta_deg = _gd.Constant("ttheta_deg", "0.6/pi*180", reg, True) + tphi_deg = _gd.Constant("tphi_deg", "0.0", reg, True) + talp1_deg = _gd.Constant("talp1_deg", "0.0", reg, True) + talp2_deg = _gd.Constant("talp2_deg", "0.0", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + tm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Trap( + "ts", + tz, + ttheta, + tphi, + ty1, + tx1, + tx2, + talp1, + ty2, + tx3, + tx4, + talp2, + reg, + "mm", + "rad", + ) + + assert ts.evaluateParameterWithUnits("pDz") == tz + assert ts.evaluateParameterWithUnits("pTheta") == ttheta + assert ts.evaluateParameterWithUnits("pDPhi") == tphi + assert ts.evaluateParameterWithUnits("pDy1") == ty1 + assert ts.evaluateParameterWithUnits("pDx1") == tx1 + assert ts.evaluateParameterWithUnits("pDx2") == tx2 + assert ts.evaluateParameterWithUnits("pAlp1") == talp1 + assert ts.evaluateParameterWithUnits("pDy2") == ty2 + assert ts.evaluateParameterWithUnits("pDx3") == tx3 + assert ts.evaluateParameterWithUnits("pDx4") == tx4 + assert ts.evaluateParameterWithUnits("pAlp2") == talp2 + ts2 = _g4.solid.Trap( + "ts2", + tz, + ttheta_deg, + tphi_deg, + ty1, + tx1, + tx2, + talp1_deg, + ty2, + tx3, + tx4, + talp2_deg, + reg, + "cm", + "deg", + ) + assert ts2.evaluateParameterWithUnits("pDz") == 10 * tz + assert ts2.evaluateParameterWithUnits("pTheta") == ttheta + assert ts2.evaluateParameterWithUnits("pDPhi") == tphi + assert ts2.evaluateParameterWithUnits("pDy1") == 10 * ty1 + assert ts2.evaluateParameterWithUnits("pDx1") == 10 * tx1 + assert ts2.evaluateParameterWithUnits("pDx2") == 10 * tx2 + assert ts2.evaluateParameterWithUnits("pAlp1") == talp1 + assert ts2.evaluateParameterWithUnits("pDy2") == 10 * ty2 + assert ts2.evaluateParameterWithUnits("pDx3") == 10 * tx3 + assert ts2.evaluateParameterWithUnits("pDx4") == 10 * tx4 + assert ts2.evaluateParameterWithUnits("pAlp2") == talp2 + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T007_Trap.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T007_Trap.gmad"), "T007_Trap.gdml" + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T008_Sphere.py b/tests/geant4/T008_Sphere.py new file mode 100644 index 000000000..6d308398e --- /dev/null +++ b/tests/geant4/T008_Sphere.py @@ -0,0 +1,124 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test( + vis=False, interactive=False, n_slice=10, n_stack=10, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + srmin = _gd.Constant("rmin", "8", reg, True) + srmax = _gd.Constant("rmax", "10", reg, True) + ssphi = _gd.Constant("sphi", "0", reg, True) + # sdphi = _gd.Constant("dphi","2*pi",reg,True) + sdphi = _gd.Constant("dphi", "1.75*pi", reg, True) + sstheta = _gd.Constant("stheta", "0", reg, True) + sdtheta = _gd.Constant("dtheta", "0.75*pi", reg, True) + # sdtheta = _gd.Constant("dtheta", "pi", reg, True) + + ssphi_deg = _gd.Constant("sphi_deg", "0", reg, True) + # sdphi_deg = _gd.Constant("dphi_deg","360",reg,True) + sdphi_deg = _gd.Constant("dphi_deg", "315", reg, True) + sstheta_deg = _gd.Constant("stheta_deg", "0", reg, True) + sdtheta_deg = _gd.Constant("dtheta_deg", "135", reg, True) + # sdtheta_deg = _gd.Constant("dtheta_deg", "180", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + sm = _g4.MaterialPredefined("G4_Fe") + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + sm = _g4.nist_material_2geant4Material("G4_Au", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + sm = _g4.MaterialPredefined("G4_Au") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ss = _g4.solid.Sphere( + "ss", + srmin, + srmax, + ssphi, + sdphi, + sstheta, + sdtheta, + reg, + "mm", + "rad", + nslice=n_slice, + nstack=n_stack, + ) + + assert ss.evaluateParameterWithUnits("pRmin") == srmin + assert ss.evaluateParameterWithUnits("pRmax") == srmax + assert ss.evaluateParameterWithUnits("pSPhi") == ssphi + assert ss.evaluateParameterWithUnits("pDPhi") == sdphi + assert ss.evaluateParameterWithUnits("pSTheta") == sstheta + assert ss.evaluateParameterWithUnits("pDTheta") == sdtheta + ss2 = _g4.solid.Sphere( + "ss2", + srmin, + srmax, + ssphi_deg, + sdphi_deg, + sstheta_deg, + sdtheta_deg, + reg, + "cm", + "deg", + nslice=n_slice, + nstack=n_stack, + ) + assert ss2.evaluateParameterWithUnits("pRmin") == 10 * srmin + assert ss2.evaluateParameterWithUnits("pRmax") == 10 * srmax + assert ss2.evaluateParameterWithUnits("pSPhi") == ssphi + assert ss2.evaluateParameterWithUnits("pDPhi") == sdphi + assert ss2.evaluateParameterWithUnits("pSTheta") == sstheta + assert ss2.evaluateParameterWithUnits("pDTheta") == sdtheta + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + sl = _g4.LogicalVolume(ss, sm, "sl", reg) + sp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], sl, "s_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T008_Sphere.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T008_Sphere.gmad"), + "T008_Sphere.gdml", + ) + + # test __repr__ + str(ss) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T009_Orb.py b/tests/geant4/T009_Orb.py new file mode 100644 index 000000000..602139938 --- /dev/null +++ b/tests/geant4/T009_Orb.py @@ -0,0 +1,69 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test( + vis=False, interactive=False, n_slice=16, n_stack=16, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + ormax = _gd.Constant("rmax", "10", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + om = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + om = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + os = _g4.solid.Orb("os", ormax, reg, "mm", nslice=n_slice, nstack=n_stack) + assert os.evaluateParameterWithUnits("pRMax") == ormax + os2 = _g4.solid.Orb("os2", ormax, reg, "cm", nslice=n_slice, nstack=n_stack) + assert os2.evaluateParameterWithUnits("pRMax") == 10 * ormax + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ol = _g4.LogicalVolume(os, om, "ol", reg) + op = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ol, "o_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T009_Orb.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T009_Orb.gmad"), "T009_Orb.gdml" + ) + + # test __repr__ + str(os) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T010_Torus.py b/tests/geant4/T010_Torus.py new file mode 100644 index 000000000..f4f4429e4 --- /dev/null +++ b/tests/geant4/T010_Torus.py @@ -0,0 +1,140 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test( + vis=False, interactive=False, n_slice=20, n_stack=20, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + trmin = _gd.Constant("rmin", "8.0", reg, True) + trmax = _gd.Constant("rmax", "10.0", reg, True) + trtor = _gd.Constant("rtor", "40.0", reg, True) + tsphi = _gd.Constant("sphi", "0", reg, True) + tsphi2 = _gd.Constant("sphi2s", "0.3*pi", reg, True) + tdphi = _gd.Constant("dphi", "1.5*pi", reg, True) + + tsphi_deg = _gd.Constant("sphi_deg", "0", reg, True) + tsphi2_deg = _gd.Constant("sphi2s_deg", "54", reg, True) + tdphi_deg = _gd.Constant("dphi_deg", "270", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + tm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts1 = _g4.solid.Torus( + "ts1", + trmin, + trmax, + trtor, + tsphi, + tdphi, + reg, + "mm", + "rad", + nslice=n_slice, + nstack=n_stack, + ) + assert ts1.evaluateParameterWithUnits("pRmin") == trmin + assert ts1.evaluateParameterWithUnits("pRmax") == trmax + assert ts1.evaluateParameterWithUnits("pRtor") == trtor + assert ts1.evaluateParameterWithUnits("pSPhi") == tsphi + assert ts1.evaluateParameterWithUnits("pDPhi") == tdphi + assert ts1.evaluateParameterWithUnits("nslice") == n_slice + assert ts1.evaluateParameterWithUnits("nstack") == n_stack + ts2 = _g4.solid.Torus( + "ts2", + trmin, + trmax, + trtor, + tsphi2, + tdphi, + reg, + "mm", + "rad", + nslice=n_slice, + nstack=n_stack, + ) + assert ts2.evaluateParameterWithUnits("pRmin") == trmin + assert ts2.evaluateParameterWithUnits("pRmax") == trmax + assert ts2.evaluateParameterWithUnits("pRtor") == trtor + assert ts2.evaluateParameterWithUnits("pSPhi") == tsphi2 + assert ts2.evaluateParameterWithUnits("pDPhi") == tdphi + assert ts2.evaluateParameterWithUnits("nslice") == n_slice + assert ts2.evaluateParameterWithUnits("nstack") == n_stack + ts3 = _g4.solid.Torus( + "ts3", + trmin, + trmax, + trtor, + tsphi_deg, + tdphi_deg, + reg, + "cm", + "deg", + nslice=n_slice, + nstack=n_stack, + ) + assert ts3.evaluateParameterWithUnits("pRmin") == 10 * trmin + assert ts3.evaluateParameterWithUnits("pRmax") == 10 * trmax + assert ts3.evaluateParameterWithUnits("pRtor") == 10 * trtor + assert ts3.evaluateParameterWithUnits("pSPhi") == tsphi + assert ts3.evaluateParameterWithUnits("pDPhi") == tdphi + assert ts3.evaluateParameterWithUnits("nslice") == n_slice + assert ts3.evaluateParameterWithUnits("nstack") == n_stack + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl1 = _g4.LogicalVolume(ts1, tm, "tl1", reg) + tl2 = _g4.LogicalVolume(ts2, tm, "tl2", reg) + tp1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl1, "t1_pv1", wl, reg) + tp2 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 2 * trmax + 5], tl2, "t2_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T010_Torus.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T010_Torus.gmad"), "T010_Torus.gdml" + ) + + # test __repr__ + str(ts1) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T011_Polycone.py b/tests/geant4/T011_Polycone.py new file mode 100644 index 000000000..0674fff0d --- /dev/null +++ b/tests/geant4/T011_Polycone.py @@ -0,0 +1,104 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, n_slice=64, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + psphi = _gd.Constant("sphi", "0", reg, True) + pdphi = _gd.Constant("dphi", "1.5*pi", reg, True) + + prmin1 = _gd.Constant("prmin1", "1", reg, True) + prmax1 = _gd.Constant("prmax1", "9", reg, True) + pz1 = _gd.Constant("z1", "-10", reg, True) + + prmin2 = _gd.Constant("prmin2", "5", reg, True) + prmax2 = _gd.Constant("prmax2", "9", reg, True) + pz2 = _gd.Constant("z2", "0", reg, True) + + prmin3 = _gd.Constant("prmin3", "3", reg, True) + prmax3 = _gd.Constant("prmax3", "5", reg, True) + pz3 = _gd.Constant("z3", "10", reg, True) + + prmin = [prmin1, prmin2, prmin3] + prmax = [prmax1, prmax2, prmax3] + pz = [pz1, pz2, pz3] + + psphi_deg = _gd.Constant("sphi_deg", "0", reg, True) + pdphi_deg = _gd.Constant("dphi_deg", "270", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + pm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.Polycone( + "ps", psphi, pdphi, pz, prmin, prmax, reg, "mm", "rad", nslice=n_slice + ) + assert ps.evaluateParameterWithUnits("pSPhi") == psphi + assert ps.evaluateParameterWithUnits("pDPhi") == pdphi + assert ps.evaluateParameterWithUnits("pZpl") == [-10, 0, 10] + assert ps.evaluateParameterWithUnits("pRMin") == [1, 5, 3] + assert ps.evaluateParameterWithUnits("pRMax") == [9, 9, 5] + ps2 = _g4.solid.Polycone( + "ps2", psphi_deg, pdphi_deg, pz, prmin, prmax, reg, "cm", "deg", nslice=n_slice + ) + assert ps2.evaluateParameterWithUnits("pSPhi") == psphi + assert ps2.evaluateParameterWithUnits("pDPhi") == pdphi + assert ps2.evaluateParameterWithUnits("pZpl") == [-100, 00, 100] + assert ps2.evaluateParameterWithUnits("pRMin") == [10, 50, 30] + assert ps2.evaluateParameterWithUnits("pRMax") == [90, 90, 50] + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T011_Polycone.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T011_Polycone.gmad"), + "T011_Polycone.gdml", + ) + + # test __repr__ + str(ps) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T012_GenericPolycone.py b/tests/geant4/T012_GenericPolycone.py new file mode 100644 index 000000000..509646eca --- /dev/null +++ b/tests/geant4/T012_GenericPolycone.py @@ -0,0 +1,132 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +two_planes = 2 + + +def Test( + vis=False, interactive=False, type=normal, n_slice=64, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + psphi = _gd.Constant("sphi", "1", reg, True) + pdphi = _gd.Constant("dphi", "4", reg, True) + + pr1 = _gd.Constant("pr1", "5", reg, True) + pz1 = _gd.Constant("z1", "-10", reg, True) + + pr2 = _gd.Constant("pr2", "7.5", reg, True) + pz2 = _gd.Constant("z2", "-10", reg, True) + + pr3 = _gd.Constant("pr3", "10", reg, True) + pz3 = _gd.Constant("z3", "0", reg, True) + + pr4 = _gd.Constant("pr4", "20", reg, True) + pz4 = _gd.Constant("z4", "-5", reg, True) + + pr5 = _gd.Constant("pr5", "7.5", reg, True) + pz5 = _gd.Constant("z5", "10", reg, True) + + pr6 = _gd.Constant("pr6", "5", reg, True) + pz6 = _gd.Constant("z6", "10", reg, True) + + pr7 = _gd.Constant("pr7", "2", reg, True) + pz7 = _gd.Constant("z7", "5", reg, True) + + pr = [pr1, pr2, pr3, pr4, pr5, pr6, pr7] + pz = [pz1, pz2, pz3, pz4, pz5, pz6, pz7] + + psphi_deg = _gd.Constant("sphi_deg", "1/pi*180", reg, True) + pdphi_deg = _gd.Constant("dphi_deg", "4/pi*180", reg, True) + + if type == two_planes: + pr = [pr1, pr2] + pz = [pz1, pz2] + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + pm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.GenericPolycone( + "ps", psphi, pdphi, pr, pz, reg, "mm", "rad", nslice=n_slice + ) + assert ps.evaluateParameterWithUnits("pSPhi") == psphi + assert ps.evaluateParameterWithUnits("pDPhi") == pdphi + if type == two_planes: + assert ps.evaluateParameterWithUnits("pR") == [5, 7.5] + assert ps.evaluateParameterWithUnits("pZ") == [-10, -10] + else: + assert ps.evaluateParameterWithUnits("pR") == [5, 7.5, 10, 20, 7.5, 5, 2] + assert ps.evaluateParameterWithUnits("pZ") == [-10, -10, 0, -5, 10, 10, 5] + ps2 = _g4.solid.GenericPolycone( + "ps2", psphi_deg, pdphi_deg, pr, pz, reg, "cm", "deg", nslice=n_slice + ) + assert ps2.evaluateParameterWithUnits("pSPhi") == psphi + assert ps2.evaluateParameterWithUnits("pDPhi") == pdphi + if type == two_planes: + assert ps2.evaluateParameterWithUnits("pR") == [50, 75] + assert ps2.evaluateParameterWithUnits("pZ") == [-100, -100] + else: + assert ps2.evaluateParameterWithUnits("pR") == [50, 75, 100, 200, 75, 50, 20] + assert ps2.evaluateParameterWithUnits("pZ") == [ + -100, + -100, + 00, + -50, + 100, + 100, + 50, + ] + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T012_GenericPolycone.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T012_GenericPolycone.gmad"), + "T012_GenericPolycone.gdml", + ) + + # test __repr__ + str(ps) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T013_Polyhedra.py b/tests/geant4/T013_Polyhedra.py new file mode 100644 index 000000000..b7ebd14a3 --- /dev/null +++ b/tests/geant4/T013_Polyhedra.py @@ -0,0 +1,105 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + psphi = _gd.Constant("sphi", "1", reg, True) + pdphi = _gd.Constant("dphi", "4", reg, True) + pnsid = _gd.Constant("pnsid", "4", reg, True) + + prmin1 = _gd.Constant("prmin1", "1", reg, True) + prmax1 = _gd.Constant("prmax1", "9", reg, True) + pz1 = _gd.Constant("z1", "-10", reg, True) + + prmin2 = _gd.Constant("prmin2", "3", reg, True) + prmax2 = _gd.Constant("prmax2", "5", reg, True) + pz2 = _gd.Constant("z2", "12", reg, True) + + prmin = [prmin1, prmin2] + prmax = [prmax1, prmax2] + pz = [pz1, pz2] + + psphi_deg = _gd.Constant("sphi_deg", "1/pi*180", reg, True) + pdphi_deg = _gd.Constant("dphi_deg", "4/pi*180", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + pm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.Polyhedra( + "ps", psphi, pdphi, pnsid, len(pz), pz, prmin, prmax, reg, "mm", "rad" + ) + assert ps.evaluateParameterWithUnits("pSPhi") == psphi + assert ps.evaluateParameterWithUnits("pDPhi") == pdphi + assert ps.evaluateParameterWithUnits("numSide") == pnsid + assert ps.evaluateParameterWithUnits("numZPlanes") == len(pz) + assert ps.evaluateParameterWithUnits("zPlane") == [-10, 12] + assert ps.evaluateParameterWithUnits("rInner") == [1, 3] + assert ps.evaluateParameterWithUnits("rOuter") == [9, 5] + ps2 = _g4.solid.Polyhedra( + "ps2", psphi_deg, pdphi_deg, pnsid, len(pz), pz, prmin, prmax, reg, "cm", "deg" + ) + assert ps2.evaluateParameterWithUnits("pSPhi") == psphi + assert ps2.evaluateParameterWithUnits("pDPhi") == pdphi + assert ps2.evaluateParameterWithUnits("numSide") == pnsid + assert ps2.evaluateParameterWithUnits("numZPlanes") == len(pz) + assert ps2.evaluateParameterWithUnits("zPlane") == [-100, 120] + assert ps2.evaluateParameterWithUnits("rInner") == [10, 30] + assert ps2.evaluateParameterWithUnits("rOuter") == [90, 50] + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T013_Polyhedra.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T013_Polyhedra.gmad"), + "T013_Polyhedra.gdml", + ) + + # test __repr__ + str(ps) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T014_GenericPolyhedra.py b/tests/geant4/T014_GenericPolyhedra.py new file mode 100644 index 000000000..e79c29add --- /dev/null +++ b/tests/geant4/T014_GenericPolyhedra.py @@ -0,0 +1,114 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +two_planes = 2 + + +def Test(vis=False, interactive=False, type=normal, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + pi = _gd.Constant("pi", "3.1415926", reg, True) + psphi = _gd.Constant("sphi", "1", reg, True) + pdphi = _gd.Constant("dphi", "4", reg, True) + pnsid = _gd.Constant("pnsid", "4", reg, True) + + pr1 = _gd.Constant("pr1", "1", reg, True) + pz1 = _gd.Constant("pz1", "-10", reg, True) + + pr2 = _gd.Constant("pr2", "2", reg, True) + pz2 = _gd.Constant("pz2", "0", reg, True) + + pr3 = _gd.Constant("pr3", "1", reg, True) + pz3 = _gd.Constant("pz3", "10", reg, True) + + pr = [pr1, pr2, pr3] + pz = [pz1, pz2, pz3] + + if type == two_planes: + pr = [pr1, pr2] + pz = [pz1, pz2] + + psphi_deg = _gd.Constant("sphi_deg", "1/pi*180", reg, True) + pdphi_deg = _gd.Constant("dphi_deg", "4/pi*180", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + pm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.GenericPolyhedra("ps", psphi, pdphi, pnsid, pr, pz, reg, "mm", "rad") + assert ps.evaluateParameterWithUnits("pSPhi") == psphi + assert ps.evaluateParameterWithUnits("pDPhi") == pdphi + assert ps.evaluateParameterWithUnits("numSide") == pnsid + if type == two_planes: + assert ps.evaluateParameterWithUnits("pZ") == [-10, 0] + assert ps.evaluateParameterWithUnits("pR") == [1, 2] + else: + assert ps.evaluateParameterWithUnits("pZ") == [-10, 0, 10] + assert ps.evaluateParameterWithUnits("pR") == [1, 2, 1] + ps2 = _g4.solid.GenericPolyhedra( + "ps2", psphi_deg, pdphi_deg, pnsid, pr, pz, reg, "cm", "deg" + ) + assert ps2.evaluateParameterWithUnits("pSPhi") == psphi + assert ps2.evaluateParameterWithUnits("pDPhi") == pdphi + assert ps2.evaluateParameterWithUnits("numSide") == pnsid + if type == two_planes: + assert ps2.evaluateParameterWithUnits("pZ") == [-100, 0] + assert ps2.evaluateParameterWithUnits("pR") == [10, 20] + else: + assert ps2.evaluateParameterWithUnits("pZ") == [-100, 0, 100] + assert ps2.evaluateParameterWithUnits("pR") == [10, 20, 10] + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T014_GenericPolyhedra.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T014_GenericPolyhedra.gmad"), + "T014_GenericPolyhedra.gdml", + ) + + # test __repr__ + str(ps) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T015_EllipticalTube.py b/tests/geant4/T015_EllipticalTube.py new file mode 100644 index 000000000..7a64e35fa --- /dev/null +++ b/tests/geant4/T015_EllipticalTube.py @@ -0,0 +1,72 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, n_slice=30, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + ex = _gd.Constant("ex", "10", reg, True) + ey = _gd.Constant("ey", "25", reg, True) + ez = _gd.Constant("ez", "20", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + em = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + em = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + es = _g4.solid.EllipticalTube("es", ex, ey, ez, reg, nslice=n_slice) + assert es.evaluateParameterWithUnits("pDx") == ex + assert es.evaluateParameterWithUnits("pDy") == ey + assert es.evaluateParameterWithUnits("pDz") == ez + es2 = _g4.solid.EllipticalTube("es2", ex, ey, ez, reg, "cm", nslice=n_slice) + assert es2.evaluateParameterWithUnits("pDx") == 10 * ex + assert es2.evaluateParameterWithUnits("pDy") == 10 * ey + assert es2.evaluateParameterWithUnits("pDz") == 10 * ez + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + el = _g4.LogicalVolume(es, em, "el", reg) + ep = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], el, "e_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T015_EllipticalTube.gdml")) + # w.writeGmadTester(_os.path.join(_os.path.dirname(__file__),"T015_EllipticalTube.gmad"),"T015_EllipticalTube.gdml") + + # test __repr__ + str(es) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T016_Ellipsoid.py b/tests/geant4/T016_Ellipsoid.py new file mode 100644 index 000000000..49a4cda93 --- /dev/null +++ b/tests/geant4/T016_Ellipsoid.py @@ -0,0 +1,88 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test( + vis=False, interactive=False, n_slice=25, n_stack=25, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + eax = _gd.Constant("eax", "10", reg, True) + eby = _gd.Constant("eby", "15", reg, True) + ecz = _gd.Constant("ecz", "20", reg, True) + ebc = _gd.Constant("ebc", "-15", reg, True) + etc = _gd.Constant("etc", "15", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + em = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + em = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + es = _g4.solid.Ellipsoid( + "es", eax, eby, ecz, ebc, etc, reg, nslice=n_slice, nstack=n_stack + ) + assert es.evaluateParameterWithUnits("pxSemiAxis") == eax + assert es.evaluateParameterWithUnits("pySemiAxis") == eby + assert es.evaluateParameterWithUnits("pzSemiAxis") == ecz + assert es.evaluateParameterWithUnits("pzBottomCut") == ebc + assert es.evaluateParameterWithUnits("pzTopCut") == etc + es2 = _g4.solid.Ellipsoid( + "es2", eax, eby, ecz, ebc, etc, reg, "cm", nslice=n_slice, nstack=n_stack + ) + assert es2.evaluateParameterWithUnits("pxSemiAxis") == 10 * eax + assert es2.evaluateParameterWithUnits("pySemiAxis") == 10 * eby + assert es2.evaluateParameterWithUnits("pzSemiAxis") == 10 * ecz + assert es2.evaluateParameterWithUnits("pzBottomCut") == 10 * ebc + assert es2.evaluateParameterWithUnits("pzTopCut") == 10 * etc + + print(es.mesh()) + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + el = _g4.LogicalVolume(es, em, "el", reg) + ep = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], el, "e_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T016_Ellipsoid.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T016_Ellipsoid.gmad"), + "T016_Ellipsoid.gdml", + ) + + # test __repr__ + str(es) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T017_EllipticalCone.py b/tests/geant4/T017_EllipticalCone.py new file mode 100644 index 000000000..0a8c579a1 --- /dev/null +++ b/tests/geant4/T017_EllipticalCone.py @@ -0,0 +1,102 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +zcut_outofrange = 2 + + +def Test( + vis=False, interactive=False, type=normal, n_slice=16, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + edx = _gd.Constant("eax", "0.5", reg, True) + edy = _gd.Constant("eby", "1", reg, True) + ezmax = _gd.Constant("ecz", "40", reg, True) + ezcut = _gd.Constant("ebc", "20", reg, True) + + if type == zcut_outofrange: + ezcut.setExpression(30) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + em = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + em = _g4.MaterialPredefined("G4_Fe") + + # solids + ubox = _g4.solid.Box("boxxx", 500, 500, 500, reg, "mm") + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + es = _g4.solid.EllipticalCone( + "es", edx, edy, ezmax, ezcut, reg, "mm", nslice=n_slice + ) + assert es.evaluateParameterWithUnits("pxSemiAxis") == edx + assert es.evaluateParameterWithUnits("pySemiAxis") == edy + assert es.evaluateParameterWithUnits("zMax") == ezmax + assert es.evaluateParameterWithUnits("pzTopCut") == ezcut + es2 = _g4.solid.EllipticalCone( + "es2", edx, edy, ezmax, ezcut, reg, "cm", nslice=n_slice + ) + assert es2.evaluateParameterWithUnits("pxSemiAxis") == 10 * edx + assert es2.evaluateParameterWithUnits("pySemiAxis") == 10 * edy + assert es2.evaluateParameterWithUnits("zMax") == 10 * ezmax + assert es2.evaluateParameterWithUnits("pzTopCut") == 10 * ezcut + union = _g4.solid.Union( + "myunion", + ubox, + es, + [ + [0, 0, 0], + [ + 0, + 0, + 0, + ], + ], + reg, + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + el = _g4.LogicalVolume(es, em, "el", reg) + # el = _g4.LogicalVolume(union, em, "ul", reg) + ep = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], el, "e_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T017_EllipticalCone.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T017_EllipticalCone.gmad"), + "T017_EllipticalCone.gdml", + ) + + # test __repr__ + str(es) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(length=20) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} diff --git a/tests/geant4/T018_Paraboloid.py b/tests/geant4/T018_Paraboloid.py new file mode 100644 index 000000000..276d4a796 --- /dev/null +++ b/tests/geant4/T018_Paraboloid.py @@ -0,0 +1,79 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test( + vis=False, interactive=False, n_slice=16, n_stack=16, writeNISTMaterials=False +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + prlo = _gd.Constant("prlo", "2", reg, True) + prhi = _gd.Constant("prhi", "15", reg, True) + pz = _gd.Constant("pz", "50", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + pm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + pm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ps = _g4.solid.Paraboloid("ps", pz, prlo, prhi, reg, nslice=n_slice, nstack=n_stack) + assert ps.evaluateParameterWithUnits("pDz") == pz + assert ps.evaluateParameterWithUnits("pR1") == prlo + assert ps.evaluateParameterWithUnits("pR2") == prhi + ps2 = _g4.solid.Paraboloid( + "ps2", pz, prlo, prhi, reg, "cm", nslice=n_slice, nstack=n_stack + ) + assert ps2.evaluateParameterWithUnits("pDz") == 10 * pz + assert ps2.evaluateParameterWithUnits("pR1") == 10 * prlo + assert ps2.evaluateParameterWithUnits("pR2") == 10 * prhi + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + pl = _g4.LogicalVolume(ps, pm, "pl", reg) + pp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], pl, "p_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T018_Paraboloid.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T018_Paraboloid.gmad"), + "T018_Paraboloid.gdml", + ) + + # test __repr__ + str(ps) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"teststatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T019_Hyperboloid.py b/tests/geant4/T019_Hyperboloid.py new file mode 100644 index 000000000..cb2f84f15 --- /dev/null +++ b/tests/geant4/T019_Hyperboloid.py @@ -0,0 +1,115 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +rmin_eq_zero = 2 +rmin_gt_rmax = 3 + + +def Test( + vis=False, + interactive=False, + type=normal, + n_slice=16, + n_stack=16, + writeNISTMaterials=False, +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + pi = _gd.Constant("pi", "3.1415926", reg, True) + hrmin = _gd.Constant("hrmin", "20", reg, True) + hrmax = _gd.Constant("hrmax", "30.0", reg, True) + hz = _gd.Constant("hz", "50.0", reg, True) + hinst = _gd.Constant("hinst", "0.7", reg, True) + houtst = _gd.Constant("houtst", "0.7", reg, True) + + hinst_deg = _gd.Constant("hinst_deg", "0.7/pi*180", reg, True) + houtst_deg = _gd.Constant("houtst_deg", "0.7/pi*180", reg, True) + + if type == rmin_eq_zero: + hrmin.setExpression(0) + + if type == rmin_gt_rmax: + hrmin.setExpression(2) + hrmax.setExpression(1) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + hm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + hm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + hs = _g4.solid.Hype( + "hs", hrmin, hrmax, hinst, houtst, hz, reg, nslice=n_slice, nstack=n_stack + ) + assert hs.evaluateParameterWithUnits("innerRadius") == hrmin + assert hs.evaluateParameterWithUnits("outerRadius") == hrmax + assert hs.evaluateParameterWithUnits("innerStereo") == hinst + assert hs.evaluateParameterWithUnits("outerStereo") == houtst + assert hs.evaluateParameterWithUnits("lenZ") == hz + hs2 = _g4.solid.Hype( + "hs2", + hrmin, + hrmax, + hinst, + houtst, + hz, + reg, + "cm", + nslice=n_slice, + nstack=n_stack, + ) + assert hs2.evaluateParameterWithUnits("innerRadius") == 10 * hrmin + assert hs2.evaluateParameterWithUnits("outerRadius") == 10 * hrmax + assert hs2.evaluateParameterWithUnits("innerStereo") == hinst + assert hs2.evaluateParameterWithUnits("outerStereo") == houtst + assert hs2.evaluateParameterWithUnits("lenZ") == 10 * hz + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + hl = _g4.LogicalVolume(hs, hm, "hl", reg) + hp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], hl, "h_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T019_Hyperboloid.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T019_Hyperboloid.gmad"), + "T019_Hyperboloid.gdml", + ) + + # test __repr__ + str(hs) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"teststatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T020_Tet.py b/tests/geant4/T020_Tet.py new file mode 100644 index 000000000..90f74c4ec --- /dev/null +++ b/tests/geant4/T020_Tet.py @@ -0,0 +1,76 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + v1 = _gd.Position("v1", "10", "10", "0", "mm", reg, True) + v2 = _gd.Position("v2", "-10", "10", "0", "mm", reg, True) + v3 = _gd.Position("v3", "-10", "-10", "0", "mm", reg, True) + v4 = _gd.Position("v4", "0", "0", "10", "mm", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + tm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Tet("ts", v1, v2, v3, v4, reg) + assert ts.evaluateParameterWithUnits("anchor") == [10, 10, 0] + assert ts.evaluateParameterWithUnits("p2") == [-10, 10, 0] + assert ts.evaluateParameterWithUnits("p3") == [-10, -10, 0] + assert ts.evaluateParameterWithUnits("p4") == [0, 0, 10] + ts2 = _g4.solid.Tet("ts2", v1, v2, v3, v4, reg, "cm") + assert ts2.evaluateParameterWithUnits("anchor") == [100, 100, 0] + assert ts2.evaluateParameterWithUnits("p2") == [-100, 100, 0] + assert ts2.evaluateParameterWithUnits("p3") == [-100, -100, 0] + assert ts2.evaluateParameterWithUnits("p4") == [0, 0, 100] + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T020_Tet.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T020_Tet.gmad"), "T020_Tet.gdml" + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T021_ExtrudedSolid.py b/tests/geant4/T021_ExtrudedSolid.py new file mode 100644 index 000000000..2fc38f9c6 --- /dev/null +++ b/tests/geant4/T021_ExtrudedSolid.py @@ -0,0 +1,146 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "150", reg, True) + wy = _gd.Constant("wy", "150", reg, True) + wz = _gd.Constant("wz", "150", reg, True) + + p1x = _gd.Constant("p1x", "-20", reg, True) + p1y = _gd.Constant("p1y", "-20", reg, True) + + p2x = _gd.Constant("p2x", "-20", reg, True) + p2y = _gd.Constant("p2y", "20", reg, True) + + p3x = _gd.Constant("p3x", "20", reg, True) + p3y = _gd.Constant("p3y", "20", reg, True) + + p4x = _gd.Constant("p4x", "20", reg, True) + p4y = _gd.Constant("p4y", "10", reg, True) + + p5x = _gd.Constant("p5x", "-10", reg, True) + p5y = _gd.Constant("p5y", "10", reg, True) + + p6x = _gd.Constant("p6x", "-10", reg, True) + p6y = _gd.Constant("p6y", "-10", reg, True) + + p7x = _gd.Constant("p7x", "20", reg, True) + p7y = _gd.Constant("p7y", "-10", reg, True) + + p8x = _gd.Constant("p8x", "20", reg, True) + p8y = _gd.Constant("p8y", "-20", reg, True) + + z1 = _gd.Constant("z1", "-20", reg, True) + x1 = _gd.Constant("x1", "5", reg, True) + y1 = _gd.Constant("y1", "5", reg, True) + s1 = _gd.Constant("s1", "1", reg, True) + + z2 = _gd.Constant("z2", "0", reg, True) + x2 = _gd.Constant("x2", "-5", reg, True) + y2 = _gd.Constant("y2", "-5", reg, True) + s2 = _gd.Constant("s2", "1", reg, True) + + z3 = _gd.Constant("z3", "20", reg, True) + x3 = _gd.Constant("x3", "0", reg, True) + y3 = _gd.Constant("y3", "0", reg, True) + s3 = _gd.Constant("s3", "2", reg, True) + + polygon = [ + [p1x, p1y], + [p2x, p2y], + [p3x, p3y], + [p4x, p4y], + [p5x, p5y], + [p6x, p6y], + [p7x, p7y], + [p8x, p8y], + ] + slices = [[z1, [x1, y1], s1], [z2, [x2, y2], s2], [z3, [x3, y3], s3]] + + polygon_float = [ + [-20, -20], + [-20, 20], + [20, 20], + [20, 10], + [-10, 10], + [-10, -10], + [20, -10], + [20, -20], + ] + slices_float = [[-20, [5, 5], 1], [0, [-5, -5], 1], [20, [0, 0], 2]] + + polygon_float_cm = [ + [-200, -200], + [-200, 200], + [200, 200], + [200, 100], + [-100, 100], + [-100, -100], + [200, -100], + [200, -200], + ] + slices_float_cm = [[-200, [50, 50], 1], [00, [-50, -50], 1], [200, [00, 00], 2]] + + wm = _g4.MaterialPredefined("G4_Galactic") + xm = _g4.MaterialPredefined("G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + xm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + xm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + xs = _g4.solid.ExtrudedSolid("xs", polygon, slices, reg) + assert xs.evaluateParameterWithUnits("pPolygon") == polygon_float + assert xs.evaluateParameterWithUnits("pZslices") == slices_float + xs2 = _g4.solid.ExtrudedSolid("xs2", polygon, slices, reg, "cm") + assert xs2.evaluateParameterWithUnits("pPolygon") == polygon_float_cm + assert xs2.evaluateParameterWithUnits("pZslices") == slices_float_cm + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + xl = _g4.LogicalVolume(xs, xm, "xl", reg) + xp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], xl, "x_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T021_ExtrudedSolid.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T021_ExtrudedSolid.gmad"), + "T021_ExtrudedSolid.gdml", + ) + + # test __repr__ + str(xs) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T022_TwistedBox.py b/tests/geant4/T022_TwistedBox.py new file mode 100644 index 000000000..abe1b41d0 --- /dev/null +++ b/tests/geant4/T022_TwistedBox.py @@ -0,0 +1,83 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + tbx = _gd.Constant("bx", "10", reg, True) + tby = _gd.Constant("by", "20", reg, True) + tbz = _gd.Constant("bz", "30", reg, True) + tbphit = _gd.Constant("bt", "1.0", reg, True) + + tbphit_deg = _gd.Constant("bt_deg", "1.0/pi*180", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + tm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.TwistedBox("ts", tbphit, tbx, tby, tbz, reg) + + assert ts.evaluateParameterWithUnits("twistedAngle") == tbphit + assert ts.evaluateParameterWithUnits("pDx") == tbx + assert ts.evaluateParameterWithUnits("pDy") == tby + assert ts.evaluateParameterWithUnits("pDz") == tbz + ts2 = _g4.solid.TwistedBox("ts2", tbphit_deg, tbx, tby, tbz, reg, "cm", "deg") + assert ts2.evaluateParameterWithUnits("twistedAngle") == tbphit + assert ts2.evaluateParameterWithUnits("pDx") == 10 * tbx + assert ts2.evaluateParameterWithUnits("pDy") == 10 * tby + assert ts2.evaluateParameterWithUnits("pDz") == 10 * tbz + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T022_TwistedBox.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T022_TwistedBox.gmad"), + "T022_TwistedBox.gdml", + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T023_TwistedTrap.py b/tests/geant4/T023_TwistedTrap.py new file mode 100644 index 000000000..b67524ecc --- /dev/null +++ b/tests/geant4/T023_TwistedTrap.py @@ -0,0 +1,129 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + ttwist = _gd.Constant("tptwist", "1.0", reg, True) + + tx1 = _gd.Constant("tx1", "5", reg, True) + tx2 = _gd.Constant("tx2", "5", reg, True) + tx3 = _gd.Constant("tx3", "10", reg, True) + tx4 = _gd.Constant("tx4", "10", reg, True) + + ty1 = _gd.Constant("ty1", "5", reg, True) + ty2 = _gd.Constant("ty2", "7.5", reg, True) + + tz = _gd.Constant("tz", "10.0", reg, True) + + ttheta = _gd.Constant("ttheta", "0.6", reg, True) + tphi = _gd.Constant("tphi", "0.0", reg, True) + talp = _gd.Constant("talp", "0.0", reg, True) + + ttwist_deg = _gd.Constant("tptwist_deg", "1.0/pi*180", reg, True) + ttheta_deg = _gd.Constant("ttheta_deg", "0.6/pi*180", reg, True) + tphi_deg = _gd.Constant("tphi_deg", "0.0/pi*180", reg, True) + talp_deg = _gd.Constant("talp_deg", "0.0/pi*180", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + tm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.TwistedTrap( + "ts", ttwist, tz, ttheta, tphi, ty1, tx1, tx2, ty2, tx3, tx4, talp, reg + ) + + assert ts.evaluateParameterWithUnits("twistedAngle") == ttwist + assert ts.evaluateParameterWithUnits("pDz") == tz + assert ts.evaluateParameterWithUnits("pTheta") == ttheta + assert ts.evaluateParameterWithUnits("pDPhi") == tphi + assert ts.evaluateParameterWithUnits("pDy1") == ty1 + assert ts.evaluateParameterWithUnits("pDx1") == tx1 + assert ts.evaluateParameterWithUnits("pDx2") == tx2 + assert ts.evaluateParameterWithUnits("pDy2") == ty2 + assert ts.evaluateParameterWithUnits("pDx3") == tx3 + assert ts.evaluateParameterWithUnits("pDx4") == tx4 + assert ts.evaluateParameterWithUnits("pAlp") == talp + ts2 = _g4.solid.TwistedTrap( + "ts2", + ttwist_deg, + tz, + ttheta_deg, + tphi_deg, + ty1, + tx1, + tx2, + ty2, + tx3, + tx4, + talp_deg, + reg, + "cm", + "deg", + ) + assert ts2.evaluateParameterWithUnits("twistedAngle") == ttwist + assert ts2.evaluateParameterWithUnits("pDz") == 10 * tz + assert ts2.evaluateParameterWithUnits("pTheta") == ttheta + assert ts2.evaluateParameterWithUnits("pDPhi") == tphi + assert ts2.evaluateParameterWithUnits("pDy1") == 10 * ty1 + assert ts2.evaluateParameterWithUnits("pDx1") == 10 * tx1 + assert ts2.evaluateParameterWithUnits("pDx2") == 10 * tx2 + assert ts2.evaluateParameterWithUnits("pDy2") == 10 * ty2 + assert ts2.evaluateParameterWithUnits("pDx3") == 10 * tx3 + assert ts2.evaluateParameterWithUnits("pDx4") == 10 * tx4 + assert ts2.evaluateParameterWithUnits("pAlp") == talp + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T023_TwistedTrap.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T023_TwistedTrap.gmad"), + "T023_TwistedTrap.gdml", + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T024_TwistedTrd.py b/tests/geant4/T024_TwistedTrd.py new file mode 100644 index 000000000..c068f56d6 --- /dev/null +++ b/tests/geant4/T024_TwistedTrd.py @@ -0,0 +1,90 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + ttwist = _gd.Constant("tptwist", "1.0", reg, True) + + tx1 = _gd.Constant("tx1", "20", reg, True) + ty1 = _gd.Constant("ty1", "25", reg, True) + tx2 = _gd.Constant("tx2", "5", reg, True) + ty2 = _gd.Constant("ty2", "7.5", reg, True) + tz = _gd.Constant("tz", "10.0", reg, True) + + ttwist_deg = _gd.Constant("tptwist_deg", "1.0/pi*180", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + tm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.TwistedTrd("ts", ttwist, tx1, tx2, ty1, ty2, tz, reg) + assert ts.evaluateParameterWithUnits("twistedAngle") == ttwist + assert ts.evaluateParameterWithUnits("pDx1") == tx1 + assert ts.evaluateParameterWithUnits("pDx2") == tx2 + assert ts.evaluateParameterWithUnits("pDy1") == ty1 + assert ts.evaluateParameterWithUnits("pDy2") == ty2 + assert ts.evaluateParameterWithUnits("pDz") == tz + ts2 = _g4.solid.TwistedTrd( + "ts2", ttwist_deg, tx1, tx2, ty1, ty2, tz, reg, "cm", "deg" + ) + assert ts2.evaluateParameterWithUnits("twistedAngle") == ttwist + assert ts2.evaluateParameterWithUnits("pDx1") == 10 * tx1 + assert ts2.evaluateParameterWithUnits("pDx2") == 10 * tx2 + assert ts2.evaluateParameterWithUnits("pDy1") == 10 * ty1 + assert ts2.evaluateParameterWithUnits("pDy2") == 10 * ty2 + assert ts2.evaluateParameterWithUnits("pDz") == 10 * tz + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T024_TwistedTrd.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T024_TwistedTrd.gmad"), + "T024_TwistedTrd.gdml", + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T025_TwistedTubs.py b/tests/geant4/T025_TwistedTubs.py new file mode 100644 index 000000000..a23b55c2c --- /dev/null +++ b/tests/geant4/T025_TwistedTubs.py @@ -0,0 +1,90 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + + ttwist = _gd.Constant("tptwist", "1.0", reg, True) + trmin = _gd.Constant("trmin", "2.5", reg, True) + trmax = _gd.Constant("trmax", "10.0", reg, True) + tz = _gd.Constant("tz", "50", reg, True) + tphi = _gd.Constant("phi", "1.5*pi", reg, True) + + ttwist_deg = _gd.Constant("tptwist_deg", "1.0/pi*180", reg, True) + tphi_deg = _gd.Constant("tphi_deg", "1.5*180", reg, True) + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_Fe") + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.TwistedTubs("ts", trmin, trmax, tz, tphi, ttwist, reg) + assert ts.evaluateParameterWithUnits("endinnerrad") == trmin + assert ts.evaluateParameterWithUnits("endouterrad") == trmax + assert ts.evaluateParameterWithUnits("zlen") == tz + assert ts.evaluateParameterWithUnits("phi") == tphi + assert ts.evaluateParameterWithUnits("twistedangle") == ttwist + ts2 = _g4.solid.TwistedTubs( + "ts2", trmin, trmax, tz, tphi_deg, ttwist_deg, reg, "cm", "deg" + ) + assert ts2.evaluateParameterWithUnits("endinnerrad") == 10 * trmin + assert ts2.evaluateParameterWithUnits("endouterrad") == 10 * trmax + assert ts2.evaluateParameterWithUnits("zlen") == 10 * tz + assert ts2.evaluateParameterWithUnits("phi") == tphi + assert ts2.evaluateParameterWithUnits("twistedangle") == ttwist + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T025_TwistedTubs.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T025_TwistedTubs.gmad"), + "T025_TwistedTubs.gdml", + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"teststatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T026_GenericTrap.py b/tests/geant4/T026_GenericTrap.py new file mode 100644 index 000000000..c3491175f --- /dev/null +++ b/tests/geant4/T026_GenericTrap.py @@ -0,0 +1,171 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +normal = 1 +zero_area_quad = 2 + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + + tv1x = _gd.Constant("v1x", "10", reg, True) + tv1y = _gd.Constant("v1y", "10", reg, True) + + tv2x = _gd.Constant("v2x", "20", reg, True) + tv2y = _gd.Constant("v2y", "30", reg, True) + + tv3x = _gd.Constant("v3x", "30", reg, True) + tv3y = _gd.Constant("v3y", "30", reg, True) + + tv4x = _gd.Constant("v4x", "40", reg, True) + tv4y = _gd.Constant("v4y", "10", reg, True) + + tv5x = _gd.Constant("v5x", "20", reg, True) + tv5y = _gd.Constant("v5y", "20", reg, True) + + tv6x = _gd.Constant("v6x", "20", reg, True) + tv6y = _gd.Constant("v6y", "40", reg, True) + + tv7x = _gd.Constant("v7x", "40", reg, True) + tv7y = _gd.Constant("v7y", "40", reg, True) + + tv8x = _gd.Constant("v8x", "40", reg, True) + tv8y = _gd.Constant("v8y", "20", reg, True) + + tz = _gd.Constant("z", "30", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + tm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.Material(name="G4_Galactic") + tm = _g4.Material(name="G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.GenericTrap( + "ts", + tv1x, + tv1y, + tv2x, + tv2y, + tv3x, + tv3y, + tv4x, + tv4y, + tv5x, + tv5y, + tv6x, + tv6y, + tv7x, + tv7y, + tv8x, + tv8y, + tz, + reg, + lunit="mm", + ) + assert ts.evaluateParameterWithUnits("v1x") == tv1x + assert ts.evaluateParameterWithUnits("v1y") == tv1y + assert ts.evaluateParameterWithUnits("v2x") == tv2x + assert ts.evaluateParameterWithUnits("v2y") == tv2y + assert ts.evaluateParameterWithUnits("v3x") == tv3x + assert ts.evaluateParameterWithUnits("v3y") == tv3y + assert ts.evaluateParameterWithUnits("v4x") == tv4x + assert ts.evaluateParameterWithUnits("v4y") == tv4y + assert ts.evaluateParameterWithUnits("v5x") == tv5x + assert ts.evaluateParameterWithUnits("v5y") == tv5y + assert ts.evaluateParameterWithUnits("v6x") == tv6x + assert ts.evaluateParameterWithUnits("v6y") == tv6y + assert ts.evaluateParameterWithUnits("v7x") == tv7x + assert ts.evaluateParameterWithUnits("v7y") == tv7y + assert ts.evaluateParameterWithUnits("v8x") == tv8x + assert ts.evaluateParameterWithUnits("v8y") == tv8y + assert ts.evaluateParameterWithUnits("dz") == tz + ts2 = _g4.solid.GenericTrap( + "ts2", + tv1x, + tv1y, + tv2x, + tv2y, + tv3x, + tv3y, + tv4x, + tv4y, + tv5x, + tv5y, + tv6x, + tv6y, + tv7x, + tv7y, + tv8x, + tv8y, + tz, + reg, + lunit="cm", + ) + assert ts2.evaluateParameterWithUnits("v1x") == 10 * tv1x + assert ts2.evaluateParameterWithUnits("v1y") == 10 * tv1y + assert ts2.evaluateParameterWithUnits("v2x") == 10 * tv2x + assert ts2.evaluateParameterWithUnits("v2y") == 10 * tv2y + assert ts2.evaluateParameterWithUnits("v3x") == 10 * tv3x + assert ts2.evaluateParameterWithUnits("v3y") == 10 * tv3y + assert ts2.evaluateParameterWithUnits("v4x") == 10 * tv4x + assert ts2.evaluateParameterWithUnits("v4y") == 10 * tv4y + assert ts2.evaluateParameterWithUnits("v5x") == 10 * tv5x + assert ts2.evaluateParameterWithUnits("v5y") == 10 * tv5y + assert ts2.evaluateParameterWithUnits("v6x") == 10 * tv6x + assert ts2.evaluateParameterWithUnits("v6y") == 10 * tv6y + assert ts2.evaluateParameterWithUnits("v7x") == 10 * tv7x + assert ts2.evaluateParameterWithUnits("v7y") == 10 * tv7y + assert ts2.evaluateParameterWithUnits("v8x") == 10 * tv8x + assert ts2.evaluateParameterWithUnits("v8y") == 10 * tv8y + assert ts2.evaluateParameterWithUnits("dz") == 10 * tz + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "t_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T026_GenericTrap.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T026_GenericTrap.gmad"), + "T026_GenericTrap.gdml", + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"teststatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T028_Union.py b/tests/geant4/T028_Union.py new file mode 100644 index 000000000..db657ae0f --- /dev/null +++ b/tests/geant4/T028_Union.py @@ -0,0 +1,101 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False, disjoint=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + if not disjoint: + us = _g4.solid.Union( + "us", bs, bs, [[0.1, 0.2, 0.3, "rad"], [bx / 2, by / 2, bz / 2, "mm"]], reg + ) + assert us.evaluateParameterWithUnits("tra2") == [[0.1, 0.2, 0.3], [5, 5, 5]] + us2 = _g4.solid.Union( + "us2", + bs, + bs, + [ + [0.1 / _np.pi * 180, 0.2 / _np.pi * 180, 0.3 / _np.pi * 180, "deg"], + [bx / 2, by / 2, bz / 2, "cm"], + ], + reg, + ) + assert us2.evaluateParameterWithUnits("tra2") == [[0.1, 0.2, 0.3], [50, 50, 50]] + else: + us = _g4.solid.Union( + "us", bs, bs, [[0.1, 0.2, 0.3, "rad"], [bx * 2, by * 2, bz * 2, "mm"]], reg + ) + assert us.evaluateParameterWithUnits("tra2") == [[0.1, 0.2, 0.3], [20, 20, 20]] + us2 = _g4.solid.Union( + "us2", + bs, + bs, + [ + [0.1 / _np.pi * 180, 0.2 / _np.pi * 180, 0.3 / _np.pi * 180, "deg"], + [bx * 2, by * 2, bz * 2, "cm"], + ], + reg, + ) + assert us2.evaluateParameterWithUnits("tra2") == [ + [0.1, 0.2, 0.3], + [200, 200, 200], + ] + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ul = _g4.LogicalVolume(us, bm, "ul", reg) + up = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ul, "u_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T028_Union.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T028_Union.gmad"), "T028_Union.gdml" + ) + + # test __repr__ + str(us) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T029_Subtraction.py b/tests/geant4/T029_Subtraction.py new file mode 100644 index 000000000..ff5e38a57 --- /dev/null +++ b/tests/geant4/T029_Subtraction.py @@ -0,0 +1,91 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.exceptions +import numpy as _np + + +def Test(vis=False, interactive=False, nullMesh=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + bs1 = _g4.solid.Box("bs1", 2 * bx, 2 * by, 2 * bz, reg, "mm") + + if not nullMesh: + ss = _g4.solid.Subtraction( + "ss", bs, bs, [[0.1, 0.2, 0.3], [bx / 2, by / 2, bz / 2]], reg + ) + assert ss.evaluateParameterWithUnits("tra2") == [[0.1, 0.2, 0.3], [5, 5, 5]] + ss2 = _g4.solid.Subtraction( + "ss2", + bs, + bs, + [ + [0.1 / _np.pi * 180, 0.2 / _np.pi * 180, 0.3 / _np.pi * 180, "deg"], + [bx / 20, by / 20, bz / 20, "cm"], + ], + reg, + ) + assert ss.evaluateParameterWithUnits("tra2") == [[0.1, 0.2, 0.3], [5, 5, 5]] + else: + ss = _g4.solid.Subtraction("ss", bs, bs1, [[0, 0, 0], [0, 0, 0]], reg) + assert ss.evaluateParameterWithUnits("tra2") == [[0, 0, 0], [5, 5, 5]] + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + sl = _g4.LogicalVolume(ss, bm, "ul", reg) + + sp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], sl, "s_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T029_Subtraction.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T029_Subtraction.gmad"), + "T029_Subtraction.gdml", + ) + + # test __repr__ + str(ss) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T030_Intersection.py b/tests/geant4/T030_Intersection.py new file mode 100644 index 000000000..f567466b4 --- /dev/null +++ b/tests/geant4/T030_Intersection.py @@ -0,0 +1,92 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import numpy as _np + +normal = 1 +non_intersecting = 2 + + +def Test(vis=False, interactive=False, type=normal, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + if type == normal: + ns = _g4.solid.Intersection( + "ns", bs, bs, [[0.1, 0.2, 0.3], [bx / 2, by / 2, bz / 2]], reg + ) + assert ns.evaluateParameterWithUnits("tra2") == [[0.1, 0.2, 0.3], [5, 5, 5]] + ns2 = _g4.solid.Intersection( + "ns2", + bs, + bs, + [ + [0.1 / _np.pi * 180, 0.2 / _np.pi * 180, 0.3 / _np.pi * 180, "deg"], + [bx / 2, by / 2, bz / 2, "cm"], + ], + reg, + ) + assert ns2.evaluateParameterWithUnits("tra2") == [[0.1, 0.2, 0.3], [50, 50, 50]] + elif type == non_intersecting: + ns = _g4.solid.Intersection( + "ns", bs, bs, [[0.1, 0.2, 0.3], [bx * 2, by * 2, bz * 22]], reg + ) + assert ns.evaluateParameterWithUnits("tra2") == [[0.1, 0.2, 0.3], [20, 20, 220]] + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + nl = _g4.LogicalVolume(ns, bm, "nl", reg) + np = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], nl, "i_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T030_Intersection.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T030_Intersection.gmad"), + "T030_Intersection.gdml", + ) + + # test __repr__ + str(ns) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"teststatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T031_MultiUnion.py b/tests/geant4/T031_MultiUnion.py new file mode 100644 index 000000000..189cb76b6 --- /dev/null +++ b/tests/geant4/T031_MultiUnion.py @@ -0,0 +1,91 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import random as _rand +import numpy as _np + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Au", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "cm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "cm") + + nbox = 15 + solids = [] + transforms = [] + for i in range(0, nbox, 1): + r = 2 * bx.eval() * _rand.uniform(0, 1) + t = _np.pi * _rand.uniform(0, 1) + p = 2 * _np.pi * _rand.uniform(0, 1) + x = r * _np.sin(t) * _np.cos(p) + y = r * _np.sin(t) * _np.sin(p) + z = r * _np.cos(t) + solids.append(bs) + transforms.append([[0, t, p], [x, y, z, "cm"]]) + + mu = _g4.solid.MultiUnion("mu", solids, transforms, reg, True) + mu_trans = mu.evaluateParameterWithUnits("transformations") + for i in range(0, nbox, 1): + for j in range(0, 2, 1): + for k in range(0, 3, 1): + assert round(mu_trans[i][j][k], 6) == round( + (10.0**j) * transforms[i][j][k], 6 + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(mu, bm, "ml", reg) + mp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "m_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T031_MultiUnion.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T031_MultiUnion.gmad"), + "T031_MultiUnion.gdml", + ) + + # test __repr__ + str(mu) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"teststatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T032_Scaled.py b/tests/geant4/T032_Scaled.py new file mode 100644 index 000000000..f0af10d01 --- /dev/null +++ b/tests/geant4/T032_Scaled.py @@ -0,0 +1,75 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "200", reg, True) + wy = _gd.Constant("wy", "200", reg, True) + wz = _gd.Constant("wz", "200", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + bm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + bsScaled = _g4.solid.Scaled("bsScaled", bs, 1, 2, 3, reg) + assert bsScaled.evaluateParameterWithUnits("pX") == 1 + assert bsScaled.evaluateParameterWithUnits("pY") == 2 + assert bsScaled.evaluateParameterWithUnits("pZ") == 3 + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + blScaled = _g4.LogicalVolume(bsScaled, bm, "blScaled", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + bpScaled = _g4.PhysicalVolume( + [0, 0, 0], [0, 0, 50], blScaled, "bscaled_pv1", wl, reg + ) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T032_Scaled.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T032_Scaled.gmad"), + "T032_Scaled.gdml", + ) + + # test __repr__ + str(bs) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T033_TessellatedSolid.py b/tests/geant4/T033_TessellatedSolid.py new file mode 100644 index 000000000..6f2601ba4 --- /dev/null +++ b/tests/geant4/T033_TessellatedSolid.py @@ -0,0 +1,73 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, writeNISTMaterials=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "5000", reg, True) + wy = _gd.Constant("wy", "5000", reg, True) + wz = _gd.Constant("wz", "5000", reg, True) + + p1 = [(-500, 500, 0), (500, 500, 0), (500, -500, 0), (-500, -500, 0)] + p2 = [ + (-1000, 1000, 2000), + (1000, 1000, 2000), + (1000, -1000, 2000), + (-1000, -1000, 2000), + ] + + polygons = [p1, p2] + + # materials + if writeNISTMaterials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", reg) + xm = _g4.nist_material_2geant4Material("G4_Fe", reg) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + xm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + xtess = _g4.solid.createTessellatedSolid("test", polygons, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tess_l = _g4.LogicalVolume(xtess, xm, "tess_l", reg) + tess_p = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tess_l, "tess_p", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T033_TessellatedSolid.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T033_TessellatedSolid.gmad"), + "T033_TessellatedSolid.gdml", + ) + + # test __repr__ + str(xtess) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T101_physical_logical.py b/tests/geant4/T101_physical_logical.py new file mode 100644 index 000000000..48b405787 --- /dev/null +++ b/tests/geant4/T101_physical_logical.py @@ -0,0 +1,92 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + + b1pos = _gd.Position("b1pos", -bx, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b2pos", 0, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b3pos", bx, 0, 0, "mm", reg, True) + + r1pos = _gd.Position("r1pos", 0, -bx, 0, "mm", reg, True) + r2pos = _gd.Position("r2pos", 0, 0, 0, "mm", reg, True) + r3pos = _gd.Position("r3pos", 0, bx, 0, "mm", reg, True) + + l1pos = _gd.Position("l1pos", 0, 0, -bx, "mm", reg, True) + l2pos = _gd.Position("l2pos", 0, 0, 0, "mm", reg, True) + l3pos = _gd.Position("l3pos", 0, 0, bx, "mm", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, bx, bx, reg, "mm") + rs = _g4.solid.Box("rs", 3 * bx, bx, bx, reg, "mm") + ls = _g4.solid.Box("ls", 3 * bx, 3 * bx, bx, reg, "mm") + cs = _g4.solid.Box("cs", 3 * bx, 3 * bx, 3 * bx, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + rl = _g4.LogicalVolume(rs, wm, "rl", reg) + ll = _g4.LogicalVolume(ls, wm, "ll", reg) + cl = _g4.LogicalVolume(cs, wm, "cl", reg) + + bp1 = _g4.PhysicalVolume([0, 0, 0], [-bx, 0, 0], bl, "b_pv1", rl, reg) + bp2 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv2", rl, reg) + bp3 = _g4.PhysicalVolume([0, 0, 0], [bx, 0, 0], bl, "b_pv3", rl, reg) + + rp1 = _g4.PhysicalVolume([0, 0, 0], [0, -bx, 0], rl, "r_pv1", ll, reg) + rp2 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], rl, "r_pv2", ll, reg) + rp3 = _g4.PhysicalVolume([0, 0, 0], [0, bx, 0], rl, "r_pv3", ll, reg) + + lp1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, -bx], ll, "l_pv1", cl, reg) + lp2 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ll, "l_pv2", cl, reg) + lp3 = _g4.PhysicalVolume([0, 0, 0], [0, 0, bx], ll, "l_pv3", cl, reg) + + cp1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], cl, "c_pv1", wl, reg) + + # check for overlaps + wl.checkOverlaps(True, True, False) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T101_physical_logical.gdml")) + + # test __repr__ + str(bl) + str(bp1) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T102_overlap_none.py b/tests/geant4/T102_overlap_none.py new file mode 100644 index 000000000..e4604c878 --- /dev/null +++ b/tests/geant4/T102_overlap_none.py @@ -0,0 +1,71 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + + b1pos = _gd.Position("b1pos", -bx, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b2pos", 0, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b3pos", bx, 0, 0, "mm", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", 0.9 * bx, 0.9 * bx, 0.9 * bx, reg, "mm") + rs = _g4.solid.Box("rs", 3 * bx, bx, bx, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + rl = _g4.LogicalVolume(rs, wm, "rl", reg) + + bp1 = _g4.PhysicalVolume([0, 0, 0], [-bx, 0, 0], bl, "b_pv1", rl, reg) + bp2 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv2", rl, reg) + bp3 = _g4.PhysicalVolume([0, 0, 0], [bx, 0, 0], bl, "b_pv3", rl, reg) + + rp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], rl, "r_pv1", wl, reg) + + # check for overlaps + wl.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T102_overlap_none.gdml")) + + # test __repr__ + str(bs) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T103_overlap_copl.py b/tests/geant4/T103_overlap_copl.py new file mode 100644 index 000000000..2c4a3f4ce --- /dev/null +++ b/tests/geant4/T103_overlap_copl.py @@ -0,0 +1,128 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "75", reg, True) + wy = _gd.Constant("wy", "25", reg, True) + wz = _gd.Constant("wz", "25", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + + b1pos = _gd.Position("b1pos", -bx, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b2pos", 0, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b3pos", bx, 0, 0, "mm", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", 1.5 * wx, 4 * wy, 2.5 * wz, reg, "mm") + bs = _g4.solid.Box("bs", 1.0 * bx, 1.0 * bx, 1.0 * bx, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + + bp1 = _g4.PhysicalVolume( + [0, 0, 0], [-1.5 * wx / 2 + bx / 2, 0, 0], bl, "b_pv1", wl, reg + ) + + bp2 = _g4.PhysicalVolume( + [0, 0, 0], [-wx / 4 + bx / 2, -2 * bx, 0], bl, "b_pv2", wl, reg + ) + bp3 = _g4.PhysicalVolume( + [0, 0, 0], + [-wx / 4 + bx / 2 + bx / 2, -2 * bx + bx / 2, bx], + bl, + "b_pv3", + wl, + reg, + ) + + bp4 = _g4.PhysicalVolume( + [0, 0, 0], [wx / 4 - bx / 2, -2 * bx, 0], bl, "b_pv4", wl, reg + ) + bp5 = _g4.PhysicalVolume( + [0, 0, 0], [wx / 4 - bx / 2, -2 * bx + bx / 2, bx], bl, "b_pv5", wl, reg + ) + + bp6 = _g4.PhysicalVolume( + [0, 0, 0], [wx / 2 - bx / 2, -2 * bx, 0], bl, "b_pv6", wl, reg + ) + bp7 = _g4.PhysicalVolume( + [0, 0, 3.14159 / 4], + [wx / 2 - bx / 2, -2 * bx + 2 * bx / 4, bx], + bl, + "b_pv7", + wl, + reg, + ) + + bp8 = _g4.PhysicalVolume( + [0, 0, 0], [-wx / 4 + bx / 2, 2 * bx, 0], bl, "b_pv8", wl, reg + ) + bp9 = _g4.PhysicalVolume( + [0, 0, 0], [-wx / 4 + bx / 2 + bx / 2, 2 * bx + bx / 2, 0], bl, "b_pv9", wl, reg + ) + + bp10 = _g4.PhysicalVolume( + [0, 0, 0], [wx / 4 - bx / 2, 2 * bx, 0], bl, "b_pv10", wl, reg + ) + bp11 = _g4.PhysicalVolume( + [0, 0, 0], [wx / 4 - bx / 2, 2 * bx + bx / 2, 0], bl, "b_pv11", wl, reg + ) + + bp12 = _g4.PhysicalVolume( + [0, 0, 0], [wx / 2 - bx / 2, 2 * bx, 0], bl, "b_pv12", wl, reg + ) + bp13 = _g4.PhysicalVolume( + [0, 0, 3.14159 / 4], + [wx / 2 - bx / 2, 2 * bx + 2 * bx / 4, 0], + bl, + "b_pv13", + wl, + reg, + ) + + bp14 = _g4.PhysicalVolume( + [0, 0, 0], [+1.5 * wx / 2 - bx / 4, 0, 0], bl, "b_pv14", wl, reg + ) + + # check for overlaps + wl.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T103_overlap_copl.gdml")) + + # test __repr__ + str(bs) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T103_overlap_copl_simple.py b/tests/geant4/T103_overlap_copl_simple.py new file mode 100644 index 000000000..67dfc4c7d --- /dev/null +++ b/tests/geant4/T103_overlap_copl_simple.py @@ -0,0 +1,62 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "25", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", 1.0 * bx, 1.0 * bx, 1.0 * bx, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + + bp1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + bp2 = _g4.PhysicalVolume([0, 0.3, 0], [0, bx, 0], bl, "b_pv2", wl, reg) + + # check for overlaps + wl.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T103_overlap_copl.gdml")) + + # test __repr__ + str(bs) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T104_overlap_volu.py b/tests/geant4/T104_overlap_volu.py new file mode 100644 index 000000000..407d869ce --- /dev/null +++ b/tests/geant4/T104_overlap_volu.py @@ -0,0 +1,79 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + + b1pos = _gd.Position("b1pos", -bx, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b2pos", 0, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b3pos", bx, 0, 0, "mm", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs1 = _g4.solid.Box("bs1", 1.1 * bx, 0.9 * bx, 0.9 * bx, reg, "mm") + bs2 = _g4.solid.Box("bs2", 1.1 * bx, 0.8 * bx, 0.8 * bx, reg, "mm") + bs3 = _g4.solid.Box("bs3", 1.1 * bx, 0.7 * bx, 0.7 * bx, reg, "mm") + + rs = _g4.solid.Box("rs", 3 * bx, 2 * bx, 2 * bx, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl1 = _g4.LogicalVolume(bs1, bm, "bl1", reg) + bl2 = _g4.LogicalVolume(bs2, bm, "bl2", reg) + bl3 = _g4.LogicalVolume(bs3, bm, "bl3", reg) + + rl = _g4.LogicalVolume(rs, wm, "rl", reg) + + bp1 = _g4.PhysicalVolume([0.0, 0, 0], [-bx, 0, 0], bl1, "b_pv1", rl, reg) + bp2 = _g4.PhysicalVolume([0.0, 0, 0], [0, 0, 0], bl2, "b_pv2", rl, reg) + bp3 = _g4.PhysicalVolume([0.0, 0, 0], [bx, 0, 0], bl3, "b_pv3", rl, reg) + + rp1 = _g4.PhysicalVolume([0, 0, 0], [3 * bx, 0, 0], rl, "r_pv1", wl, reg) + rp2 = _g4.PhysicalVolume( + [0, 0, 0], [-3 * bx, 0, 0], rl, "r_pv2", wl, reg, True, [-1, 1, 1] + ) + # check overlaps + wl.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T104_overlap_volu.gdml")) + + # test __repr__ + str(bs1) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T105_assembly.py b/tests/geant4/T105_assembly.py new file mode 100644 index 000000000..e5b6b2c58 --- /dev/null +++ b/tests/geant4/T105_assembly.py @@ -0,0 +1,66 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "2", reg, True) + wy = _gd.Constant("wy", "2", reg, True) + wz = _gd.Constant("wz", "2", reg, True) + + halfPi = _gd.Constant("HALPPI", "pi/2.", reg, True) + twoPi = _gd.Constant("TWOPI", "2*pi", reg, True) + centre = _gd.Position("centre", 0, 0, 0, "m", reg, True) + indentity = _gd.Rotation("identity", 0, 0, 0, "rad", reg, True) + alignSurfX = _gd.Rotation("alignSurfX", 0, halfPi, 0, "rad", reg, True) + alignSurfY = _gd.Rotation("alignSurfY", halfPi, 0, 0, "rad", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "m") + ts = _g4.solid.Tubs("ts", 0.1075, 0.1875, 0.1875, 0, twoPi, reg, "m", "rad") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + wa = _g4.AssemblyVolume("wa", reg, True) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + + tp1 = _g4.PhysicalVolume(alignSurfX, [0, 0, 500], tl, "t_pv1", wa, reg) + tp2 = _g4.PhysicalVolume(alignSurfY, [0, 0, -500], tl, "t_pv2", wa, reg) + + a_pv1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], wa, "a_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T105_assembly.gdml")) + + # test __repr__ + str(wa) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T106_replica_x.py b/tests/geant4/T106_replica_x.py new file mode 100644 index 000000000..515421582 --- /dev/null +++ b/tests/geant4/T106_replica_x.py @@ -0,0 +1,68 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "100", reg, True) + by = _gd.Constant("by", "100", reg, True) + bz = _gd.Constant("bz", "100", reg, True) + + mbx = _gd.Constant("mbx", "800", reg, True) + mby = _gd.Constant("mby", "100", reg, True) + mbz = _gd.Constant("mbz", "100", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + mbs = _g4.solid.Box("mbs", mbx, mby, mbz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + ml = _g4.LogicalVolume(mbs, wm, "ml", reg) + mbl = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kXAxis, 8, 100, 0, reg, True, "mm", "mm" + ) + + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T106_replica_x.gdml")) + + # test __repr__ + str(mbl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T107_replica_y.py b/tests/geant4/T107_replica_y.py new file mode 100644 index 000000000..5390b420e --- /dev/null +++ b/tests/geant4/T107_replica_y.py @@ -0,0 +1,68 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "100", reg, True) + by = _gd.Constant("by", "100", reg, True) + bz = _gd.Constant("bz", "100", reg, True) + + mbx = _gd.Constant("mbx", "100", reg, True) + mby = _gd.Constant("mby", "800", reg, True) + mbz = _gd.Constant("mbz", "100", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + mbs = _g4.solid.Box("mbs", mbx, mby, mbz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + ml = _g4.LogicalVolume(mbs, wm, "ml", reg) + mbl = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kYAxis, 8, 100, 0, reg, True, "mm", "mm" + ) + + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T107_replica_y.gdml")) + + # test __repr__ + str(mbl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T108_replica_z.py b/tests/geant4/T108_replica_z.py new file mode 100644 index 000000000..3262f5e00 --- /dev/null +++ b/tests/geant4/T108_replica_z.py @@ -0,0 +1,68 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "100", reg, True) + by = _gd.Constant("by", "100", reg, True) + bz = _gd.Constant("bz", "100", reg, True) + + mbx = _gd.Constant("mbx", "100", reg, True) + mby = _gd.Constant("mby", "100", reg, True) + mbz = _gd.Constant("mbz", "800", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + mbs = _g4.solid.Box("mbs", mbx, mby, mbz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + ml = _g4.LogicalVolume(mbs, wm, "ml", reg) + mbl = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kZAxis, 8, 100, 0, reg, True, "mm", "mm" + ) + + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T107_replica_y.gdml")) + + # test __repr__ + str(mbl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T109_replica_phi.py b/tests/geant4/T109_replica_phi.py new file mode 100644 index 000000000..50e489224 --- /dev/null +++ b/tests/geant4/T109_replica_phi.py @@ -0,0 +1,70 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", 1000, reg, True) + wy = _gd.Constant("wy", 1000, reg, True) + wz = _gd.Constant("wz", 1000, reg, True) + + bx = _gd.Constant("bx", 100, reg, True) + by = _gd.Constant("by", 100, reg, True) + bz = _gd.Constant("bz", 100, reg, True) + + trmin = _gd.Constant("rmin", 100, reg, True) + trmax = _gd.Constant("rmax", 200, reg, True) + tz = _gd.Constant("z", 800, reg, True) + mtdphi = _gd.Constant("mtdphi", "2*pi", reg, True) + tdphi = _gd.Constant("tdphi", "2*pi/8.0", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Tubs("ts", trmin, trmax, tz, 0, tdphi, reg, "mm", "rad", 16, True) + mts = _g4.solid.Tubs("mts", trmin, trmax, tz, 0, mtdphi, reg, "mm", "rad", 16, True) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + ml = _g4.LogicalVolume(mts, wm, "ml", reg) + mtl = _g4.ReplicaVolume( + "mtl", tl, ml, _g4.ReplicaVolume.Axis.kPhi, 8, tdphi, 0, reg, True, "mm", "mm" + ) + + mtp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T109_replica_phi.gdml")) + + # test __repr__ + str(mtl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T110_replica_rho.py b/tests/geant4/T110_replica_rho.py new file mode 100644 index 000000000..479e64db3 --- /dev/null +++ b/tests/geant4/T110_replica_rho.py @@ -0,0 +1,86 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", 1000, reg, True) + wy = _gd.Constant("wy", 1000, reg, True) + wz = _gd.Constant("wz", 1000, reg, True) + + bx = _gd.Constant("bx", 100, reg, True) + by = _gd.Constant("by", 100, reg, True) + bz = _gd.Constant("bz", 100, reg, True) + + trmin = _gd.Constant("rmin", 100, reg, True) + trmax = _gd.Constant("rmax", 200, reg, True) + tz = _gd.Constant("z", 800, reg, True) + mtdphi = _gd.Constant("mtdphi", "2*pi", reg, True) + tdphi = _gd.Constant("tdphi", "2*pi", reg, True) + nreplicas = _gd.Constant("nreplicas", 8, reg, True) + tdR = _gd.Constant("tdR", trmax / nreplicas, reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Tubs("ts", 0, trmax, tz, 0, tdphi, reg, "mm", "rad", 16, True) + mts = _g4.solid.Tubs("mts", 0, trmax, tz, 0, mtdphi, reg, "mm", "rad", 16, True) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, bm, "tl", reg) + ml = _g4.LogicalVolume(mts, wm, "ml", reg) + mtl = _g4.ReplicaVolume( + "mtl", + tl, + ml, + _g4.ReplicaVolume.Axis.kRho, + nreplicas, + tdR, + 0, + reg, + True, + "mm", + "mm", + ) + + mtp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T110_replica_rho.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T110_replica_rho.gmad"), + "T110_replica_rho.gdml", + ) + + # test __repr__ + str(mtl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T111_parameterised_box.py b/tests/geant4/T111_parameterised_box.py new file mode 100644 index 000000000..af36d0f54 --- /dev/null +++ b/tests/geant4/T111_parameterised_box.py @@ -0,0 +1,121 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs1 = _g4.solid.Box("bs", 20 * bx, 20 * by, 20 * bz, reg, "mm") + bs2 = _g4.solid.Box("bsp", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl1 = _g4.LogicalVolume(bs1, bm, "bl1", reg) + bl2 = _g4.LogicalVolume(bs2, bm, "bl2", reg) + bp1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl1, "b_pv1", wl, reg) + + pbd1 = _g4.ParameterisedVolume.BoxDimensions(0.8 * bx, 0.8 * by, 0.4 * bz) + pbp1 = _gd.Position("bp1", 0.0, 0.0, -8 * bx, "mm", reg) + pbr1 = _gd.Rotation("br1", 0.0, 0.0, -0.4, "rad", reg) + + pbd2 = _g4.ParameterisedVolume.BoxDimensions(0.85 * bx, 0.85 * by, 0.5 * bz) + pbp2 = _gd.Position("bp2", 0.0, 0.0, -6 * bx, "mm", reg) + pbr2 = _gd.Rotation("br2", 0.0, 0.0, -0.3, "rad", reg) + + pbd3 = _g4.ParameterisedVolume.BoxDimensions(0.9 * bx, 0.9 * by, 0.6 * bz) + pbp3 = _gd.Position("bp3", 0.0, 0.0, -4 * bx, "mm", reg) + pbr3 = _gd.Rotation("br3", 0.0, 0.0, -0.2, "rad", reg) + + pbd4 = _g4.ParameterisedVolume.BoxDimensions(0.95 * bx, 0.95 * by, 0.7 * bz) + pbp4 = _gd.Position("bp4", 0.0, 0.0, -2 * bx, "mm", reg) + pbr4 = _gd.Rotation("br4", 0.0, 0.0, -0.1, "rad", reg) + + pbd5 = _g4.ParameterisedVolume.BoxDimensions(1.00 * bx, 1.00 * by, 0.8 * bz) + pbp5 = _gd.Position("bp5", 0.0, 0.0, 0 * bx, "mm", reg) + pbr5 = _gd.Rotation("br5", 0.0, 0.0, 0.0, "rad", reg) + + pbd6 = _g4.ParameterisedVolume.BoxDimensions(1.05 * bx, 1.05 * by, 0.9 * bz) + pbp6 = _gd.Position("bp6", 0.0, 0.0, 2 * bx, "mm", reg) + pbr6 = _gd.Rotation("br6", 0.0, 0.0, 0.1, "rad", reg) + + pbd7 = _g4.ParameterisedVolume.BoxDimensions(1.05 * bx, 1.05 * by, 1.0 * bz) + pbp7 = _gd.Position("bp7", 0.0, 0.0, 4 * bx, "mm", reg) + pbr7 = _gd.Rotation("br7", 0.0, 0.0, 0.2, "rad", reg) + + pbd8 = _g4.ParameterisedVolume.BoxDimensions(1.15 * bx, 1.15 * by, 1.1 * bz) + pbp8 = _gd.Position("bp8", 0.0, 0.0, 6 * bx, "mm", reg) + pbr8 = _gd.Rotation("br8", 0.0, 0.0, 0.3, "rad", reg) + + pbd9 = _g4.ParameterisedVolume.BoxDimensions(1.2 * bx, 1.2 * by, 1.2 * bz) + pbp9 = _gd.Position("bp9", 0.0, 0.0, 8 * bx, "mm", reg) + pbr9 = _gd.Rotation("br9", 0.0, 0.0, 0.4, "rad", reg) + + pbv = _g4.ParameterisedVolume( + "pbv", + bl2, + bl1, + 9, + [pbd1, pbd2, pbd3, pbd4, pbd5, pbd6, pbd7, pbd8, pbd9], + [ + [pbr1, pbp1], + [pbr2, pbp2], + [pbr3, pbp3], + [pbr4, pbp4], + [pbr5, pbp5], + [pbr6, pbp6], + [pbr7, pbp7], + [pbr8, pbp8], + [pbr9, pbp9], + ], + reg, + ) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T111_parameterised_box.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T111_parameterised_box.gmad"), + "T111_parameterised_box.gdml", + ) + + # test __repr__ + str(pbv) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + extentParam = pbv.extent() + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T112_parameterised_tube.py b/tests/geant4/T112_parameterised_tube.py new file mode 100644 index 000000000..73ba3bbc9 --- /dev/null +++ b/tests/geant4/T112_parameterised_tube.py @@ -0,0 +1,145 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + pRMin = _gd.Constant("pRMin", "5", reg, True) + pRMax = _gd.Constant("pRMax", "25", reg, True) + pDz = _gd.Constant("pDz", "50", reg, True) + pSPhi = _gd.Constant("pSPhi", "0", reg, True) + pDPhi = _gd.Constant("pDPhi", "2*pi", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs1 = _g4.solid.Box("bs", 20 * bx, 20 * by, 20 * bz, reg, "mm") + ts2 = _g4.solid.Tubs("tsp", pRMin, pRMax, pDz, pSPhi, pDPhi, reg, "mm", "rad") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl1 = _g4.LogicalVolume(bs1, bm, "bl1", reg) + tl2 = _g4.LogicalVolume(ts2, bm, "tl2", reg) + bp1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl1, "b_pv1", wl, reg) + + ptd1 = _g4.ParameterisedVolume.TubeDimensions( + 0.1, 1.0, 2.5, 0, "2*pi*0.1", "mm", "rad" + ) + ptp1 = _gd.Position("bp1", 0.0, 0.0, -8 * bx, "mm", reg) + ptr1 = _gd.Rotation("br1", 0.0, 0.0, -0.4, "rad", reg) + + ptd2 = _g4.ParameterisedVolume.TubeDimensions( + 0.2, 1.2, 2.5, 0, "2*pi*0.2", "mm", "rad" + ) + ptp2 = _gd.Position("bp2", 0.0, 0.0, -6 * bx, "mm", reg) + ptr2 = _gd.Rotation("br2", 0.0, 0.0, -0.3, "rad", reg) + + ptd3 = _g4.ParameterisedVolume.TubeDimensions( + 0.3, 1.4, 2.5, 0, "2*pi*0.3", "mm", "rad" + ) + ptp3 = _gd.Position("bp3", 0.0, 0.0, -4 * bx, "mm", reg) + ptr3 = _gd.Rotation("br3", 0.0, 0.0, -0.2, "rad", reg) + + ptd4 = _g4.ParameterisedVolume.TubeDimensions( + 0.4, 1.6, 2.5, 0, "2*pi*0.4", "mm", "rad" + ) + ptp4 = _gd.Position("bp4", 0.0, 0.0, -2 * bx, "mm", reg) + ptr4 = _gd.Rotation("br4", 0.0, 0.0, -0.1, "rad", reg) + + ptd5 = _g4.ParameterisedVolume.TubeDimensions( + 0.5, 1.8, 2.5, 0, "2*pi*0.5", "mm", "rad" + ) + ptp5 = _gd.Position("bp5", 0.0, 0.0, 0 * bx, "mm", reg) + ptr5 = _gd.Rotation("br5", 0.0, 0.0, 0.0, "rad", reg) + + ptd6 = _g4.ParameterisedVolume.TubeDimensions( + 0.6, 2.0, 2.5, 0, "2*pi*0.6", "mm", "rad" + ) + ptp6 = _gd.Position("bp6", 0.0, 0.0, 2 * bx, "mm", reg) + ptr6 = _gd.Rotation("br6", 0.0, 0.0, 0.1, "rad", reg) + + ptd7 = _g4.ParameterisedVolume.TubeDimensions( + 0.7, 2.2, 2.5, 0, "2*pi*0.7", "mm", "rad" + ) + ptp7 = _gd.Position("bp7", 0.0, 0.0, 4 * bx, "mm", reg) + ptr7 = _gd.Rotation("br7", 0.0, 0.0, 0.2, "rad", reg) + + ptd8 = _g4.ParameterisedVolume.TubeDimensions( + 0.8, 2.4, 2.5, 0, "2*pi*0.8", "mm", "rad" + ) + ptp8 = _gd.Position("bp8", 0.0, 0.0, 6 * bx, "mm", reg) + ptr8 = _gd.Rotation("br8", 0.0, 0.0, 0.3, "rad", reg) + + ptd9 = _g4.ParameterisedVolume.TubeDimensions( + 0.9, 2.6, 2.5, 0, "2*pi*0.9", "mm", "rad" + ) + ptp9 = _gd.Position("bp9", 0.0, 0.0, 8 * bx, "mm", reg) + ptr9 = _gd.Rotation("br9", 0.0, 0.0, 0.4, "rad", reg) + + ptv = _g4.ParameterisedVolume( + "ptv", + tl2, + bl1, + 9, + [ptd1, ptd2, ptd3, ptd4, ptd5, ptd6, ptd7, ptd8, ptd9], + [ + [ptr1, ptp1], + [ptr2, ptp2], + [ptr3, ptp3], + [ptr4, ptp4], + [ptr5, ptp5], + [ptr6, ptp6], + [ptr7, ptp7], + [ptr8, ptp8], + [ptr9, ptp9], + ], + reg, + ) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T112_parameterised_tube.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T112_parameterised_tube.gmad"), + "T112_parameterised_tube.gdml", + ) + + # test __repr__ + str(ptv) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + extentParam = ptv.extent() + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T113_parameterised_cone.py b/tests/geant4/T113_parameterised_cone.py new file mode 100644 index 000000000..10d4a65df --- /dev/null +++ b/tests/geant4/T113_parameterised_cone.py @@ -0,0 +1,120 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "1000", reg, True) + wy = _gd.Constant("wy", "1000", reg, True) + wz = _gd.Constant("wz", "1000", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs1 = _g4.solid.Box("bs", 20 * bx, 20 * by, 20 * bz, reg, "mm") + bs2 = _g4.solid.Box("bsp", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl1 = _g4.LogicalVolume(bs1, bm, "bl1", reg) + bl2 = _g4.LogicalVolume(bs2, bm, "bl2", reg) + bp1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl1, "b_pv1", wl, reg) + + pbd1 = _g4.ParameterisedVolume.BoxDimensions(0.8 * bx, 0.8 * by, 0.4 * bz) + pbp1 = _gd.Position("bp1", 0.0, 0.0, -8 * bx, "mm", reg) + pbr1 = _gd.Rotation("br1", 0.0, 0.0, -0.4, "rad", reg) + + pbd2 = _g4.ParameterisedVolume.BoxDimensions(0.85 * bx, 0.85 * by, 0.5 * bz) + pbp2 = _gd.Position("bp2", 0.0, 0.0, -6 * bx, "mm", reg) + pbr2 = _gd.Rotation("br2", 0.0, 0.0, -0.3, "rad", reg) + + pbd3 = _g4.ParameterisedVolume.BoxDimensions(0.9 * bx, 0.9 * by, 0.6 * bz) + pbp3 = _gd.Position("bp3", 0.0, 0.0, -4 * bx, "mm", reg) + pbr3 = _gd.Rotation("br3", 0.0, 0.0, -0.2, "rad", reg) + + pbd4 = _g4.ParameterisedVolume.BoxDimensions(0.95 * bx, 0.95 * by, 0.7 * bz) + pbp4 = _gd.Position("bp4", 0.0, 0.0, -2 * bx, "mm", reg) + pbr4 = _gd.Rotation("br4", 0.0, 0.0, -0.1, "rad", reg) + + pbd5 = _g4.ParameterisedVolume.BoxDimensions(1.00 * bx, 1.00 * by, 0.8 * bz) + pbp5 = _gd.Position("bp5", 0.0, 0.0, 0 * bx, "mm", reg) + pbr5 = _gd.Rotation("br5", 0.0, 0.0, 0.0, "rad", reg) + + pbd6 = _g4.ParameterisedVolume.BoxDimensions(1.05 * bx, 1.05 * by, 0.9 * bz) + pbp6 = _gd.Position("bp6", 0.0, 0.0, 2 * bx, "mm", reg) + pbr6 = _gd.Rotation("br6", 0.0, 0.0, 0.1, "rad", reg) + + pbd7 = _g4.ParameterisedVolume.BoxDimensions(1.05 * bx, 1.05 * by, 1.0 * bz) + pbp7 = _gd.Position("bp7", 0.0, 0.0, 4 * bx, "mm", reg) + pbr7 = _gd.Rotation("br7", 0.0, 0.0, 0.2, "rad", reg) + + pbd8 = _g4.ParameterisedVolume.BoxDimensions(1.15 * bx, 1.15 * by, 1.1 * bz) + pbp8 = _gd.Position("bp8", 0.0, 0.0, 6 * bx, "mm", reg) + pbr8 = _gd.Rotation("br8", 0.0, 0.0, 0.3, "rad", reg) + + pbd9 = _g4.ParameterisedVolume.BoxDimensions(1.2 * bx, 1.2 * by, 1.2 * bz) + pbp9 = _gd.Position("bp9", 0.0, 0.0, 8 * bx, "mm", reg) + pbr9 = _gd.Rotation("br9", 0.0, 0.0, 0.4, "rad", reg) + + pbv = _g4.ParameterisedVolume( + "pbv", + bl2, + bl1, + 9, + [pbd1, pbd2, pbd3, pbd4, pbd5, pbd6, pbd7, pbd8, pbd9], + [ + [pbr1, pbp1], + [pbr2, pbp2], + [pbr3, pbp3], + [pbr4, pbp4], + [pbr5, pbp5], + [pbr6, pbp6], + [pbr7, pbp7], + [pbr8, pbp8], + [pbr9, pbp9], + ], + reg, + ) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T113_parameterised_cone.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T113_parameterised_cone.gmad"), + "T111_parameterised_box.gdml", + ) + + # test __repr__ + str(pbv) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T114_physical_reflection_x.py b/tests/geant4/T114_physical_reflection_x.py new file mode 100644 index 000000000..38f9422d8 --- /dev/null +++ b/tests/geant4/T114_physical_reflection_x.py @@ -0,0 +1,93 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test( + vis=False, + interactive=False, + n_slice=20, + n_stack=20, + scale=[-1, 1, 1], + title="T114_physical_reflection_x", +): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "200", reg, True) + wy = _gd.Constant("wy", "200", reg, True) + wz = _gd.Constant("wz", "200", reg, True) + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + trmin = _gd.Constant("rmin", "2.0", reg, True) + trmax = _gd.Constant("rmax", "10.0", reg, True) + trtor = _gd.Constant("rtor", "40.0", reg, True) + tsphi = _gd.Constant("sphi", "0.05*pi/2.0", reg, True) + tdphi = _gd.Constant("dphi", "0.9*pi/2.0", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + tm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + ts = _g4.solid.Torus( + "ts", + trmin, + trmax, + trtor, + tsphi, + tdphi, + reg, + "mm", + "rad", + nslice=n_slice, + nstack=n_stack, + ) + + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + us = _g4.solid.Union("us", bs, bs, [[0.1, 0.2, 0.3], [bx / 2, by / 2, bz / 2]], reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + tl = _g4.LogicalVolume(ts, tm, "tl", reg) + ul = _g4.LogicalVolume(us, tm, "ul", reg) + tp1 = _g4.PhysicalVolume([0, 0, 0], [20, 20, 20], tl, "t_pv1", wl, reg) + tp2 = _g4.PhysicalVolume([0, 0, 0], [20, 20, 20], tl, "t_pv2", wl, reg, scale=scale) + up = _g4.PhysicalVolume([0, 0, 0], [20, 10, 60], ul, "u_pv1", wl, reg) + up2 = _g4.PhysicalVolume([0, 0, 0], [20, 10, 60], ul, "u_pv2", wl, reg, scale=scale) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), title + ".gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), title + ".gmad"), title + ".gdml" + ) + + # test __repr__ + str(ts) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T115_physical_reflection_y.py b/tests/geant4/T115_physical_reflection_y.py new file mode 100644 index 000000000..09ae41971 --- /dev/null +++ b/tests/geant4/T115_physical_reflection_y.py @@ -0,0 +1,11 @@ +import T114_physical_reflection_x + + +def Test(vis=False, interactive=False, n_slice=20, n_stack=20, scale=[1, -1, 1]): + return T114_physical_reflection_x.Test( + vis, interactive, n_slice, n_stack, scale, title="T115_physical_reflection_y" + ) + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T116_physical_reflection_z.py b/tests/geant4/T116_physical_reflection_z.py new file mode 100644 index 000000000..99e854fb4 --- /dev/null +++ b/tests/geant4/T116_physical_reflection_z.py @@ -0,0 +1,11 @@ +import T114_physical_reflection_x + + +def Test(vis=False, interactive=False, n_slice=20, n_stack=20, scale=[1, 1, -1]): + return T114_physical_reflection_x.Test( + vis, interactive, n_slice, n_stack, scale, title="T116_physical_reflection_z" + ) + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T201_Materials.py b/tests/geant4/T201_Materials.py new file mode 100644 index 000000000..fe24b87a1 --- /dev/null +++ b/tests/geant4/T201_Materials.py @@ -0,0 +1,398 @@ +import os as _os + +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd + + +def Test_MaterialPredefined(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T201_MaterialPredefined.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T201_MaterialPredefined.gmad"), + "T201_MaterialPredefined.gdml", + ) + + +def Test_MaterialSingleElement(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialSingleElement( + "galactic", 1, 1.008, 1e-25, reg + ) # low density hydrogen + bm = _g4.MaterialSingleElement( + "iron", 26, 55.8452, 7.874, reg + ) # iron at near room temp + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T201_MaterialSingleElement.gdml") + ) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T201_MaterialSingleElement.gmad"), + "T201_MaterialSingleElement.gdml", + ) + + +def Test_MaterialCompoundMassFraction(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialCompound("air", 1.290e-3, 2, reg) + ne = _g4.ElementSimple("nitrogen", "N", 7, 14.01) + oe = _g4.ElementSimple("oxygen", "O", 8, 16.0) + wm.add_element_massfraction(ne, 0.7) + wm.add_element_massfraction(oe, 0.3) + bm = _g4.MaterialSingleElement( + "iron", 26, 55.8452, 7.874, reg + ) # iron at near room temp + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T201_MaterialCompoundMassFraction.gdml" + ) + ) + w.writeGmadTester( + _os.path.join( + _os.path.dirname(__file__), "T201_MaterialCompoundMassFraction.gmad" + ), + "T201_MaterialCompoundMassFractiion.gdml", + ) + + +def Test_MaterialCompoundAtoms(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialPredefined("G4_Galactic") + # bm = _g4.MaterialCompound("plastic",1.38,3,reg) # Generic PET C_10 H_8 O_4 + # he = _g4.ElementSimple("hydrogen","H",1,1.008) + # ce = _g4.ElementSimple("carbon","C",6,12.0096) + # oe = _g4.ElementSimple("oxygen","O",8,16.0) + # bm.add_element_natoms(he,8) + # bm.add_element_natoms(ce,10) + # bm.add_element_natoms(oe,4) + + bm = _g4.MaterialCompound("water", 1.0, 2, reg) + he = _g4.ElementSimple("hydrogen", "H", 1, 1.01) + oe = _g4.ElementSimple("oxygen", "O", 8, 16.0) + bm.add_element_natoms(he, 2) + bm.add_element_natoms(oe, 1) + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + + w.write( + _os.path.join( + _os.path.dirname(__file__), "T201_MaterialCompoundNumberAtoms.gdml" + ) + ) + w.writeGmadTester( + _os.path.join( + _os.path.dirname(__file__), "T201_MaterialCompoundNumberAtoms.gmad" + ), + "T201_MaterialCompoundNumberAtoms.gdml", + ) + + +def Test_MaterialMixture(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialPredefined("G4_Galactic") + copper = _g4.MaterialPredefined("G4_Cu") + zinc = _g4.MaterialPredefined("G4_Zn") + bm = _g4.MaterialCompound("YellowBrass_C26800", 8.14, 2, reg) + bm.add_material(copper, 0.67) + bm.add_material(zinc, 0.33) + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + + w.write(_os.path.join(_os.path.dirname(__file__), "T201_MaterialMixture.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T201_MaterialMixture.gmad"), + "T201_MaterialMixture.gdml", + ) + + +def Test_MaterialIsotopes(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialPredefined("G4_Galactic") + + u235 = _g4.Isotope("U235", 92, 235, 235.044) + u238 = _g4.Isotope("U238", 92, 238, 238.051) + uranium = _g4.ElementIsotopeMixture("uranium", "U", 2) + uranium.add_isotope(u235, 0.00716) + uranium.add_isotope(u238, 0.99284) + + bm = _g4.MaterialCompound("natural_uranium", 19.1, 2, reg) + bm.add_element_massfraction(uranium, 1) + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T201_MaterialIsotopes.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T201_MaterialIsotopes.gmad"), + "T201_MaterialIsotopes.gdml", + ) + + +def Test_MaterialPressureTemperature(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialCompound("air", 1.290e-3, 2, reg) + ne = _g4.ElementSimple("nitrogen", "N", 7, 14.01) + oe = _g4.ElementSimple("oxygen", "O", 8, 16.0) + wm.add_element_massfraction(ne, 0.7) + wm.add_element_massfraction(oe, 0.3) + wm.set_pressure(1100, "pascal") + wm.set_temperature(293.15) + + # Enure the state variables are set properly + assert wm.state_variables["temperature"] == 293.15 + assert wm.state_variables["temperature_unit"] == "K" # Check the default unit + assert wm.state_variables["pressure"] == 1100 + assert wm.state_variables["pressure_unit"] == "pascal" + + bm = _g4.MaterialSingleElement( + "iron", 26, 55.8452, 7.874, reg + ) # iron at near room temp + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T201_MaterialPressureTemperature.gdml" + ) + ) + w.writeGmadTester( + _os.path.join( + _os.path.dirname(__file__), "T201_MaterialPressureTemperature.gmad" + ), + "T201_MaterialPressureTemperature.gdml", + ) + + +def Test_MaterialState(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialCompound("air", 1.290e-3, 2, reg) + ne = _g4.ElementSimple("nitrogen", "N", 7, 14.01) + oe = _g4.ElementSimple("oxygen", "O", 8, 16.0) + wm.add_element_massfraction(ne, 0.7) + wm.add_element_massfraction(oe, 0.3) + wm.set_state("liquid") + + # Enure the state is set properly + assert wm.state == "liquid" + + bm = _g4.MaterialSingleElement( + "iron", 26, 55.8452, 7.874, reg + ) # iron at near room temp + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T201_MaterialState.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T201_MaterialState.gmad"), + "T201_MaterialState.gdml", + ) diff --git a/tests/geant4/T202_OpticalSurface.py b/tests/geant4/T202_OpticalSurface.py new file mode 100644 index 000000000..d4a3be2d9 --- /dev/null +++ b/tests/geant4/T202_OpticalSurface.py @@ -0,0 +1,100 @@ +import os as _os + +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd + + +def Test_OpticalSurface(): + reg = _g4.Registry() + + # World box + wx = _gd.Constant("wx", "150", reg, True) + wy = _gd.Constant("wy", "150", reg, True) + wz = _gd.Constant("wz", "150", reg, True) + + # Outer big box + ox = _gd.Constant("ox", "100", reg, True) + oy = _gd.Constant("oy", "100", reg, True) + oz = _gd.Constant("oz", "100", reg, True) + + # Water tank + tx = _gd.Constant("tx", "50", reg, True) + ty = _gd.Constant("ty", "50", reg, True) + tz = _gd.Constant("tz", "50", reg, True) + + # Air bubble + bx = _gd.Constant("bx", "10", reg, True) + by = _gd.Constant("by", "10", reg, True) + bz = _gd.Constant("bz", "10", reg, True) + + ####################################################################################### + wm = _g4.MaterialPredefined("G4_Galactic") + + ne = _g4.ElementSimple("Nitrogen", "N", 7, 14.01) + he = _g4.ElementSimple("Hydrogen", "H", 1, 1.01) + oe = _g4.ElementSimple("Oxygen", "O", 8, 16.0) + + air = _g4.MaterialCompound("Air", 1.290e-3, 2, reg) + air.add_element_massfraction(ne, 0.7) + air.add_element_massfraction(oe, 0.3) + air.addVecProperty( + "RINDEX", [2.034e-03, 2.068e-03, 2.103e-03, 2.139e-03], [1, 1, 1, 1] + ) + + water = _g4.MaterialCompound("Water", 1.0, 2, reg) + water.add_element_massfraction(he, 0.112) + water.add_element_massfraction(oe, 0.888) + water.addVecProperty( + "RINDEX", + [2.034e-03, 2.068e-03, 2.103e-03, 2.139e-03], + [1.3435, 1.344, 1.3445, 1.345], + ) + water.addVecProperty( + "ABSLENGTH", + [2.034e-03, 2.068e-03, 2.103e-03, 2.139e-03], + [3448, 4082, 6329, 9174], + vunit="m", + ) + water.addConstProperty("YIELDRATIO", 0.8) + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bigbox = _g4.solid.Box("bigbox", ox, oy, oz, reg, "mm") + tank = _g4.solid.Box("tank", tx, ty, tz, reg, "mm") + bubble = _g4.solid.Box("bubble", bx, by, bz, reg, "mm") + + opa = _g4.solid.OpticalSurface( + "AirSurface", finish="0", model="0", surf_type="1", value="1", registry=reg + ) + opw = _g4.solid.OpticalSurface( + "WaterSurface", finish="3", model="1", surf_type="1", value="0", registry=reg + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ol = _g4.LogicalVolume(bigbox, wm, "bigbox_logical", reg) + tl = _g4.LogicalVolume(tank, water, "tank_logical", reg) + bl = _g4.LogicalVolume(bubble, air, "bubble_logical", reg) + op = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ol, "bigbox_pv", wl, reg) + tp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], tl, "tank_pv1", ol, reg) + bp = _g4.PhysicalVolume([0, 0, 0], [0, 2.5, 0], bl, "bubble_pv1", tl, reg) + _g4.SkinSurface("AirSurface", bl, opa, reg) + _g4.BorderSurface("WaterSurface", bp, op, opw, reg) + + ####################################################################################### + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T202_Optical.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T201_Optical.gmad"), + "T201_Optical.gdml", + ) + + +if __name__ == "__main__": + Test_OpticalSurface() diff --git a/tests/geant4/T203_MaterialsRegistry.py b/tests/geant4/T203_MaterialsRegistry.py new file mode 100644 index 000000000..e7ae72d65 --- /dev/null +++ b/tests/geant4/T203_MaterialsRegistry.py @@ -0,0 +1,92 @@ +import os as _os + +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd + + +def Test_MaterialsRegistry(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "500", reg, True) + wy = _gd.Constant("wy", "500", reg, True) + wz = _gd.Constant("wz", "500", reg, True) + + ####################################################################################### + wm = _g4.MaterialPredefined("G4_Galactic", reg) + + bm1 = _g4.MaterialPredefined("G4_Fe", reg) + bm2 = _g4.MaterialSingleElement( + "iron", 26, 55.8452, 7.874, reg + ) # iron at near room temp + + bm3 = _g4.MaterialCompound("air", 1.290e-3, 2, reg) + ne = _g4.ElementSimple("nitrogen", "N", 7, 14.01, reg) + oe = _g4.ElementSimple("oxygen", "O", 8, 16.0, reg) + bm3.add_element_massfraction(ne, 0.7) + bm3.add_element_massfraction(oe, 0.3) + + bm3 = _g4.MaterialCompound("water", 1.0, 2, reg) + he = _g4.ElementSimple("hydrogen", "H", 1, 1.01, reg) + bm3.add_element_natoms(he, 2) + bm3.add_element_natoms(oe, 1) + + copper = _g4.MaterialPredefined("G4_Cu", reg) + zinc = _g4.MaterialPredefined("G4_Zn", reg) + bm4 = _g4.MaterialCompound("YellowBrass_C26800", 8.14, 2, reg) + bm4.add_material(copper, 0.67) + bm4.add_material(zinc, 0.33) + + u235 = _g4.Isotope("U235", 92, 235, 235.044, reg) # Explicitly registered + u238 = _g4.Isotope("U238", 92, 238, 238.051) # Not explicitly registered + uranium = _g4.ElementIsotopeMixture("uranium", "U", 2, reg) + uranium.add_isotope(u235, 0.00716) + uranium.add_isotope(u238, 0.99284) + bm5 = _g4.MaterialCompound("natural_uranium", 19.1, 2, reg) + bm5.add_element_massfraction(uranium, 1) + + bm6 = _g4.MaterialCompound("RadioactiveBrass", 8.14, 2, reg) + bm6.add_material(bm4, 0.99) + bm6.add_material(bm5, 0.01) + + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + + bs = _g4.solid.Box("bs", 10, 10, 10, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl1 = _g4.LogicalVolume(bs, bm1, "bl1", reg) + bl2 = _g4.LogicalVolume(bs, bm2, "bl2", reg) + bl3 = _g4.LogicalVolume(bs, bm3, "bl3", reg) + bl4 = _g4.LogicalVolume(bs, bm4, "bl4", reg) # Material specified by object + bl5 = _g4.LogicalVolume( + bs, "natural_uranium", "bl5", reg + ) # Material specified by name + bl6 = _g4.LogicalVolume(bs, "RadioactiveBrass", "bl6", reg) + + bp1 = _g4.PhysicalVolume([0, 0, 0], [40, 0, 0], bl1, "b_pv1", wl, reg) + bp2 = _g4.PhysicalVolume([0, 0, 0], [0, 40, 0], bl2, "b_pv2", wl, reg) + bp3 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 40], bl3, "b_pv3", wl, reg) + bp4 = _g4.PhysicalVolume([0, 0, 0], [20, 20, 20], bl4, "b_pv4", wl, reg) + bp5 = _g4.PhysicalVolume([0, 0, 0], [-20, -20, -20], bl5, "b_pv5", wl, reg) + bp6 = _g4.PhysicalVolume([0, 0, 0], [-40, 0, 0], bl6, "b_pv6", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # Order the materials - not generally needed for a normal workflow + reg.orderMaterials() + assert len(reg.materialList) > 0 # Ensure the material list is populated + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T203_MaterialsRegistry.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T203_MaterialsRegistry.gmad"), + "T203_MaterialsRegistry.gdml", + ) diff --git a/tests/geant4/T204_NIST_Element.py b/tests/geant4/T204_NIST_Element.py new file mode 100644 index 000000000..aadb8ee5a --- /dev/null +++ b/tests/geant4/T204_NIST_Element.py @@ -0,0 +1,46 @@ +import os as _os + +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd + + +def Test_NIST_Element(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "500", reg, True) + wy = _gd.Constant("wy", "500", reg, True) + wz = _gd.Constant("wz", "500", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic", reg) + + ####################################################################################### + bm1 = _g4.nist_material_2geant4Material("G4_H", reg) + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + + bs = _g4.solid.Box("bs", 10, 10, 10, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl1 = _g4.LogicalVolume(bs, bm1, "bl1", reg) + bp1 = _g4.PhysicalVolume([0, 0, 0], [40, 0, 0], bl1, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # Order the materials - not generally needed for a normal workflow + reg.orderMaterials() + assert len(reg.materialList) > 0 # Ensure the material list is populated + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + name = "T204_NIST_Element" + w.write(_os.path.join(_os.path.dirname(__file__), name + ".gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), name + ".gmad"), name + ".gdml" + ) diff --git a/tests/geant4/T205_NIST_Material.py b/tests/geant4/T205_NIST_Material.py new file mode 100644 index 000000000..2a8921255 --- /dev/null +++ b/tests/geant4/T205_NIST_Material.py @@ -0,0 +1,50 @@ +import os as _os + +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd + + +def Test_NIST_Material(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "500", reg, True) + wy = _gd.Constant("wy", "500", reg, True) + wz = _gd.Constant("wz", "500", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic", reg) + + ####################################################################################### + bm1 = _g4.nist_material_2geant4Material("G4_CONCRETE", reg) + ####################################################################################### + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + + bs = _g4.solid.Box("bs", 10, 10, 10, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl1 = _g4.LogicalVolume(bs, bm1, "bl1", reg) + bp1 = _g4.PhysicalVolume([0, 0, 0], [40, 0, 0], bl1, "b_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # Order the materials - not generally needed for a normal workflow + reg.orderMaterials() + assert len(reg.materialList) > 0 # Ensure the material list is populated + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + name = "T204_NIST_Element" + w.write(_os.path.join(_os.path.dirname(__file__), name + ".gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), name + ".gmad"), name + ".gdml" + ) + + +if __name__ == "__main__": + Test_NIST_Material() diff --git a/tests/geant4/T300_overlap_assembly_regular_lv.py b/tests/geant4/T300_overlap_assembly_regular_lv.py new file mode 100644 index 000000000..6eebb8a15 --- /dev/null +++ b/tests/geant4/T300_overlap_assembly_regular_lv.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import ECamelAssembly + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + vacuum = _g4.MaterialPredefined("G4_Galactic") + + assembly = ECamelAssembly.MakeECamelAssembly(reg) + worldSolid = _g4.solid.Box("world_solid", 200, 200, 200, reg) + worldLV = _g4.LogicalVolume(worldSolid, vacuum, "world_lv", reg) + aBox = _g4.solid.Box("abox_solid", 20, 30, 40, reg) + aBoxLV = _g4.LogicalVolume(aBox, vacuum, "abox_lv", reg) + + asPV1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], assembly, "part_pv1", worldLV, reg) + boxPV1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 20], aBoxLV, "abox_pv1", worldLV, reg) + + # check for overlaps + worldLV.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(worldLV) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T301_overlap_assembly_none.gdml") + ) + + # test __repr__ + str(worldSolid) + + # test extent of physical volume + extentBB = worldLV.extent(includeBoundingSolid=True) + extent = worldLV.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": worldLV, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T301_overlap_assembly_none.py b/tests/geant4/T301_overlap_assembly_none.py new file mode 100644 index 000000000..406024877 --- /dev/null +++ b/tests/geant4/T301_overlap_assembly_none.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import ECamelAssembly + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + vacuum = _g4.MaterialPredefined("G4_Galactic") + + assembly = ECamelAssembly.MakeECamelAssembly(reg) + worldSolid = _g4.solid.Box("world_solid", 200, 200, 200, reg) + worldLV = _g4.LogicalVolume(worldSolid, vacuum, "world_lv", reg) + + asPV1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], assembly, "part_pv1", worldLV, reg) + asPV2 = _g4.PhysicalVolume( + [0, 0, 0], [50, 0, 0], assembly, "part_pv2", worldLV, reg + ) + + # check for overlaps + worldLV.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(worldLV) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T301_overlap_assembly_none.gdml") + ) + + # test __repr__ + str(worldSolid) + + # test extent of physical volume + extentBB = worldLV.extent(includeBoundingSolid=True) + extent = worldLV.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": worldLV, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T302_overlap_assembly_coplanar.py b/tests/geant4/T302_overlap_assembly_coplanar.py new file mode 100644 index 000000000..ee1d34e66 --- /dev/null +++ b/tests/geant4/T302_overlap_assembly_coplanar.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import ECamelAssembly + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + vacuum = _g4.MaterialPredefined("G4_Galactic") + + assembly = ECamelAssembly.MakeECamelAssembly(reg, margin=0, separation=-1e-12) + worldSolid = _g4.solid.Box("world_solid", 200, 200, 200, reg) + worldLV = _g4.LogicalVolume(worldSolid, vacuum, "world_lv", reg) + + asPV1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], assembly, "part_pv1", worldLV, reg) + asPV2 = _g4.PhysicalVolume( + [0, 0, 0], [50, 0, 0], assembly, "part_pv2", worldLV, reg + ) + + # check for overlaps + worldLV.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(worldLV) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T302_overlap_assembly_coplanar.gdml") + ) + + # test __repr__ + str(worldSolid) + + # test extent of physical volume + extentBB = worldLV.extent(includeBoundingSolid=True) + extent = worldLV.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": worldLV, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T303_overlap_assembly_daughter_collision.py b/tests/geant4/T303_overlap_assembly_daughter_collision.py new file mode 100644 index 000000000..c44694710 --- /dev/null +++ b/tests/geant4/T303_overlap_assembly_daughter_collision.py @@ -0,0 +1,57 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import ECamelAssembly + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + vacuum = _g4.MaterialPredefined("G4_Galactic") + + assembly = ECamelAssembly.MakeECamelAssembly(reg, separation=-5) + worldSolid = _g4.solid.Box("world_solid", 200, 200, 200, reg) + worldLV = _g4.LogicalVolume(worldSolid, vacuum, "world_lv", reg) + + asPV1 = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], assembly, "part_pv1", worldLV, reg) + asPV2 = _g4.PhysicalVolume( + [0, 0, 0], [50, 0, 0], assembly, "part_pv2", worldLV, reg + ) + + # check for overlaps + worldLV.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(worldLV) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T303_overlap_assembly_daughter_collision.gdml" + ) + ) + + # test __repr__ + str(worldSolid) + + # test extent of physical volume + extentBB = worldLV.extent(includeBoundingSolid=True) + extent = worldLV.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": worldLV, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T304_overlap_assembly_volumetric.py b/tests/geant4/T304_overlap_assembly_volumetric.py new file mode 100644 index 000000000..845afdebc --- /dev/null +++ b/tests/geant4/T304_overlap_assembly_volumetric.py @@ -0,0 +1,63 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import numpy as _np + +import ECamelAssembly + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + vacuum = _g4.MaterialPredefined("G4_Galactic") + + assembly = ECamelAssembly.MakeECamelAssembly(reg, separation=5) + worldSolid = _g4.solid.Box("world_solid", 200, 200, 200, reg) + worldLV = _g4.LogicalVolume(worldSolid, vacuum, "world_lv", reg) + + asPV1 = _g4.PhysicalVolume( + [0, 0, 0], [0, -20, 0], assembly, "part_pv1", worldLV, reg + ) + asPV2 = _g4.PhysicalVolume( + [0, _np.pi / 15, _np.pi / 6], [10, -20, 5], assembly, "part_pv2", worldLV, reg + ) + asPV3 = _g4.PhysicalVolume( + [0, -_np.pi / 15, _np.pi / 6], [-40, -20, 5], assembly, "part_pv3", worldLV, reg + ) + + # check for overlaps + worldLV.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(worldLV) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T304_overlap_assembly_volumetric.gdml" + ) + ) + + # test __repr__ + str(worldSolid) + + # test extent of physical volume + extentBB = worldLV.extent(includeBoundingSolid=True) + extent = worldLV.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": worldLV, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T305_overlap_assembly_nested.py b/tests/geant4/T305_overlap_assembly_nested.py new file mode 100644 index 000000000..39cc4ef15 --- /dev/null +++ b/tests/geant4/T305_overlap_assembly_nested.py @@ -0,0 +1,72 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import numpy as _np + +import ECamelAssembly + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + vacuum = _g4.MaterialPredefined("G4_Galactic") + + assembly = ECamelAssembly.MakeECamelAssembly(reg, separation=5) + worldSolid = _g4.solid.Box("world_solid", 200, 200, 200, reg) + worldLV = _g4.LogicalVolume(worldSolid, vacuum, "world_lv", reg) + + masterAssembly = _g4.AssemblyVolume("assembly2", reg) + asPV1 = _g4.PhysicalVolume( + [0, 0, 0], [0, 0, 0], assembly, "part_pv1", masterAssembly, reg + ) + asPV2 = _g4.PhysicalVolume( + [0, 0, 0], [0, 0, 12], assembly, "part_pv2", masterAssembly, reg + ) + asPV3 = _g4.PhysicalVolume( + [0, 0, 0], [0, 0, 24], assembly, "part_pv3", masterAssembly, reg + ) + + _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], masterAssembly, "ma_pv1", worldLV, reg) + _g4.PhysicalVolume( + [-_np.pi / 12, _np.pi / 24, 0], + [30, 0, 7], + masterAssembly, + "ma_pv2", + worldLV, + reg, + ) + + # check for overlaps + worldLV.checkOverlaps(recursive=True, coplanar=True, debugIO=False) + + # set world volume + reg.setWorld(worldLV) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T305_overlap_assembly_nested.gdml") + ) + + # test __repr__ + str(worldSolid) + + # test extent of physical volume + extentBB = worldLV.extent(includeBoundingSolid=True) + extent = worldLV.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": worldLV, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T306_overlap_replica_x.py b/tests/geant4/T306_overlap_replica_x.py new file mode 100644 index 000000000..b54067a25 --- /dev/null +++ b/tests/geant4/T306_overlap_replica_x.py @@ -0,0 +1,64 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + mbx = _gd.Constant("mbx", "800", reg, True) + mby = _gd.Constant("mby", "100", reg, True) + mbz = _gd.Constant("mbz", "100", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", 1000, 1000, 1000, reg) + bs = _g4.solid.Box("bs", 100, 100, 100, reg) + mbs = _g4.solid.Box("mbs", mbx, mby, mbz, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + ml = _g4.LogicalVolume(mbs, wm, "ml", reg) + ml2 = _g4.LogicalVolume(mbs, wm, "ml2", reg) + mbl = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kXAxis, 8, 100, 0, reg, True, "mm", "mm" + ) + + # the replica mother overlaps with another big box with no contents + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 40, 0], ml2, "ml2_pv1", wl, reg) + + wl.checkOverlaps(recursive=True, coplanar=True) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T106_replica_x.gdml")) + + # test __repr__ + str(mbl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T307_overlap_replica_x_internal.py b/tests/geant4/T307_overlap_replica_x_internal.py new file mode 100644 index 000000000..79b7174b3 --- /dev/null +++ b/tests/geant4/T307_overlap_replica_x_internal.py @@ -0,0 +1,64 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + mbx = _gd.Constant("mbx", "800", reg, True) + mby = _gd.Constant("mby", "100", reg, True) + mbz = _gd.Constant("mbz", "100", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", 1000, 1000, 1000, reg) + # we define bs:x to be > mbx / 8 => 100, so this should be a wrong replica + # the internal boxes will overlap and also protrude from the mother + bs = _g4.solid.Box("bs", 110, 100, 100, reg) + mbs = _g4.solid.Box("mbs", mbx, mby, mbz, reg) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + ml = _g4.LogicalVolume(mbs, wm, "ml", reg) + ml2 = _g4.LogicalVolume(mbs, wm, "ml2", reg) + mbl = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kXAxis, 8, 100, 0, reg, True, "mm", "mm" + ) + + mbp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ml, "ml_pv1", wl, reg) + + wl.checkOverlaps(recursive=True, coplanar=True) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T106_replica_x.gdml")) + + # test __repr__ + str(mbl) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T400_MergeRegistry.py b/tests/geant4/T400_MergeRegistry.py new file mode 100644 index 000000000..758e2e9c2 --- /dev/null +++ b/tests/geant4/T400_MergeRegistry.py @@ -0,0 +1,103 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def MakeGeometry(size=50, lowOxygen=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", size, reg, True) + wy = _gd.Constant("wy", size, reg, True) + wz = _gd.Constant("wz", size, reg, True) + + # "size" argument allows us to define different sizes with the same name + # to test resolution when we merge + bx = _gd.Constant("bx", size / 5, reg, True) + by = _gd.Constant("by", size / 5, reg, True) + bz = _gd.Constant("bz", size / 5, reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + + # this allows us to define two technically different materials but called + # "air" so they should be resolved correctly in the merging + air = _g4.MaterialCompound("air", 1.290e-3, 2, reg) + oe = _g4.ElementSimple("oxygen", "O", 8, 16.0) + if lowOxygen: + ne = _g4.ElementSimple("nitrogen", "N", 7, 15.01) + air.add_element_massfraction(ne, 0.95) + air.add_element_massfraction(oe, 0.05) + else: + ne = _g4.ElementSimple("nitrogen", "N", 7, 14.01) + air.add_element_massfraction(ne, 0.7) + air.add_element_massfraction(oe, 0.3) + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + bl = _g4.LogicalVolume(bs, air, "bl", reg) + + scale = _gd.Defines.Scale("sca_reflection", 1, 1, -1, registry=reg) + + bp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], bl, "b_pv1", wl, reg, scale=scale) + + # set world volume + reg.setWorld(wl.name) + + return reg + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + reg1 = MakeGeometry() + reg2 = MakeGeometry(size=70, lowOxygen=True) + reg3 = MakeGeometry(size=100, lowOxygen=True) + + l1 = reg1.getWorldVolume() + l2 = reg2.getWorldVolume() + l3 = reg3.getWorldVolume() + + wx0 = _gd.Constant("wx0", "400", reg0, True) + wy0 = _gd.Constant("wy0", "400", reg0, True) + wz0 = _gd.Constant("wz0", "400", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + p3 = _g4.PhysicalVolume([0, 0, 0], [150, 0, 0], l3, "l3_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + reg0.addVolumeRecursive(p3) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T400_MergeRegistry.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"teststatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T401_MergeRegistry_Box.py b/tests/geant4/T401_MergeRegistry_Box.py new file mode 100644 index 000000000..4a71ffe08 --- /dev/null +++ b/tests/geant4/T401_MergeRegistry_Box.py @@ -0,0 +1,52 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T001_Box.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T401_MergeRegistry_Box.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T402_MergeRegistry_Tubs.py b/tests/geant4/T402_MergeRegistry_Tubs.py new file mode 100644 index 000000000..392e5dbdb --- /dev/null +++ b/tests/geant4/T402_MergeRegistry_Tubs.py @@ -0,0 +1,52 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T002_Tubs + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T002_Tubs.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T402_MergeRegistry_Tubs.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "registrty": reg0} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T403_MergeRegistry_CutTubs.py b/tests/geant4/T403_MergeRegistry_CutTubs.py new file mode 100644 index 000000000..e89999a70 --- /dev/null +++ b/tests/geant4/T403_MergeRegistry_CutTubs.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T003_CutTubs + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T003_CutTubs.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T403_MergeRegistry_CutTubs.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T404_MergeRegistry_Cons.py b/tests/geant4/T404_MergeRegistry_Cons.py new file mode 100644 index 000000000..f04d9790d --- /dev/null +++ b/tests/geant4/T404_MergeRegistry_Cons.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T004_Cons + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T004_Cons.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T404_MergeRegistry_Cons.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T405_MergeRegistry_Para.py b/tests/geant4/T405_MergeRegistry_Para.py new file mode 100644 index 000000000..fe9c832dd --- /dev/null +++ b/tests/geant4/T405_MergeRegistry_Para.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T005_Para + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T005_Para.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T405_MergeRegistry_Para.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T406_MergeRegistry_Trd.py b/tests/geant4/T406_MergeRegistry_Trd.py new file mode 100644 index 000000000..8be9ed17a --- /dev/null +++ b/tests/geant4/T406_MergeRegistry_Trd.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T006_Trd + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T006_Trd.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T406_MergeRegistry_Trd.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T407_MergeRegistry_Trap.py b/tests/geant4/T407_MergeRegistry_Trap.py new file mode 100644 index 000000000..d0890ae23 --- /dev/null +++ b/tests/geant4/T407_MergeRegistry_Trap.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T007_Trap + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T007_Trap.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T407_MergeRegistry_Trap.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T408_MergeRegistry_Sphere.py b/tests/geant4/T408_MergeRegistry_Sphere.py new file mode 100644 index 000000000..607d1c378 --- /dev/null +++ b/tests/geant4/T408_MergeRegistry_Sphere.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T008_Sphere + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T008_Sphere.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T408_MergeRegistry_Sphere.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T409_MergeRegistry_Orb.py b/tests/geant4/T409_MergeRegistry_Orb.py new file mode 100644 index 000000000..bb869333a --- /dev/null +++ b/tests/geant4/T409_MergeRegistry_Orb.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T009_Orb + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T009_Orb.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T409_MergeRegistry_Orb.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T410_MergeRegistry_Torus.py b/tests/geant4/T410_MergeRegistry_Torus.py new file mode 100644 index 000000000..32b94f5d3 --- /dev/null +++ b/tests/geant4/T410_MergeRegistry_Torus.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T010_Torus + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T010_Torus.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T410_MergeRegistry_Torus.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T411_MergeRegistry_Polycone.py b/tests/geant4/T411_MergeRegistry_Polycone.py new file mode 100644 index 000000000..6b858bf01 --- /dev/null +++ b/tests/geant4/T411_MergeRegistry_Polycone.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T011_Polycone + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T011_Polycone.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T411_MergeRegistry_Polycone.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T412_MergeRegistry_GenericPolycone.py b/tests/geant4/T412_MergeRegistry_GenericPolycone.py new file mode 100644 index 000000000..55bca23f0 --- /dev/null +++ b/tests/geant4/T412_MergeRegistry_GenericPolycone.py @@ -0,0 +1,57 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T012_GenericPolycone + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T012_GenericPolycone.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T412_MergeRegistry_GenericPolycone.gdml" + ) + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T413_MergeRegistry_Polyhedra.py b/tests/geant4/T413_MergeRegistry_Polyhedra.py new file mode 100644 index 000000000..9ab9e19f8 --- /dev/null +++ b/tests/geant4/T413_MergeRegistry_Polyhedra.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T013_Polyhedra + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T013_Polyhedra.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T413_MergeRegistry_Polyhedra.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T414_MergeRegistry_GenericPolyhedra.py b/tests/geant4/T414_MergeRegistry_GenericPolyhedra.py new file mode 100644 index 000000000..97baf2a3d --- /dev/null +++ b/tests/geant4/T414_MergeRegistry_GenericPolyhedra.py @@ -0,0 +1,52 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T014_GenericPolyhedra + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T014_GenericPolyhedra.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T414_MergeRegistry_GenericPolyhedra.gdml" + ) + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T415_MergeRegistry_EllipticalTube.py b/tests/geant4/T415_MergeRegistry_EllipticalTube.py new file mode 100644 index 000000000..ad3acbe85 --- /dev/null +++ b/tests/geant4/T415_MergeRegistry_EllipticalTube.py @@ -0,0 +1,57 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T015_EllipticalTube + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T015_EllipticalTube.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T415_MergeRegistry_EllipticalTube.gdml" + ) + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T416_MergeRegistry_Ellipoid.py b/tests/geant4/T416_MergeRegistry_Ellipoid.py new file mode 100644 index 000000000..2bc6b4f0e --- /dev/null +++ b/tests/geant4/T416_MergeRegistry_Ellipoid.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T016_Ellipsoid + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T016_Ellipsoid.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T416_MergeRegistry_Ellipsoid.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T417_MergeRegistry_EllipticalCone.py b/tests/geant4/T417_MergeRegistry_EllipticalCone.py new file mode 100644 index 000000000..1cab335ff --- /dev/null +++ b/tests/geant4/T417_MergeRegistry_EllipticalCone.py @@ -0,0 +1,57 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T017_EllipticalCone + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T017_EllipticalCone.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T417_MergeRegistry_EllipticalCone.gdml" + ) + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T418_MergeRegistry_Paraboloid.py b/tests/geant4/T418_MergeRegistry_Paraboloid.py new file mode 100644 index 000000000..6b858bf01 --- /dev/null +++ b/tests/geant4/T418_MergeRegistry_Paraboloid.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T011_Polycone + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T011_Polycone.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T411_MergeRegistry_Polycone.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T419_MergeRegistry_Hyperboloid.py b/tests/geant4/T419_MergeRegistry_Hyperboloid.py new file mode 100644 index 000000000..9cc8f6405 --- /dev/null +++ b/tests/geant4/T419_MergeRegistry_Hyperboloid.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T019_Hyperboloid + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T019_Hyperboloid.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T419_MergeRegistry_Hyperboloid.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T420_MergeRegistry_Tet.py b/tests/geant4/T420_MergeRegistry_Tet.py new file mode 100644 index 000000000..e56215e6a --- /dev/null +++ b/tests/geant4/T420_MergeRegistry_Tet.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T020_Tet + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T020_Tet.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T420_MergeRegistry_Tet.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T421_MergeRegistry_ExtrudedSolid.py b/tests/geant4/T421_MergeRegistry_ExtrudedSolid.py new file mode 100644 index 000000000..16fda9063 --- /dev/null +++ b/tests/geant4/T421_MergeRegistry_ExtrudedSolid.py @@ -0,0 +1,57 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T021_ExtrudedSolid + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T021_ExtrudedSolid.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T421_MergeRegistry_ExtrudedSolid.gdml" + ) + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T422_MergeRegistry_TwistedBox.py b/tests/geant4/T422_MergeRegistry_TwistedBox.py new file mode 100644 index 000000000..e2d2c1531 --- /dev/null +++ b/tests/geant4/T422_MergeRegistry_TwistedBox.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T022_TwistedBox + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T022_TwistedBox.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T422_MergeRegistry_TwistedBox.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T423_MergeRegistry_TwistedTrap.py b/tests/geant4/T423_MergeRegistry_TwistedTrap.py new file mode 100644 index 000000000..3dff3ffde --- /dev/null +++ b/tests/geant4/T423_MergeRegistry_TwistedTrap.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T023_TwistedTrap + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T023_TwistedTrap.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T423_MergeRegistry_TwistedTrap.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T424_MergeRegistry_TwistedTrd.py b/tests/geant4/T424_MergeRegistry_TwistedTrd.py new file mode 100644 index 000000000..325f6c514 --- /dev/null +++ b/tests/geant4/T424_MergeRegistry_TwistedTrd.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T024_TwistedTrd + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T024_TwistedTrd.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T424_MergeRegistry_TwistedTrd.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T425_MergeRegistry_TwistedTubs.py b/tests/geant4/T425_MergeRegistry_TwistedTubs.py new file mode 100644 index 000000000..b6f9401bc --- /dev/null +++ b/tests/geant4/T425_MergeRegistry_TwistedTubs.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T025_TwistedTubs + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T025_TwistedTubs.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T425_MergeRegistry_TwistedTubs.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T426_MergeRegistry_GenericTrap.py b/tests/geant4/T426_MergeRegistry_GenericTrap.py new file mode 100644 index 000000000..aeec2c8e3 --- /dev/null +++ b/tests/geant4/T426_MergeRegistry_GenericTrap.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T026_GenericTrap + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T026_GenericTrap.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T426_MergeRegistry_GenericTrap.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T428_MergeRegistry_Union.py b/tests/geant4/T428_MergeRegistry_Union.py new file mode 100644 index 000000000..4dd788722 --- /dev/null +++ b/tests/geant4/T428_MergeRegistry_Union.py @@ -0,0 +1,53 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T028_Union + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T028_Union.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write(_os.path.join(_os.path.dirname(__file__), "T428_MergeRegistry_Union.gdml")) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T429_MergeRegistry_Subtraction.py b/tests/geant4/T429_MergeRegistry_Subtraction.py new file mode 100644 index 000000000..b84d77fcc --- /dev/null +++ b/tests/geant4/T429_MergeRegistry_Subtraction.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T029_Subtraction + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T029_Subtraction.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T429_MergeRegistry_Subtraction.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T430_MergeRegistry_Intersection.py b/tests/geant4/T430_MergeRegistry_Intersection.py new file mode 100644 index 000000000..def139465 --- /dev/null +++ b/tests/geant4/T430_MergeRegistry_Intersection.py @@ -0,0 +1,57 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T030_Intersection + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T030_Intersection.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T430_MergeRegistry_Intersection.gdml" + ) + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T431_MergeRegistry_MultiUnion.py b/tests/geant4/T431_MergeRegistry_MultiUnion.py new file mode 100644 index 000000000..724865102 --- /dev/null +++ b/tests/geant4/T431_MergeRegistry_MultiUnion.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T031_MultiUnion + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T031_MultiUnion.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T431_MergeRegistry_MultiUnion.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T432_MergeRegistry_Box_AssemblyConversion.py b/tests/geant4/T432_MergeRegistry_Box_AssemblyConversion.py new file mode 100644 index 000000000..b9ab85975 --- /dev/null +++ b/tests/geant4/T432_MergeRegistry_Box_AssemblyConversion.py @@ -0,0 +1,60 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T001_Box.Test(False, False)["logicalVolume"] + av1 = l1.assemblyVolume() + av2 = l2.assemblyVolume() + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "world", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-25, 0, 0], av1, "av1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [25, 0, 0], av2, "av2_pv", wl, reg0) + + wl.checkOverlaps(recursive=True) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T432_MergeRegistry_Box_AssemblyConversion.gdml" + ) + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T433_MergeRegistry_Scale.py b/tests/geant4/T433_MergeRegistry_Scale.py new file mode 100644 index 000000000..712502e78 --- /dev/null +++ b/tests/geant4/T433_MergeRegistry_Scale.py @@ -0,0 +1,57 @@ +import pyg4ometry +import os as _os + + +def Test(vis=False, interactive=False): + reg0 = pyg4ometry.geant4.Registry() + scale = pyg4ometry.gdml.Defines.Scale("sca_reflection", 1, 1, -1, registry=reg0) + + vacuum = pyg4ometry.geant4.MaterialPredefined("G4_Galactic", reg0) + iron = pyg4ometry.geant4.MaterialPredefined("G4_Fe", reg0) + + world = pyg4ometry.geant4.solid.Box("world_solid", 200, 200, 200, reg0) + worldLV = pyg4ometry.geant4.LogicalVolume(world, vacuum, "world_lv", reg0) + + box = pyg4ometry.geant4.solid.Box("box_solid", 10, 20, 50, reg0) + boxLV = pyg4ometry.geant4.LogicalVolume(box, iron, "box_lv", reg0) + + pv1 = pyg4ometry.geant4.PhysicalVolume( + [0, 0, 0], [50, 0, 0], boxLV, "box_pv1", worldLV, reg0 + ) + + pv2 = pyg4ometry.geant4.PhysicalVolume( + [0, 0, 0], [-50, 0, 0], boxLV, "box_pv2", worldLV, reg0, scale=scale + ) + + pv3 = pyg4ometry.geant4.PhysicalVolume( + [0, 0, 0], [-50, -50, 0], boxLV, "box_pv3", worldLV, reg0, scale=scale + ) + + # create another registry and add the world to it + reg1 = pyg4ometry.geant4.Registry() + reg1.addVolumeRecursive(worldLV) + + world2 = pyg4ometry.geant4.solid.Box("bigger_world", 100, 100, 100, reg1) + world2LV = pyg4ometry.geant4.LogicalVolume(world2, vacuum, "bigger_world_lv", reg1) + reg1.setWorld(world2LV) + + smallWorldPV = pyg4ometry.geant4.PhysicalVolume( + [0, 0, 0], [0, 0, 0], worldLV, "smaller_world_pv", world2LV, reg1 + ) + + # gdml output + w = pyg4ometry.gdml.Writer() + w.addDetector(reg1) + w.write(_os.path.join(_os.path.dirname(__file__), "T433_MergeRegistry_Scale.gdml")) + + v = None + if vis: + v = pyg4ometry.visualisation.VtkViewer() + v.addLogicalVolume(worldLV) + v.view() + + return {"testStatus": True, "logicalVolume": worldLV, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T434_MergeRegistry_CollapseAssembly.py b/tests/geant4/T434_MergeRegistry_CollapseAssembly.py new file mode 100644 index 000000000..67169b118 --- /dev/null +++ b/tests/geant4/T434_MergeRegistry_CollapseAssembly.py @@ -0,0 +1,100 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def MakeGeometry(): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", 250, reg, True) + wy = _gd.Constant("wy", 250, reg, True) + wz = _gd.Constant("wz", 250, reg, True) + + bx = _gd.Constant("bx", 40, reg, True) + by = _gd.Constant("by", 20, reg, True) + bz = _gd.Constant("bz", 1, reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Si") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, by, bz, reg, "mm") + + # structure + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + + al = _g4.AssemblyVolume("al", reg) + bp1 = _g4.PhysicalVolume([0, 0, 0, "deg"], [0, -35, 0, "mm"], bl, "b_pv1", al, reg) + bp2 = _g4.PhysicalVolume([0, 0, 90, "deg"], [35, 0, 0, "mm"], bl, "b_pv2", al, reg) + bp3 = _g4.PhysicalVolume([0, 0, 180, "deg"], [0, 35, 0, "mm"], bl, "b_pv3", al, reg) + bp4 = _g4.PhysicalVolume( + [0, 0, 270, "deg"], [-35, 0, 0, "mm"], bl, "b_pv4", al, reg + ) + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ap1 = _g4.PhysicalVolume([0, 0, 0, "deg"], [0, 0, -100, "mm"], al, "a_pv1", wl, reg) + ap2 = _g4.PhysicalVolume([0, 0, 0, "deg"], [0, 0, -50, "mm"], al, "a_pv2", wl, reg) + ap3 = _g4.PhysicalVolume([0, 0, 0, "deg"], [0, 0, 0, "mm"], al, "a_pv3", wl, reg) + ap4 = _g4.PhysicalVolume([0, 0, 0, "deg"], [0, 0, 50, "mm"], al, "a_pv4", wl, reg) + ap5 = _g4.PhysicalVolume([0, 0, 0, "deg"], [0, 0, 100, "mm"], al, "a_pv5", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + return reg + + +def Test(vis=False, interactive=False): + reg0 = MakeGeometry() + wl = reg0.getWorldVolume() + + reg1 = _g4.Registry() + reg1.addVolumeRecursive(wl, collapseAssemblies=True) + reg1.setWorld(wl) + + # check assembly collapse has produced correct results + assert len(wl.daughterVolumes) == 20 + for i in range(1, 5, 1): + for j in range(1, 4, 1): + pvname = f"a_pv{i}_b_pv{j}" + assert pvname in wl._daughterVolumesDict + pv = wl._daughterVolumesDict[pvname] + assert round(float(pv.rotation[2]), 6) == round( + (j - 1) * 90 * _gd.Units.unit("deg"), 6 + ) + assert round(float(pv.position[2]), 1) == round( + (i - 3) * 50 * _gd.Units.unit("mm"), 1 + ) + + # check for overlaps + wl.checkOverlaps(recursive=True, coplanar=False) + + # gdml output + w = _gd.Writer() + w.addDetector(reg1) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T434_MergeRegistry_CollapseAssembly.gdml" + ) + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T505_MergeRegistry_Assembly.py b/tests/geant4/T505_MergeRegistry_Assembly.py new file mode 100644 index 000000000..724865102 --- /dev/null +++ b/tests/geant4/T505_MergeRegistry_Assembly.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T031_MultiUnion + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T031_MultiUnion.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T431_MergeRegistry_MultiUnion.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T511_MergeRegistry_DefineTree.py b/tests/geant4/T511_MergeRegistry_DefineTree.py new file mode 100644 index 000000000..ed5aeef45 --- /dev/null +++ b/tests/geant4/T511_MergeRegistry_DefineTree.py @@ -0,0 +1,55 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + +import T001_Box +import T0034_CutTubs_DefineTree + + +def Test(vis=False, interactive=False): + reg0 = _g4.Registry() + + l1 = T001_Box.Test(False, False)["logicalVolume"] + l2 = T0034_CutTubs_DefineTree.Test(False, False)["logicalVolume"] + + wx0 = _gd.Constant("wx0", "200", reg0, True) + wy0 = _gd.Constant("wy0", "200", reg0, True) + wz0 = _gd.Constant("wz0", "200", reg0, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + ws = _g4.solid.Box("ws", wx0, wy0, wz0, reg0, "mm") + wl = _g4.LogicalVolume(ws, wm, "wl", reg0) + + p1 = _g4.PhysicalVolume([0, 0, 0], [-50, 0, 0], l1, "l1_pv", wl, reg0) + p2 = _g4.PhysicalVolume([0, 0, 0], [50, 0, 0], l2, "l2_pv", wl, reg0) + + reg0.addVolumeRecursive(p1) + reg0.addVolumeRecursive(p2) + + reg0.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg0) + w.write( + _os.path.join(_os.path.dirname(__file__), "T511_MergeRegistry_DefineTree.gdml") + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg0.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T600_LVTessellated.py b/tests/geant4/T600_LVTessellated.py new file mode 100644 index 000000000..43dfe1fc8 --- /dev/null +++ b/tests/geant4/T600_LVTessellated.py @@ -0,0 +1,85 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "150", reg, True) + wy = _gd.Constant("wy", "150", reg, True) + wz = _gd.Constant("wz", "150", reg, True) + + # pi = _gd.Constant("pi","3.1415926",reg,True) + ctrmin = _gd.Constant("trmin", "2.5", reg, True) + ctrmax = _gd.Constant("trmax", "10.0", reg, True) + ctz = _gd.Constant("tz", "110", reg, True) + ctstartphi = _gd.Constant("startphi", "0", reg, True) + ctdeltaphi = _gd.Constant("deltaphi", "1.5*pi", reg, True) + ctlowx = _gd.Constant("ctlowx", "-1", reg, True) + ctlowy = _gd.Constant("ctlowy", "-1", reg, True) + ctlowz = _gd.Constant("ctlowz", "-1", reg, True) + cthighx = _gd.Constant("cthighx", "1", reg, True) + cthighy = _gd.Constant("cthighy", "1", reg, True) + cthighz = _gd.Constant("cthighz", "1", reg, True) + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + cts = _g4.solid.CutTubs( + "ts", + ctrmin, + ctrmax, + ctz, + ctstartphi, + ctdeltaphi, + [ctlowx, ctlowy, ctlowz], + [cthighx, cthighy, cthighz], + reg, + "mm", + "rad", + ) + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ctl = _g4.LogicalVolume(cts, bm, "ctl", reg) + + # Replace the standard solid of the logical volume with a Tessellated Solid version of itself + ctl.makeSolidTessellated() # Operation is in-place + + # Place the lv as normal + ctp = _g4.PhysicalVolume([3.14 / 2.0, 0, 0], [0, 0, 0], ctl, "ct_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T600_LVTessellated.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T600_LVTessellated.gmad"), + "T600_LVTessellated.gdml", + ) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T601_reflect.py b/tests/geant4/T601_reflect.py new file mode 100644 index 000000000..7f968268a --- /dev/null +++ b/tests/geant4/T601_reflect.py @@ -0,0 +1,68 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + bx = _gd.Constant("bx", "10", reg, True) + + b1pos = _gd.Position("b1pos", -bx, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b2pos", 0, 0, 0, "mm", reg, True) + b2pos = _gd.Position("b3pos", bx, 0, 0, "mm", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs1 = _g4.solid.Box("bs1", 1.1 * bx, 0.9 * bx, 0.9 * bx, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl1 = _g4.LogicalVolume(bs1, bm, "bl1", reg) + + bp1 = _g4.PhysicalVolume([0.0, 0, 0], [-bx, 0, 0], bl1, "b_pv1", wl, reg) + bp2 = _g4.PhysicalVolume( + [0.0, 0, 0], [bx, 0, 0], bl1, "b_pv2", wl, reg, True, [-1, 1, 1] + ) + + # check overlaps + wl.checkOverlaps(recursive=True) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T601_reflect.gdml")) + + # test __repr__ + str(bs1) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T602_lv_cull_daughters.py b/tests/geant4/T602_lv_cull_daughters.py new file mode 100644 index 000000000..e09996238 --- /dev/null +++ b/tests/geant4/T602_lv_cull_daughters.py @@ -0,0 +1,67 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", 3, 3, 3, reg, "m") + + x = 1 + ds = _g4.solid.Box("ds", x, x, x, reg, "m") + dds = _g4.solid.Box("dds", 0.2, 0.2, 0.2, reg, "m") + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + dlv = _g4.LogicalVolume(ds, wm, "dlv", reg) + ddlv = _g4.LogicalVolume(dds, bm, "ddlv", reg) + + nX = 4 + dX = x * 1000 / nX + x0 = -0.5 * x * 1000 + 0.5 * dX + for xi in range(nX): + for yi in range(nX): + pos = [x0 + xi * dX, x0 + yi * dX, 0] + _g4.PhysicalVolume( + [0, 0, 0], pos, ddlv, "ddpv_" + str(xi) + str(yi), dlv, reg + ) + + _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], dlv, "dlv_pv", wl, reg) + + # now for the culling + clipFW = 500 # this should cut out the middle 4 from 16 + clipBox = _g4.solid.Box("clipper", clipFW, clipFW, clipFW, reg, "mm") + dlv.cullDaughtersOutsideSolid(clipBox) + + # set world volume + reg.setWorld(wl) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T602_lv_cull_daughters.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__)) + "T602_lv_cull_daughters.gmad", + "T602_lv_cull_daughters.gdml", + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addSolid(clipBox) + v.view(interactive=interactive) + + assert len(dlv.daughterVolumes) == 4 + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(vis=True) diff --git a/tests/geant4/T603_lv_change_solid_and_trim.py b/tests/geant4/T603_lv_change_solid_and_trim.py new file mode 100644 index 000000000..bfde1dfcc --- /dev/null +++ b/tests/geant4/T603_lv_change_solid_and_trim.py @@ -0,0 +1,71 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", 3, 3, 3, reg, "m") + + x = 1 + ds = _g4.solid.Box("ds", x, x, x, reg, "m") + dds = _g4.solid.Box("dds", 0.2, 0.2, 0.2, reg, "m") + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + dlv = _g4.LogicalVolume(ds, wm, "dlv", reg) + ddlv = _g4.LogicalVolume(dds, bm, "ddlv", reg) + + nX = 4 + dX = x * 1000 / nX + x0 = -0.5 * x * 1000 + 0.5 * dX + for xi in range(nX): + for yi in range(nX): + pos = [x0 + xi * dX, x0 + yi * dX, 0] + _g4.PhysicalVolume( + [0, 0, 0], pos, ddlv, "ddpv_" + str(xi) + str(yi), dlv, reg + ) + + _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], dlv, "dlv_pv", wl, reg) + + # now for the culling + # 800 should mean that the middle 4 out of 16 boxes remain untouched, but + # the outer 12 should be intersected + clipFW = 800 + clipBox = _g4.solid.Box("clipper", clipFW, clipFW, clipFW, reg, "mm") + dlv.changeSolidAndTrimGeometry(clipBox) + + # set world volume + reg.setWorld(wl) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T603_lv_change_solid_and_trim.gdml") + ) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__)) + + "T603_lv_change_solid_and_trim.gmad", + "T603_lv_change_solid_and_trim.gdml", + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.view(interactive=interactive) + + assert len(dlv.daughterVolumes) == 16 + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(vis=True) diff --git a/tests/geant4/T604_lv_change_solid_and_trim_rot.py b/tests/geant4/T604_lv_change_solid_and_trim_rot.py new file mode 100644 index 000000000..c95d0f047 --- /dev/null +++ b/tests/geant4/T604_lv_change_solid_and_trim_rot.py @@ -0,0 +1,115 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", 3, 3, 3, reg, "m") + + x = 1 + ds = _g4.solid.Box("ds", x, x, x, reg, "m") + dds = _g4.solid.Box("dds", 0.2, 0.2, 0.2, reg, "m") + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + dlv = _g4.LogicalVolume(ds, wm, "dlv", reg) + ddlv = _g4.LogicalVolume(dds, bm, "ddlv", reg) + + nX = 4 + dX = x * 1000 / nX + x0 = -0.5 * x * 1000 + 0.5 * dX + for xi in [0, 1, 2, 3]: + for yi in [0, 1, 2, 3]: + pos = [x0 + xi * dX, x0 + yi * dX, 0] + _g4.PhysicalVolume( + [0, 0, 0.0], pos, ddlv, "ddpv_" + str(xi) + str(yi), dlv, reg + ) + + _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], dlv, "dlv_pv", wl, reg) + + # now for the culling + # 800 should mean that the middle 4 out of 16 boxes remain untouched, but + # the outer 12 should be intersected + clipFW = 800 + rotation = [_np.pi / 4, _np.pi / 4, _np.pi / 4] + position = [250, 0, 0] + clipBox = _g4.solid.Box("clipper", clipFW, clipFW, clipFW, reg, "mm") + # dlv.changeSolidAndTrimGeometry(clipBox, rotation=rotation, position=position) + [outside, inside, intersections] = dlv.clipGeometry( + clipBox, rotation=rotation, position=position + ) + + # set world volume + reg.setWorld(wl) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T604_lv_change_solid_and_trim_rot.gdml" + ) + ) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__)) + + "T604_lv_change_solid_and_trim_rot.gmad", + "T604_lv_change_solid_and_trim_rot.gdml", + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addSolid(clipBox, rotation, position) + + """' + i = 0 + print("outside") + for m in outside : + print(i,m) + visOptions = _vi.VisualisationOptions() + visOptions.colour = [1, 0, 0] + visOptions.alpha = 0.0 + + v.addMeshSimple(m,visOptions,name="outside_"+str(i)) + + i=i+1 + + i = 0 + print("intersection") + for m in intersection : + print(i,m) + visOptions = _vi.VisualisationOptions() + visOptions.colour = [0, 1, 0] + visOptions.alpha = 0.0 + + v.addMeshSimple(m,visOptions,name="inter_"+str(i)) + i=i+1 + + i = 0 + print("inside") + for m in inside : + print(i,m) + visOptions = _vi.VisualisationOptions() + visOptions.colour = [0, 0, 1] + visOptions.alpha = 0.0 + + v.addMeshSimple(m,visOptions,name="inside_"+str(i)) + i=i+1 + """ + + v.view(interactive=interactive) + + return reg, {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(vis=True) diff --git a/tests/geant4/T605_LvChangeSolid.py b/tests/geant4/T605_LvChangeSolid.py new file mode 100644 index 000000000..c3ebdfe3a --- /dev/null +++ b/tests/geant4/T605_LvChangeSolid.py @@ -0,0 +1,73 @@ +import os as _os +import pyg4ometry.transformation as _trans +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import numpy as _np + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", 3, 3, 3, reg, "m") + + x = 1 + ds = _g4.solid.Box("ds", x, x, x, reg, "m") + dds = _g4.solid.Box("dds", 0.2, 0.2, 0.2, reg, "m") + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + dlv = _g4.LogicalVolume(ds, wm, "dlv", reg) + ddlv = _g4.LogicalVolume(dds, bm, "ddlv", reg) + + nX = 4 + dX = x * 1000 / nX + x0 = -0.5 * x * 1000 + 0.5 * dX + for xi in [0, 1, 2, 3]: + for yi in [0, 1, 2, 3]: + pos = [x0 + xi * dX, x0 + yi * dX, 0] + _g4.PhysicalVolume( + [0, 0, 0.0], pos, ddlv, "ddpv_" + str(xi) + str(yi), dlv, reg + ) + + _g4.PhysicalVolume([0, 0, 0.0], [0, 0, 0], dlv, "dlv_pv", wl, reg) + + # now for the culling + # 800 should mean that the middle 4 out of 16 boxes remain untouched, but + # the outer 12 should be intersected + clipFW = 800 + rotation = [0, _np.pi / 4, _np.pi / 4] + rotation1 = _trans.matrix2tbxyz(_np.linalg.inv(_trans.tbxyz2matrix(rotation))) + position = [0, 0, 0] + clipBox = _g4.solid.Box("clipper", clipFW, clipFW, clipFW, reg, "mm") + + dlv.replaceSolid(clipBox, rotation=rotation, position=position) + + # set world volume + reg.setWorld(wl) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T605_LvChangeSolid.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T605_LvChangeSolid.gmad"), + "T605_LvChangeSolid.gdml", + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addSolid(clipBox, rotation1, position) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(vis=True) diff --git a/tests/geant4/T606_LvClipSolid.py b/tests/geant4/T606_LvClipSolid.py new file mode 100644 index 000000000..2c799a301 --- /dev/null +++ b/tests/geant4/T606_LvClipSolid.py @@ -0,0 +1,78 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.misc as _misc +import numpy as _np + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", 3, 3, 3, reg, "m") + + x = 1 + ds = _g4.solid.Box("ds", x, x, x, reg, "m") + dds = _g4.solid.Box("dds", 0.2, 0.2, 0.2, reg, "m") + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + dlv = _g4.LogicalVolume(ds, wm, "dlv", reg) + ddlv = _g4.LogicalVolume(dds, bm, "ddlv", reg) + + nX = 4 + dX = x * 1000 / nX + x0 = -0.5 * x * 1000 + 0.5 * dX + for xi in [0, 1, 2, 3]: + for yi in [0, 1, 2, 3]: + pos = [x0 + xi * dX, x0 + yi * dX, 0] + _g4.PhysicalVolume( + [0.1, 0.2, 0.3], pos, ddlv, "ddpv_" + str(xi) + str(yi), dlv, reg + ) + + _g4.PhysicalVolume([0, 0, 0.0], [0, 0, 0], dlv, "dlv_pv", wl, reg) + + # now for the culling + # 800 should mean that the middle 4 out of 16 boxes remain untouched, but + # the outer 12 should be intersected + clipFW = 800 + rotation = [0, 0, 0] + position = [0, 0, 0] + clipBox = _g4.solid.Box("clipper", clipFW, clipFW, clipFW, reg, "mm") + clipBoxes = _misc.NestedBoxes( + "clipper", clipFW, clipFW, clipFW, reg, "mm", 50, 50, 50, dlv.depth() + ) + + # dlv.replaceSolid(clipBox, rotation=rotation, position=position) + # dlv.clipGeometry(clipBox,(0,0,0),(0,0,0)) + print(clipBoxes) + dlv.clipGeometry(clipBoxes, rotation, position) + + # set world volume + reg.setWorld(wl) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T606_LvClipSolid.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T606_LvClipSolid.gmad"), + "T606_LvClipSolid.gdml", + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addSolid(clipBox, rotation, position) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(vis=True) diff --git a/tests/geant4/T607_LvChangeAndClipSolid.py b/tests/geant4/T607_LvChangeAndClipSolid.py new file mode 100644 index 000000000..4471927e9 --- /dev/null +++ b/tests/geant4/T607_LvChangeAndClipSolid.py @@ -0,0 +1,76 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.misc as _misc +import numpy as _np + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", 3, 3, 3, reg, "m") + + x = 1 + ds = _g4.solid.Box("ds", x, x, x, reg, "m") + dds = _g4.solid.Box("dds", 0.2, 0.2, 0.2, reg, "m") + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + dlv = _g4.LogicalVolume(ds, wm, "dlv", reg) + ddlv = _g4.LogicalVolume(dds, bm, "ddlv", reg) + + nX = 4 + dX = x * 1000 / nX + x0 = -0.5 * x * 1000 + 0.5 * dX + for xi in [0, 1, 2, 3]: + for yi in [0, 1, 2, 3]: + pos = [x0 + xi * dX, x0 + yi * dX, 0] + _g4.PhysicalVolume( + [0.1, 0.2, 0.3], pos, ddlv, "ddpv_" + str(xi) + str(yi), dlv, reg + ) + + _g4.PhysicalVolume([0, 0, 0.0], [0, 0, 0], dlv, "dlv_pv", wl, reg) + + # now for the culling + # 800 should mean that the middle 4 out of 16 boxes remain untouched, but + # the outer 12 should be intersected + clipFW = 800 + rotation = [0, _np.pi / 4.0, _np.pi / 4.0] + position = [0.4, 0.4, 0] + clipBox = _g4.solid.Box("clipper", clipFW, clipFW, clipFW, reg, "mm") + clipBoxes = _misc.NestedBoxes( + "clipper", clipFW, clipFW, clipFW, reg, "mm", 50, 50, 50, dlv.depth() + ) + + dlv.replaceSolid(clipBoxes[0], rotation=rotation, position=position, punit="m") + dlv.clipGeometry(clipBoxes, (0, 0, 0), (0, 0, 0)) + + # set world volume + reg.setWorld(wl) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T607_LvChangeAndClipSolid.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T607_LvChangeAndClipSolid.gmad"), + "T607_LvChangeAndClipSolid.gdml", + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addSolid(clipBoxes[0], rotation, position) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(vis=True) diff --git a/tests/geant4/T608_LvClipSolidRecursive.py b/tests/geant4/T608_LvClipSolidRecursive.py new file mode 100644 index 000000000..1dcf05a03 --- /dev/null +++ b/tests/geant4/T608_LvClipSolidRecursive.py @@ -0,0 +1,82 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.misc as _misc +import numpy as _np + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", 3000, 3000, 3000, reg, "mm") + + x = 1 + ds = _g4.solid.Box("ds", 1000, 1000, 1000, reg, "mm") + dds = _g4.solid.Box("dds", 200, 200, 200, reg, "mm") + ddds = _g4.solid.Box("ddds", 150, 150, 150, reg, "mm") + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + dlv = _g4.LogicalVolume(ds, wm, "dlv", reg) + ddlv = _g4.LogicalVolume(dds, bm, "ddlv", reg) + dddlv = _g4.LogicalVolume(ddds, bm, "dddlv", reg) + + _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], dddlv, "dddpv", ddlv, reg) + + nX = 4 + dX = x * 1000 / nX + x0 = -0.5 * x * 1000 + 0.5 * dX + for xi in [0, 1, 2, 3]: + for yi in [0, 1, 2, 3]: + pos = [x0 + xi * dX, x0 + yi * dX, 0] + _g4.PhysicalVolume( + [0.1, 0.2, 0.3], pos, ddlv, "ddpv_" + str(xi) + str(yi), dlv, reg + ) + + _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], dlv, "dlv_pv", wl, reg) + + # now for the culling + # 800 should mean that the middle 4 out of 16 boxes remain untouched, but + # the outer 12 should be intersected + clipFW = 800 + rotation = [0, 0, 0] + position = [0, 0, 0] + clipBox = _g4.solid.Box("clipper", clipFW, clipFW, clipFW, reg, "mm") + clipBoxes = _misc.NestedBoxes( + "clipper", clipFW, clipFW, clipFW, reg, "mm", 50, 50, 50, dlv.depth() + ) + + # dlv.replaceSolid(clipBox, rotation=rotation, position=position) + # dlv.clipGeometry(clipBox,(0,0,0),(0,0,0)) + + dlv.clipGeometry(clipBoxes, rotation, position) + + # set world volume + reg.setWorld(wl) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T608_LvClipSolidRecursive.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T608_LvClipSolidRecursive.gmad"), + "T608_LvClipSolidRecursive.gdml", + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addSolid(clipBoxes[0], rotation, position) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(vis=True) diff --git a/tests/geant4/T609_LvClipSolidRecursiveAssembly.py b/tests/geant4/T609_LvClipSolidRecursiveAssembly.py new file mode 100644 index 000000000..46b2bc704 --- /dev/null +++ b/tests/geant4/T609_LvClipSolidRecursiveAssembly.py @@ -0,0 +1,87 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi +import pyg4ometry.misc as _misc +import numpy as _np + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + wm = _g4.Material(name="G4_Galactic") + bm = _g4.Material(name="G4_W") + + # solids + ws = _g4.solid.Box("ws", 3000, 3000, 3000, reg, "mm") + + x = 1 + ds = _g4.solid.Box("ds", 1000, 1000, 1000, reg, "mm") + dds = _g4.solid.Box("dds", 200, 200, 200, reg, "mm") + ddds = _g4.solid.Box("ddds", 150, 150, 150, reg, "mm") + + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + dlv = _g4.LogicalVolume(ds, wm, "dlv", reg) + ddlv = _g4.AssemblyVolume("ddlv", reg) + dddlv = _g4.LogicalVolume(ddds, bm, "dddlv", reg) + + _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], dddlv, "dddpv", ddlv, reg) + + nX = 4 + dX = x * 1000 / nX + x0 = -0.5 * x * 1000 + 0.5 * dX + for xi in [0, 1, 2, 3]: + for yi in [0, 1, 2, 3]: + pos = [x0 + xi * dX, x0 + yi * dX, 0] + _g4.PhysicalVolume( + [0.1, 0.2, 0.3], pos, ddlv, "ddpv_" + str(xi) + str(yi), dlv, reg + ) + + _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], dlv, "dlv_pv", wl, reg) + + # now for the culling + # 800 should mean that the middle 4 out of 16 boxes remain untouched, but + # the outer 12 should be intersected + clipFW = 800 + rotation = [0, 0, 0] + position = [0, 0, 0] + clipBox = _g4.solid.Box("clipper", clipFW, clipFW, clipFW, reg, "mm") + clipBoxes = _misc.NestedBoxes( + "clipper", clipFW, clipFW, clipFW, reg, "mm", 50, 50, 50, dlv.depth() + ) + + # dlv.replaceSolid(clipBox, rotation=rotation, position=position) + # dlv.clipGeometry(clipBox,(0,0,0),(0,0,0)) + dlv.clipGeometry(clipBoxes, rotation, position) + + # set world volume + reg.setWorld(wl) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join( + _os.path.dirname(__file__), "T609_LvClipSolidRecursiveAssembly.gdml" + ) + ) + w.writeGmadTester( + _os.path.join( + _os.path.dirname(__file__), "T609_LvClipSolidRecursiveAssembly.gmad" + ), + "T608_LvClipSolidRecursiveAssembly.gdml", + ) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addSolid(clipBoxes[0], rotation, position) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(vis=True) diff --git a/tests/geant4/T700_ComparisonMaterial.py b/tests/geant4/T700_ComparisonMaterial.py new file mode 100644 index 000000000..ebd1cb22c --- /dev/null +++ b/tests/geant4/T700_ComparisonMaterial.py @@ -0,0 +1,125 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + r = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r) + + # predefined materials + comp1 = pyg4ometry.compare.materials(galactic1, galactic2, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # different predefined + iron = _g4.MaterialPredefined("G4_Fe", r) + comp2 = pyg4ometry.compare.materials(galactic1, iron, tests) + if printOut: + comp2.print() + assert len(comp2) > 0 + + # predefined vs single element + iron2 = _g4.MaterialSingleElement( + "iron", 26, 55.8452, 7.874, r + ) # iron at near room temp + comp3 = pyg4ometry.compare.materials(galactic1, iron2, tests) + if printOut: + comp3.print() + assert len(comp3) > 0 + + # single element material with itself + comp4 = pyg4ometry.compare.materials(iron2, iron2, tests) + if printOut: + comp4.print() + assert len(comp4) == 0 + + # material of elements with mass fraction + air = _g4.MaterialCompound("air", 1.290e-3, 2, r) + ne = _g4.ElementSimple("nitrogen", "N", 7, 14.01, r) + oe = _g4.ElementSimple("oxygen", "O", 8, 16.0, r) + air.add_element_massfraction(ne, 0.7) + air.add_element_massfraction(oe, 0.3) + comp5 = pyg4ometry.compare.materials(air, air, tests) + if printOut: + comp5.print() + assert len(comp5) == 0 + + comp6 = pyg4ometry.compare.materials(air, iron2, tests) + if printOut: + comp6.print() + assert len(comp6) > 0 + + # different density + air2 = _g4.MaterialCompound("air2", 1.291e-3, 2, r) + air2.add_element_massfraction(ne, 0.7) + air2.add_element_massfraction(oe, 0.3) + comp7 = pyg4ometry.compare.materials(air, air2, tests) + if printOut: + comp7.print() + assert len(comp7) > 0 + + # different mass fraction + air3 = _g4.MaterialCompound("air3", 1.291e-3, 2, r) + air3.add_element_massfraction(ne, 0.701) + air3.add_element_massfraction(oe, 0.299) + comp8 = pyg4ometry.compare.materials(air2, air3, tests) + if printOut: + comp8.print() + assert len(comp8) > 0 + + # different n components + air4 = _g4.MaterialCompound("air4", 1.291e-3, 3, r) + air4.add_element_massfraction(ne, 0.700) + air4.add_element_massfraction(oe, 0.299) + are = _g4.ElementSimple("argon", "Ar", 18, 40.0, r) + air4.add_element_massfraction(are, 0.001) + + comp9 = pyg4ometry.compare.materials(air3, air4, tests) + if printOut: + comp9.print() + assert len(comp9) > 0 + + water = _g4.MaterialCompound("water", 1.0, 2, r) + he = _g4.ElementSimple("hydrogen", "H", 1, 1.01) + oe = _g4.ElementSimple("oxygen", "O", 8, 16.0) + water.add_element_natoms(he, 2) + water.add_element_natoms(oe, 1) + + # n atoms no difference + comp10 = pyg4ometry.compare.materials(water, water, tests) + if printOut: + comp10.print() + assert len(comp10) == 0 + + # n atoms type vs fractional mass type - can't compare + comp11 = pyg4ometry.compare.materials(air3, water, tests) + if printOut: + comp11.print() + assert len(comp11) > 0 + + tests2 = pyg4ometry.compare.Tests() + tests2.materialCompositionType = False + comp11b = pyg4ometry.compare.materials(air3, water, tests2) + if printOut: + comp11b.print() + assert len(comp11) > 0 + + # n atoms difference + water2 = _g4.MaterialCompound("water2", 1.0, 2, r) + water2.add_element_natoms(he, 3) + water2.add_element_natoms(oe, 1) + comp12 = pyg4ometry.compare.materials(water, water2, tests) + if printOut: + comp12.print() + assert len(comp12) > 0 + + return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T701_ComparisonSolid.py b/tests/geant4/T701_ComparisonSolid.py new file mode 100644 index 000000000..a60ae2a92 --- /dev/null +++ b/tests/geant4/T701_ComparisonSolid.py @@ -0,0 +1,104 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + r = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + box1 = _g4.solid.Box("box1", 100, 80, 60, r) + + # solid with itself + comp1 = pyg4ometry.compare.solids(box1, box1, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + wx = pyg4ometry.gdml.Constant("wx", 10, r) + box2 = _g4.solid.Box("box2", "1*wx", 0.8 * wx, 0.6 * wx, r, lunit="cm") + + # solid with itself - using expressions + comp2 = pyg4ometry.compare.solids(box2, box2, tests) + if printOut: + comp2.print() + assert len(comp2) == 0 + + # box with numbers vs box with expressions but equivalent + # only name should be different + comp3 = pyg4ometry.compare.solids(box1, box2, tests) + if printOut: + comp3.print() + assert len(comp3) == 2 # 2 name tests + + testsNoName = pyg4ometry.compare.Tests() + testsNoName.names = False + comp4 = pyg4ometry.compare.solids( + box1, box2, testsNoName, "maintest", includeAllTestResults=True + ) + if printOut: + comp4.print() + assert len(comp4) > 0 # because we include all tests + + # test a solid where a parameter is potentially a list or not just a number + p1x = pyg4ometry.gdml.Constant("p1x", "-20", r, True) + p1y = pyg4ometry.gdml.Constant("p1y", "-20", r, True) + z1, x1, y1, s1 = -20, 5, 5, 1 + z2, x2, y2, s2 = 0, -5, -5, 1 + z3, x3, y3, s3 = 20, 0, 0, 2 + polygon = [ + [p1x, p1y], + [-20, 20], + [20, 20], + [20, 10], + [-10, 10], + [-10, 10], + [20, -10], + [20, -20], + ] + slices = [[z1, [x1, y1], s1], [z2, [x2, y2], s2], [z3, [x3, y3], s3]] + xs = _g4.solid.ExtrudedSolid("xs", polygon, slices, r) + + # complex solid with other with simple values + comp5 = pyg4ometry.compare.solids(box1, xs, tests) + if printOut: + comp5.print() + assert len(comp5) > 0 + + comp6 = pyg4ometry.compare.solids(xs, xs, tests) + if printOut: + comp6.print() + assert len(comp6) == 0 + + # one number deep inside that's slightly different + polygon2 = [ + [p1x, p1y], + [-20, 20], + [30, 20], + [20, 10], + [-10, 10], + [-10, 10], + [20, -10], + [20, -20], + ] + slices2 = [[z1, [6, y1], s1], [z2, [x2, y2], s2], [z3, [x3, y3], s3]] + xs2 = _g4.solid.ExtrudedSolid("xs2", polygon2, slices2, r) + comp7 = pyg4ometry.compare.solids(xs, xs2, tests) + if printOut: + comp7.print() + assert len(comp7) > 0 + + # different units + polygon3 = [[-2, -2], [-2, 2], [2, 2], [2, 1], [-1, 1], [-1, 1], [2, -1], [2, -2]] + slices3 = [[-2, [0.5, 0.5], 1], [0, [-0.5, -0.5], 1], [2, [0, 0], 2]] + xs3 = _g4.solid.ExtrudedSolid("xs3", polygon3, slices3, r, lunit="cm") + comp8 = pyg4ometry.compare.solids(xs, xs3, tests) + if printOut: + comp8.print() + assert len(comp8) == 2 # 2 name tests + + return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T702_ComparisonLogicalVolume.py b/tests/geant4/T702_ComparisonLogicalVolume.py new file mode 100644 index 000000000..00b64fadc --- /dev/null +++ b/tests/geant4/T702_ComparisonLogicalVolume.py @@ -0,0 +1,167 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + # make 2 copies independently so we can have degenerate names, which we couldn't + # have in just 1 registry + r1 = _g4.Registry() + r2 = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r1) + copper1 = _g4.MaterialPredefined("G4_Cu", r1) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r1) + copper2 = _g4.MaterialPredefined("G4_Cu", r2) + + # ctdeltaphi = pyg4ometry.gdml.Constant("deltaphi","2*pi",r1) + ts1 = _g4.solid.Tubs("ts", 0, 50, 100, 0, "2*pi", r1) + tl1 = _g4.LogicalVolume(ts1, copper1, "tl1_lv", r1) + ts2 = _g4.solid.Tubs("ts", 0, 50, 100, 0, "2*pi", r2) + tl2 = _g4.LogicalVolume(ts2, copper2, "tl1_lv", r2) + tl2b = _g4.LogicalVolume(ts2, galactic2, "tl1b_lv", r2) + + # same lvs + comp1 = pyg4ometry.compare.logicalVolumes(tl1, tl1, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # same lvs, different registry + comp2 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests) + if printOut: + comp2.print() + assert len(comp2) == 0 + + # different material + comp3 = pyg4ometry.compare.logicalVolumes(tl1, tl2b, tests) + if printOut: + comp3.print() + assert len(comp3) > 0 + + miniBox1 = _g4.solid.Box("mb1", 1, 2, 3, r1) + miniBox1LV = _g4.LogicalVolume(miniBox1, galactic1, "mb1_lv", r1) + miniBox2 = _g4.solid.Box("mb2", 1, 2, 3, r1) + miniBox2LV = _g4.LogicalVolume(miniBox1, galactic1, "mb2_lv", r1) + miniBox3 = _g4.solid.Box("mb3", 3, 2, 1, r1) + miniBox3LV = _g4.LogicalVolume(miniBox1, galactic1, "mb3_lv", r1) + miniBox1PV1 = _g4.PhysicalVolume( + [0, 0.1, 0], [-1, 0, -10], miniBox1LV, "mb1_pv1", tl1, r1 + ) + miniBox1PV2 = _g4.PhysicalVolume( + [0, -0.1, 0], [5, 0, 10], miniBox1LV, "mb1_pv2", tl1, r1 + ) + miniBox1PV3 = _g4.PhysicalVolume( + [0.1, -0.1, 3.14159265], + [-5, 0, 30], + miniBox1LV, + "mb1_pv3", + tl1, + r1, + copyNumber=3, + scale=[1, 1, -1], + ) + + # same daughters + comp4 = pyg4ometry.compare.logicalVolumes( + tl1, tl1, tests, recursive=True + ) # recursive = check daughter placements + if printOut: + comp4.print() + assert len(comp4) == 0 + + # make it all again in reg2 (adding "pointer" to end of lv and pv names) + miniBox12 = _g4.solid.Box("mb1", 1, 2, 3, r2) + miniBox12LV = _g4.LogicalVolume(miniBox12, galactic2, "mb1_lv0x1234567", r2) + miniBox22 = _g4.solid.Box("mb2", 1, 2, 3, r2) + miniBox22LV = _g4.LogicalVolume(miniBox12, galactic2, "mb2_lv0x1234567", r2) + miniBox32 = _g4.solid.Box("mb3", 3, 2, 1, r2) + miniBox32LV = _g4.LogicalVolume(miniBox12, galactic2, "mb3_lv0x1234567", r2) + miniBox12PV1 = _g4.PhysicalVolume( + [0, 0.1, 0], [-1, 0, -10], miniBox12LV, "mb1_pv10x1234567", tl2, r2 + ) + miniBox12PV2 = _g4.PhysicalVolume( + [0, -0.1, 0], [5, 0, 10], miniBox12LV, "mb1_pv20x1234567", tl2, r2 + ) + miniBox12PV3 = _g4.PhysicalVolume( + [0.1, -0.1, -3.14159265], + [-5, 0, 30], + miniBox12LV, + "mb1_pv30x1234567", + tl2, + r2, + copyNumber=3, + scale=[1, 1, -1], + ) + # NOTE rotation of -pi vs pi in miniBox1PV3 - it is equivalent so should not result in an error + + # same daughters + tests.names = False # disable exact name matching + comp5 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests, recursive=True) + if printOut: + comp5.print() + assert len(comp5) == 0 + + # extra placement in 2nd one now + miniBox12PV4 = _g4.PhysicalVolume( + [0, 0, 0], [-5, 0, 40], miniBox12LV, "mb1_pv4", tl2, r2 + ) + comp6 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests, recursive=True) + if printOut: + comp6.print() + assert len(comp6) > 0 + + # different copyNumber + miniBox1PV5 = _g4.PhysicalVolume( + [0, 0, 0], [0, 10, 40], miniBox1LV, "mb1_pv5", tl1, r1, copyNumber=2 + ) + miniBox12PV5 = _g4.PhysicalVolume( + [0, 0, 0], [0, 10, 40], miniBox12LV, "mb1_pv5", tl2, r2, copyNumber=3 + ) + comp7 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests, recursive=True) + if printOut: + comp7.print() + assert len(comp7.test["copyNumber"]) > 0 + + # different scale + miniBox1PV6 = _g4.PhysicalVolume( + [0, 0, 0], [0, -10, 40], miniBox1LV, "mb1_pv6", tl1, r1, scale=[1, 1, 1] + ) + miniBox12PV6 = _g4.PhysicalVolume( + [0, 0, 0], [0, -10, 40], miniBox12LV, "mb1_pv6", tl2, r2, scale=[1, 1, -1] + ) + comp8 = pyg4ometry.compare.logicalVolumes(tl1, tl2, tests, recursive=True) + if printOut: + comp8.print() + assert len(comp8.test["scale"]) > 0 + + # equivalent volume but different solids + # NOTE solids go with LogicalVolumes in pyg4ometry, not solids + r3 = _g4.Registry() + boxA = _g4.solid.Box("box_a", 10, 20, 50, r3) + boxALV = _g4.LogicalVolume(boxA, copper1, "boxA_lv", r3) + r4 = _g4.Registry() + boxB_A = _g4.solid.Box("box_b_a", 10, 30, 100, r3) + boxB_B = _g4.solid.Box("box_b_b", 10, 20, 50, r3) + boxB = _g4.solid.Intersection("box_b", boxB_A, boxB_B, [[0, 0, 0], [0, 0, 0]], r3) + boxBLV = _g4.LogicalVolume(boxB, copper1, "boxB_lv", r3) + testVolumeAreaOnly = pyg4ometry.compare.Tests("shapeVolume", "shapeArea") + comp9 = pyg4ometry.compare.logicalVolumes(boxALV, boxBLV, testVolumeAreaOnly) + if printOut: + comp9.print() + assert len(comp9) == 0 + + # update the shape of one solid and convince ourselves the area and volume checks work + boxB_B.pY = 12 + boxBLV.reMesh() + comp10 = pyg4ometry.compare.logicalVolumes(boxALV, boxBLV, testVolumeAreaOnly) + if printOut: + comp10.print() + assert len(comp10) == 2 + + return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T704_ComparisonAssemblyVolume.py b/tests/geant4/T704_ComparisonAssemblyVolume.py new file mode 100644 index 000000000..74d644b4d --- /dev/null +++ b/tests/geant4/T704_ComparisonAssemblyVolume.py @@ -0,0 +1,121 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + r = _g4.Registry() + + # in all of these we force testsAlreadyDone=[] as an argument to reset + # the one 'definition' of it in python. We have to be careful with this + # trick for pass by reference-like arguments + + # we use successive new registries for a mish-mash of bits (not caring about writing out) + # so we can have degenerate names - the comparison doesn't care - it just looks at parameters + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r) + + # predefined materials + comp1 = pyg4ometry.compare.materials(galactic1, galactic2, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # some geometry + a_a_solid = _g4.solid.Box("a_a_solid", 50, 40, 30, r) + a_b_solid = _g4.solid.Tubs("a_b_solid", 0, 12, 30, 0, "2*pi", r) + iron = _g4.MaterialPredefined("G4_Fe") + copper = _g4.MaterialPredefined("G4_Cu") + a_a_lv = _g4.LogicalVolume(a_a_solid, copper, "a_a_lv", r) + a_b_lv = _g4.LogicalVolume(a_b_solid, copper, "a_b_lv", r) + a_ass = _g4.AssemblyVolume("a_assembly", r) + a_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_a_pv1", a_ass, r) + a_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", a_ass, r) + + # with itself + comp2 = pyg4ometry.compare.assemblyVolumes(a_ass, a_ass, tests, testsAlreadyDone=[]) + if printOut: + comp2.print() + assert len(comp2) == 0 + + # missing daughter + r2 = _g4.Registry() + b_ass = _g4.AssemblyVolume("a_assembly", r2) + b_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_a_pv1", b_ass, r2) + comp3 = pyg4ometry.compare.assemblyVolumes(a_ass, b_ass, tests, testsAlreadyDone=[]) + if printOut: + comp3.print() + assert len(comp3) == 2 + + # extra daughter + r3 = _g4.Registry() + c_ass = _g4.AssemblyVolume("a_assembly", r3) + c_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_a_pv1", c_ass, r3) + c_b1_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", c_ass, r3) + c_b2_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], a_b_lv, "a_b_pv2", c_ass, r3) + comp4 = pyg4ometry.compare.assemblyVolumes(a_ass, c_ass, tests, testsAlreadyDone=[]) + if printOut: + comp4.print() + assert len(comp4) == 2 + + # different daughter by name + r4 = _g4.Registry() + d_ass = _g4.AssemblyVolume("a_assembly", r4) + d_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_aaaa_pv1", d_ass, r4) + d_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", d_ass, r4) + comp5 = pyg4ometry.compare.assemblyVolumes(a_ass, d_ass, tests, testsAlreadyDone=[]) + if printOut: + comp5.print() + assert len(comp5) == 2 # both missing and extra + + # different values of pvs + r5 = _g4.Registry() + e_ass = _g4.AssemblyVolume("a_assembly", r5) + e_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, -100], a_a_lv, "a_a_pv1", e_ass, r5) + e_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", e_ass, r5) + comp6 = pyg4ometry.compare.assemblyVolumes(a_ass, e_ass, tests, testsAlreadyDone=[]) + if printOut: + comp6.print() + assert ( + len(comp6) == 3 + ) # 1 pv pos fail, 1x bounding box min fail, 1x bounding box max fail + + # different values of lv material inside pvs inside avs + r6 = _g4.Registry() + f_ass = _g4.AssemblyVolume("a_assembly", r6) + a_b_lv = _g4.LogicalVolume(a_b_solid, iron, "a_b_lv", r6) + f_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], a_a_lv, "a_a_pv1", f_ass, r6) + f_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", f_ass, r6) + comp7 = pyg4ometry.compare.assemblyVolumes(a_ass, f_ass, tests, testsAlreadyDone=[]) + if printOut: + comp7.print() + assert len(comp7) == 3 # materialName, materialNameIgnorePointer materialNameNIST + + # mesh volume / area testing + r7 = _g4.Registry() + # should be equivalent to a_a_solid = _g4.solid.Box("a_a_solid", 50, 40, 30, r) + c_a_solidA = _g4.solid.Box("c_a_solidA", 80, 40, 30, r7) + c_a_solidB = _g4.solid.Box("c_a_solidB", 50, 90, 30, r7) + c_a_solid = _g4.solid.Intersection( + "c_a_solid", c_a_solidA, c_a_solidB, [[0, 0, 0], [0, 0, 0]], r7 + ) + c_a_lv = _g4.LogicalVolume(c_a_solid, copper, "c_a_lv", r7) + g_ass = _g4.AssemblyVolume("a_assembly", r7) + a_a_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 100], c_a_lv, "a_a_pv1", g_ass, r7) + a_b_pv = _g4.PhysicalVolume([0, 0, 0], [0, 0, 50], a_b_lv, "a_b_pv1", g_ass, r7) + testVolumeAreaOnly = pyg4ometry.compare.Tests("shapeVolume", "shapeArea") + assert len(testVolumeAreaOnly) == 2 + comp8 = pyg4ometry.compare.assemblyVolumes( + a_ass, g_ass, testVolumeAreaOnly, testsAlreadyDone=[] + ) + if printOut: + comp8.print() + assert len(comp8) == 0 + + return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T705_ComparisonReplicaVolume.py b/tests/geant4/T705_ComparisonReplicaVolume.py new file mode 100644 index 000000000..b32017f2e --- /dev/null +++ b/tests/geant4/T705_ComparisonReplicaVolume.py @@ -0,0 +1,48 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + r = _g4.Registry() + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + ws = _g4.solid.Box("ws", 1000, 1000, 1000, r) + bs = _g4.solid.Box("bs", 100, 100, 100, r) + mbs = _g4.solid.Box("mbs", 800, 100, 100, r) + wl = _g4.LogicalVolume(ws, wm, "wl", r) + bl = _g4.LogicalVolume(bs, bm, "bl", r) + ml = _g4.LogicalVolume(mbs, wm, "ml", r) + mbl = _g4.ReplicaVolume("mbl", bl, ml, _g4.ReplicaVolume.Axis.kXAxis, 8, 100, 0, r) + + tests = pyg4ometry.compare.Tests() + + comp1 = pyg4ometry.compare.replicaVolumes(mbl, mbl, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # different number of replicas + r2 = _g4.Registry() + mbl2 = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kXAxis, 7, 100, 0, r2 + ) + comp2 = pyg4ometry.compare.replicaVolumes(mbl, mbl2, tests) + if printOut: + comp2.print() + assert len(comp2) == 1 + + # different axis + r3 = _g4.Registry() + mbl3 = _g4.ReplicaVolume( + "mbl", bl, ml, _g4.ReplicaVolume.Axis.kYAxis, 8, 100, 0, r3 + ) + comp3 = pyg4ometry.compare.replicaVolumes(mbl, mbl3, tests) + if printOut: + comp3.print() + assert len(comp3) == 1 + + return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T706_ComparisonDivisionVolume.py b/tests/geant4/T706_ComparisonDivisionVolume.py new file mode 100644 index 000000000..fd9a26023 --- /dev/null +++ b/tests/geant4/T706_ComparisonDivisionVolume.py @@ -0,0 +1,25 @@ +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + r = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r) + + # predefined materials + comp1 = pyg4ometry.compare.materials(galactic1, galactic2, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # TBC + + return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T707_ComparisonParameterisedVolume.py b/tests/geant4/T707_ComparisonParameterisedVolume.py new file mode 100644 index 000000000..8638f3c1f --- /dev/null +++ b/tests/geant4/T707_ComparisonParameterisedVolume.py @@ -0,0 +1,26 @@ +import os as _os +import pyg4ometry +import pyg4ometry.geant4 as _g4 + + +def Test(printOut=False): + r = _g4.Registry() + + tests = pyg4ometry.compare.Tests() + + galactic1 = _g4.MaterialPredefined("G4_Galactic", r) + galactic2 = _g4.MaterialPredefined("G4_Galactic", r) + + # predefined materials + comp1 = pyg4ometry.compare.materials(galactic1, galactic2, tests) + if printOut: + comp1.print() + assert len(comp1) == 0 + + # TBC + + return {"teststatus": True} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T720_featureExtract.py b/tests/geant4/T720_featureExtract.py new file mode 100644 index 000000000..02bf7400c --- /dev/null +++ b/tests/geant4/T720_featureExtract.py @@ -0,0 +1,23 @@ +import pyg4ometry as _pyg4 +import os as _os + + +def Test(vis=False, interactive=False): + pathToStl = _os.path.dirname(_pyg4.__file__) + "/../../test/stl/ST0372507_01_a.stl" + cs1 = _pyg4.features.algos.CoordinateSystem([0, 0, 0], [1, 0, 0], [0, 1, 0]) + cs2 = _pyg4.features.algos.CoordinateSystem([0, 0, 20], [1, 0, 0], [0, 1, 0]) + r = _pyg4.features.extract( + pathToStl, + planes=[], + outputFileName=_os.path.join( + _os.path.dirname(__file__), "T720_featureExtract.dat" + ), + bViewer=vis, + bViewerInteractive=interactive, + ) + + return True + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T721_featureExtract_cutTubs.py b/tests/geant4/T721_featureExtract_cutTubs.py new file mode 100644 index 000000000..04f0dec0b --- /dev/null +++ b/tests/geant4/T721_featureExtract_cutTubs.py @@ -0,0 +1,82 @@ +import pyg4ometry as _pyg4 +import os as _os +import numpy as _np + + +def Test(vis=False, interactive=False): + reg = _pyg4.geant4.Registry() + radius1 = 7 + radius2 = 9 + theta = 0.1 + rho = 500 + + s = theta * rho + d = _np.sin(theta / 2.0) * rho * 2 + + n1 = [_np.cos(_np.pi / 2 - theta / 2.0), 0, -_np.sin(_np.pi / 2 - theta / 2.0)] + n2 = [_np.cos(_np.pi / 2 - theta / 2.0), 0, _np.sin(_np.pi / 2 - theta / 2.0)] + + t = _pyg4.geant4.solid.CutTubs( + "t1", radius1, radius2, d, 0, 2 * _np.pi, n1, n2, reg + ) + + stlFileName = _os.path.join( + _os.path.dirname(__file__), "T721_featureExtract_cutTubs.stl" + ) + datFileName = stlFileName.replace("stl", "dat") + _pyg4.convert.pycsgMeshToStl(t.mesh(), stlFileName) + + p1 = _pyg4.features.algos.Plane([0, 0, 0], [0, 0, 1]) + v = _pyg4.features.extract( + stlFileName, + angle=46, + circumference=2 * _np.pi * 8, + planes=[], + outputFileName=datFileName, + bViewer=vis, + bViewerInteractive=interactive, + ) + + fd = _pyg4.features.algos.FeatureData() + fd.readFile(datFileName) + + p1 = fd.features[2]["plane"] + p2 = fd.features[3]["plane"] + + pp1 = _pyg4.features.Plane(p1[0:3], p1[3:]) + pp2 = _pyg4.features.Plane(p2[0:3], p2[3:]) + pp3 = _pyg4.features.Plane([0, 0, 0], [0, 1, 0]) + + cs = _pyg4.features.CoordinateSystem() + cs.makeFromPlanes(pp1, pp2, pp3) + + cs1 = cs.coordinateSystem(0, 0.01, 0) + cs2 = cs.coordinateSystem(0, 0.02, 0) + cs3 = cs.coordinateSystem(0, 0.03, 0) + cs4 = cs.coordinateSystem(0, 0.04, 0) + + if v is None: + return True + + v.addPlane(cs.origin, cs.e1, cs.e2, cs.dist) + v.addPlane(cs.origin, cs1.e1, cs1.e2, cs.dist) + v.addAxis( + cs.origin, [cs.dist, cs.dist, cs.dist], cs.rot, label=True, disableCone=True + ) + v.view(interactive=interactive) + + v = _pyg4.features.extract( + stlFileName, + angle=46, + circumference=2 * _np.pi * 8, + planes=[cs1, cs2, cs3, cs4], + outputFileName=datFileName, + bViewer=vis, + bViewerInteractive=interactive, + ) + + return True + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/T800_physical_logical_units.py b/tests/geant4/T800_physical_logical_units.py new file mode 100644 index 000000000..6c2b4ba06 --- /dev/null +++ b/tests/geant4/T800_physical_logical_units.py @@ -0,0 +1,85 @@ +import os as _os +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False): + reg = _g4.Registry() + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + bx = _gd.Constant("bx", "10", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + bm = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + bs = _g4.solid.Box("bs", bx, bx, bx, reg, "mm") + rs = _g4.solid.Box("rs", 3 * bx, bx, bx, reg, "mm") + ls = _g4.solid.Box("ls", 3 * bx, 3 * bx, bx, reg, "mm") + cs = _g4.solid.Box("cs", 3 * bx, 3 * bx, 3 * bx, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + + bl = _g4.LogicalVolume(bs, bm, "bl", reg) + rl = _g4.LogicalVolume(rs, wm, "rl", reg) + ll = _g4.LogicalVolume(ls, wm, "ll", reg) + cl = _g4.LogicalVolume(cs, wm, "cl", reg) + + bp1 = _g4.PhysicalVolume([0, 0, 0, "rad"], [-bx, 0, 0, "mm"], bl, "b_pv1", rl, reg) + bp2 = _g4.PhysicalVolume([0, 0, 0, "mrad"], [0, 0, 0, "m"], bl, "b_pv2", rl, reg) + bp3 = _g4.PhysicalVolume([0, 0, 0, "urad"], [bx, 0, 0, "mm"], bl, "b_pv3", rl, reg) + + rp1 = _g4.PhysicalVolume( + [0, 0, 0, "rad"], [0, -bx / 3, 0, "cm"], rl, "r_pv1", ll, reg + ) + rp2 = _g4.PhysicalVolume([0, 0, 0, "mrad"], [0, 0, 0, "um"], rl, "r_pv2", ll, reg) + rp3 = _g4.PhysicalVolume( + [100, 0, 0, "urad"], [0, bx, 0, "mm"], rl, "r_pv3", ll, reg + ) + + lp1 = _g4.PhysicalVolume([0, 0, 0, "rad"], [0, 0, -bx, "mm"], ll, "l_pv1", cl, reg) + lp2 = _g4.PhysicalVolume([0, 0, 0, "mrad"], [0, 0, 0, "um"], ll, "l_pv2", cl, reg) + lp3 = _g4.PhysicalVolume([0, 0, 0, "urad"], [0, 0, bx, "mm"], ll, "l_pv3", cl, reg) + + cp1 = _g4.PhysicalVolume([0, 0, 0, "rad"], [0, 0, 0, "mm"], cl, "c_pv1", wl, reg) + + # check for overlaps + wl.checkOverlaps(True, True, False) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write( + _os.path.join(_os.path.dirname(__file__), "T800_physical_logical_units.gdml") + ) + + # test __repr__ + str(bl) + str(bp1) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test(1, 1) diff --git a/tests/geant4/T900_global_settings.py b/tests/geant4/T900_global_settings.py new file mode 100644 index 000000000..2419517d2 --- /dev/null +++ b/tests/geant4/T900_global_settings.py @@ -0,0 +1,69 @@ +import os as _os + +import pyg4ometry.config as _config +import pyg4ometry.gdml as _gd +import pyg4ometry.geant4 as _g4 +import pyg4ometry.visualisation as _vi + + +def Test(vis=False, interactive=False, n_slice=16, n_stack=16): + reg = _g4.Registry() + + # Set the default mesh density (both nstack and nslice) to the same value + # for all curved solids. The global default value must be set before any of the + # solid constructors are called. + _config.setGlobalMeshSliceAndStack(n_slice) + + # nstack and nslice can be set individually for one solid via: + _config.SolidDefaults.Orb.nslice = 40 + + # defines + wx = _gd.Constant("wx", "100", reg, True) + wy = _gd.Constant("wy", "100", reg, True) + wz = _gd.Constant("wz", "100", reg, True) + + ormax = _gd.Constant("rmax", "10", reg, True) + + wm = _g4.MaterialPredefined("G4_Galactic") + om = _g4.MaterialPredefined("G4_Fe") + + # solids + ws = _g4.solid.Box("ws", wx, wy, wz, reg, "mm") + os = _g4.solid.Orb("os", ormax, reg, "mm") + + # structure + wl = _g4.LogicalVolume(ws, wm, "wl", reg) + ol = _g4.LogicalVolume(os, om, "ol", reg) + op = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], ol, "o_pv1", wl, reg) + + # set world volume + reg.setWorld(wl.name) + + # gdml output + w = _gd.Writer() + w.addDetector(reg) + w.write(_os.path.join(_os.path.dirname(__file__), "T009_Orb.gdml")) + w.writeGmadTester( + _os.path.join(_os.path.dirname(__file__), "T009_Orb.gmad"), "T009_Orb.gdml" + ) + + # test __repr__ + str(os) + + # test extent of physical volume + extentBB = wl.extent(includeBoundingSolid=True) + extent = wl.extent(includeBoundingSolid=False) + + # visualisation + v = None + if vis: + v = _vi.VtkViewer() + v.addLogicalVolume(reg.getWorldVolume()) + v.addAxes(_vi.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + + return {"testStatus": True, "logicalVolume": wl, "vtkViewer": v} + + +if __name__ == "__main__": + Test() diff --git a/tests/geant4/__init__.py b/tests/geant4/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/geant4/fixture_geant4solids.py b/tests/geant4/fixture_geant4solids.py new file mode 100644 index 000000000..2cb182640 --- /dev/null +++ b/tests/geant4/fixture_geant4solids.py @@ -0,0 +1,289 @@ +import pytest +import pyg4ometry.geant4 as _g4 +import pyg4ometry.gdml as _gd + + +@pytest.fixture() +def registry(): + return _g4.Registry() + + +@pytest.fixture() +def two_materials(registry): + def _two_materials(nist_materials=False): + if nist_materials: + wm = _g4.nist_material_2geant4Material("G4_Galactic", registry) + sm = _g4.nist_material_2geant4Material("G4_Au", registry) + else: + wm = _g4.MaterialPredefined("G4_Galactic") + sm = _g4.MaterialPredefined("G4_Au") + + return {"wm": wm, "sm": sm} + + return _two_materials + + +@pytest.fixture() +def geant4_world(registry): + wx = _gd.Constant("wx", "100", registry, True) + wy = _gd.Constant("wy", "100", registry, True) + wz = _gd.Constant("wz", "100", registry, True) + + ws = _g4.solid.Box("ws", wx, wy, wz, registry, "mm") + + return ws + + +@pytest.fixture() +def geant4_box(registry): + bx = _gd.Constant("bx", "10", registry, True) + by = _gd.Constant("by", "10", registry, True) + bz = _gd.Constant("bz", "10", registry, True) + + bs = _g4.solid.Box("bs", bx, by, bz, registry, "mm") + + return bs + + +@pytest.fixture() +def geant4_tubs(registry): + trmin = _gd.Constant("trmin", "2.5", registry, True) + trmax = _gd.Constant("trmax", "10.0", registry, True) + tz = _gd.Constant("tz", "50", registry, True) + tstartphi = _gd.Constant("startphi", "0", registry, True) + tdeltaphi = _gd.Constant("deltaphi", "1.5*pi", registry, True) + + tstartphi_deg = _gd.Constant("startphi_deg", "0", registry, True) + tdeltaphi_deg = _gd.Constant("deltaphi_deg", "270", registry, True) + + ts = _g4.solid.Tubs( + "ts", trmin, trmax, tz, tstartphi, tdeltaphi, registry, "mm", "rad", nslice=16 + ) + + return ts + + +@pytest.fixture() +def geant4_cuttubs(registry): + ctrmin = _gd.Constant("trmin", "2.5", registry, True) + ctrmax = _gd.Constant("trmax", "10.0", registry, True) + ctz = _gd.Constant("tz", "50", registry, True) + ctstartphi = _gd.Constant("startphi", "0", registry, True) + ctdeltaphi = _gd.Constant("deltaphi", "1.5*pi", registry, True) + ctlowx = _gd.Constant("ctlowx", "-1", registry, True) + ctlowy = _gd.Constant("ctlowy", "-1", registry, True) + ctlowz = _gd.Constant("ctlowz", "-1", registry, True) + cthighx = _gd.Constant("cthighx", "1", registry, True) + cthighy = _gd.Constant("cthighy", "1", registry, True) + cthighz = _gd.Constant("cthighz", "1", registry, True) + + cts = _g4.solid.CutTubs( + "ts", + ctrmin, + ctrmax, + ctz, + ctstartphi, + ctdeltaphi, + [ctlowx, ctlowy, ctlowz], + [cthighx, cthighy, cthighz], + registry, + "mm", + "rad", + nslice=16, + ) + return cts + + +@pytest.fixture() +def geant4_cons(registry): + crmin1 = _gd.Constant("crmin1", "6", registry, True) + crmax1 = _gd.Constant("crmax1", "20", registry, True) + crmin2 = _gd.Constant("crmin2", "5", registry, True) + crmax2 = _gd.Constant("crmax2", "10", registry, True) + cz = _gd.Constant("cz", "100", registry, True) + cdp = _gd.Constant("cdp", "1.5*pi", registry, True) + zero = _gd.Constant("zero", "0.0", registry, False) + + cdp_deg = _gd.Constant("cdp_deg", "270", registry, True) + + cs = _g4.solid.Cons( + "cs", + crmin1, + crmax1, + crmin2, + crmax2, + cz, + zero, + cdp, + registry, + "mm", + "rad", + nslice=16, + ) + + return cs + + +@pytest.fixture() +def geant4_para(registry): + px = _gd.Constant("px", "10", registry, True) + py = _gd.Constant("py", "20", registry, True) + pz = _gd.Constant("pz", "30", registry, True) + pAlpha = _gd.Constant("pAlpha", "0.2", registry, True) + pTheta = _gd.Constant("pTheta", "0.3", registry, True) + pPhi = _gd.Constant("pPhi", "0.4", registry, True) + + pAlpha_deg = _gd.Constant("pAlpha_deg", "0.2/pi*180", registry, True) + pTheta_deg = _gd.Constant("pTheta_deg", "0.3/pi*180", registry, True) + pPhi_deg = _gd.Constant("pPhi_deg", "0.4/pi*180", registry, True) + + ps = _g4.solid.Para("ps", px, py, pz, pAlpha, pTheta, pPhi, registry, "mm", "rad") + + return ps + + +@pytest.fixture() +def geant4_trd(registry): + tx1 = _gd.Constant("tx1", "20", registry, True) + ty1 = _gd.Constant("ty1", "25", registry, True) + tx2 = _gd.Constant("tx2", "5", registry, True) + ty2 = _gd.Constant("ty2", "7.5", registry, True) + tz = _gd.Constant("tz", "10.0", registry, True) + + ts = _g4.solid.Trd("ts", tx1, tx2, ty1, ty2, tz, registry, "mm") + + return ts + + +@pytest.fixture() +def geant4_trap(registry): + tx1 = _gd.Constant("tx1", "5", registry, True) + tx2 = _gd.Constant("tx2", "5", registry, True) + tx3 = _gd.Constant("tx3", "10", registry, True) + tx4 = _gd.Constant("tx4", "10", registry, True) + + ty1 = _gd.Constant("ty1", "5", registry, True) + ty2 = _gd.Constant("ty2", "7.5", registry, True) + + tz = _gd.Constant("tz", "10.0", registry, True) + + ttheta = _gd.Constant("ttheta", "0.6", registry, True) + tphi = _gd.Constant("tphi", "0.0", registry, True) + talp1 = _gd.Constant("talp1", "0.0", registry, True) + talp2 = _gd.Constant("talp2", "0.0", registry, True) + + ttheta_deg = _gd.Constant("ttheta_deg", "0.6/pi*180", registry, True) + tphi_deg = _gd.Constant("tphi_deg", "0.0", registry, True) + talp1_deg = _gd.Constant("talp1_deg", "0.0", registry, True) + talp2_deg = _gd.Constant("talp2_deg", "0.0", registry, True) + + ts = _g4.solid.Trap( + "ts", + tz, + ttheta, + tphi, + ty1, + tx1, + tx2, + talp1, + ty2, + tx3, + tx4, + talp2, + registry, + "mm", + "rad", + ) + + return ts + + +@pytest.fixture() +def geant4_sphere(registry): + srmin = _gd.Constant("rmin", "8", registry, True) + srmax = _gd.Constant("rmax", "10", registry, True) + ssphi = _gd.Constant("sphi", "0", registry, True) + sdphi = _gd.Constant("dphi", "1.75*pi", registry, True) + sstheta = _gd.Constant("stheta", "0", registry, True) + sdtheta = _gd.Constant("dtheta", "0.75*pi", registry, True) + + ss = _g4.solid.Sphere( + "ss", + srmin, + srmax, + ssphi, + sdphi, + sstheta, + sdtheta, + registry, + "mm", + "rad", + nslice=16, + nstack=16, + ) + + return ss + + +@pytest.fixture() +def geant4_structure(): + def _geant4_structure(solid, registry, two_materials, geant4_world): + wl = _g4.LogicalVolume(geant4_world, two_materials()["wm"], "wl", registry) + sl = _g4.LogicalVolume(solid, two_materials()["sm"], "sl", registry) + sp = _g4.PhysicalVolume([0, 0, 0], [0, 0, 0], sl, "spv1", wl, registry) + + # set world volume + registry.setWorld(wl.name) + + return registry + + return _geant4_structure + + +def test_geant4_box( + geant4_box, registry, two_materials, geant4_world, geant4_structure +): + reg = geant4_structure(geant4_box, registry, two_materials, geant4_world) + # vertex count, poly count, area, volume, minEdge, maxEdge + + +def test_geant4_tubs( + geant4_tubs, registry, two_materials, geant4_world, geant4_structure +): + reg = geant4_structure(geant4_tubs, registry, two_materials, geant4_world) + + +def test_geant4_cuttubs( + geant4_cuttubs, registry, two_materials, geant4_world, geant4_structure +): + reg = geant4_structure(geant4_cuttubs, registry, two_materials, geant4_world) + + +def test_geant4_cons( + geant4_cons, registry, two_materials, geant4_world, geant4_structure +): + reg = geant4_structure(geant4_cons, registry, two_materials, geant4_world) + + +def test_geant4_para( + geant4_para, registry, two_materials, geant4_world, geant4_structure +): + reg = geant4_structure(geant4_para, registry, two_materials, geant4_world) + + +def test_geant4_trd( + geant4_trd, registry, two_materials, geant4_world, geant4_structure +): + reg = geant4_structure(geant4_trd, registry, two_materials, geant4_world) + + +def test_geant4_trap( + geant4_trap, registry, two_materials, geant4_world, geant4_structure +): + reg = geant4_structure(geant4_trap, registry, two_materials, geant4_world) + + +def test_geant4_sphere( + geant4_sphere, registry, two_materials, geant4_world, geant4_structure +): + reg = geant4_structure(geant4_sphere, registry, two_materials, geant4_world) diff --git a/tests/geant4/test_geant4.py b/tests/geant4/test_geant4.py new file mode 100644 index 000000000..d6fc7ba59 --- /dev/null +++ b/tests/geant4/test_geant4.py @@ -0,0 +1,391 @@ +import numpy as _np +import pytest + +import pyg4ometry.transformation as _trans +from pyg4ometry.geant4.solid import TwoVector + + +# ############################# +# solid two vector +# ############################# +def test_Python_TwoVector_T001Constructor(): + v = TwoVector(1, 2) + + +def test_Python_TwoVector_T002Repr(): + v = TwoVector(1, 2) + s = str(v) + + +def test_Python_TwoVector_T003GetItem(): + v = TwoVector(1, 2) + assert v[0] == 1 + assert v[1] == 2 + try: + print(v[2]) + except IndexError: + pass + + +def test_Python_TwoVector_T004Add(): + v1 = TwoVector(1, 2) + v2 = TwoVector(3, 4) + + i = 5 + f = 6.0 + s = "r" + + assert (v1 + v2)[0] == 4 + assert (v1 + v2)[1] == 6 + + assert (v1 + i)[0] == 6 + assert (v1 + i)[1] == 7 + + assert (v1 + f)[0] == 7.0 + assert (v1 + f)[1] == 8.0 + + try: + v1 + s + except ValueError: + pass + + +def test_Python_TwoVector_T005Sub(): + v1 = TwoVector(1, 2) + v2 = TwoVector(3, 4) + + i = 5 + f = 6.0 + s = "r" + + assert (v1 - v2)[0] == -2 + assert (v1 - v2)[1] == -2 + + assert (v1 - i)[0] == -4 + assert (v1 - i)[1] == -3 + + assert (v1 - f)[0] == -5.0 + assert (v1 - f)[1] == -4.0 + + try: + v1 - s + except ValueError: + pass + + +def test_Python_TwoVector_T006Mul(): + v1 = TwoVector(1, 2) + + f = 5 + s = "r" + + assert (v1 * f)[0] == 5 + assert (v1 * f)[1] == 10 + + try: + vv = v1 * s + except ValueError: + pass + + +# ############################# +# Transformation +# ############################# +def test_Python_Rad2Deg(): + assert _trans.rad2deg(_np.pi) == 180 + + +def test_Python_Deg2Rad(): + assert _trans.deg2rad(180) == _np.pi + + +def test_Python_Tbxyz2axisangleX(): + assert _trans.tbxyz2axisangle([_np.pi / 2.0, 0.0, 0.0]) == [ + [1.0, 0.0, 0.0], + 1.5707963267948966, + ] + + +def test_Python_Tbxyz2axisangleY(): + assert _trans.tbxyz2axisangle([0.0, _np.pi / 2.0, 0.0]) == [ + [0.0, 1.0, 0.0], + 1.5707963267948966, + ] + + +def test_Python_Tbxyz2axisangleZ(): + assert _trans.tbxyz2axisangle([0.0, 0.0, _np.pi / 2.0]) == [ + [0.0, 0.0, 1.0], + 1.5707963267948966, + ] + + +def test_Python_Matrix2axisangleX(): + theta = 0.5 + m = _np.array( + [ + [1, 0, 0], + [0, _np.cos(theta), -_np.sin(theta)], + [0, _np.sin(theta), _np.cos(theta)], + ] + ) + aa = _trans.matrix2axisangle(m) + assert pytest.approx(aa[0]) == [1.0, 0.0, 0.0] + assert pytest.approx(aa[1]) == 0.5 + + +def test_Python_Matrix2axisangleY(): + theta = 0.5 + m = _np.array( + [ + [_np.cos(theta), 0, -_np.sin(theta)], + [0, 1, 0], + [_np.sin(theta), 0, _np.cos(theta)], + ] + ) + aa = _trans.matrix2axisangle(m) + assert pytest.approx(aa[0]) == [0.0, -1.0, 0.0] + assert pytest.approx(aa[1]) == 0.5 + + +def test_Python_Matrix2axisangleZ(): + theta = 0.5 + m = _np.array( + [ + [_np.cos(theta), -_np.sin(theta), 0], + [_np.sin(theta), _np.cos(theta), 0], + [0, 0, 1], + ] + ) + aa = _trans.matrix2axisangle(m) + assert pytest.approx(aa[0]) == [0.0, 0.0, 1.0] + assert pytest.approx(aa[1]) == 0.5 + + +def test_Python_Axisangle2matrixX(): + print(_trans.axisangle2matrix([1.0, 0, 0], _np.pi / 2.0)) + + +def test_Python_Axisangle2matrixY(): + print(_trans.axisangle2matrix([0, 1, 0], _np.pi / 2.0)) + + +def test_Python_Axisangle2matrixZ(): + print(_trans.axisangle2matrix([0, 0, 1], _np.pi / 2.0)) + + +def test_Python_Matrix2tbxyz(): + pass + + +def test_Python_Tbxyz2matrix(): + pass + + +def test_Python_Matrix_MatrixFromTo(): + print(_trans.matrix_from([0, 0, 1], [0, 1, 0])) + + +# ############################# +# Freecad +# ############################# +def test_Python_FreeCadImportFail(): + import sys + + # remove freecad + for p in sys.path: + if p.find("freecad") != -1: + sys.path.remove(p) + + import pyg4ometry.freecad + + +# ############################# +# Mesh +# ############################# + + +# ############################# +# CSG +# ############################# + + +def test_Python_GetLocalMesh(): + import pyg4ometry + + reg = pyg4ometry.geant4.Registry() + s1 = pyg4ometry.geant4.solid.Box("s1", 10, 10, 10, reg, "mm") + l1 = pyg4ometry.geant4.LogicalVolume(s1, "G4_Galactic", "l1", reg) + l1.mesh.getLocalMesh() + + +def test_Python_Remesh(): + import pyg4ometry + + reg = pyg4ometry.geant4.Registry() + s1 = pyg4ometry.geant4.solid.Box("s1", 10, 10, 10, reg, "mm") + l1 = pyg4ometry.geant4.LogicalVolume(s1, "G4_Galactic", "l1", reg) + l1.mesh.remesh() + + +def test_Python_ExceptionNullMeshErrorIntersection(): + import pyg4ometry + + try: + reg = pyg4ometry.geant4.Registry() + s1 = pyg4ometry.geant4.solid.Box("s1", 10, 10, 10, reg, "mm") + s2 = pyg4ometry.geant4.solid.Box("s2", 10, 10, 10, reg, "mm") + + inter = pyg4ometry.geant4.solid.Intersection( + "inter", s1, s2, [[0, 0, 0], [0, 0, 0]], reg + ) + raise pyg4ometry.exceptions.NullMeshError(inter) + except pyg4ometry.exceptions.NullMeshError: + pass + + +def test_Python_ExceptionNullMeshErrorSubtraction(): + import pyg4ometry + + try: + reg = pyg4ometry.geant4.Registry() + s1 = pyg4ometry.geant4.solid.Box("s1", 10, 10, 10, reg, "mm") + s2 = pyg4ometry.geant4.solid.Box("s2", 10, 10, 10, reg, "mm") + + subtra = pyg4ometry.geant4.solid.Subtraction( + "subtra", s1, s2, [[0, 0, 0], [0, 0, 0]], reg + ) + raise pyg4ometry.exceptions.NullMeshError(subtra) + except pyg4ometry.exceptions.NullMeshError: + pass + + +def test_Python_ExceptionNullMeshErrorOtherSolid(): + import pyg4ometry + + try: + reg = pyg4ometry.geant4.Registry() + s1 = pyg4ometry.geant4.solid.Box("s1", 10, 10, 10, reg, "mm") + raise pyg4ometry.exceptions.NullMeshError(s1) + except pyg4ometry.exceptions.NullMeshError: + pass + + +def test_Python_ExceptionNullMeshErrorBasestring(): + import pyg4ometry + + try: + msg = "s1" + raise pyg4ometry.exceptions.NullMeshError(msg) + except pyg4ometry.exceptions.NullMeshError: + pass + + +def test_Python_ExceptionIdenticalNameError(): + import pyg4ometry + + try: + msg = "solid_name" + raise pyg4ometry.exceptions.IdenticalNameError(msg) + except pyg4ometry.exceptions.IdenticalNameError: + pass + + try: + msg = "solid_name" + raise pyg4ometry.exceptions.IdenticalNameError(msg, "solid") + except pyg4ometry.exceptions.IdenticalNameError: + pass + + +############################## +# VtkVisualisation +############################## + + +def test_Python_VisualisationVtk_setOpacity(simple_box): + r = simple_box + v = r["vtkViewer"] + if v is not None: + v.setOpacity(0, 0) + v.setOpacity(0.5, -1) + + +def test_Python_VisualisationVtk_setWireframe(simple_box): + r = simple_box + v = r["vtkViewer"] + if v is not None: + v.setWireframe() + + +def test_Python_VisualisationVtk_setSurface(simple_box): + r = simple_box + v = r["vtkViewer"] + if v is not None: + v.setSurface() + + +def test_Python_VisualisationVtk_setWireframe_VisualisationOptions(simple_box): + import pyg4ometry.visualisation.VtkViewer + + r = simple_box + lv = r["logicalVolume"] + dv = lv.daughterVolumes[0] + dv.visOptions.representation = "wireframe" + + v = pyg4ometry.visualisation.VtkViewer() + v.addLogicalVolume(lv) + # v.view(interactive=False) + + +def test_Python_VisualisationVtk_setOpacityOverlap(simple_box): + r = simple_box + v = r["vtkViewer"] + if v is not None: + v.setOpacityOverlap(0) + + +def test_Python_VisualisationVtk_setWireframeOverlap(simple_box): + r = simple_box + v = r["vtkViewer"] + if v is not None: + v.setWireframeOverlap() + + +def test_Python_VisualisationVtk_setSurfaceOverlap(simple_box): + r = simple_box + v = r["vtkViewer"] + if v is not None: + v.setSurfaceOverlap() + + +def test_Python_VisualisationVtk_setRandomColours(simple_box): + r = simple_box + v = r["vtkViewer"] + if v is not None: + v.setRandomColours() + + +def test_Python_VisualisationVtk_RandomColour(simple_box): + import pyg4ometry + + wlv = simple_box["logicalVolume"] + v = pyg4ometry.visualisation.VtkViewerColoured(defaultColour="random") + v.addLogicalVolume(wlv) + + +def test_Python_VisualisationVtk_DefaultMaterial(simple_box): + import pyg4ometry + + wlv = simple_box["logicalVolume"] + v = pyg4ometry.visualisation.VtkViewerColouredMaterial() + v.addLogicalVolume(wlv) + + +# TODO reinstate test +# def test_Python_VisualisationVtk_CustomMaterialColours(lhc_blm): +# import pyg4ometry +# +# wlv = lhc_blm +# colours = lhc_blm.materialToColour +# v = pyg4ometry.visualisation.VtkViewerColoured(materialVisOptions=colours) +# v.addLogicalVolume(wlv) diff --git a/tests/geant4/test_geant4solids.py b/tests/geant4/test_geant4solids.py new file mode 100644 index 000000000..4af727cc2 --- /dev/null +++ b/tests/geant4/test_geant4solids.py @@ -0,0 +1,652 @@ +import numpy as _np +import os as _os + +import pyg4ometry + +import T000_SolidBase +import T001_Box +import T002_Tubs +import T003_CutTubs +import T0031_CutTubs_number +import T0032_CutTubs_string +import T0033_CutTubs_expression +import T0034_CutTubs_DefineTree +import T004_Cons +import T005_Para +import T006_Trd +import T007_Trap +import T008_Sphere +import T009_Orb +import T010_Torus +import T011_Polycone +import T012_GenericPolycone +import T013_Polyhedra +import T014_GenericPolyhedra +import T015_EllipticalTube +import T016_Ellipsoid +import T017_EllipticalCone +import T018_Paraboloid +import T019_Hyperboloid +import T020_Tet +import T021_ExtrudedSolid +import T022_TwistedBox +import T023_TwistedTrap +import T024_TwistedTrd +import T025_TwistedTubs +import T026_GenericTrap +import T028_Union +import T029_Subtraction +import T030_Intersection +import T031_MultiUnion +import T032_Scaled +import T033_TessellatedSolid +import T101_physical_logical +import T102_overlap_none +import T103_overlap_copl +import T103_overlap_copl_simple +import T104_overlap_volu +import T105_assembly +import T106_replica_x +import T107_replica_y +import T108_replica_z +import T109_replica_phi +import T110_replica_rho +import T111_parameterised_box +import T112_parameterised_tube +import T201_Materials +import T202_OpticalSurface +import T203_MaterialsRegistry +import T204_NIST_Element +import T205_NIST_Material +import T300_overlap_assembly_regular_lv +import T301_overlap_assembly_none +import T302_overlap_assembly_coplanar +import T303_overlap_assembly_daughter_collision +import T304_overlap_assembly_volumetric +import T305_overlap_assembly_nested +import T306_overlap_replica_x +import T307_overlap_replica_x_internal +import T400_MergeRegistry +import T401_MergeRegistry_Box +import T402_MergeRegistry_Tubs +import T403_MergeRegistry_CutTubs +import T404_MergeRegistry_Cons +import T405_MergeRegistry_Para +import T406_MergeRegistry_Trd +import T407_MergeRegistry_Trap +import T408_MergeRegistry_Sphere +import T409_MergeRegistry_Orb +import T410_MergeRegistry_Torus +import T411_MergeRegistry_Polycone +import T412_MergeRegistry_GenericPolycone +import T413_MergeRegistry_Polyhedra +import T414_MergeRegistry_GenericPolyhedra +import T415_MergeRegistry_EllipticalTube +import T416_MergeRegistry_Ellipoid +import T417_MergeRegistry_EllipticalCone +import T418_MergeRegistry_Paraboloid +import T419_MergeRegistry_Hyperboloid +import T420_MergeRegistry_Tet +import T421_MergeRegistry_ExtrudedSolid +import T422_MergeRegistry_TwistedBox +import T423_MergeRegistry_TwistedTrap +import T424_MergeRegistry_TwistedTrd +import T425_MergeRegistry_TwistedTubs +import T426_MergeRegistry_GenericTrap +import T428_MergeRegistry_Union +import T429_MergeRegistry_Subtraction +import T430_MergeRegistry_Intersection +import T431_MergeRegistry_MultiUnion +import T432_MergeRegistry_Box_AssemblyConversion +import T433_MergeRegistry_Scale +import T434_MergeRegistry_CollapseAssembly +import T600_LVTessellated +import T601_reflect + +# from . import T602_lv_cull_daughters +# from . import T603_lv_change_solid_and_trim +# from . import T604_lv_change_solid_and_trim_rot +import T605_LvChangeSolid +import T606_LvClipSolid +import T607_LvChangeAndClipSolid +import T608_LvClipSolidRecursive +import T609_LvClipSolidRecursiveAssembly + +writeNISTMaterials = True + + +def test_PythonGeant_Plane(): + p = pyg4ometry.geant4.solid.Plane("plane", [0, 0, 1], 1000) + str(p) + + +def test_PythonGeant_Wedge(): + w = pyg4ometry.geant4.solid.Wedge("wedge", 1000, 0, 1.5 * _np.pi, 10000) + str(w) + + +def test_PythonGeant_T000_SolidBase(): + assert T000_SolidBase.Test()["testStatus"] + + +def test_PythonGeant_T001_Box(): + assert T001_Box.Test(False, False, writeNISTMaterials)["testStatus"] + + +def test_PythonGeant_T002_Tubs(): + assert T002_Tubs.Test(False, False, writeNISTMaterials=writeNISTMaterials) + + +def test_PythonGeant_T003_CutTubs(): + assert T003_CutTubs.Test( + False, False, T003_CutTubs.normal, writeNISTMaterials=writeNISTMaterials + )["testStatus"] + assert T003_CutTubs.Test(False, False, T003_CutTubs.flat_ends)["testStatus"] + assert T0031_CutTubs_number.Test(False, False)["testStatus"] + assert T0032_CutTubs_string.Test(False, False)["testStatus"] + # TODO + # assert T0033_CutTubs_expression.Test(False, False)["testStatus"] + assert T0034_CutTubs_DefineTree.Test(False, False)["testStatus"] + + +def test_PythonGeant_T004_Cons(): + try: + assert T004_Cons.Test( + False, + False, + T004_Cons.r1min_gt_r1max, + writeNISTMaterials=writeNISTMaterials, + )["testStatus"] + except ValueError: + pass + + try: + assert T004_Cons.Test(False, False, T004_Cons.r2min_gt_r2max)["testStatus"] + except ValueError: + pass + + try: + assert T004_Cons.Test(False, False, T004_Cons.dphi_gt_2pi)["testStatus"] + except ValueError: + pass + + assert T004_Cons.Test(False, False, T004_Cons.dphi_eq_2pi)["testStatus"] + assert T004_Cons.Test(False, False, T004_Cons.cone_up)["testStatus"] + assert T004_Cons.Test(False, False, T004_Cons.inner_cylinder)["testStatus"] + + assert T004_Cons.Test(False, False)["testStatus"] + + +def test_PythonGeant_T005_Para(): + assert T005_Para.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T006_Trd(): + assert T006_Trd.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T007_Trap(): + assert T007_Trap.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T008_Sphere(): + assert T008_Sphere.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T009_Orb(): + assert T009_Orb.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T010_Torus(): + assert T010_Torus.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T011_Polycone(): + assert T011_Polycone.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T012_GenericPolycone(): + assert T012_GenericPolycone.Test( + False, False, T012_GenericPolycone.normal, writeNISTMaterials=writeNISTMaterials + )["testStatus"] + + try: + T012_GenericPolycone.Test(False, False, T012_GenericPolycone.two_planes)[ + "testStatus" + ] + except ValueError: + pass + + +def test_PythonGeant_T013_Polyhedra(): + assert T013_Polyhedra.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T014_GenericPolyhedra(): + assert T014_GenericPolyhedra.Test( + False, + False, + T014_GenericPolyhedra.normal, + writeNISTMaterials=writeNISTMaterials, + )["testStatus"] + + try: + T014_GenericPolyhedra.Test(False, False, T014_GenericPolyhedra.two_planes)[ + "testStatus" + ] + except ValueError: + pass + + +def test_PythonGeant_T015_EllipticalTube(): + assert T015_EllipticalTube.Test( + False, False, writeNISTMaterials=writeNISTMaterials + )["testStatus"] + + +def test_PythonGeant_T016_Ellipsoid(): + assert T016_Ellipsoid.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T017_EllipticalCone(): + assert T017_EllipticalCone.Test( + False, False, writeNISTMaterials=writeNISTMaterials + )["testStatus"] + + try: + T017_EllipticalCone.Test( + False, + False, + T017_EllipticalCone.zcut_outofrange, + writeNISTMaterials=writeNISTMaterials, + )["testStatus"] + except ValueError: + pass + + +def test_PythonGeant_T018_Paraboloid(): + assert T018_Paraboloid.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "teststatus" + ] + + +def test_PythonGeant_T019_Hyperboloid(): + assert T019_Hyperboloid.Test( + False, False, T019_Hyperboloid.normal, writeNISTMaterials=writeNISTMaterials + )["teststatus"] + assert T019_Hyperboloid.Test( + False, + False, + T019_Hyperboloid.rmin_eq_zero, + writeNISTMaterials=writeNISTMaterials, + )["teststatus"] + + try: + T019_Hyperboloid.Test( + False, + False, + T019_Hyperboloid.rmin_gt_rmax, + writeNISTMaterials=writeNISTMaterials, + )["testStatus"] + except ValueError: + pass + + +def test_PythonGeant_T020_Tet(): + assert T020_Tet.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T021_ExtrudedSolid(): + assert T021_ExtrudedSolid.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T022_TwistedBox(): + assert T022_TwistedBox.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T023_TwistedTrap(): + assert T023_TwistedTrap.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T024_TwistedTrd(): + assert T024_TwistedTrd.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T025_TwistedTubs(): + assert T025_TwistedTubs.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "teststatus" + ] + + +def test_PythonGeant_T026_GenericTrap(): + assert T026_GenericTrap.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "teststatus" + ] + + +def test_PythonGeant_T028_Union(): + assert T028_Union.Test(False, False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + assert T028_Union.Test(False, False, True, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T029_Subtraction(): + assert T029_Subtraction.Test( + False, False, False, writeNISTMaterials=writeNISTMaterials + )["testStatus"] + + # try : + # T029_Subtraction.Test(False,False,True) + # except pyg4ometry.exceptions.NullMeshError : + # pass + + +def test_PythonGeant_T030_Intersection(): + assert T030_Intersection.Test( + False, False, T030_Intersection.normal, writeNISTMaterials=writeNISTMaterials + )["teststatus"] + + # try : + # T030_Intersection.Test(False,False,T030_Intersection.non_intersecting) + # except pyg4ometry.exceptions.NullMeshError : + # pass + + +def test_PythonGeant_T031_MultiUnion(): + assert T031_MultiUnion.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "teststatus" + ] + + +def test_PythonGeant_T032_Scaled(): + assert T032_Scaled.Test(False, False, writeNISTMaterials=writeNISTMaterials)[ + "testStatus" + ] + + +def test_PythonGeant_T033_Tessellated(): + assert T033_TessellatedSolid.Test( + False, False, writeNISTMaterials=writeNISTMaterials + )["testStatus"] + + +def test_PythonGeant_T101_PhysicalLogical(): + assert T101_physical_logical.Test()["testStatus"] + + +def test_PythonGeant_T102_OverlapMone(): + assert T102_overlap_none.Test()["testStatus"] + + +def test_PythonGeant_T103_OverlapCopl(): + assert T103_overlap_copl.Test()["testStatus"] + + +def test_PythonGeant_T103_OverlapCopl_Simple(): + assert T103_overlap_copl_simple.Test()["testStatus"] + + +def test_PythonGeant_T104_OverlapVolu(): + assert T104_overlap_volu.Test()["testStatus"] + + +def test_PythonGeant_T105_Assembly(): + assert T105_assembly.Test()["testStatus"] + + +def test_PythonGeant_T106_ReplicaX(): + assert T106_replica_x.Test()["testStatus"] + + +def test_PythonGeant_T107_ReplicaY(): + assert T107_replica_y.Test()["testStatus"] + + +def test_PythonGeant_T108_ReplicaZ(): + assert T108_replica_z.Test()["testStatus"] + + +def test_PythonGeant_T109_ReplicaPhi(): + assert T109_replica_phi.Test()["testStatus"] + + +def test_PythonGeant_T110_ReplicaRho(): + assert T110_replica_rho.Test()["testStatus"] + + +def test_PythonGeant_T111_parameterised_box(): + assert T111_parameterised_box.Test()["testStatus"] + + +def test_PythonGeant_T112_parameterised_tube(): + assert T112_parameterised_tube.Test()["testStatus"] + + +def test_PythonGeant_T201_Materials(): + T201_Materials.Test_MaterialPredefined() + T201_Materials.Test_MaterialSingleElement() + T201_Materials.Test_MaterialCompoundMassFraction() + T201_Materials.Test_MaterialCompoundAtoms() + T201_Materials.Test_MaterialMixture() + T201_Materials.Test_MaterialIsotopes() + + +def test_PythonGeant_T202_OpticalSurface(): + T202_OpticalSurface.Test_OpticalSurface() + + +def test_PythonGeant_T203_MaterialsRegistry(): + T203_MaterialsRegistry.Test_MaterialsRegistry() + + +def test_PythonGeant_T204_NIST_Element(): + T204_NIST_Element.Test_NIST_Element() + + +def test_PythonGeant_T205_NIST_Material(): + T205_NIST_Material.Test_NIST_Material() + + +def test_PythonGeant_T400_MergeRegistry(): + assert T400_MergeRegistry.Test()["teststatus"] + + +def test_PythonGeant_T401_MergeRegistry_Box(): + assert T401_MergeRegistry_Box.Test(False, False)["testStatus"] + + +def test_PythonGeant_T402_MergeRegistry_Tubs(): + assert T402_MergeRegistry_Tubs.Test()["testStatus"] + + +def test_PythonGeant_T403_MergeRegistry_CutTubs(): + assert T403_MergeRegistry_CutTubs.Test()["testStatus"] + + +def test_PythonGeant_T404_MergeRegistry_Cons(): + assert T404_MergeRegistry_Cons.Test()["testStatus"] + + +def test_PythonGeant_T405_MergeRegistry_Para(): + assert T405_MergeRegistry_Para.Test()["testStatus"] + + +def test_PythonGeant_T406_MergeRegistry_Trd(): + assert T406_MergeRegistry_Trd.Test()["testStatus"] + + +def test_PythonGeant_T407_MergeRegistry_Trap(): + assert T407_MergeRegistry_Trap.Test()["testStatus"] + + +def test_PythonGeant_T408_MergeRegistry_Sphere(): + assert T408_MergeRegistry_Sphere.Test()["testStatus"] + + +def test_PythonGeant_T409_MergeRegistry_Orb(): + assert T409_MergeRegistry_Orb.Test()["testStatus"] + + +def test_PythonGeant_T410_MergeRegistry_Torus(): + assert T410_MergeRegistry_Torus.Test()["testStatus"] + + +def test_PythonGeant_T411_MergeRegistry_Polycone(): + assert T411_MergeRegistry_Polycone.Test()["testStatus"] + + +def test_PythonGeant_T412_MergeRegistry_GenericPolycone(): + assert T412_MergeRegistry_GenericPolycone.Test()["testStatus"] + + +def test_PythonGeant_T413_MergeRegistry_Polyhedra(): + assert T413_MergeRegistry_Polyhedra.Test()["testStatus"] + + +def test_PythonGeant_T414_MergeRegistry_GenericPolyhedra(): + assert T414_MergeRegistry_GenericPolyhedra.Test()["testStatus"] + + +def test_PythonGeant_T415_MergeRegistry_EllipticalTube(): + assert T415_MergeRegistry_EllipticalTube.Test()["testStatus"] + + +def test_PythonGeant_T416_MergeRegistry_Ellipsoid(): + assert T416_MergeRegistry_Ellipoid.Test()["testStatus"] + + +def test_PythonGeant_T417_MergeRegistry_EllipticalCone(): + assert T417_MergeRegistry_EllipticalCone.Test()["testStatus"] + + +def test_PythonGeant_T418_MergeRegistry_EllipticalParaboloid(): + assert T418_MergeRegistry_Paraboloid.Test()["testStatus"] + + +def test_PythonGeant_T419_MergeRegistry_Hyperboloid(): + assert T419_MergeRegistry_Hyperboloid.Test()["testStatus"] + + +def test_PythonGeant_T420_MergeRegistry_Tet(): + assert T420_MergeRegistry_Tet.Test()["testStatus"] + + +def test_PythonGeant_T421_MergeRegistry_ExtrudedSolid(): + assert T421_MergeRegistry_ExtrudedSolid.Test()["testStatus"] + + +def test_PythonGeant_T422_MergeRegistry_TwistedBox(): + assert T422_MergeRegistry_TwistedBox.Test()["testStatus"] + + +def test_PythonGeant_T423_MergeRegistry_TwistedTrap(): + assert T423_MergeRegistry_TwistedTrap.Test()["testStatus"] + + +def test_PythonGeant_T424_MergeRegistry_TwistedTrd(): + assert T424_MergeRegistry_TwistedTrd.Test()["testStatus"] + + +def test_PythonGeant_T425_MergeRegistry_TwistedTubs(): + assert T425_MergeRegistry_TwistedTubs.Test()["testStatus"] + + +def test_PythonGeant_T426_MergeRegistry_GenericTrap(): + assert T426_MergeRegistry_GenericTrap.Test()["testStatus"] + + +def test_PythonGeant_T428_MergeRegistry_Union(): + assert T428_MergeRegistry_Union.Test()["testStatus"] + + +def test_PythonGeant_T429_MergeRegistry_Subtraction(): + assert T429_MergeRegistry_Subtraction.Test()["testStatus"] + + +def test_PythonGeant_T430_MergeRegistry_Intersection(): + assert T430_MergeRegistry_Intersection.Test()["testStatus"] + + +def test_PythonGeant_T431_MergeRegistry_MultiUnion(): + assert T431_MergeRegistry_MultiUnion.Test()["testStatus"] + + +def test_PythonGeant_T432_MergeRegistryBoxAssemblyConverion(): + assert T432_MergeRegistry_Box_AssemblyConversion.Test()["testStatus"] + + +def test_PythonGeant_T433_MergeRegistry_Scale(): + assert T433_MergeRegistry_Scale.Test()["testStatus"] + + +def test_PythonGeant_T434_MergeRegistry_CollapseAssembly(): + assert T434_MergeRegistry_CollapseAssembly.Test()["testStatus"] + + +def test_PythonGeant_T600_LVTessellated(): + assert T600_LVTessellated.Test()["testStatus"] + + +def test_PythonGeant_T601_reflect(): + assert T601_reflect.Test()["testStatus"] + + +# def test_PythonGeant_T602_lv_cull_daughters(): +# assert T602_lv_cull_daughters.Test()["testStatus"] + +# def test_PythonGeant_T603_lv_change_solid_and_trim(): +# assert T603_lv_change_solid_and_trim.Test()["testStatus"] + +# def test_PythonGeant_T604_lv_change_solid_and_trim_rot(): +# assert T604_lv_change_solid_and_timr_rot.Test()["testStatus"] + + +def test_PythonGeant_T605_LvChangeSolid(): + assert T605_LvChangeSolid.Test()["testStatus"] + + +def test_PythonGeant_T606_LvClipSolid(): + assert T606_LvClipSolid.Test()["testStatus"] + + +def test_PythonGeant_T607_LvChangeAndClipSolid(): + assert T607_LvChangeAndClipSolid.Test()["testStatus"] + + +def test_PythonGeant_T608_LvClipSolidRecursive(): + assert T608_LvClipSolidRecursive.Test()["testStatus"] + + +def test_PythonGeant_T609_LvClipSolidRecursiveAssembly(): + assert T609_LvClipSolidRecursiveAssembly.Test()["testStatus"] diff --git a/tests/io/disable_RootReader.py b/tests/io/disable_RootReader.py new file mode 100644 index 000000000..a4e552677 --- /dev/null +++ b/tests/io/disable_RootReader.py @@ -0,0 +1,223 @@ +import os as _os + +import ROOT as _ROOT +import pyg4ometry as _pyg4ometry + + +def gdml2ROOT(gdmlFileName, rootFileName): + _ROOT.TGeoManager.SetVerboseLevel(0) + tgm = _ROOT.TGeoManager.Import( + _os.path.join(_os.path.dirname(__file__), gdmlFileName) + ) + tgm.Export(_os.path.join(_os.path.dirname(__file__), rootFileName)) + + +def loadROOTFile(rootFileName): + r = _pyg4ometry.io.ROOTTGeo.Reader( + _os.path.join(_os.path.dirname(__file__), rootFileName) + ) + return r + + +def deleteROOTFile(rootFileName): + _os.remove(_os.path.join(_os.path.dirname(__file__), rootFileName)) + + +def visGeometry(wl, vis=False, interactive=False): + extentBB = wl.extent(includeBoundingSolid=True) + + if vis: + v = _pyg4ometry.visualisation.VtkViewer() + v.addLogicalVolume(wl) + v.addAxes(_pyg4ometry.visualisation.axesFromExtents(extentBB)[0]) + v.view(interactive=interactive) + return v + + +def test_ROOT_T001Box(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T001_Box.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T002Tubs(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T002_Tubs.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T003CutTubs(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T003_CutTubs.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T004Cons(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T004_Cons.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T005Para(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T005_Para.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T006Trd(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T006_Trd.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T007Trap(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T007_Trap.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T008Sphere(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T008_Sphere.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T009Orb(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T009_Orb.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T010Torus(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T010_Torus.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T011Polycone(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T011_Polycone.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +# Generic polycone does not exist in ROOT + + +def test_ROOT_T013Polyhedra(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T013_Polyhedra.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +# Generic polyheda does not exist in ROOT + + +def test_ROOT_T015EllipticalTube(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T015_EllipticalTube.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +# Ellipsoid used scaled and boolean +def test_ROOT_T016Ellipsoid(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T016_Ellipsoid.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +# phi range does not exist for ROOT Cons +def test_ROOT_T017EllipticalCone(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T017_EllipticalCone.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +def test_ROOT_T018Paraboloid(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T018_Paraboloid.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +def test_ROOT_T019Hyperboloid(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T019_Hyperboloid.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +# Tet does not exist + + +def test_ROOT_T021ExtrudedSolid(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T021_ExtrudedSolid.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +# Twisted don't exist + +# Generic trap does not exist either + + +def test_ROOT_T028Union(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T028_Union.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(r.getRegistry().getWorldVolume(), vis, interactive) + + +def test_ROOT_T029Subtraction(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T029_Subtraction.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +def test_ROOT_T030Intersection(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T030_Intersection.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +# Multiunion does not exist +# def test_ROOT_T031MultiUnion(vis = False, interactive = False): +# gdml2ROOT("T031_MultiUnion.gdml","T031_MultiUnion.root") +# r = loadROOTFile("T031_MultiUnion.root") +# l = r.getRegistry().getWorldVolume() +# v = visGeometry(l, vis, interactive) +# return {"testStatus": True, "logicalVolume":l, "vtkViewer":v} + +# Scaled cannot be read by ROOT? + + +def test_ROOT_T033TessellatedSolid(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T033_TessellatedSolid.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +def test_ROOT_T101PhysicalLogical(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T101_physical_logical.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +def test_ROOT_T102OverlapNone(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T102_overlap_none.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +def test_ROOT_T103OverlapCopl(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T103_overlap_copl.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +def test_ROOT_T900LHT(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/lht.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive) + + +def test_ROOT_T901BoxPlacement(testdata, vis=False, interactive=False): + r = loadROOTFile(testdata["root/T001_geant4Box2Fluka.root"]) + l = r.getRegistry().getWorldVolume() + v = visGeometry(l, vis, interactive)