Core

class core_ct.core.Core(data: ndarray | list[float], pixel_dimensions: tuple[float, float, float] = (1.0, 1.0, 1.0))[source]

Abstracts properties of a core CT-scan and methods for manipulating it.

data

3D numpy array of pixel data that make up the core

Type:

np.ndarray

pixel_dimensions

tuple containing the dimensions of each pixel/voxel in mm

Type:

tuple[float, float, float]

__getitem__(index: slice | int | Tuple[slice | int, ...]) Core | Slice[source]

Overloads the bracket operator ([]) to support numpy-like indexing behavior.

Parameters:

index (slice, int, or tuple of slice and/or int) – Index to use for the slicing operation. Can be a single slice, integer, or a tuple containing a combination of slices and integers (up to 3 items total).

Returns:

  • Core - If the indices result in a 3-dimensional subset of the data

  • Slice - If the indices result in a 2-dimensional subset of the data

Return type:

Core or Slice

Raises:
  • IndexError – If any provided indices are out of range or the end index comes before the start index on an axis.

  • ValueError – If the provided index would result in a data shape other than 2D or 3D. If the provided index specifies more than 3 axes. If a step other than 1 is defined on any axis.

  • RuntimeError – If the resulting shape is 2D and slice axis cannot be determined.

Examples

Trim 25 pixels off both ends of the x-axis:

trimmed = core[25:-25]

Get a Core containing only 100th-500th pixels along the x-axis:

trimmed = core[100:500]

Trim 50 pixels off the start of the y-axis:

trimmed = core[:, 50:]

Trim 50 pixels off the end of the z-axis:

trimmed = core[:, :, :-50]

Trim 30 pixels from all sides:

trimmed = core[30:-30, 30:-30, 30:-30]

Take a slice at the 100th pixel on the z axis (indices start at 0, so the 100th pixel is at index 99):

slice = core[:, :, 99]

Take a slice at the 25th pixel on the y axis and trim 25 pixels off the beginning of the x-axis:

slice = core[25:, 24, :]

Take a slice at the 100th pixel on the z axis and trim 25 pixels from all sides:

slice = core[25:-25, 25:-25, 99]

Take a slice at the first x pixel and constrain z-axis to indices 50-249:

slice = core[0, :, 50:250]
dimensions() tuple[float, float, float][source]

Get the dimensions of the scan in mm.

Returns:

A three-element tuple containing the dimensions of the scan in mm.

Return type:

tuple[float, float, float]

filter(brightness_filter: Callable[[float], bool]) Core[source]

Create new Core containing data filtered according to the provided function.

The filter function (lambda) is run on every brightness value in data. If the lambda returns True, the new Core will contain that brightness value. If the lambda returns False, the new Core will not contain that datapoint, substituting it with numpy.nan (np.nan).

This function can take a long time to run depending on how much data the Core contains. Consider using Core.trim(), Core.trim_radial(), or Core.chunk() to reduce the amount of data you are filtering.

Parameters:

brightness_filter (Callable[[float], bool]) – Lambda function that defines what will be filtered out. Function must either return False if the value should not be included or True if the value should be included.

Returns:

New core object with only matching brightness values left, everything else is set to numpy.nan (np.nan).

Return type:

Core

flip(axis: int) Core[source]

Create a new Core object with data reversed along the given axis.

Parameters:

axis (int) –

Integer either 0, 1, 2 specifying which axis to reverse

0: corresponds to x-axis

1: corresponds to y-axis

2: corresponds to z-axis

Returns:

New Core object containing flipped data

Return type:

Core

Raises:

ValueError – If axis is a value other than 0, 1, or 2

join(core: Core, axis: int = 0) Core[source]

Join a core to the current core on a specified axis.

Parameters:
  • core (Core) – The Core object to join with the current core

  • axis (int) –

    Integer either 0, 1, 2 specifying which axis to join on

    0: corresponds to x-axis

    1: corresponds to y-axis

    2: corresponds to z-axis

Returns:

New core object made up of the two joined arrays

Return type:

Core

Raises:
  • ValueError – If axis is a value other than 0, 1, or 2

  • ValueError – If the pixel_dimensions of the cores don’t match

  • ValueError – If the shapes of the cores along an axis don’t match

rotate(axis: int, k: int = 1, clockwise: bool = False) Core[source]

Create a new Core object with data rotated 90 degrees about axis k times.

Rotates counter-clockwise by default, set clockwise to True to rotate clockwise instead.

Parameters:
  • axis (int) –

    Integer either 0, 1, 2 specifying which axis to rotate about

    0: corresponds to x-axis

    1: corresponds to y-axis

    2: corresponds to z-axis

  • k (int) – Number of times to rotate pixel_array 90 degrees

  • clockwise (bool) – whether or not to rotate clockwise instead of counter-clockwise

Returns:

New Core object containing rotated data and pixel dimensions

Return type:

Core

Raises:

ValueError – If axis is a value other than 0, 1, or 2

shape() tuple[int, int, int][source]

Get the dimensions of the pixel array of the core scan.

Returns:

The pixel dimensions of the core scan.

Return type:

tuple[int, int, int]

slice(axis: int, loc: int) Slice[source]

Get a 2D Slice of the core at a specific location along an axis.

Parameters:
  • axis (int) –

    Integer either 0, 1, 2 specifying which dimension to collapse

    0: corresponds to x-axis

    1: corresponds to y-axis

    2: corresponds to z-axis

  • loc (int) – Integer value along the axis specifying the location of the slice

Returns:

Slice object containing pixel data and dimensions

Return type:

Slice

Raises:

ValueError – If axis is a value other than 0, 1, or 2

swapaxes(axis1: int, axis2: int) Core[source]

Create a new Core object with swapped axes and updated pixel dimensions.

Parameters:
  • axis1 (int) –

    Integer either 0, 1, 2 specifying the first axis:

    0: corresponds to x-axis

    1: corresponds to y-axis

    2: corresponds to z-axis

  • axis2 (int) –

    Integer either 0, 1, 2 specifying the second axis:

    0: corresponds to x-axis

    1: corresponds to y-axis

    2: corresponds to z-axis

Returns:

New Core object containing swapped data and updated pixel dimensions

Return type:

Core

Raises:

ValueError – If axes are values other than 0, 1, or 2

trim_radial(axis: int, radius: float, x_center: int | None = None, y_center: int | None = None, z_center: int | None = None) Core[source]

Trims the Core radially given an axis and a center.

Replaces all data outside of the user specified area with NaN. Also reduces the dimensions of data as much as possible.

The user specifies a cylindrical shape by an axis and a center. For example, if axis is set to 2 (z-axis) the user should specify the center via x_center and y_center. After trimming, every z-slice will only contain data within a circle of the given radius centered at (x_center, y_center).

This function is inclusive on radius, i.e. the returned Core maintains data where distance from center is equal to radius.

The user does not need to specify the center argument for their chosen axis. All center arguments default to the middle of their respective axes if not provided.

Parameters:
  • axis (int) –

    axis to radially trim about

    0 corresponds to x-axis

    1 corresponds to y-axis

    2 corresponds to z-axis

  • radius (float) – radius from given center to trim values outside of

  • x_center (int) – index to center the cylinder on along the x-axis

  • y_center (int) – index to center the cylinder on along the y-axis

  • z_center (int) – index to center the cylinder on along the z-axis

Returns:

A new trimmed core object

Return type:

Core

Raises:

ValueError – If axis is a value other than 0, 1, or 2

volume() float[source]

Approximates the core volume in mm; ignores any NaN values.

Returns:

The approximate volume of the core in cubic mm ignoring NaN values.

Return type:

float