Ejemplo n.º 1
0
    def testphoton_range(self):
        material = Material.pure(29)
        xrayline = XrayLine(29, 'Ka1')

        actual = photon_range(20e3,
                              material,
                              xrayline,
                              reference='perkins1991')
        self.assertAlmostEqual(8.42816e-7, actual, 10)
Ejemplo n.º 2
0
 def testphoton_range(self):
     material = Material.pure(29)
     transition = Transition(29, siegbahn='Ka1')
     self.assertAlmostEqual(8.4064e-7, photon_range(20e3, material, transition), 10)
Ejemplo n.º 3
0
    def _append_spatial_distribution(self, lines, options, geoinfo, matinfos,
                                     phdets_key_index, phdets_index_keys, *args):
        lines.append(self._COMMENT_SPATIALDIST())

        # Photon depth detectors
        detectors = dict(options.detectors.iterclass(PhotonDepthDetector))
        if not detectors:
            lines.append(self._COMMENT_SKIP())
            return

        if len(detectors) != 1:
            raise ExporterException("PENEPMA can only have one photon depth detector")

        key, detector = next(iter(detectors.items()))

        ## Get materials
        materials = options.geometry.get_materials()

        ## Get transitions
        if not detector.transitions:
            zs = set()
            for material in materials:
                zs |= set(material.composition.keys())

            energylow = min(mat.absorption_energy_eV[ELECTRON] for mat in materials)
            energyhigh = options.beam.energy_eV

            transitions = []
            for z in zs:
                transitions += get_transitions(z, energylow, energyhigh)

            if not transitions:
                message = "No transition found for PRZ distribution with high enough probability"
                warnings.warn(message, ExporterWarning)
        else:
            transitions = list(detector.transitions)

        transitions.sort(key=attrgetter('probability'), reverse=True)

        ## Restrain number of transitions to maximum number of PRZ
        if len(transitions) > MAX_SPATIAL_DISTRIBUTION // 2:
            message = 'Too many transitions (%i). Only the most probable is/are kept.' % \
                          len(transitions)
            warnings.warn(message, ExporterWarning)

            transitions = transitions[:MAX_SPATIAL_DISTRIBUTION // 2]

        logging.debug('PRZ of the following transitions: %s',
                      ', '.join(map(str, transitions)))

        ## Retrieve range
        e0 = options.beam.energy_eV
        safety_factor = 3.0

        zmax_m = 1e-08 # PENPEMA forces the minimum depth to be 1e-6 cm
        for material in materials:
            for transition in transitions:
                tmpzmax_m = photon_range(e0, material, transition) * safety_factor
                zmax_m = max(zmax_m, tmpzmax_m)

        ## Create lines
        text = ' '.join(map(str, [-3, 3, 1]))
        lines.append(self._KEYWORD_GRIDX(text))

        text = ' '.join(map(str, [-3, 3, 1]))
        lines.append(self._KEYWORD_GRIDY(text))

        channels = min(100, detector.channels) # Maximum of 100 channels
        text = ' '.join(map(str, [-zmax_m * 1e2, 0, channels]))
        lines.append(self._KEYWORD_GRIDZ(text))

        index = phdets_key_index[key] + 1

        for transition in transitions:
            code = int(transition.z * 1e6 + \
                   transition.dest.index * 1e4 + \
                   transition.src.index * 1e2)

            text = ' '.join(map(str, [code, 0])) # No absorption
            lines.append(self._KEYWORD_XRLINE(text))

            text = ' '.join(map(str, [code, index])) # With absorption
            lines.append(self._KEYWORD_XRLINE(text))

        lines.append(self._COMMENT_SKIP())
Ejemplo n.º 4
0
def test_photon_range():
    material = Material.pure(29)
    energy_eV = pyxray.xray_transition_energy_eV(29, "Ka1", reference="jeol")

    actual = photon_range(20e3, material, 29, energy_eV)
    assert actual == pytest.approx(8.4063e-7, abs=1e-10)
Ejemplo n.º 5
0
    def _append_spatial_distribution(self, lines, options, geoinfo, matinfos,
                                     phdets_key_index, phdets_index_keys,
                                     *args):
        lines.append(self._COMMENT_SPATIALDIST())

        # Photon depth detectors
        detectors = dict(options.detectors.iterclass(PhotonDepthDetector))
        if not detectors:
            lines.append(self._COMMENT_SKIP())
            return

        if len(detectors) != 1:
            raise ExporterException(
                "PENEPMA can only have one photon depth detector")

        key, detector = next(iter(detectors.items()))

        ## Get materials
        materials = options.geometry.get_materials()

        ## Get transitions
        if not detector.transitions:
            zs = set()
            for material in materials:
                zs |= set(material.composition.keys())

            energylow = min(mat.absorption_energy_eV[ELECTRON]
                            for mat in materials)
            energyhigh = options.beam.energy_eV

            transitions = []
            for z in zs:
                transitions += get_transitions(z, energylow, energyhigh)

            if not transitions:
                message = "No transition found for PRZ distribution with high enough probability"
                warnings.warn(message, ExporterWarning)
        else:
            transitions = list(detector.transitions)

        transitions.sort(key=attrgetter('probability'), reverse=True)

        ## Restrain number of transitions to maximum number of PRZ
        if len(transitions) > MAX_SPATIAL_DISTRIBUTION // 2:
            message = 'Too many transitions (%i). Only the most probable is/are kept.' % \
                          len(transitions)
            warnings.warn(message, ExporterWarning)

            transitions = transitions[:MAX_SPATIAL_DISTRIBUTION // 2]

        logging.debug('PRZ of the following transitions: %s',
                      ', '.join(map(str, transitions)))

        ## Retrieve range
        e0 = options.beam.energy_eV
        safety_factor = 3.0

        zmax_m = 1e-08  # PENPEMA forces the minimum depth to be 1e-6 cm
        for material in materials:
            for transition in transitions:
                tmpzmax_m = photon_range(e0, material,
                                         transition) * safety_factor
                zmax_m = max(zmax_m, tmpzmax_m)

        ## Create lines
        text = ' '.join(map(str, [-3, 3, 1]))
        lines.append(self._KEYWORD_GRIDX(text))

        text = ' '.join(map(str, [-3, 3, 1]))
        lines.append(self._KEYWORD_GRIDY(text))

        channels = min(100, detector.channels)  # Maximum of 100 channels
        text = ' '.join(map(str, [-zmax_m * 1e2, 0, channels]))
        lines.append(self._KEYWORD_GRIDZ(text))

        index = phdets_key_index[key] + 1

        for transition in transitions:
            code = int(transition.z * 1e6 + \
                   transition.dest.index * 1e4 + \
                   transition.src.index * 1e2)

            text = ' '.join(map(str, [code, 0]))  # No absorption
            lines.append(self._KEYWORD_XRLINE(text))

            text = ' '.join(map(str, [code, index]))  # With absorption
            lines.append(self._KEYWORD_XRLINE(text))

        lines.append(self._COMMENT_SKIP())