Source code for sksurgeryfred.algorithms.fle

#  -*- coding: utf-8 -*-

"""
Functions for adding fiducial localisation error
"""

import numpy as np


def _set_fle(fle, dims):
    """ Internal function to check and set the fle """
    if isinstance(fle, np.ndarray):
        if fle.size == 1:
            fle_array = np.full(dims, fle.item(0), dtype=np.float64)
        else:
            if fle.size != dims:
                raise ValueError("FLE value must be single value or array",
                                 " of length ", dims)
            return fle
    else:
        fle_array = np.full(dims, fle, dtype=np.float64)

    assert fle_array.size == dims
    return fle_array

[docs]class FLE: """ Provides methods to add Fiducial Localisation Error to a point :param independent_fle: the magnitude(s) of the independent FLE's, used for the default ind_fle_function. Do not use if using your own ind_fle_function. A single float will yield isotropic error, or an array can be passed for anisotropic errors. :param ind_fle_function: the function to use for sampling the independent fle. Defaults to numpy.random.normal :param systematic_fle: the magnitude(s) of the systematic FLE's, used for the default sys_fle_function. Do not use if using your own sys_fle_function. A single float will yield isotropic error, or an array can be passed for anisotropic errors. :param sys_fle_function: the function to use for sampling the independent fle. Defaults to numpy.add :param dimension: the dimensions to use, defaults to 3. :raises ValueError: If independent_fle is not single value or array of length dimension. :raises ValueError: If both fle function and fle value are set. :raises TypeError: If either error function is invalid. """ def __init__(self, independent_fle=None, ind_fle_function=None, systematic_fle=None, sys_fle_function=None, dimension=3): if ind_fle_function is None: if independent_fle is None: independent_fle = 0.0 ind_fle = _set_fle(independent_fle, dimension) def ind_fle_function(): return np.random.normal(loc=0.0, scale=ind_fle, size=dimension) else: if independent_fle is not None: raise ValueError("Set independent_fle and ind_fle_function, ", "independent_fle will be ignored") self.ind_fle_function = ind_fle_function try: self.ind_fle_function() except TypeError: raise TypeError("Failed to run function, ", ind_fle_function, "check function") from TypeError if sys_fle_function is None: if systematic_fle is None: systematic_fle = 0.0 sys_fle = _set_fle(systematic_fle, dimension) def sys_fle_function(): return sys_fle else: if systematic_fle is not None: raise ValueError("Set systematic_fle and sys_fle_function, ", "systematic_fle will be ignored") self.sys_fle_function = sys_fle_function try: self.sys_fle_function() except TypeError: raise TypeError("Failed to run function, ", sys_fle_function, "check function") from TypeError
[docs] def perturb_fiducial(self, fiducial_marker): """ Adds the FLE to the marker position :param fiducial_marker: the true position of the marker. :returns: The perturbed position of the marker """ return fiducial_marker + self.sys_fle_function() + \ self.ind_fle_function()