File: test_goniometer_parameters.py

package info (click to toggle)
dials 3.25.0%2Bdfsg3-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 20,112 kB
  • sloc: python: 134,740; cpp: 34,526; makefile: 160; sh: 142
file content (73 lines) | stat: -rw-r--r-- 2,524 bytes parent folder | download | duplicates (2)
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
from __future__ import annotations

import math

import pytest

from dxtbx.model import Goniometer
from libtbx.test_utils import approx_equal
from scitbx import matrix
from scitbx.array_family import flex

from dials.algorithms.refinement.parameterisation.goniometer_parameters import (
    GoniometerParameterisation,
)
from dials.algorithms.refinement.refinement_helpers import (
    get_fd_gradients,
    random_param_shift,
)


def random_gonio():
    # make a random rotation axis with a random setting matrix
    axis = matrix.col(flex.random_double_point_on_sphere())
    fixed_rotation = matrix.sqr((1, 0, 0, 0, 1, 0, 0, 0, 1))
    setting_rotation = matrix.sqr(flex.random_double_r3_rotation_matrix())
    goniometer = Goniometer(axis, fixed_rotation, setting_rotation)
    return goniometer


def test():
    goniometer = random_gonio()
    gonp = GoniometerParameterisation(goniometer)

    # Let's do some basic tests. First, can we change parameter values and
    # update the laboratory frame rotation axis?
    e_lab = matrix.col(goniometer.get_rotation_axis())
    gonp.set_param_vals([1000 * 0.1, 1000 * 0.1])
    assert matrix.col(goniometer.get_rotation_axis()).angle(e_lab) == pytest.approx(
        0.1413033
    )

    # random goniometers and random parameter shifts
    attempts = 1000
    for i in range(attempts):
        # make a random goniometer and parameterise it
        goniometer = random_gonio()
        gonp = GoniometerParameterisation(goniometer)

        # apply a random parameter shift
        p_vals = gonp.get_param_vals()
        p_vals = random_param_shift(p_vals, [1000 * math.pi / 9, 1000 * math.pi / 9])
        gonp.set_param_vals(p_vals)

        # compare analytical and finite difference derivatives
        an_ds_dp = gonp.get_ds_dp()
        fd_ds_dp = get_fd_gradients(
            gonp, [1.0e-5 * math.pi / 180, 1.0e-5 * math.pi / 180]
        )

        null_mat = matrix.sqr((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))
        for j in range(2):
            try:
                assert approx_equal((fd_ds_dp[j] - an_ds_dp[j]), null_mat, eps=1.0e-6)
            except Exception:
                print("for try", i)
                print("failure for parameter number", j)
                print("with fd_ds_dp = ")
                print(fd_ds_dp[j])
                print("and an_ds_dp = ")
                print(an_ds_dp[j])
                print("so that difference fd_ds_dp - an_ds_dp =")
                print(fd_ds_dp[j] - an_ds_dp[j])
                raise