def test_partition_measurement(): atoms = read( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data/amorphous_carbon.cif')) potential = Potential(atoms, gpts=512, slice_thickness=1, projection='infinite', parametrization='kirkland').build(pbar=False) detector = AnnularDetector(inner=70, outer=100) gridscan = GridScan(start=[0, 0], end=potential.extent, gpts=16) S = SMatrix(expansion_cutoff=15, interpolation=1, energy=300e3) S = S.multislice(potential, pbar=False) measurements = S.scan(gridscan, [detector], pbar=False) scans = gridscan.partition_scan((2, 2)) partitioned_measurements = { detector: detector.allocate_measurement(S.collapse((0, 0)), gridscan) } for scan in scans: partitioned_measurements = S.scan(scan, measurements, pbar=False) assert np.allclose(partitioned_measurements[detector].array, measurements[detector].array)
def test_partition_measurement(): atoms = read( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data/amorphous_carbon.cif')) potential = Potential(atoms, gpts=256, slice_thickness=1, projection='infinite', parametrization='kirkland').build(pbar=False) detector = AnnularDetector(inner=70, outer=100) gridscan = GridScan(start=[0, 0], end=potential.extent, gpts=4) probe = Probe(semiangle_cutoff=15, energy=300e3) measurements = probe.scan(gridscan, detector, potential, pbar=False) scans = gridscan.partition_scan((2, 2)) partitioned_measurements = detector.allocate_measurement(probe, gridscan) for scan in scans: probe.scan(scan, detector, potential, measurements=partitioned_measurements, pbar=False) assert np.allclose(partitioned_measurements.array, measurements.array)
def test_calibration_coordinates(): for endpoint in (True, False): gridscan = GridScan(sampling=.7, start=(0, 0), end=(4, 4), endpoint=endpoint) calibration_coordinates = gridscan.calibrations[0].coordinates( gridscan.gpts[0]) assert np.all(calibration_coordinates == gridscan.get_positions() [::gridscan.gpts[0], 0])
def test_crop(): S = SMatrix(expansion_cutoff=30, interpolation=3, energy=300e3, extent=10, sampling=.02).build() gridscan = GridScan(start=[0, 0], end=S.extent, gpts=64) scans = gridscan.partition_scan((2, 2)) cropped = S.crop_to_scan(scans[0]) assert cropped.gpts != S.gpts position = (4.9, 0.) assert np.allclose( S.collapse(position).array - cropped.collapse(position).array, 0.)
def test_downsample_detect(): atoms = read('data/srtio3_100.cif') atoms *= (4, 4, 1) potential = Potential(atoms, gpts=256, projection='infinite', slice_thickness=.5, parametrization='kirkland').build(pbar=False) detector = FlexibleAnnularDetector() end = (potential.extent[0] / 4, potential.extent[1] / 4) gridscan = GridScan(start=[0, 0], end=end, sampling=.2) S = SMatrix(energy=300e3, semiangle_cutoff=9.4, rolloff=0.05, expansion_cutoff=10) S_exit = S.multislice(potential, pbar=False) measurement = S_exit.scan(gridscan, detector, pbar=False) S_downsampled = S_exit.downsample() downsampled_measurement = S_downsampled.scan(gridscan, detector, pbar=False) assert S_downsampled.array.shape != S_exit.array.shape assert not np.all(measurement.array == downsampled_measurement.array) assert np.allclose(measurement.array, downsampled_measurement.array)
def test_gridscan_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 = GridScan(start=[0, 0], end=[0, potential.extent[1]], gpts=(10, 9)) 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]
def test_flexible_annular_detector(): atoms = read('data/srtio3_100.cif') atoms *= (4, 4, 1) potential = Potential( atoms, gpts=512, projection='infinite', slice_thickness=.5, parametrization='kirkland', ).build(pbar=False) probe = Probe(energy=300e3, semiangle_cutoff=9.4, rolloff=0.05) flexible_detector = FlexibleAnnularDetector() annular_detector = AnnularDetector(inner=30, outer=80) end = (potential.extent[0] / 4, potential.extent[1] / 4) gridscan = GridScan(start=[0, 0], end=end, sampling=.2) measurements = probe.scan(gridscan, [flexible_detector, annular_detector], potential, pbar=False) assert np.allclose(measurements[flexible_detector].integrate(30, 80).array, measurements[annular_detector].array)
def test_unequal_interpolation(): from ase.build import nanotube def make_atoms(l): atoms = nanotube(6, 0, length=l) atoms.rotate(-90, 'x', rotate_cell=True) atoms.center(vacuum=5, axis=(0, 1)) cell = atoms.cell.copy() cell[1] = np.abs(atoms.cell[2]) cell[2] = np.abs(atoms.cell[1]) atoms.set_cell(cell) return atoms detector = AnnularDetector(50, 150) atoms1 = make_atoms(8) S1 = SMatrix(energy=80e3, expansion_cutoff=10, semiangle_cutoff=10, interpolation=(2, 4), device='cpu', gpts=(256, 512)) S1.extent = np.diag(atoms1.cell)[:2] scan = GridScan((0, 0), (atoms1.cell[0, 0], atoms1.cell[1, 1] / 2), sampling=S1.ctf.nyquist_sampling * .9) measurement1 = S1.scan(scan, detector, atoms1, pbar=False) atoms2 = make_atoms(4) S2 = SMatrix(energy=80e3, expansion_cutoff=10, semiangle_cutoff=10, interpolation=(2, 2), device='cpu', gpts=(256, 256)) S2.extent = np.diag(atoms2.cell)[:2] scan = GridScan((0, 0), (atoms2.cell[0, 0], atoms2.cell[1, 1]), sampling=S2.ctf.nyquist_sampling * .9) measurement2 = S2.scan(scan, detector, atoms2, pbar=False) assert len(S1) == len(S2) assert np.allclose((S1.build().collapse().intensity() - S2.build().collapse().intensity()).array, 0) assert np.allclose((measurement2 - measurement1).array, 0, atol=1e-5)
def test_probe_waves_grid_scan(): probe = Probe(energy=60e3) detector = DummyDetector() potential = DummyPotential(extent=5, sampling=.1) scan = GridScan((0, 0), (1, 1), gpts=10) measurement = probe.scan(scan, detector, potential, max_batch=1, pbar=False) assert detector._detect_count == 100 assert np.all(measurement.array == 1.)
def test_cropped_scan(): atoms = read( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data/amorphous_carbon.cif')) potential = Potential(atoms, gpts=512, slice_thickness=1, device='gpu', projection='infinite', parametrization='kirkland', storage='gpu').build(pbar=True) detector = AnnularDetector(inner=40, outer=60) gridscan = GridScan(start=[0, 0], end=potential.extent, gpts=16) S = SMatrix(expansion_cutoff=20, interpolation=4, energy=300e3, device='gpu', storage='cpu') # .build() S = S.multislice(potential, pbar=True) S = S.downsample('limit') measurements = S.scan(gridscan, [detector], max_batch_probes=64) scans = gridscan.partition_scan((2, 2)) cropped_measurements = { detector: detector.allocate_measurement(S.collapse((0, 0)), gridscan) } for scan in scans: cropped = S.crop_to_scan(scan) cropped = cropped.transfer('gpu') cropped_measurements = cropped.scan(scan, cropped_measurements, pbar=False) assert np.allclose(cropped_measurements[detector].array, measurements[detector].array)
def test_partition(): gridscan = GridScan(start=(0, 0), end=(2, 2), sampling=.5, endpoint=False) scans = gridscan.partition_scan((2, 2)) positions = [] for scan in scans: positions.append(scan.get_positions()) assert np.allclose(((np.vstack(positions)[None] - gridscan.get_positions()[:, None])**2).min(0), 0) assert np.allclose(((np.vstack(positions)[None] - gridscan.get_positions()[:, None])**2).min(1), 0) gridscan = GridScan(start=(0, 0), end=(2, 2), sampling=.5, endpoint=True) scans = gridscan.partition_scan((2, 2)) positions = [] for scan in scans: positions.append(scan.get_positions()) assert np.allclose(((np.vstack(positions)[None] - gridscan.get_positions()[:, None])**2).min(0), 0) assert np.allclose(((np.vstack(positions)[None] - gridscan.get_positions()[:, None])**2).min(1), 0)
def test_grid_scan(): start = (0, 0) end = (1, 2) scan = GridScan(start, end, gpts=5, endpoint=True) positions = scan.get_positions() assert np.all(positions[0] == start) assert np.all(positions[-1] == end) assert np.allclose(positions[4], [start[1], end[1]]) assert np.allclose(np.linalg.norm(np.diff(positions[:4], axis=0), axis=1), scan.sampling[1]) scan = GridScan(start, end, gpts=5, endpoint=False) positions = scan.get_positions() assert np.all(positions[0] == start) assert np.allclose(positions[-1], (end[0] - (end[0] - start[0]) / 5, end[1] - (end[1] - start[1]) / 5))
def test_preallocated_measurement(): atoms = read( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data/amorphous_carbon.cif')) potential = Potential(atoms, gpts=256, slice_thickness=1, projection='infinite', parametrization='kirkland').build(pbar=False) scan = GridScan(start=[0, 0], end=potential.extent, gpts=4) detector1 = AnnularDetector(inner=70, outer=100) probe = Probe(semiangle_cutoff=15, energy=300e3, extent=potential.extent, gpts=512) measurement = detector1.allocate_measurement(probe, scan) probe.scan(scan, detector1, potential, measurement, pbar=False) assert np.any(measurement.array > 0) detector2 = PixelatedDetector() measurement1 = detector1.allocate_measurement(probe, scan) measurement2 = detector2.allocate_measurement(probe, scan) with pytest.raises(ValueError) as e: probe.scan(scan, [detector1, detector2], potential, measurement1, pbar=False) probe.scan(scan, [detector1, detector2], potential, { detector1: measurement1, detector2: measurement2 }, pbar=False)
def test_gridscan_raises(): with pytest.raises(ValueError) as e: GridScan(start=0, end=1) assert str(e.value) == 'Scan start/end has incorrect shape'