Esempio n. 1
0
    def interpolate_line(self, start, end, gpts=None, sampling=None):
        from abtem.scan import LineScan

        if not (self.dimensions == 2):
            raise RuntimeError()

        if (self.calibrations[0] is None) or (self.calibrations[1] is None):
            raise RuntimeError()

        if self.calibrations[0].units != self.calibrations[1].units:
            raise RuntimeError()

        if (gpts is None) & (sampling is None):
            sampling = (self.calibrations[0].sampling +
                        self.calibrations[1].sampling) / 2.

        x = np.linspace(self.calibrations[0].offset,
                        self.shape[0] * self.calibrations[0].sampling,
                        self.shape[0])
        y = np.linspace(self.calibrations[1].offset,
                        self.shape[1] * self.calibrations[1].sampling,
                        self.shape[1])

        scan = LineScan(start=start, end=end, gpts=gpts, sampling=sampling)

        interpolated_array = interpn((x, y), self.array, scan.get_positions())

        calibration = Calibration(offset=0,
                                  sampling=scan.sampling[0],
                                  units=self.calibrations[0].units,
                                  name=self.calibrations[0].name)
        return Measurement(interpolated_array, calibration)
Esempio n. 2
0
def test_linescan_to_file(tmp_path):
    d = tmp_path / 'sub'
    d.mkdir()
    path = d / 'measurement2.hdf5'

    atoms = read(_set_path('orthogonal_graphene.cif'))
    potential = Potential(atoms=atoms, sampling=.05)

    probe = Probe(energy=200e3, semiangle_cutoff=30)

    probe.grid.match(potential)

    scan = LineScan(start=[0, 0], end=[0, potential.extent[1]], gpts=20)

    detector = PixelatedDetector()
    export_detector = PixelatedDetector(save_file=path)

    measurements = probe.scan(scan, [detector, export_detector],
                              potential,
                              pbar=False)

    measurement = measurements[0]
    imported_measurement = Measurement.read(measurements[1])

    assert np.allclose(measurement.array, imported_measurement.array)
    assert measurement.calibrations[0] == imported_measurement.calibrations[0]
    assert measurement.calibrations[1] == imported_measurement.calibrations[1]
Esempio n. 3
0
def test_probe_waves_line_scan():
    probe = Probe(energy=60e3)
    detector = DummyDetector()
    potential = DummyPotential(extent=5, sampling=.1)

    scan = LineScan((0, 0), (1, 1), gpts=10)
    measurement = probe.scan(scan,
                             detector,
                             potential,
                             max_batch=1,
                             pbar=False)

    assert detector._detect_count == 10
    assert np.all(measurement.array == 1.)

    measurement = probe.scan(scan, [detector], potential, pbar=False)
    assert detector._detect_count == 11
    assert np.all(measurement.array == 1.)

    measurement = probe.scan(scan,
                             detector,
                             potential,
                             max_batch=3,
                             pbar=False)
    assert detector._detect_count == 15
    assert np.all(measurement.array == 1.)
Esempio n. 4
0
def test_fig():
    atoms = Atoms('CSiCuAuU',
                  positions=[(x, 25, 4) for x in np.linspace(5, 45, 5)],
                  cell=(50, 50, 8))

    gpts = 2048

    potential = Potential(atoms=atoms,
                          gpts=gpts,
                          parametrization='kirkland',
                          slice_thickness=8)

    probe = Probe(energy=200e3, defocus=700, Cs=1.3e7, semiangle_cutoff=10.37)

    probe.grid.match(potential)

    scan = LineScan(start=[5, 25], end=[45, 25], gpts=5)

    detector = AnnularDetector(inner=40, outer=200)

    measurements = probe.scan(scan, [detector], potential, pbar=False)

    #assert np.allclose(measurements[detector].array, [0.00010976, 0.00054356, 0.00198158, 0.00997221, 0.01098883])
    assert np.allclose(
        measurements[detector].array,
        [0.0001168, 0.00059303, 0.00214667, 0.00977803, 0.01167613],
        atol=1e-5)
Esempio n. 5
0
def test_interpolation_scan():
    atoms = Atoms('C', positions=[(2.5, 2.5, 2)], cell=(5, 5, 4))
    potential = Potential(atoms)
    linescan = LineScan(start=[0, 0], end=[2.5, 2.5], gpts=10)
    detector = AnnularDetector(inner=80, outer=200)

    probe = Probe(semiangle_cutoff=30, energy=80e3, gpts=250)
    measurements = probe.scan(linescan, [detector],
                              potential,
                              max_batch=50,
                              pbar=False)

    S_builder = SMatrix(semiangle_cutoff=30.,
                        energy=80e3,
                        interpolation=2,
                        gpts=500)
    atoms = Atoms('C', positions=[(2.5, 2.5, 2)], cell=(5, 5, 4))
    atoms *= (2, 2, 1)
    potential = Potential(atoms)
    S = S_builder.multislice(potential, pbar=False)
    prism_measurements = S.scan(linescan,
                                detector,
                                max_batch_probes=10,
                                pbar=False)

    assert np.allclose(measurements.array, prism_measurements.array, atol=1e-6)
Esempio n. 6
0
def test_probe_waves_line_scan():
    atoms = Atoms('CO',
                  positions=[(2.5, 2.5, 2), (2.5, 2.5, 3)],
                  cell=(5, 5, 4))
    frozen_phonons = FrozenPhonons(atoms, 2, sigmas={'C': 0, 'O': 0.})

    potential = Potential(atoms, sampling=.05)
    tds_potential = Potential(frozen_phonons, sampling=.05)

    linescan = LineScan(start=[0, 0], end=[2.5, 2.5], gpts=10)
    detector = AnnularDetector(inner=80, outer=200)

    probe = Probe(semiangle_cutoff=30, energy=80e3, gpts=500)

    measurements = probe.scan(linescan, [detector],
                              potential,
                              max_batch=50,
                              pbar=False)
    tds_measurements = probe.scan(linescan, [detector],
                                  tds_potential,
                                  max_batch=50,
                                  pbar=False)
    assert np.allclose(measurements[detector].array,
                       tds_measurements[detector].array,
                       atol=1e-6)

    frozen_phonons = FrozenPhonons(atoms, 2, sigmas={'C': 0, 'O': 0.1})
    tds_potential = Potential(frozen_phonons, sampling=.05)
    tds_measurements = probe.scan(linescan, [detector],
                                  tds_potential,
                                  max_batch=50,
                                  pbar=False)
    assert not np.allclose(measurements[detector].array,
                           tds_measurements[detector].array,
                           atol=1e-6)
Esempio n. 7
0
def interpolate_line(measurement: Measurement,
                     start: Sequence[float],
                     end: Sequence[float],
                     sampling: Sequence[float] = None):
    from abtem.scan import LineScan

    array = np.squeeze(measurement.array)

    if not (len(array.shape) == 2):
        raise RuntimeError()

    if (measurement.calibrations[-1] is None) or (measurement.calibrations[-2]
                                                  is None):
        raise RuntimeError()

    if measurement.calibrations[-2].units != measurement.calibrations[-1].units:
        raise RuntimeError()

    if (sampling is None):
        sampling = (measurement.calibrations[-2].sampling +
                    measurement.calibrations[-1].sampling) / 2.

    x = np.linspace(
        measurement.calibrations[-2].offset,
        measurement.shape[-2] * measurement.calibrations[-2].sampling,
        measurement.shape[-2])
    y = np.linspace(
        measurement.calibrations[1].offset,
        measurement.shape[-1] * measurement.calibrations[-1].sampling,
        measurement.shape[-1])

    line_scan = LineScan(start=start, end=end, sampling=sampling)

    interpolated_array = interpn((x, y), array, line_scan.get_positions())

    return Measurement(
        interpolated_array,
        Calibration(offset=0,
                    sampling=line_scan.sampling[0],
                    units=measurement.calibrations[-2].units,
                    name=measurement.calibrations[-2].name))
Esempio n. 8
0
    def interpolate_line(self, start, end, gpts=None, sampling=None, width=None, interpolation='splinef2d'):
        from abtem.scan import LineScan
        self = self.squeeze()

        if (self.calibrations[0] is None) or (self.calibrations[1] is None):
            raise RuntimeError()

        if self.calibrations[0].units != self.calibrations[1].units:
            raise RuntimeError()

        if (gpts is None) & (sampling is None):
            sampling = (self.calibrations[0].sampling + self.calibrations[1].sampling) / 2.

        x = np.linspace(self.calibrations[0].offset, self.shape[0] * self.calibrations[0].sampling, self.shape[0])
        y = np.linspace(self.calibrations[1].offset, self.shape[1] * self.calibrations[1].sampling, self.shape[1])

        scan = LineScan(start=start, end=end, gpts=gpts, sampling=sampling)

        if width is not None:
            direction = scan.direction
            perpendicular_direction = np.array([-direction[1], direction[0]])
            n = int(np.ceil(width / scan.sampling[0]))
            perpendicular_positions = np.linspace(-width, width, n)[:, None] * perpendicular_direction[None]
            positions = scan.get_positions()[None] + perpendicular_positions[:, None]
            positions = positions.reshape((-1, 2))
            interpolated_array = interpn((x, y), self.array, positions, method=interpolation, bounds_error=False,
                                         fill_value=0)
            interpolated_array = interpolated_array.reshape((n, -1)).mean(0)

        else:
            interpolated_array = interpn((x, y), self.array, scan.get_positions(), method=interpolation,
                                         bounds_error=False, fill_value=0)

        calibration = Calibration(offset=0, sampling=scan.sampling[0],
                                  units=self.calibrations[0].units,
                                  name=self.calibrations[0].name)
        return Measurement(interpolated_array, calibration)
Esempio n. 9
0
def test_probe_waves_line_scan():
    potential = Potential(Atoms('C', positions=[(2.5, 2.5, 2)],
                                cell=(5, 5, 4)))
    linescan = LineScan(start=[0, 0], end=[2.5, 2.5], gpts=10)
    detector = AnnularDetector(inner=80, outer=200)

    S = SMatrix(30, 80e3, 1, gpts=500).multislice(potential, pbar=False)
    probe = Probe(semiangle_cutoff=30, energy=80e3, gpts=500)

    prism_measurement = S.scan(linescan,
                               detector,
                               max_batch_probes=10,
                               pbar=False)
    measurement = probe.scan(linescan,
                             detector,
                             potential,
                             max_batch=50,
                             pbar=False)

    assert np.allclose(measurement.array, prism_measurement.array, atol=1e-6)
Esempio n. 10
0
def test_line_scan():
    start = (0, 0)
    end = (1, 1)
    scan = LineScan(start, end, gpts=5)

    positions = scan.get_positions()
    assert np.allclose(positions[0], start)
    assert np.allclose(positions[-1], end)
    assert np.allclose(positions[2], np.mean([start, end], axis=0))
    assert np.allclose(np.linalg.norm(np.diff(positions, axis=0), axis=1), scan.sampling[0])

    scan = LineScan(start, end, gpts=5, endpoint=False)
    positions = scan.get_positions()
    assert np.allclose(positions[0], start)
    assert np.allclose(positions[-1], (end[0] - (end[0] - start[0]) / 5, end[1] - (end[1] - start[1]) / 5))
Esempio n. 11
0
def test_fig_5_22():
    atoms = Atoms('CSiCuAuU',
                  positions=[(x, 25, 4) for x in np.linspace(5, 45, 5)],
                  cell=(50, 50, 8))
    gpts = 2048
    potential = Potential(atoms=atoms,
                          gpts=gpts,
                          parametrization='kirkland',
                          slice_thickness=8)
    #probe = Probe(energy=200e3, defocus=700, Cs=1.3e7, semiangle_cutoff=10.37, rolloff=.1)
    probe = Probe(energy=200e3, defocus=700, Cs=1.3e7, semiangle_cutoff=10.37)

    probe.grid.match(potential)
    scan = LineScan(start=[5, 25], end=[45, 25], gpts=5)
    detector = AnnularDetector(inner=40, outer=200)
    measurement = probe.scan(scan, detector, potential, pbar=False)

    #correct_values = np.array([0.0001168, 0.00059303, 0.00214667, 0.00977803, 0.01167613])
    correct_values = np.array(
        [0.00010675, 0.00055145, 0.00199743, 0.00911063, 0.01087296])
    assert np.allclose(measurement.array, correct_values, atol=1e-5)
Esempio n. 12
0
def test_linescan_raises():
    with pytest.raises(ValueError) as e:
        LineScan(start=0, end=1)

    assert str(e.value) == 'Scan start/end has incorrect shape'
Esempio n. 13
0
    def interpolate_line(
            self,
            start: Tuple[float, float],
            end: Tuple[float, float],
            gpts: int = None,
            sampling: float = None,
            width: float = None,
            interpolation_method: str = 'splinef2d') -> 'Measurement':
        """
        Interpolate 2d measurement along a line.

        Parameters
        ----------
        start : two float
            Start point on line [Å].
        end : two float
            End point on line [Å].
        gpts : int
            Number of grid points along line.
        sampling : float
            Sampling rate of grid points along line [1 / Å].
        width : float
            The interpolation will be averaged across
        interpolation_method : str


        Returns
        -------
        Measurement
            Line profile measurement.
        """
        from abtem.scan import LineScan
        measurement = self.squeeze()

        if measurement.dimensions != 2:
            raise RuntimeError('measurement must be 2d')

        if measurement.calibrations[0].units != measurement.calibrations[
                1].units:
            raise RuntimeError(
                'the units of the interpolation dimensions must match')

        if (gpts is None) & (sampling is None):
            sampling = (measurement.calibrations[0].sampling +
                        measurement.calibrations[1].sampling) / 2.

        x = np.linspace(
            measurement.calibrations[0].offset,
            measurement.shape[0] * measurement.calibrations[0].sampling +
            measurement.calibrations[0].offset, measurement.shape[0])
        y = np.linspace(
            measurement.calibrations[1].offset,
            measurement.shape[1] * measurement.calibrations[1].sampling +
            measurement.calibrations[1].offset, measurement.shape[1])

        scan = LineScan(start=start, end=end, gpts=gpts, sampling=sampling)

        if width is not None:
            direction = scan.direction
            perpendicular_direction = np.array([-direction[1], direction[0]])
            n = int(np.ceil(width / scan.sampling[0]))
            perpendicular_positions = np.linspace(
                -width, width, n)[:, None] * perpendicular_direction[None]
            positions = scan.get_positions(
            )[None] + perpendicular_positions[:, None]
            positions = positions.reshape((-1, 2))
            interpolated_array = interpn((x, y),
                                         measurement.array,
                                         positions,
                                         method=interpolation_method,
                                         bounds_error=False,
                                         fill_value=0)
            # import matplotlib.pyplot as plt
            # plt.plot(*positions.T,'ro')
            # plt.show()

            interpolated_array = interpolated_array.reshape((n, -1)).mean(0)

        else:
            interpolated_array = interpn((x, y),
                                         measurement.array,
                                         scan.get_positions(),
                                         method=interpolation_method,
                                         bounds_error=False,
                                         fill_value=0)

        calibration = Calibration(offset=0,
                                  sampling=scan.sampling[0],
                                  units=measurement.calibrations[0].units,
                                  name=measurement.calibrations[0].name)
        return Measurement(interpolated_array, calibration)