def setUp(self): super().setUp() self.testdatadir = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'pengeom') self.geo = Geometry('Test Geometry') surface1 = zplane(1e-8) surface2 = zplane(-1e-1) surface3 = cylinder(1.0) surface4 = xplane(0.0) self.mat1 = Material('copper', {29: 1.0}, 8.9) self.module1 = Module(self.mat1) self.module1.add_surface(surface1, SIDEPOINTER_NEGATIVE) self.module1.add_surface(surface2, SIDEPOINTER_POSITIVE) self.module1.add_surface(surface3, SIDEPOINTER_NEGATIVE) self.module1.add_surface(surface4, SIDEPOINTER_POSITIVE) self.geo.add_module(self.module1) self.mat2 = Material('zinc', {30: 1.0}, 7.14) self.module2 = Module(self.mat2) self.module2.add_surface(surface1, SIDEPOINTER_NEGATIVE) self.module2.add_surface(surface2, SIDEPOINTER_POSITIVE) self.module2.add_surface(surface3, SIDEPOINTER_NEGATIVE) self.module2.add_module(self.module1) self.geo.add_module(self.module2) self.geo.tilt_deg = 45
def _read(self, fileobj, material_lookup, surface_lookup, module_lookup): line = self._read_next_line(fileobj) if line != LINE_START: raise IOError('Expected start line') line = self._read_next_line(fileobj) self.title = '' while line != LINE_SEPARATOR: line = line.lstrip('C').strip() self.title += line line = self._read_next_line(fileobj) line = self._peek_next_line(fileobj) while line != LINE_END: # Parse section name section_name, index, _ = self._parse_line(line) index = int(index) # Parse surface or module if section_name == 'SURFACE': # Read 2 lines down the INDICES line offset = fileobj.tell() self._read_next_line(fileobj) indices_line = self._read_next_line(fileobj) _, indices, _ = self._parse_line(indices_line) indices = map(int, indices.split(',')) fileobj.seek(offset) if sum(indices) == 0: surface = SurfaceImplicit() else: surface = SurfaceReduced() surface._read(fileobj, material_lookup, surface_lookup, module_lookup) surface_lookup[index] = surface elif section_name == 'MODULE': module = Module() module._read(fileobj, material_lookup, surface_lookup, module_lookup) self.add_module(module) module_lookup[index] = module else: raise IOError('Cannot read {} section'.format(section_name)) # Next line line = self._peek_next_line(fileobj).rstrip()
def create_example2_plane(): # Create materials material_h2o = Material('H2O', {8: 0.8881, 1: 0.1119}, 1.0) # Create geometry module_detector = Module(material_h2o, 'Fluence detector') module_detector.add_surface(sphere(2.0), SIDEPOINTER_NEGATIVE) module_phantom = Module(material_h2o, 'Water phantom') module_phantom.add_surface(zplane(0.0), SIDEPOINTER_POSITIVE) module_phantom.add_surface(zplane(30.0), SIDEPOINTER_NEGATIVE) geometry = Geometry('Semi-infinite water phantom') geometry.add_module(module_detector) geometry.add_module(module_phantom) index_lookup = geometry.indexify() # Create input input = PenmainInput() input.TITLE.set('Dose in a water phantom with a spherical impact detector') input.SKPAR.set(2) input.SENERG.set(3e7) input.SPOSIT.set(0.0, 0.0, -25.0) input.SCONE.set(0.0, 0.0, 5.0) input.materials.add(1, material_h2o.filename, 1e5, 1e4, 1e5, 0.05, 0.05, 5e3, 5e3) input.GEOMFN.set('plane.geo') input.NBE.set(1e5, 3e7, 100) input.NBANGL.set(45, 18) detector = input.impact_detectors.add(1e5, 0.0, 100, 0, 2) detector.IDBODY.add(index_lookup[module_detector]) input.GRIDZ.set(0, 30.0, 60) input.GRIDR.set(30.0, 60.0) input.RESUME.set('dump.dat') input.DUMPTO.set('dump.dat') input.DUMPP.set(60) input.NSIMSH.set(1e7) input.TIME.set(2e9) return input
def setUp(self): super().setUp() self.mat1 = Material('copper', {29: 1.0}, 8.9) self.surface1 = SurfaceImplicit() self.surface2 = SurfaceImplicit() self.module2 = Module(VACUUM) self.module1 = Module(self.mat1, 'Test') self.module1.add_surface(self.surface1, -1) self.module1.add_surface(self.surface2, 1) self.module1.add_module(self.module2) self.module1.rotation.phi_deg = 180 self.module1.shift.z_cm = -1e5
def _create_extra_module(self): extra = Module(VACUUM, description='Extra module for rotation and tilt') ## Find all unlinked modules all_modules = set(self.get_modules()) linked_modules = set( chain(*map(methodcaller('get_modules'), all_modules))) unlinked_modules = all_modules - linked_modules for module in unlinked_modules: extra.add_module(module) ## Change of Euler angles convention from ZXZ to ZYZ extra.rotation.omega_deg = (self.rotation_deg - 90.0) % 360.0 extra.rotation.theta_deg = self.tilt_deg extra.rotation.phi_deg = 90.0 return extra
def _export_sample_sphere(self, sample, options, erracc, geometry, dsmaxs): self._validate_sample_sphere(sample, options, erracc) # Surfaces diameter_m = apply_lazy(sample.diameter_m, sample, options) radius_m = diameter_m / 2.0 surface_sphere = sphere(radius_m * 100.0) # Modules material = apply_lazy(sample.material, sample, options) penmaterial = self._export_material(material, options, erracc, index=1) module = Module(penmaterial, "Sphere") module.add_surface(surface_sphere, SidePointer.NEGATIVE) module.shift.z_m = -radius_m dsmaxs[module] = diameter_m geometry.title = "Sphere" geometry.add_module(module) geometry.tilt_rad = apply_lazy(sample.tilt_rad, sample, options) geometry.rotation_rad = apply_lazy(sample.azimuth_rad, sample, options)
def test_write_read(self): material_lookup = {0: VACUUM, 1: self.mat1} surface_lookup = {1: self.surface1, 2: self.surface2} module_lookup = {2: self.module2} index_lookup = { VACUUM: 0, self.mat1: 1, self.surface1: 1, self.surface2: 2, self.module1: 1, self.module2: 2 } # Module 1 fileobj = io.StringIO() try: self.module1._write(fileobj, index_lookup) lines = fileobj.getvalue().splitlines() self.assertListEqual(self.LINES1, lines) fileobj.seek(0) module = Module() module._read(fileobj, material_lookup, surface_lookup, module_lookup) self._test_module1(module) finally: fileobj.close() # Module 2 fileobj = io.StringIO() try: self.module2._write(fileobj, index_lookup) lines = fileobj.getvalue().splitlines() self.assertListEqual(self.LINES2, lines) fileobj.seek(0) module = Module() module._read(fileobj, material_lookup, surface_lookup, module_lookup) self._test_module2(module) finally: fileobj.close()
def create_example1_disc(): # Create materials material_cu = Material('Cu', {29: 1.0}, 8.9) # Create geometry module = Module(material_cu, 'Solid cylinder') module.add_surface(zplane(0.0), SIDEPOINTER_POSITIVE) module.add_surface(zplane(0.005), SIDEPOINTER_NEGATIVE) module.add_surface(cylinder(1.0), SIDEPOINTER_NEGATIVE) geometry = Geometry('A solid cylinder.') geometry.add_module(module) # Create input input = PenmainInput() input.TITLE.set('Point source and a homogeneous cylinder.') input.SKPAR.set(1) input.SENERG.set(40e3) input.SPOSIT.set(0.0, 0.0, -0.0001) input.SCONE.set(0.0, 0.0, 5.0) input.materials.add(1, material_cu.filename, 1e3, 1e3, 1e3, 0.05, 0.05, 1e3, 1e3) input.GEOMFN.set('disc.geo') input.PARINP.add(1, 0.005) input.PARINP.add(2, 0.01) input.DSMAX.add(1, 1e-4) input.IFORCE.add(1, 1, 4, 2000, 0.1, 2.0) input.IFORCE.add(1, 1, 5, 200, 0.1, 2.0) input.IBRSPL.add(1, 2) input.IXRSPL.add(1, 2) input.NBE.set(0, 0, 100) input.NBANGL.set(45, 18) detector = input.impact_detectors.add(0.0, 0.0, 100, 0, 2) detector.IDBODY.add(1) detector = input.energy_deposition_detectors.add(0, 0, 100) detector.EDBODY.add(1) input.GRIDZ.set(0, 0.005, 100) input.GRIDR.set(0.01, 50) input.RESUME.set('dump.dat') input.DUMPTO.set('dump.dat') input.DUMPP.set(60) input.NSIMSH.set(2e9) input.TIME.set(600) return input
def _export_sample_substrate(self, sample, options, erracc, geometry, dsmaxs): self._validate_sample_substrate(sample, options, erracc) # Geometry surface_cylinder = cylinder(100) # 100 cm radius surface_top = zplane(0.0) # z = 0 surface_bottom = zplane(-100) # z = -100 cm material = apply_lazy(sample.material, sample, options) penmaterial = self._export_material(material, options, erracc, index=1) module = Module(penmaterial, "Substrate") module.add_surface(surface_cylinder, SidePointer.NEGATIVE) module.add_surface(surface_top, SidePointer.NEGATIVE) module.add_surface(surface_bottom, SidePointer.POSITIVE) geometry.title = "Substrate" geometry.add_module(module) geometry.tilt_rad = apply_lazy(sample.tilt_rad, sample, options) geometry.rotation_rad = apply_lazy(sample.azimuth_rad, sample, options)
def create_epma2(): # Create geometry surface_top = zplane(0.0) surface_bottom = zplane(-0.1) surface_cylinder = cylinder(1.0) surface_divider = xplane(0.0) module_right = Module(MATERIAL_CU, 'Right half of the sample') module_right.add_surface(surface_top, SIDEPOINTER_NEGATIVE) module_right.add_surface(surface_bottom, SIDEPOINTER_POSITIVE) module_right.add_surface(surface_cylinder, SIDEPOINTER_NEGATIVE) module_right.add_surface(surface_divider, SIDEPOINTER_POSITIVE) module_left = Module(MATERIAL_FE, 'Left half of the sample') module_left.add_surface(surface_top, SIDEPOINTER_NEGATIVE) module_left.add_surface(surface_bottom, SIDEPOINTER_POSITIVE) module_left.add_surface(surface_cylinder, SIDEPOINTER_NEGATIVE) module_left.add_module(module_right) geometry = Geometry('Cylindrical homogeneous foil') geometry.add_module(module_right) geometry.add_module(module_left) index_lookup = geometry.indexify() index_lookup[MATERIAL_CU] = 1 index_lookup[MATERIAL_FE] = 2 # Create input input = PenepmaInput() input.TITLE.set('A CU-Fe couple') input.SENERG.set(15e3) input.SPOSIT.set(2e-5, 0.0, 1.0) input.SDIREC.set(180, 0.0) input.SAPERT.set(0.0) input.materials.add(index_lookup[MATERIAL_FE], MATERIAL_FE.filename, 1e3, 1e3, 1e3, 0.2, 0.2, 1e3, 1e3) # Note inversion input.materials.add(index_lookup[MATERIAL_CU], MATERIAL_CU.filename, 1e3, 1e3, 1e3, 0.2, 0.2, 1e3, 1e3) input.GEOMFN.set('epma2.geo') input.DSMAX.add(index_lookup[module_right], 1e-4) input.DSMAX.add(index_lookup[module_left], 1e-4) input.IFORCE.add(index_lookup[module_right], 1, 4, -5, 0.9, 1.0) input.IFORCE.add(index_lookup[module_right], 1, 5, -250, 0.9, 1.0) input.IFORCE.add(index_lookup[module_right], 2, 2, 10, 1e-3, 1.0) input.IFORCE.add(index_lookup[module_right], 2, 3, 10, 1e-3, 1.0) input.IFORCE.add(index_lookup[module_left], 1, 4, -5, 0.9, 1.0) input.IFORCE.add(index_lookup[module_left], 1, 5, -7, 0.9, 1.0) input.IFORCE.add(index_lookup[module_left], 2, 2, 10, 1e-3, 1.0) input.IFORCE.add(index_lookup[module_left], 2, 3, 10, 1e-3, 1.0) input.IBRSPL.add(index_lookup[module_right], 2) input.IBRSPL.add(index_lookup[module_left], 2) input.IXRSPL.add(index_lookup[module_right], 2) input.IXRSPL.add(index_lookup[module_left], 2) input.NBE.set(0, 0, 300) input.NBANGL.set(45, 30) input.photon_detectors.add(0, 90, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(5, 15, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(15, 25, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(25, 35, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(35, 45, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(45, 55, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(55, 65, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(65, 75, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(75, 85, 0, 360, 0, 0.0, 0.0, 1000) input.GRIDX.set(-1e-5, 5e-5, 60) input.GRIDY.set(-3e-5, 3e-5, 60) input.GRIDZ.set(-6e-5, 0.0, 60) input.XRLINE.add(26010300) input.XRLINE.add(29010300) input.RESUME.set('dump2.dat') input.DUMPTO.set('dump2.dat') input.DUMPP.set(60) input.RSEED.set(-10, 1) input.REFLIN.set(26010300, 1, 1.5e-3) input.NSIMSH.set(2e9) input.TIME.set(2e9) return input
def create_epma1(): # Create geometry module = Module(MATERIAL_CU, 'Sample') module.add_surface(zplane(0.0), SIDEPOINTER_NEGATIVE) module.add_surface(zplane(-0.1), SIDEPOINTER_POSITIVE) module.add_surface(cylinder(1.0), SIDEPOINTER_NEGATIVE) geometry = Geometry('Cylindrical homogeneous foil') geometry.add_module(module) index_lookup = geometry.indexify() # Create input input = PenepmaInput() input.TITLE.set('A Cu slab') input.SENERG.set(15e3) input.SPOSIT.set(0.0, 0.0, 1.0) input.SDIREC.set(180, 0.0) input.SAPERT.set(0.0) input.materials.add(index_lookup[MATERIAL_CU], MATERIAL_CU.filename, 1e3, 1e3, 1e3, 0.2, 0.2, 1e3, 1e3) input.GEOMFN.set('epma1.geo') input.DSMAX.add(index_lookup[module], 1e-4) input.IFORCE.add(index_lookup[module], 1, 4, -5, 0.9, 1.0) input.IFORCE.add(index_lookup[module], 1, 5, -250, 0.9, 1.0) input.IFORCE.add(index_lookup[module], 2, 2, 10, 1e-3, 1.0) input.IFORCE.add(index_lookup[module], 2, 3, 10, 1e-3, 1.0) input.IBRSPL.add(index_lookup[module], 2) input.IXRSPL.add(index_lookup[module], 2) input.NBE.set(0, 0, 300) input.NBANGL.set(45, 30) input.photon_detectors.add(0, 90, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(5, 15, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(15, 25, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(25, 35, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(35, 45, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(45, 55, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(55, 65, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(65, 75, 0, 360, 0, 0.0, 0.0, 1000) input.photon_detectors.add(75, 85, 0, 360, 0, 0.0, 0.0, 1000) input.GRIDX.set(-4e-5, 4e-5, 60) input.GRIDY.set(-4e-5, 4e-5, 60) input.GRIDZ.set(-6e-5, 0.0, 60) input.XRLINE.set(29010300) input.RESUME.set('dump1.dat') input.DUMPTO.set('dump1.dat') input.DUMPP.set(60) input.RSEED.set(-10, 1) input.REFLIN.set(29010300, 1, 1.25e-3) input.NSIMSH.set(2e9) input.TIME.set(2e9) return input
class TestModule(unittest.TestCase): LINES1 = [ 'MODULE ( 1) Test', 'MATERIAL( 1)', 'SURFACE ( 1), SIDE POINTER=(-1)', 'SURFACE ( 2), SIDE POINTER=( 1)', 'MODULE ( 2)', '1111111111111111111111111111111111111111111111111111111111111111', ' OMEGA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' THETA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' PHI=(+1.800000000000000E+02, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(-1.000000000000000E+05, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000' ] LINES2 = [ 'MODULE ( 2) ', 'MATERIAL( 0)', '1111111111111111111111111111111111111111111111111111111111111111', ' OMEGA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' THETA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' PHI=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000' ] def setUp(self): super().setUp() self.mat1 = Material('copper', {29: 1.0}, 8.9) self.surface1 = SurfaceImplicit() self.surface2 = SurfaceImplicit() self.module2 = Module(VACUUM) self.module1 = Module(self.mat1, 'Test') self.module1.add_surface(self.surface1, -1) self.module1.add_surface(self.surface2, 1) self.module1.add_module(self.module2) self.module1.rotation.phi_deg = 180 self.module1.shift.z_cm = -1e5 def _test_module1(self, module1): self.assertEqual('copper', module1.material.name) self.assertEqual('Test', module1.description) self.assertAlmostEqual(180, module1.rotation.phi_deg, 4) self.assertAlmostEqual(-1e5, module1.shift.z_cm, 4) self.assertEqual(2, len(module1.get_surfaces())) self.assertEqual(1, len(module1.get_modules())) def _test_module2(self, module2): self.assertEqual(str(VACUUM), str(module2.material)) self.assertEqual(0, len(module2.get_surfaces())) self.assertEqual(0, len(module2.get_modules())) def testskeleton(self): self._test_module1(self.module1) self._test_module2(self.module2) def test_write_read(self): material_lookup = {0: VACUUM, 1: self.mat1} surface_lookup = {1: self.surface1, 2: self.surface2} module_lookup = {2: self.module2} index_lookup = { VACUUM: 0, self.mat1: 1, self.surface1: 1, self.surface2: 2, self.module1: 1, self.module2: 2 } # Module 1 fileobj = io.StringIO() try: self.module1._write(fileobj, index_lookup) lines = fileobj.getvalue().splitlines() self.assertListEqual(self.LINES1, lines) fileobj.seek(0) module = Module() module._read(fileobj, material_lookup, surface_lookup, module_lookup) self._test_module1(module) finally: fileobj.close() # Module 2 fileobj = io.StringIO() try: self.module2._write(fileobj, index_lookup) lines = fileobj.getvalue().splitlines() self.assertListEqual(self.LINES2, lines) fileobj.seek(0) module = Module() module._read(fileobj, material_lookup, surface_lookup, module_lookup) self._test_module2(module) finally: fileobj.close()
def _export_sample_verticallayers(self, sample, options, erracc, geometry, dsmaxs): self._validate_sample_verticallayers(sample, options, erracc) layers = apply_lazy(sample.layers, sample, options) xpositions_m = sample.layers_xpositions_m # Surfaces surface_cylinder = cylinder(100) # 100 cm radius surface_top = zplane(0.0) # z = 0 depth_m = apply_lazy(sample.depth_m, sample, options) if math.isfinite(depth_m): surface_bottom = zplane(-depth_m * 100.0) else: surface_bottom = zplane(-100.0) # z = -100 cm surface_layers = [] if layers: for layer, (xmin_m, _xmax_m) in zip(layers, xpositions_m): surface = xplane(xmin_m * 100.0) surface_layers.append(surface) _xmin_m, xmax_m = xpositions_m[-1] surface = xplane(xmax_m * 100.0) surface_layers.append(surface) else: surface = xplane(0.0) surface_layers.append(surface) # Modules index = 1 ## Left substrate left_material = apply_lazy(sample.left_material, sample, options) penmaterial = self._export_material(left_material, options, erracc, index) module = Module(penmaterial, "Left substrate") module.add_surface(surface_cylinder, SidePointer.NEGATIVE) module.add_surface(surface_top, SidePointer.NEGATIVE) module.add_surface(surface_bottom, SidePointer.POSITIVE) module.add_surface(surface_layers[0], SidePointer.NEGATIVE) if math.isfinite(depth_m): dsmaxs[module] = depth_m geometry.add_module(module) index += 1 ## Layers for layer, (surface_left, surface_right) in zip(layers, _pairwise(surface_layers)): material = apply_lazy(layer.material, layer, options) penmaterial = self._export_material(material, options, erracc, index) module = Module(penmaterial, "Layer {}".format(index - 1)) module.add_surface(surface_cylinder, SidePointer.NEGATIVE) module.add_surface(surface_top, SidePointer.NEGATIVE) module.add_surface(surface_bottom, SidePointer.POSITIVE) module.add_surface(surface_left, SidePointer.POSITIVE) module.add_surface(surface_right, SidePointer.NEGATIVE) thickness_m = apply_lazy(layer.thickness_m, layer, options) dsmaxs[module] = min(thickness_m, depth_m) geometry.add_module(module) index += 1 ## Right substrate right_material = apply_lazy(sample.right_material, sample, options) penmaterial = self._export_material(right_material, options, erracc, index) module = Module(penmaterial, "Right substrate") module.add_surface(surface_cylinder, SidePointer.NEGATIVE) module.add_surface(surface_top, SidePointer.NEGATIVE) module.add_surface(surface_bottom, SidePointer.POSITIVE) module.add_surface(surface_layers[-1], SidePointer.POSITIVE) if math.isfinite(depth_m): dsmaxs[module] = depth_m geometry.title = "Vertical layers" geometry.add_module(module) geometry.tilt_rad = apply_lazy(sample.tilt_rad, sample, options) geometry.rotation_rad = apply_lazy(sample.azimuth_rad, sample, options)
def _export_sample_horizontallayers(self, sample, options, erracc, geometry, dsmaxs): self._validate_sample_horizontallayers(sample, options, erracc) layers = apply_lazy(sample.layers, sample, options) zpositions_m = sample.layers_zpositions_m # Surfaces surface_cylinder = cylinder(100) # 100 cm radius surface_layers = [zplane(0.0)] for layer, (zmin_m, _zmax_m) in zip(layers, zpositions_m): surface = zplane(zmin_m * 100.0) surface_layers.append(surface) # Modules index = 0 tmpgrouping = [] for layer, (surface_top, surface_bottom) in zip(layers, _pairwise(surface_layers)): material = apply_lazy(layer.material, layer, options) penmaterial = self._export_material(material, options, erracc, index) module = Module(penmaterial, "Layer {}".format(index)) module.add_surface(surface_cylinder, SidePointer.NEGATIVE) module.add_surface(surface_top, SidePointer.NEGATIVE) module.add_surface(surface_bottom, SidePointer.POSITIVE) thickness_m = apply_lazy(layer.thickness_m, layer, options) dsmaxs[module] = thickness_m geometry.add_module(module) tmpgrouping.append((module, surface_bottom)) index += 1 if sample.has_substrate(): surface_top = surface_layers[-1] surface_bottom = zplane(surface_top.shift.z_cm - 100) # 100 cm below last layer substrate_material = apply_lazy(sample.substrate_material, sample, options) penmaterial = self._export_material(substrate_material, options, erracc, index) module = Module(penmaterial, "Substrate") module.add_surface(surface_cylinder, SidePointer.NEGATIVE) module.add_surface(surface_top, SidePointer.NEGATIVE) module.add_surface(surface_bottom, SidePointer.POSITIVE) geometry.add_module(module) tmpgrouping.append((module, surface_bottom)) # Grouping # G0: s0, s2, m0, m1 # G1: s0, s3, m2, g0 # G2: s0, s4, m3, g1 # etc. if len(tmpgrouping) <= 2: # no grouping required if only 2 modules return module, surface_bottom = tmpgrouping[1] group = Module(PENELOPE_VACUUM, "grouping") group.add_surface(surface_cylinder, SidePointer.NEGATIVE) group.add_surface(surface_layers[0], SidePointer.NEGATIVE) # top z = 0.0 group.add_surface(surface_bottom, SidePointer.POSITIVE) group.add_module(tmpgrouping[0][0]) # m0 group.add_module(module) # m1 geometry.add_module(group) for module, surface_bottom in tmpgrouping[2:]: oldgroup = group group = Module(PENELOPE_VACUUM, "grouping") group.add_surface(surface_cylinder, SidePointer.NEGATIVE) group.add_surface(surface_layers[0], SidePointer.NEGATIVE) # top z = 0.0 group.add_surface(surface_bottom, SidePointer.POSITIVE) group.add_module(module) group.add_module(oldgroup) geometry.add_module(group) geometry.title = "Horizontal layers" geometry.tilt_rad = apply_lazy(sample.tilt_rad, sample, options) geometry.rotation_rad = apply_lazy(sample.azimuth_rad, sample, options)
def _export_sample_inclusion(self, sample, options, erracc, geometry, dsmaxs): self._validate_sample_inclusion(sample, options, erracc) # Surface inclusion_diameter_m = apply_lazy(sample.inclusion_diameter_m, sample, options) surface_cylinder = cylinder(100.0) # 100 cm radius surface_top = zplane(0.0) # z = 0 surface_bottom = zplane(-100.0) # z = -100 cm surface_sphere = sphere(inclusion_diameter_m / 2.0 * 100.0) # Inclusion module inclusion_material = apply_lazy(sample.inclusion_material, sample, options) penmaterial = self._export_material(inclusion_material, options, erracc, index=1) module_inclusion = Module(penmaterial, "Inclusion") module_inclusion.add_surface(surface_top, SidePointer.NEGATIVE) module_inclusion.add_surface(surface_sphere, SidePointer.NEGATIVE) dsmaxs[module_inclusion] = inclusion_diameter_m # Substrate module substrate_material = apply_lazy(sample.substrate_material, sample, options) penmaterial = self._export_material(substrate_material, options, erracc, index=2) module_substrate = Module(penmaterial, "Substrate") module_substrate.add_surface(surface_cylinder, SidePointer.NEGATIVE) module_substrate.add_surface(surface_top, SidePointer.NEGATIVE) module_substrate.add_surface(surface_bottom, SidePointer.POSITIVE) module_substrate.add_module(module_inclusion) # Geometry geometry.title = "Inclusion" geometry.add_module(module_substrate) geometry.add_module(module_inclusion) geometry.tilt_rad = apply_lazy(sample.tilt_rad, sample, options) geometry.rotation_rad = apply_lazy(sample.azimuth_rad, sample, options)
class TestGeometry(unittest.TestCase): LINES = [ 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', ' Test Geometry', '0000000000000000000000000000000000000000000000000000000000000000', 'SURFACE ( 1) Plane Z=0.00 m', 'INDICES=( 0, 0, 0, 1, 0)', 'X-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', 'Y-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', 'Z-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', ' OMEGA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' THETA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' PHI=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(+1.000000000000000E-08, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000', 'SURFACE ( 2) Cylinder of radius 0.01 m along z-axis', 'INDICES=( 1, 1, 0, 0,-1)', 'X-SCALE=(+1.000000000000000E-02, 0) (DEFAULT=1.0)', 'Y-SCALE=(+1.000000000000000E-02, 0) (DEFAULT=1.0)', 'Z-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', ' OMEGA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' THETA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' PHI=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000', 'SURFACE ( 3) Plane Z=-0.00 m', 'INDICES=( 0, 0, 0, 1, 0)', 'X-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', 'Y-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', 'Z-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', ' OMEGA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' THETA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' PHI=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(-1.000000000000000E-01, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000', 'SURFACE ( 4) Plane X=0.00 m', 'INDICES=( 0, 0, 0, 1, 0)', 'X-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', 'Y-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', 'Z-SCALE=(+1.000000000000000E+00, 0) (DEFAULT=1.0)', ' OMEGA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' THETA=(+9.000000000000000E+01, 0) DEG (DEFAULT=0.0)', ' PHI=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000', 'MODULE ( 1) ', 'MATERIAL( 1)', 'SURFACE ( 1), SIDE POINTER=(-1)', 'SURFACE ( 2), SIDE POINTER=(-1)', 'SURFACE ( 3), SIDE POINTER=( 1)', 'SURFACE ( 4), SIDE POINTER=( 1)', '1111111111111111111111111111111111111111111111111111111111111111', ' OMEGA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' THETA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' PHI=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000', 'MODULE ( 2) ', 'MATERIAL( 2)', 'SURFACE ( 1), SIDE POINTER=(-1)', 'SURFACE ( 2), SIDE POINTER=(-1)', 'SURFACE ( 3), SIDE POINTER=( 1)', 'MODULE ( 1)', '1111111111111111111111111111111111111111111111111111111111111111', ' OMEGA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' THETA=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', ' PHI=(+0.000000000000000E+00, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000', 'MODULE ( 3) Extra module for rotation and tilt', 'MATERIAL( 0)', 'MODULE ( 2)', '1111111111111111111111111111111111111111111111111111111111111111', ' OMEGA=(+2.700000000000000E+02, 0) DEG (DEFAULT=0.0)', ' THETA=(+4.500000000000000E+01, 0) DEG (DEFAULT=0.0)', ' PHI=(+9.000000000000000E+01, 0) DEG (DEFAULT=0.0)', 'X-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Y-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', 'Z-SHIFT=(+0.000000000000000E+00, 0) (DEFAULT=0.0)', '0000000000000000000000000000000000000000000000000000000000000000', 'END 0000000000000000000000000000000000000000000000000000000' ] def setUp(self): super().setUp() self.testdatadir = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'pengeom') self.geo = Geometry('Test Geometry') surface1 = zplane(1e-8) surface2 = zplane(-1e-1) surface3 = cylinder(1.0) surface4 = xplane(0.0) self.mat1 = Material('copper', {29: 1.0}, 8.9) self.module1 = Module(self.mat1) self.module1.add_surface(surface1, SIDEPOINTER_NEGATIVE) self.module1.add_surface(surface2, SIDEPOINTER_POSITIVE) self.module1.add_surface(surface3, SIDEPOINTER_NEGATIVE) self.module1.add_surface(surface4, SIDEPOINTER_POSITIVE) self.geo.add_module(self.module1) self.mat2 = Material('zinc', {30: 1.0}, 7.14) self.module2 = Module(self.mat2) self.module2.add_surface(surface1, SIDEPOINTER_NEGATIVE) self.module2.add_surface(surface2, SIDEPOINTER_POSITIVE) self.module2.add_surface(surface3, SIDEPOINTER_NEGATIVE) self.module2.add_module(self.module1) self.geo.add_module(self.module2) self.geo.tilt_deg = 45 def _test_geometry(self, geometry): self.assertEqual('Test Geometry', geometry.title) self.assertEqual(3, len(geometry.get_modules())) self.assertEqual(4, len(geometry.get_surfaces())) self.assertEqual(3, len(geometry.get_materials())) def testskeleton(self): self.assertEqual('Test Geometry', self.geo.title) self.assertEqual(2, len(self.geo.get_modules())) self.assertEqual(4, len(self.geo.get_surfaces())) self.assertEqual(2, len(self.geo.get_materials())) self.assertAlmostEqual(45, self.geo.tilt_deg, 4) self.assertAlmostEqual(0.0, self.geo.rotation_deg, 4) def testindexify(self): index_lookup = self.geo.indexify() # 4 surfaces, 2 materials, 2 modules, 1 extra module self.assertEqual(4 + 2 + 2 + 1, len(index_lookup)) index_lookup2 = self.geo.indexify() self.assertDictEqual(index_lookup, index_lookup2) def testwriteread(self): material_lookup = {0: VACUUM, 1: self.mat1, 2: self.mat2} fileobj = io.StringIO() try: self.geo.write(fileobj) fileobj.seek(0) lines = fileobj.getvalue().splitlines() self.assertListEqual(self.LINES[:3], lines[:3]) self.assertEqual(self.LINES[14], lines[14]) self.assertEqual(self.LINES[26], lines[26]) self.assertEqual(self.LINES[38], lines[38]) self.assertEqual(self.LINES[50], lines[50]) self.assertEqual(self.LINES[51], lines[51]) self.assertListEqual(self.LINES[57:65], lines[57:65]) self.assertEqual(self.LINES[65], lines[65]) self.assertListEqual(self.LINES[71:], lines[71:]) fileobj.seek(0) geometry = Geometry() geometry.read(fileobj, material_lookup) self._test_geometry(geometry) index_lookup = geometry.indexify() self.assertEqual(4 + 3 + 3, len(index_lookup)) finally: fileobj.close() def test_epma1_read(self): material_lookup = {1: self.mat1} filepath = os.path.join(self.testdatadir, 'epma1.geo') geometry = Geometry() with open(filepath, 'r') as fp: geometry.read(fp, material_lookup) self.assertEqual('Cylindrical homogeneous foil', geometry.title) self.assertEqual(3, len(geometry.get_surfaces())) self.assertEqual(1, len(geometry.get_modules())) self.assertEqual(1, len(geometry.get_materials())) def test_epma2_read(self): material_lookup = {1: self.mat1, 2: self.mat2} filepath = os.path.join(self.testdatadir, 'epma2.geo') geometry = Geometry() with open(filepath, 'r') as fp: geometry.read(fp, material_lookup) self.assertEqual('Cylindrical foil with a material couple', geometry.title) self.assertEqual(4, len(geometry.get_surfaces())) self.assertEqual(2, len(geometry.get_modules())) self.assertEqual(2, len(geometry.get_materials()))