t4_geom_convert.Kernel.Transformation package

Submodules

t4_geom_convert.Kernel.Transformation.Transformation module

t4_geom_convert.Kernel.Transformation.Transformation.adjust_matrix(matrix)

Perform a certain number of magical tweaks to the matrix that make sure that it is orthogonal.

MCNP tolerates some skewness but internally adjusts the matrix. We need to do the same thing, or we will not generate the same geometry.

>>> adjust_matrix([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0])
[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
>>> from math import cos, sin, isclose
>>> cos_a, sin_a = cos(1.23), sin(1.23)
>>> rot = [1.0, 0.0, 0.0, 0.0, cos_a, sin_a, 0.0, -sin_a, cos_a]
>>> rot2 = adjust_matrix(rot)
>>> all(isclose(x, y) for x, y in zip(rot, rot2))
True

The following matrix has too few significant digits, so adjust_matrix() raises a warning:

>>> import pytest
>>> mat = [ 0.8021,  0.1056, -0.5878,
...        -0.1305,  0.9914,  0.0000,
...         0.5828,  0.0767,  0.8090]
>>> with pytest.warns(UserWarning, match='is not orthogonal'):
...     mat2 = adjust_matrix(mat)

The new matrix is close to the original one, with a tolerance of 1e-4:

>>> all(isclose(x, y, abs_tol=1e-4) for x, y in zip(mat, mat2))
True

Based on r̶a̶t̶i̶o̶n̶a̶l̶ ̶g̶e̶o̶m̶e̶t̶r̶i̶c̶a̶l̶ ̶c̶o̶n̶s̶i̶d̶e̶r̶a̶t̶i̶o̶n̶s̶ c̶a̶r̶e̶f̶u̶l̶ ̶r̶e̶a̶d̶i̶n̶g̶ ̶o̶f̶ ̶t̶h̶e̶ ̶M̶C̶N̶P̶ ̶s̶o̶u̶r̶c̶e̶ ̶c̶o̶d̶e̶ desperate debugging with gdb, the adjusted matrix generated by MCNP is:

>>> mat2_expected = [
...     0.80207826071476684, 0.10559100917526101, -0.58781034566441959,
...     -0.13050431946672519, 0.99144774047316964, 2.260914180407525e-05,
...     0.58278562635784137, 0.07669365483530112, 0.80899876206252763
...     ]

The matrix generated by adjust_mat() is close to the expected value:

>>> all(isclose(x, y) for x, y in zip(mat2_expected, mat2))
True

The entries are really close to the expected values!

>>> for x, y in zip(mat2_expected, mat2):
...     ratio = (x-y)/x
...     print(f'{x: 20.18e} {y: 20.18e} {ratio: 7.5e}')
 8.020782607147668442e-01  8.020782607147668442e-01  0.00000e+00
 1.055910091752610136e-01  1.055910091752610136e-01  0.00000e+00
-5.878103456644195868e-01 -5.878103456644196978e-01 -1.88874e-16
-1.305043194667251938e-01 -1.305043194667251938e-01 -0.00000e+00
 9.914477404731696364e-01  9.914477404731696364e-01  0.00000e+00
 2.260914180407525009e-05  2.260914180407525348e-05 -1.49857e-16
 5.827856263578413687e-01  5.827856263578413687e-01  0.00000e+00
 7.669365483530111993e-02  7.669365483530111993e-02  0.00000e+00
 8.089987620625276321e-01  8.089987620625278542e-01 -2.74468e-16
Parameters:

matrix (list(float)) – a list of 9 floats, representing the entries of a rotation matrix.

t4_geom_convert.Kernel.Transformation.Transformation.compose_transform(trans1, trans2)

Compose trans1 and trans2.

Returns trans2 o trans1 (i.e. trans1 is applied first).

t4_geom_convert.Kernel.Transformation.Transformation.get_mcnp_transforms(parser)

Return the dictionary of parsed MCNP transformation, in a canonical, 12-parameter form.

Parameters:

parser – the MCNP parser

Returns:

a dictionary associating each transformation number to a list of 12 transformation parameters.

t4_geom_convert.Kernel.Transformation.Transformation.is_matrix_rowwise(matrix)

Returns True if the matrix has at least one fully defined row.

>>> is_matrix_rowwise([1, 2, 3, 4, 5, 6, 7, 8, 9])
True
>>> is_matrix_rowwise([None, None, None, 4, 5, 6, 7, 8, 9])
True
>>> is_matrix_rowwise([1, 2, 3, None, None, None, 7, 8, 9])
True
>>> is_matrix_rowwise([1, 2, 3, 4, 5, 6, None, None, None])
True
>>> is_matrix_rowwise([None, 2, 3, None, 5, 6, None, 8, 9])
False
>>> is_matrix_rowwise([1, None, 3, 4, None, 6, 7, None, 9])
False
>>> is_matrix_rowwise([1, 2, None, 4, 5, None, 7, 8, None])
False
>>> is_matrix_rowwise([None, None, None, None, None, None, 7, 8, 9])
True
>>> is_matrix_rowwise([None, None, None, 4, 5, 6, None, None, None])
True
>>> is_matrix_rowwise([1, 2, 3, None, None, None, None, None, None])
True
>>> is_matrix_rowwise([None, None, 3, None, None, 6, None, None, 9])
False
>>> is_matrix_rowwise([1, None, None, 4, None, None, 7, None, None])
False
>>> is_matrix_rowwise([None, 2, None, None, 5, None, None, 8, None])
False
t4_geom_convert.Kernel.Transformation.Transformation.normalize_matrix(matrix)

Return a normalized version of the given 3x3 rotation matrix.

The input matrix may be missing some elements (3, 5, 6 and 9 elements are possible) or some of the elements may be None. The rules for normalizing a 3x3 rotation matrix are given in the MCNP6 manual, section 3.3.1.3 (TR card, Surface coordinate transformation).

t4_geom_convert.Kernel.Transformation.Transformation.normalize_matrix3(matrix)

Return the canonical form of a 3x3 matrix where exactly one row has been defined.

>>> from ..VectUtils import scal, rotate
>>> mat = normalize_matrix3([1.0, 0.0, 0.0,
...                          None, None, None,
...                          None, None, None])
>>> rows = matrix_rows(mat)
>>> rows[0] == [1, 0, 0]
True
>>> scal(rows[0], rows[1])
0.0
>>> scal(rows[0], rows[2])
0.0
>>> scal(rows[1], rows[2])
0.0
>>> scal(rows[0], rows[0])
1.0
>>> scal(rows[1], rows[1])
1.0
>>> scal(rows[2], rows[2])
1.0

We can also check that it works with a somewhat generically aligned vector:

>>> vec = rotate((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), 37.5)
>>> vec = rotate(vec, (0.0, 0.0, 1.0), 194.2)
>>> vec = rotate(vec, (1.0, 0.0, 0.0), -446.3)
>>> mat = normalize_matrix3([None]*3 + list(vec) + [None]*3)
>>> rows = matrix_rows(mat)
>>> rows[1] == list(vec)
True
>>> abs(scal(rows[0], rows[1])) < 1e-10
True
>>> abs(scal(rows[0], rows[2])) < 1e-10
True
>>> abs(scal(rows[1], rows[2])) < 1e-10
True
>>> abs(scal(rows[0], rows[0]) - 1.0) < 1e-10
True
>>> abs(scal(rows[1], rows[1]) - 1.0) < 1e-10
True
>>> abs(scal(rows[2], rows[2]) - 1.0) < 1e-10
True
t4_geom_convert.Kernel.Transformation.Transformation.normalize_matrix5(matrix)

Return the canonical form of a 3x3 matrix where exactly one row and one column have been defined.

>>> from math import sqrt, cos, sin
>>> def make_euler(alpha, beta, gamma):
...     s1, c1 = sin(alpha), cos(alpha)
...     s2, c2 = sin(beta), cos(beta)
...     s3, c3 = sin(gamma), cos(gamma)
...     mat = [c2, -c3*s2, s2*s3,
...            c1*s2, c1*c2*c3 - s1*s3, - c3*s1 - c1*c2*s3,
...            s1*s2, c1*s3 + c2*c3*s1, c1*c3 - c2*s1*s3]
...     return mat
>>> full_mat = make_euler(100.0, 200.0, 300.0)
>>> some_mat = full_mat[0:4] + [None]*2 + [full_mat[6]] + [None]*2
>>> norm_mat = normalize_matrix5(some_mat)
>>> np.allclose(norm_mat, full_mat)
True
>>> some_mat = [full_mat[0]] + [None]*2 + full_mat[3:7] + [None]*2
>>> norm_mat = normalize_matrix5(some_mat)
>>> np.allclose(norm_mat, full_mat)
True
t4_geom_convert.Kernel.Transformation.Transformation.normalize_matrix6(matrix)

Return the canonical form of a 3x3 matrix where exactly two rows have been defined.

t4_geom_convert.Kernel.Transformation.Transformation.normalize_transform(transf)

Return a normalized, 12-param version of the affine transformation.

t4_geom_convert.Kernel.Transformation.Transformation.to_numpy(trans)

Split a transformation into a NumPy 3x3 matrix and a vector.

>>> to_numpy([1., 2., 3.,
...           1., 0., 0.,
...           0., 1., 0.,
...           0., 0., 1.])
(array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]]), array([1., 2., 3.]))
t4_geom_convert.Kernel.Transformation.Transformation.transform_vector(trans, vec)

Apply the (normalised) transformation trans to the vector vec.

If trans is (b, A), then this function returns

v’ = A*v+b

t4_geom_convert.Kernel.Transformation.Transformation.transformation(trpl, surface)

Apply a transformation to the given surface parameters.

Parameters:
  • trpl – the transformation

  • surface (SurfaceMCNP) – an MCNP surface

t4_geom_convert.Kernel.Transformation.TransformationError module

Module that defines an error type for affine transformations.

exception t4_geom_convert.Kernel.Transformation.TransformationError.TransformationError

Bases: Exception

A class to represent errors in the application of affine transformations.

t4_geom_convert.Kernel.Transformation.TransformationQuad module

t4_geom_convert.Kernel.Transformation.TransformationQuad.transformation_quad(params, trans)

Apply the trans affine transformation to the quadric described by the params parameters.

Parameters:
  • params (list(float)) – the list of 10 quadric parameters

  • trans (list(float)) – the affine transformation (12 elements)

Returns:

the parameters of the transformed quadric

Return type:

list(float)

Module contents