1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
from __future__ import annotations
import glob
import os
import shutil
import subprocess
import pytest
from cctbx import crystal
from dxtbx.model.experiment_list import ExperimentList, ExperimentListFactory
from dxtbx.serialize import load
from dials.command_line import cluster_unit_cell
def test_dials_cluster_unit_cell_command_line(dials_data, tmp_path):
pytest.importorskip("scipy")
data_dir = dials_data("polyhedra_narrow_wedges", pathlib=True)
experiments = sorted(data_dir.glob("sweep_*_experiments.json"))
result = subprocess.run(
[shutil.which("dials.cluster_unit_cell"), "plot.show=False"] + experiments,
cwd=tmp_path,
capture_output=True,
)
assert not result.returncode
assert tmp_path.joinpath("cluster_unit_cell.png").is_file()
def test_dials_cluster_unit_cell_command_line_output_files(dials_data, tmp_path):
pytest.importorskip("scipy")
data_dir = dials_data("polyhedra_narrow_wedges", pathlib=True)
experiments = sorted(data_dir.glob("sweep_*_experiments.json"))
reflections = sorted(data_dir.glob("sweep_*_reflections.pickle"))
# Combine experiments. Write PHIL file to avoid "command line is too long" error on Windows
with open(tmp_path / "input.phil", "w") as f:
f.writelines(f"input.reflections={i}" + os.linesep for i in reflections)
f.writelines(f"input.experiments={i}" + os.linesep for i in experiments)
result = subprocess.run(
[shutil.which("dials.combine_experiments"), "input.phil"],
cwd=tmp_path,
capture_output=True,
)
assert not result.returncode
assert (tmp_path / "combined.refl").is_file()
assert (tmp_path / "combined.expt").is_file()
result = subprocess.run(
[
shutil.which("dials.cluster_unit_cell"),
"plot.show=False",
tmp_path / "combined.refl",
tmp_path / "combined.expt",
"output.clusters=True",
"threshold=40",
],
cwd=tmp_path,
capture_output=True,
)
assert not result.returncode
assert (tmp_path / "cluster_unit_cell.png").is_file()
assert (tmp_path / "cluster_1.refl").is_file()
assert (tmp_path / "cluster_1.expt").is_file()
expts = load.experiment_list(tmp_path / "cluster_1.expt", check_format=False)
assert len(expts) == 101
assert (tmp_path / "cluster_2.refl").is_file()
assert (tmp_path / "cluster_2.expt").is_file()
expts = load.experiment_list(tmp_path / "cluster_2.expt", check_format=False)
assert len(expts) == 1
assert (tmp_path / "cluster_3.refl").is_file()
assert (tmp_path / "cluster_3.expt").is_file()
expts = load.experiment_list(tmp_path / "cluster_3.expt", check_format=False)
assert len(expts) == 1
result = subprocess.run(
[
shutil.which("dials.split_experiments"),
tmp_path / "combined.refl",
tmp_path / "combined.expt",
],
cwd=tmp_path,
capture_output=True,
)
assert not result.returncode
experiments = list(tmp_path.glob("split_*.expt"))
reflections = list(tmp_path.glob("split_*.refl"))
# Write PHIL file to avoid "command line is too long" error on Windows
with open(tmp_path / "input.phil", "w") as f:
f.writelines(f"input.reflections={i}" + os.linesep for i in reflections)
f.writelines(f"input.experiments={i}" + os.linesep for i in experiments)
result = subprocess.run(
[
shutil.which("dials.cluster_unit_cell"),
"output.clusters=True",
"threshold=40",
"plot.show=False",
"input.phil",
],
cwd=tmp_path,
capture_output=True,
)
assert not result.returncode
def test_cluster_unit_cell_api(dials_data):
pytest.importorskip("scipy")
data_dir = dials_data("polyhedra_narrow_wedges", pathlib=True)
experiments = ExperimentList(
[
ExperimentListFactory.from_json_file(expt, check_format=False)[0]
for expt in glob.glob(os.path.join(data_dir, "sweep_*_experiments.json"))
]
)
crystal_symmetries = [
crystal.symmetry(
unit_cell=expt.crystal.get_unit_cell(),
space_group=expt.crystal.get_space_group(),
)
for expt in experiments
]
params = cluster_unit_cell.phil_scope.extract()
params.plot.show = False
params.plot.name = None
clusters = cluster_unit_cell.do_cluster_analysis(crystal_symmetries, params)
assert len(clusters) == 1
cluster = clusters[0]
assert len(cluster) == 40
assert cluster.median_cell == pytest.approx(
[
90.9430182020995,
90.9430182020995,
90.9430182020995,
109.47122063449069,
109.47122063449069,
109.47122063449069,
],
abs=1e-6,
)
assert cluster.cell_std == pytest.approx(
[0.09509739126548639, 0.09509739126548526, 0.0950973912654865, 0, 0, 0],
abs=1e-6,
)
|