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
Beispiel #2
0
    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()
Beispiel #3
0
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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
    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)
Beispiel #7
0
    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()
Beispiel #8
0
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
Beispiel #9
0
    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)
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
0
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()
Beispiel #13
0
    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)
Beispiel #14
0
    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)
Beispiel #15
0
    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()))