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
|
"""Trivial check for whether classification of reflections as exiting or
entering the Ewald sphere is done the right way round"""
from __future__ import annotations
import math
import pytest
from . import geometry_phil, minimiser_phil
def test():
from cctbx.sgtbx import space_group, space_group_symbols
# We will set up a mock scan
from dxtbx.model import ScanFactory
from dxtbx.model.experiment_list import Experiment, ExperimentList
from libtbx.phil import parse
from scitbx import matrix
from scitbx.array_family import flex
from dials.algorithms.refinement.prediction.managed_predictors import (
ScansExperimentsPredictor,
ScansRayPredictor,
)
# Reflection prediction
from dials.algorithms.spot_prediction import IndexGenerator
# Building experimental models
from .setup_geometry import Extract
master_phil = parse(f"{geometry_phil}\n{minimiser_phil}")
overrides = """geometry.parameters.crystal.a.length.range = 10 50
geometry.parameters.crystal.b.length.range = 10 50
geometry.parameters.crystal.c.length.range = 10 50"""
models = Extract(master_phil, local_overrides=overrides)
mydetector = models.detector
mygonio = models.goniometer
mycrystal = models.crystal
mybeam = models.beam
#############################
# Generate some reflections #
#############################
# All indices in a 2.0 Angstrom sphere
resolution = 2.0
index_generator = IndexGenerator(
mycrystal.get_unit_cell(),
space_group(space_group_symbols(1).hall()).type(),
resolution,
)
indices = index_generator.to_array()
# Build a mock scan for a 30 degree sequence
sf = ScanFactory()
myscan = sf.make_scan(
image_range=(1, 300),
exposure_times=0.1,
oscillation=(0, 0.1),
epochs=list(range(300)),
deg=True,
)
sequence_range = myscan.get_oscillation_range(deg=False)
assert sequence_range == pytest.approx((0.0, math.pi / 6.0))
im_width = myscan.get_oscillation(deg=False)[1]
assert im_width == pytest.approx(0.1 * math.pi / 180.0)
# Create an ExperimentList for ScansRayPredictor
experiments = ExperimentList()
experiments.append(
Experiment(
beam=mybeam,
detector=mydetector,
goniometer=mygonio,
scan=myscan,
crystal=mycrystal,
imageset=None,
)
)
# Select those that are excited in a 30 degree sequence and get angles
ray_predictor = ScansRayPredictor(experiments, sequence_range)
obs_refs = ray_predictor(indices)
# Set the experiment number
obs_refs["id"] = flex.int(len(obs_refs), 0)
# Calculate intersections
ref_predictor = ScansExperimentsPredictor(experiments)
obs_refs = ref_predictor(obs_refs)
print("Total number of observations made", len(obs_refs))
s0 = matrix.col(mybeam.get_s0())
spindle = matrix.col(mygonio.get_rotation_axis())
for ref in obs_refs.rows():
# get the s1 vector of this reflection
s1 = matrix.col(ref["s1"])
r = s1 - s0
r_orig = r.rotate_around_origin(spindle, -1.0, deg=True)
# is it outside the Ewald sphere (i.e. entering)?
test = (s0 + r_orig).length() > s0.length()
assert ref["entering"] == test
|