bluemira.utilities.tools

A collection of miscellaneous tools.

Attributes

wrap

norm

dot

cross

Classes

NumpyJSONEncoder

A JSON encoder that can handle numpy arrays.

EinsumWrapper

Preallocator for einsum versions of dot, cross and norm.

ColourDescriptor

Colour Descriptor for use with dataclasses

Functions

json_writer(→ str | None)

Write json in the bluemria style.

numpy_to_vtk(data, output_name[, scaling])

Convert a numpy array to a VTK image data file.

write_csv(data, base_name, col_names[, metadata, ext, ...])

Write data in comma-separated value format.

asciistr(→ str)

Get a string of characters of desired length.

levi_civita_tensor(→ numpy.ndarray)

N dimensional Levi-Civita Tensor.

floatify(→ float)

Converts the np array or float into a float by returning

iterable_to_list(→ list[Any])

Convert object(s) to an explicit list of objects

is_num(→ bool)

Determine whether or not the input is a number.

is_num_array(→ bool)

is_num() but also includes arrays

abs_rel_difference(→ float)

Calculate the absolute relative difference between a new value and an old

set_random_seed(→ list[numpy.random.SeedSequence])

Sets the random seed number in numpy and NLopt. Useful when repeatable

flatten_iterable(iters)

Expands a nested iterable structure, flattening it into one iterable

consec_repeat_elem(→ numpy.ndarray)

Get array of repeated elements with n or more repeats

slope(→ float)

Calculate gradient of a 2x2 point array

yintercept(→ tuple[float, float])

Calculate the y intercept and gradient of an array

ten_power(x)

Get the power for the base ten notation, set 0 to 0.

sig_fig_round(x, s[, low_lim])

Fuction to round to a given number of significant figures,

cross_2d(→ numpy.float64)

Cross products of 2d vectors,

cross_2d_3d(→ numpy.ndarray)

Cross products of pairs of 2d or 3d vectors,

cartesian_to_polar(→ tuple[numpy.ndarray, numpy.ndarray])

Convert from 2-D Cartesian coordinates to polar coordinates about a reference point.

polar_to_cartesian(→ tuple[numpy.ndarray, numpy.ndarray])

Convert from 2-D polar to Cartesian coordinates about a reference point.

toroidal_to_cylindrical(R_0, Z_0, tau, sigma)

Convert from toroidal coordinates to cylindrical coordinates in the poloidal plane

cylindrical_to_toroidal(R_0, Z_0, R, Z)

Convert from cylindrical coordinates to toroidal coordinates in the poloidal plane

compare_dicts(→ bool)

Compares two dictionaries. Will print information about the differences

get_module(→ types.ModuleType)

Load module dynamically.

_loadfromspec(→ types.ModuleType)

Load module from filename.

get_class_from_module(→ type)

Load a class from a module dynamically.

array_or_num(→ numpy.ndarray | float)

Always returns a numpy array or a float

deprecation_wrapper(→ collections.abc.Callable[[Any], Any])

Deprecate any callable.

qtapp_instance(→ PySide6.QtWidgets.QApplication)

Get at QtWidgets.QApplication instance

Module Contents

class bluemira.utilities.tools.NumpyJSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)

Bases: json.JSONEncoder

Inheritance diagram of bluemira.utilities.tools.NumpyJSONEncoder

A JSON encoder that can handle numpy arrays.

default(o)

Override the JSONEncoder default object handling behaviour for np.arrays.

Returns:

The default json encoder object

bluemira.utilities.tools.json_writer(data: dict[str, Any], file: os.PathLike | str | None = None, *, return_output: bool = False, cls: type[json.JSONEncoder] = NumpyJSONEncoder, **kwargs) str | None

Write json in the bluemria style.

Parameters:
  • data (dict[str, Any]) – dictionary to write to json

  • filename – filename to write to

  • return_output (bool) – return the json as a string

  • cls (type[json.JSONEncoder]) – json encoder child class

  • kwargs – all further kwargs passed to the json writer

  • file (os.PathLike | str | None)

Returns:

The json dictionary if requested

Return type:

str | None

bluemira.utilities.tools.numpy_to_vtk(data, output_name, scaling=(1, 1, 1))

Convert a numpy array to a VTK image data file.

bluemira.utilities.tools.write_csv(data: numpy.ndarray, base_name: str, col_names: list[str], metadata: str = '', ext: str = '.csv', comment_char: str = '#')

Write data in comma-separated value format.

Parameters:
  • data (numpy.ndarray) – Array of data to be written to csv file. Will raise an error if the dimensionality of the data is not two

  • base_name (str) – Name of file to write to, minus the extension.

  • col_names (list[str]) – List of strings for column headings for each data field provided.

  • metadata (str) – Optional argument for metadata to be written as a header.

  • ext (str) – Optional argument for file extension, defaults to “.csv”.

  • comment_char (str) – Optional argument to specify character(s) to prepend to metadata lines as a comment character (defaults to “#”).

Raises:

ValueError – Columns names not available for all columns

bluemira.utilities.tools.asciistr(length: int) str

Get a string of characters of desired length.

Current max is 52 characters

Parameters:

length (int) – number of characters to return

Return type:

str of length specified

Raises:

ValueError – String length > 52 characters

bluemira.utilities.tools.levi_civita_tensor(dim: int = 3) numpy.ndarray

N dimensional Levi-Civita Tensor.

Parameters:

dim (int) – The number of dimensions for the LCT

Return type:

np.array (n_0,n_1,…n_n)

Notes

The Levi-Civita symbol in n dimensions is defined as:

\[\begin{split}\epsilon_{i_1 i_2 \dots i_n} = \begin{cases} \\ +1 & \text{for even permutation of } (1, 2, \dots, n) \\ -1 & \text{for odd permutation of } (1, 2, \dots, n) \\ 0 & \text{for indices are equal} \\ \end{cases}\end{split}\]

For dim=3, this looks like:

\[\begin{split}\epsilon_{ijk} = \begin{cases} 1 & \text{if } (i, j, k) \text{ is } (0, 1, 2), (1, 2, 0), (2, 0, 1) \\ -1 & \text{if } (i, j, k) \text{ is } (0, 2, 1), (2, 1, 0), (1, 0, 2) \\ 0 & \text{otherwise} \end{cases}\end{split}\]
class bluemira.utilities.tools.EinsumWrapper

Preallocator for einsum versions of dot, cross and norm.

norm_strs
dot_1x1 = 'i, i -> ...'
dot_1x2 = 'i, ik -> k'
dot_2x1 = 'ij, j -> i'
dot_2x2 = 'ij, jk -> ik'
dot_1xn = 'y, {}yz -> {}z'
dot_nx1 = '{}z, z -> {}'
dot_nxn = '{}y, {}yz -> {}z'
cross_strs
cross_lcts
norm(ix: numpy.ndarray, axis: int = 0) numpy.ndarray

Emulates some of the functionality of np.linalg.norm for 2D arrays.

Specifically: np.linalg.norm(ix, axis=0) np.linalg.norm(ix, axis=1)

For optimum speed and customisation use np.einsum modified for your use case.

Parameters:
  • ix (numpy.ndarray) – Array to perform norm on

  • axis (int) – axis for the norm to occur on

Returns:

The norm of the array

Raises:

ValueError – Matrix dimensions >2 unsupported

Return type:

numpy.ndarray

dot(ix: numpy.ndarray, iy: numpy.ndarray, out: numpy.ndarray | None = None) numpy.ndarray

A dot product emulation using np.einsum.

For optimum speed and customisation use np.einsum modified for your use case.

Should follow the same mechanics as np.dot, a few examples:

ein_str = ‘i, i -> …’ ein_str = ‘ij, jk -> ik’ # Classic dot product ein_str = ‘ij, j -> i’ ein_str = ‘i, ik -> k’ ein_str = ‘aij, ajk -> aik’ # for loop needed with np.dot

Parameters:
  • ix (numpy.ndarray) – First array

  • iy (numpy.ndarray) – Second array

  • out (numpy.ndarray | None) – output array for inplace dot product

Returns:

The dot product of the array

Raises:

ValueError – Undefined dot product behaviour for array shapes

Return type:

numpy.ndarray

cross(ix: numpy.ndarray, iy: numpy.ndarray, out: numpy.ndarray | None = None) numpy.ndarray

A row-wise cross product of a 2D matrices of vectors.

This function mirrors the properties of np.cross such as vectors of 2 or 3 elements. 1D is also accepted but just do x * y. Only 7D has similar orthogonal properties above 3D.

For optimum speed and customisation use np.einsum modified for your use case.

Parameters:
  • ix (numpy.ndarray) – 1st array to cross

  • iy (numpy.ndarray) – 2nd array to cross

  • out (numpy.ndarray | None) – output array for inplace cross product

Returns:

the cross product of the arrays

Raises:

ValueError – If the dimensions of the cross product are > 3

Return type:

numpy.ndarray

bluemira.utilities.tools.wrap
bluemira.utilities.tools.norm
bluemira.utilities.tools.dot
bluemira.utilities.tools.cross
bluemira.utilities.tools.floatify(x: numpy.typing.ArrayLike) float

Converts the np array or float into a float by returning the first element or the element itself.

Returns:

the extracted float

Raises:
  • ValueError – If array like object has more than 1 element

  • TypeError – If object is None

Parameters:

x (numpy.typing.ArrayLike)

Return type:

float

Notes

This function aims to avoid numpy warnings for float(x) for >0 rank scalars it emulates the functionality of float conversion

class bluemira.utilities.tools.ColourDescriptor

Colour Descriptor for use with dataclasses

_default = '#'
__set_name__(_, name: str)

Set the attribute name from a dataclass

Parameters:

name (str)

__get__(obj: Any, _) str

Get the hex colour

Returns:

The hex colour string

Parameters:

obj (Any)

Return type:

str

__set__(obj: Any, value: str | tuple[float, Ellipsis] | bluemira.display.palettes.ColorPalette)

Set the colour

Notes

The value can be anything accepted by matplotlib.colors.to_hex

Parameters:
bluemira.utilities.tools.iterable_to_list(obj: Any | collections.abc.Iterable[Any]) list[Any]

Convert object(s) to an explicit list of objects

Returns:

The object converted to a list

Parameters:

obj (Any | collections.abc.Iterable[Any])

Return type:

list[Any]

bluemira.utilities.tools.is_num(thing: Any) bool

Determine whether or not the input is a number.

Parameters:

thing (Any) – The input which we need to determine is a number or not

Returns:

Whether or not the input is a number

Return type:

bool

bluemira.utilities.tools.is_num_array(thing: Any) bool

is_num() but also includes arrays

Returns:

Whether or not the input is a number

Parameters:

thing (Any)

Return type:

bool

bluemira.utilities.tools.abs_rel_difference(v2: float, v1_ref: float) float

Calculate the absolute relative difference between a new value and an old reference value.

Parameters:
  • v2 (float) – The new value to compare to the old

  • v1_ref (float) – The old reference value

Returns:

The absolute relative difference between v2 and v1ref

Return type:

float

bluemira.utilities.tools.set_random_seed(seed_number: int, no_sequences: int = 1) list[numpy.random.SeedSequence]

Sets the random seed number in numpy and NLopt. Useful when repeatable results are desired in Monte Carlo methods and stochastic optimisation methods.

Parameters:
  • seed_number (int) – The random seed number, preferably a very large integer

  • no_sequences (int) – The number of seed sequences to produce

Returns:

The requested seed sequences

Return type:

list[numpy.random.SeedSequence]

bluemira.utilities.tools.flatten_iterable(iters: collections.abc.Iterable[Any])

Expands a nested iterable structure, flattening it into one iterable

Parameters:

iters (collections.abc.Iterable[Any]) – The object(s) to de-nest

Yields:

elements of iterable

Notes

Does not cater for nested dictionaries

bluemira.utilities.tools.consec_repeat_elem(arr: numpy.ndarray, num_rep: int) numpy.ndarray

Get array of repeated elements with n or more repeats

Parameters:
  • arr (numpy.ndarray) – array to find repeats in

  • num_rep (int) – number of repetitions to find

Returns:

The repeated element array

Return type:

numpy.ndarray

bluemira.utilities.tools.slope(arr: numpy.ndarray) float

Calculate gradient of a 2x2 point array

Returns:

The gradient of the array

Parameters:

arr (numpy.ndarray)

Return type:

float

bluemira.utilities.tools.yintercept(arr: numpy.ndarray) tuple[float, float]

Calculate the y intercept and gradient of an array

Returns:

The y-intercept of the array

Parameters:

arr (numpy.ndarray)

Return type:

tuple[float, float]

bluemira.utilities.tools.ten_power(x)

Get the power for the base ten notation, set 0 to 0.

Returns:

the nearest log10 power

bluemira.utilities.tools.sig_fig_round(x, s, low_lim=-16)

Fuction to round to a given number of significant figures, with any number below a lower limit set to zero.

Parameters:
  • x – value or values to round.

  • s – number of significant figures

  • low_lim – power below which values are set to 0, default: low_lim = -16 (i.e, numbers below 1e-16)

Returns:

Rounded value

bluemira.utilities.tools.cross_2d(v1: numpy.typing.ArrayLike, v2: numpy.typing.ArrayLike) numpy.float64

Cross products of 2d vectors, since numpy >= v2 deprecated support for 2d vector inputs in np.cross.

Parameters:
  • v1 (numpy.typing.ArrayLike) – 2d vector

  • v2 (numpy.typing.ArrayLike) – 2d vector

Returns:

The cross product of the two vectors

Return type:

numpy.float64

bluemira.utilities.tools.cross_2d_3d(v1: numpy.typing.ArrayLike, v2: numpy.typing.ArrayLike) numpy.ndarray

Cross products of pairs of 2d or 3d vectors, since numpy >= v2 deprecated support for 2d vector inputs in np.cross. For when needing to handle both cases

Parameters:
  • v1 (numpy.typing.ArrayLike) – Vector 1

  • v2 (numpy.typing.ArrayLike) – Vector 2

Returns:

The cross product of the two vectors

Return type:

numpy.ndarray

bluemira.utilities.tools.cartesian_to_polar(x: numpy.ndarray, z: numpy.ndarray, x_ref: float = 0.0, z_ref: float = 0.0) tuple[numpy.ndarray, numpy.ndarray]

Convert from 2-D Cartesian coordinates to polar coordinates about a reference point.

Parameters:
  • x (numpy.ndarray) – Radial coordinates

  • z (numpy.ndarray) – Vertical coordinates

  • x_ref (float) – Reference radial coordinate

  • z_ref (float) – Reference vertical coordinate

Returns:

  • r – Polar radial coordinates

  • phi – Polar angle coordinates

Return type:

tuple[numpy.ndarray, numpy.ndarray]

bluemira.utilities.tools.polar_to_cartesian(r: numpy.ndarray, phi: numpy.ndarray, x_ref: float = 0.0, z_ref: float = 0.0) tuple[numpy.ndarray, numpy.ndarray]

Convert from 2-D polar to Cartesian coordinates about a reference point.

Parameters:
  • r (numpy.ndarray) – Polar radial coordinates

  • phi (numpy.ndarray) – Polar angle coordinates

  • x_ref (float) – Reference radial coordinate

  • z_ref (float) – Reference vertical coordinate

Returns:

  • x – Radial coordinates

  • z – Vertical coordinate

Return type:

tuple[numpy.ndarray, numpy.ndarray]

bluemira.utilities.tools.toroidal_to_cylindrical(R_0: float, Z_0: float, tau: numpy.ndarray, sigma: numpy.ndarray)

Convert from toroidal coordinates to cylindrical coordinates in the poloidal plane Toroidal coordinates are denoted by (tau, sigma, phi) Cylindrical coordinates are denoted by (r, z, phi) We are in the poloidal plane so take the angle phi = 0

\[R = R_{0} \frac{\sinh{\tau}}{\cosh{\tau} - \cos{\sigma}} z = R_{0} \frac{\sin{\tau}}{\cosh{\tau} - \cos{\sigma}} + z_{0}\]
Parameters:
  • R_0 (float) – r coordinate of focus in poloidal plane

  • Z_0 (float) – z coordinate of focus in poloidal plane

  • tau (numpy.ndarray) – the tau coordinates to transform

  • sigma (numpy.ndarray) – the sigma coordinates to transform

Returns:

Tuple of transformed coordinates in cylindrical form

Return type:

R, Z

bluemira.utilities.tools.cylindrical_to_toroidal(R_0: float, Z_0: float, R: numpy.ndarray, Z: numpy.ndarray)

Convert from cylindrical coordinates to toroidal coordinates in the poloidal plane Toroidal coordinates are denoted by (tau, sigma, phi) Cylindrical coordinates are denoted by (r, z, phi) We are in the poloidal plane so take the angle phi = 0

\[ \begin{align}\begin{aligned}\tau = \ln\frac{d_{1}}{d_{2}} \sigma = sign(z - z_{0}) \arccos\frac{d_{1}^2 + d_{2}^2 - 4 R_{0}^2}{2 d_{1} d_{2}}\\d_{1}^2 = (R + R_{0})^2 + (z - z_{0})^2 d_{2}^2 = (R - R_{0})^2 + (z - z_{0})^2\end{aligned}\end{align} \]
Parameters:
  • R_0 (float) – r coordinate of focus in poloidal plane

  • Z_0 (float) – z coordinate of focus in poloidal plane

  • R (numpy.ndarray) – the r coordinates to transform

  • Z (numpy.ndarray) – the z coordinates to transform

Returns:

Tuple of transformed coordinates in toroidal form

Return type:

tau, sigma

bluemira.utilities.tools.compare_dicts(d1: dict[str, Any], d2: dict[str, Any], *, almost_equal: bool = False, verbose: bool = True, rtol: float = 1e-05, atol: float = 1e-08) bool

Compares two dictionaries. Will print information about the differences between the two to the console. Dictionaries are compared by length, keys, and values per common keys

Parameters:
  • d1 (dict[str, Any]) – The reference dictionary

  • d2 (dict[str, Any]) – The dictionary to be compared with the reference

  • almost_equal (bool) – Whether or not to use np.isclose and np.allclose for numbers and arrays

  • verbose (bool) – Whether or not to print to the console

  • rtol (float) – The relative tolerance parameter, used if almost_equal is True

  • atol (float) – The absolute tolerance parameter, used if almost_equal is True

Return type:

Whether or not the dictionaries are the same

bluemira.utilities.tools.get_module(name: str) types.ModuleType

Load module dynamically.

Parameters:

name (str) – Filename or python path (a.b.c) of module to import

Returns:

Loaded module

Raises:

ImportError – Unable to import module

Return type:

types.ModuleType

bluemira.utilities.tools._loadfromspec(name: str) types.ModuleType

Load module from filename.

Parameters:

name (str) – Filename of module to import

Returns:

Loaded module

Raises:
  • ImportError – Unable to import module

  • FileNotFoundError – Cant find specified module file

  • ModuleNotFoundError – Cant find module

Return type:

types.ModuleType

bluemira.utilities.tools.get_class_from_module(name: str, default_module: str = '') type

Load a class from a module dynamically.

Parameters:
  • name (str) – Filename or python path (a.b.c) of module to import, with specific class to load appended following :: e.g. my_package.my_module::my_class. If the default_module is provided then only the class name (e.g. my_class) needs to be provided.

  • default_module (str) – The default module to search for the class, by default “”. If provided then if name does not contain a module path then this the default module will be used to search for the class. Can be overridden if the name provides a module path.

Returns:

Loaded class

Raises:

ImportError – Unable to import class from module

Return type:

type

bluemira.utilities.tools.array_or_num(array: Any) numpy.ndarray | float

Always returns a numpy array or a float

Parameters:

array (Any) – The value to convert into a numpy array or number.

Return type:

The value as a numpy array or number.

Raises:

TypeError – If the value cannot be converted to a numpy or number.

bluemira.utilities.tools.deprecation_wrapper(message: collections.abc.Callable[[Any], Any] | str | None) collections.abc.Callable[[Any], Any]

Deprecate any callable.

Parameters:

message (collections.abc.Callable[[Any], Any] | str | None) – The callable to deprecate or the message to show

Returns:

The wrapped function

Return type:

collections.abc.Callable[[Any], Any]

bluemira.utilities.tools.qtapp_instance() PySide6.QtWidgets.QApplication

Get at QtWidgets.QApplication instance

Can be used as a crude way to detect ipython/jupyter instances

Returns:

QApplication instance

Return type:

PySide6.QtWidgets.QApplication