pytomography.utils#

This module contains utility functions used in the other modules of PyTomography

Submodules#

Package Contents#

Classes#

HammingFilter

Implementation of the Hamming filter given by \(\Pi(\omega) = \frac{1}{2}\left(1+\cos\left(\frac{\pi(|\omega|-\omega_L)}{\omega_H-\omega_L} \right)\right)\) for \(\omega_L \leq |\omega| < \omega_H\) and \(\Pi(\omega) = 1\) for \(|\omega| \leq \omega_L\) and \(\Pi(\omega) = 0\) for \(|\omega|>\omega_H\). Arguments wl and wh should be expressed as fractions of the Nyquist frequency (i.e. wh=0.93 represents 93% the Nyquist frequency).

RampFilter

Implementation of the Ramp filter \(\Pi(\omega) = |\omega|\)

Functions#

rev_cumsum(x)

Reverse cumulative sum along the first axis of a tensor of shape [batch_size, Lx, Ly, Lz].

get_distance(Lx, r, dx)

Given the radial distance to center of object space from the scanner, computes the distance between each parallel plane (i.e. (y-z plane)) and a detector located at +x. This function is used for SPECT PSF modeling where the amount of blurring depends on thedistance from the detector.

get_object_nearest_neighbour(object, shifts)

Given an object tensor, finds the nearest neighbour (corresponding to shifts) for each voxel (done by shifting object by i,j,k)

get_blank_below_above(proj)

Obtains the number of blank z-slices at the sup (blank_above) and inf (blank_below) of the projection data. This method is entirely empircal, and looks for z slices where there are zero detected counts.

print_collimator_parameters()

Prints all the available SPECT collimator parameters

rotate_detector_z(x, angles[, mode, negative])

Returns an object tensor in a rotated reference frame such that the scanner is located at the +x axis. Note that the scanner angle \(\beta\) is related to \(\phi\) (azimuthal angle) by \(\phi = 3\pi/2 - \beta\).

compute_pad_size(width)

Computes the pad width required such that subsequent rotation retains the entire object

pad_proj(proj[, mode, value])

Pads projections along the Lr axis

pad_object(object[, mode])

Pads object tensors by enough pixels in the xy plane so that subsequent rotations don't crop out any of the object

unpad_proj(proj)

Unpads the projections back to original Lr dimensions

unpad_object(object)

Unpads a padded object tensor in the xy plane back to its original dimensions

pad_object_z(object, pad_size[, mode])

Pads an object tensor along z. Useful for PSF modeling

unpad_object_z(object, pad_size)

Unpads an object along the z dimension

dual_sqrt_exponential(energy, c1, c2, d1, d2)

Function used for curve fitting of linear attenuation coefficient vs. photon energy curves from NIST. It's given by the functional form \(f(x) = c_1e^{-d_1\sqrt{x}} + c_2e^{-d_2\sqrt{x}}\). It was chosen purely because it gave good fit results.

get_E_mu_data_from_datasheet(file)

Return energy and linear attenuation data from NIST datafiles of mass attenuation coefficients between 50keV and 511keV.

get_mu_from_spectrum_interp(file, energy)

Gets linear attenuation corresponding to a given energy in in the data from file.

compute_TEW(projection_lower, projection_upper, ...)

pytomography.utils.rev_cumsum(x)[source]#

Reverse cumulative sum along the first axis of a tensor of shape [batch_size, Lx, Ly, Lz]. since this is used with SPECT attenuation correction, the initial voxel only contributes 1/2.

Parameters:

x (torch.tensor[batch_size,Lx,Ly,Lz]) – Tensor to be summed

Returns:

The cumulatively summed tensor.

Return type:

torch.tensor[batch_size, Lx, Ly, Lz]

pytomography.utils.get_distance(Lx, r, dx)[source]#

Given the radial distance to center of object space from the scanner, computes the distance between each parallel plane (i.e. (y-z plane)) and a detector located at +x. This function is used for SPECT PSF modeling where the amount of blurring depends on thedistance from the detector.

Parameters:
  • Lx (int) – The number of y-z planes to compute the distance of

  • r (float) – The radial distance between the central y-z plane and the detector at +x.

  • dx (float) – The spacing between y-z planes in Euclidean distance.

Returns:

An array of distances for each y-z plane to the detector.

Return type:

np.array[Lx]

pytomography.utils.get_object_nearest_neighbour(object, shifts)[source]#

Given an object tensor, finds the nearest neighbour (corresponding to shifts) for each voxel (done by shifting object by i,j,k)

Parameters:
  • object (torch.Tensor) – Original object

  • shifts (list[int]) – List of three integers [i,j,k] corresponding to neighbour location

Returns:

Shifted object whereby each voxel corresponding to neighbour [i,j,k] of the object.

Return type:

torch.Tensor

pytomography.utils.get_blank_below_above(proj)[source]#

Obtains the number of blank z-slices at the sup (blank_above) and inf (blank_below) of the projection data. This method is entirely empircal, and looks for z slices where there are zero detected counts.

Parameters:

proj (torch.tensor) – Projection data from a scanner

Returns:

A tuple of two elements corresponding to the number of blank slices at the inf, and the number of blank slices at the sup.

Return type:

Sequence[int]

pytomography.utils.print_collimator_parameters()[source]#

Prints all the available SPECT collimator parameters

pytomography.utils.rotate_detector_z(x, angles, mode='bilinear', negative=False)[source]#

Returns an object tensor in a rotated reference frame such that the scanner is located at the +x axis. Note that the scanner angle \(\beta\) is related to \(\phi\) (azimuthal angle) by \(\phi = 3\pi/2 - \beta\).

Parameters:
  • x (torch.tensor[batch_size, Lx, Ly, Lz]) – Tensor aligned with cartesian coordinate system specified

  • manual. (by the) –

  • angles (torch.Tensor) – The angles \(\beta\) where the scanner is located for each element in the batch x.

  • mode (str, optional) – Method of interpolation used to get rotated object. Defaults to bilinear.

  • negative (bool, optional) – If True, applies an inverse rotation. In this case, the tensor

:param x is an object in a coordinate system aligned with \(\beta\): :param and the function rotates the: :param x back to the original cartesian coordinate system specified by the users manual. In particular: :param if one: :param uses this function on a tensor with negative=False: :param then applies this function to that returned: :param tensor with negative=True: :param it should return the same tensor. Defaults to False.:

Returns:

Rotated tensor.

Return type:

torch.tensor[batch_size, Lx, Ly, Lz]

Parameters:
  • x (torch.Tensor) –

  • angles (torch.tensor) –

  • mode (str) –

  • negative (bool) –

pytomography.utils.compute_pad_size(width)[source]#

Computes the pad width required such that subsequent rotation retains the entire object

Parameters:

width (int) – width of the corresponding axis (i.e. number of elements in the dimension)

Returns:

the number of pixels by which the axis needs to be padded on each side

Return type:

int

pytomography.utils.pad_proj(proj, mode='constant', value=0)[source]#

Pads projections along the Lr axis

Parameters:
  • proj (torch.Tensor[batch_size, Ltheta, Lr, Lz]) – Projections tensor.

  • mode (str, optional) – Padding mode to use. Defaults to ‘constant’.

  • value (float, optional) – If padding mode is constant, fill with this value. Defaults to 0.

Returns:

Padded projections tensor.

Return type:

torch.Tensor[batch_size, Ltheta, Lr’, Lz]

pytomography.utils.pad_object(object, mode='constant')[source]#

Pads object tensors by enough pixels in the xy plane so that subsequent rotations don’t crop out any of the object

Parameters:
  • object (torch.Tensor[batch_size, Lx, Ly, Lz]) – object tensor to be padded

  • mode (str, optional) – _description_. Defaults to ‘constant’.

Returns:

_description_

Return type:

_type_

pytomography.utils.unpad_proj(proj)[source]#

Unpads the projections back to original Lr dimensions

Parameters:

proj (torch.Tensor[batch_size, Ltheta, Lr', Lz]) – Padded projections tensor

Returns:

Unpadded projections tensor

Return type:

torch.Tensor[batch_size, Ltheta, Lr, Lz]

pytomography.utils.unpad_object(object)[source]#

Unpads a padded object tensor in the xy plane back to its original dimensions

Parameters:

object (torch.Tensor[batch_size, Lx', Ly', Lz]) – padded object tensor

Returns:

Object tensor back to it’s original dimensions.

Return type:

torch.Tensor[batch_size, Lx, Ly, Lz]

pytomography.utils.pad_object_z(object, pad_size, mode='constant')[source]#

Pads an object tensor along z. Useful for PSF modeling

Parameters:
  • object (torch.Tensor[batch_size, Lx, Ly, Lz]) – Object tensor

  • pad_size (int) – Amount by which to pad in -z and +z

  • mode (str, optional) – Padding mode. Defaults to ‘constant’.

Returns:

Padded object tensor along z.

Return type:

torch.Tensor[torch.Tensor[batch_size, Lx, Ly, Lz’]]

pytomography.utils.unpad_object_z(object, pad_size)[source]#

Unpads an object along the z dimension

Parameters:
  • object (torch.Tensor[batch_size, Lx, Ly, Lz']) – Padded object tensor along z.

  • pad_size (int) – Amount by which the padded tensor was padded in the z direcion

Returns:

Unpadded object tensor.

Return type:

torch.Tensor[batch_size, Lx, Ly, Lz]

pytomography.utils.dual_sqrt_exponential(energy, c1, c2, d1, d2)[source]#

Function used for curve fitting of linear attenuation coefficient vs. photon energy curves from NIST. It’s given by the functional form \(f(x) = c_1e^{-d_1\sqrt{x}} + c_2e^{-d_2\sqrt{x}}\). It was chosen purely because it gave good fit results.

Parameters:
  • energy (float) – Energy of photon

  • c1 (float) – Fit parameter 1

  • c2 (float) – Fit parameter 2

  • d1 (float) – Fit parameter 3

  • d2 (float) – Fit parameter 4

Returns:

_description_

Return type:

float

pytomography.utils.get_E_mu_data_from_datasheet(file)[source]#

Return energy and linear attenuation data from NIST datafiles of mass attenuation coefficients between 50keV and 511keV.

Parameters:

file (str) – Location of NIST data file. Corresponds to a particular element/material.

Returns:

Energy and linear attenuation values.

Return type:

tuple[np.array, np.array]

pytomography.utils.get_mu_from_spectrum_interp(file, energy)[source]#

Gets linear attenuation corresponding to a given energy in in the data from file.

Parameters:
  • file (str) – Filepath of the mu-energy data

  • energy (float) – Energy at which mu is computed

Returns:

Linear attenuation coefficient (in 1/cm) at the desired energies.

Return type:

np.array

pytomography.utils.compute_TEW(projection_lower, projection_upper, width_lower, width_upper, width_peak)[source]#
class pytomography.utils.HammingFilter(wl, wh)[source]#

Implementation of the Hamming filter given by \(\Pi(\omega) = \frac{1}{2}\left(1+\cos\left(\frac{\pi(|\omega|-\omega_L)}{\omega_H-\omega_L} \right)\right)\) for \(\omega_L \leq |\omega| < \omega_H\) and \(\Pi(\omega) = 1\) for \(|\omega| \leq \omega_L\) and \(\Pi(\omega) = 0\) for \(|\omega|>\omega_H\). Arguments wl and wh should be expressed as fractions of the Nyquist frequency (i.e. wh=0.93 represents 93% the Nyquist frequency).

__call__(w)[source]#
class pytomography.utils.RampFilter[source]#

Implementation of the Ramp filter \(\Pi(\omega) = |\omega|\)

__call__(w)[source]#