File: tst_minimum_covering_ellipsoid.py

package info (click to toggle)
cctbx 2024.10%2Bds2%2B~3.22.1%2Bds1-5
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 136,708 kB
  • sloc: python: 892,916; cpp: 299,439; ansic: 22,625; fortran: 18,268; javascript: 2,046; sh: 1,114; sql: 632; csh: 519; java: 368; makefile: 317; xml: 25
file content (67 lines) | stat: -rw-r--r-- 2,219 bytes parent folder | download | duplicates (3)
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
from __future__ import absolute_import, division, print_function
from six.moves import range
def run(args):
  assert len(args) == 0
  n_trials = 100
  from scitbx.math.minimum_covering_ellipsoid import compute as mce_compute
  from scitbx.array_family import flex
  from libtbx.test_utils import approx_equal, is_below_limit
  # XXX point group 222 should be sufficient, but 432 is currently needed
  point_group_432_rotation_matrices = [
    (1,0,0,0,1,0,0,0,1),
    (1,0,0,0,0,-1,0,1,0),
    (1,0,0,0,0,1,0,-1,0),
    (0,0,1,0,1,0,-1,0,0),
    (0,0,-1,0,1,0,1,0,0),
    (0,-1,0,1,0,0,0,0,1),
    (0,1,0,-1,0,0,0,0,1),
    (0,0,1,1,0,0,0,1,0),
    (0,1,0,0,0,1,1,0,0),
    (0,-1,0,0,0,-1,1,0,0),
    (0,0,1,-1,0,0,0,-1,0),
    (0,-1,0,0,0,1,-1,0,0),
    (0,0,-1,-1,0,0,0,1,0),
    (0,0,-1,1,0,0,0,-1,0),
    (0,1,0,0,0,-1,-1,0,0),
    (1,0,0,0,-1,0,0,0,-1),
    (-1,0,0,0,1,0,0,0,-1),
    (-1,0,0,0,-1,0,0,0,1),
    (0,1,0,1,0,0,0,0,-1),
    (0,-1,0,-1,0,0,0,0,-1),
    (0,0,1,0,-1,0,1,0,0),
    (0,0,-1,0,-1,0,-1,0,0),
    (-1,0,0,0,0,1,0,1,0),
    (-1,0,0,0,0,-1,0,-1,0)]
  def check(center, radii, rotation):
    a,b,c = radii
    points_principal = flex.vec3_double([
      (-a,0,0),
      (a,0,0),
      (0,-b,0),
      (0,b,0),
      (0,0,-c),
      (0,0,c)])
    points = rotation * points_principal + center
    mce = mce_compute(points)
    assert approx_equal(mce.center, center)
    assert approx_equal(sorted(mce.radii), sorted(radii))
    assert approx_equal(mce.rotation.determinant(), 1)
    points_mce = mce.rotation.inverse().elems * (points - mce.center)
    rms = []
    for r in point_group_432_rotation_matrices:
      rp = r * points_mce
      rms.append(rp.rms_difference(points_principal))
    assert is_below_limit(value=min(rms), limit=1e-8, eps=0)
  mt = flex.mersenne_twister(seed=0)
  check((0,0,0), (1,2,3), (1,0,0,0,1,0,0,0,1))
  for i_trial in range(n_trials):
    center = list(mt.random_double(size=3)*8-4)
    radii = list(mt.random_double(size=3)*3+0.1)
    rotation = mt.random_double_r3_rotation_matrix()
    check(center, radii, rotation)
  from libtbx.utils import format_cpu_times
  print(format_cpu_times())

if (__name__ == "__main__"):
  import sys
  run(args=sys.argv[1:])