API

dynamicpet.temporalobject

TemporalObject abstract base class.

class dynamicpet.temporalobject.temporalobject.TemporalObject

TemporalObject abstract base class.

frame_start

vector containing the start times of each frame

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

frame_duration

vector containing the durations of each frame

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

abstract concatenate(other)

Concatenate with another TemporalObject of same type.

Parameters:

other (T) – TemporalObject to concatenate

Returns:

concatenated TemporalObject

Return type:

T

cumulative_integral(integration_type='trapz')

Cumulative integration starting at t=0 and ending at each frame_end.

If start_time > 0, the triangular area between (t=0, 0) and (t=start_time, dataobj value at 0th frame) will be added to each cumulative integral.

Parameters:

integration_type (Literal['rect', 'trapz']) – rect (rectangular) or trapz (trapezoidal).

Returns:

cumulative integral, with same shape as dataobj

Raises:

ValueError – invalid integration type

Return type:

ndarray[Any, dtype[number[Any]]]

abstract property dataobj: ndarray[Any, dtype[number[Any]]]

Get data object, which can be a 2-D or a 3-D matrix.

The last dimension of dataobj corresponds to time.

property end_time: float

Get the ending time of last frame.

abstract extract(start_time, end_time)

Extract a time interval.

Parameters:
  • start_time (int | float | integer[Any] | floating[Any]) – time at which to begin, inclusive

  • end_time (int | float | integer[Any] | floating[Any]) – time at which to stop, inclusive

Returns:

extracted time interval

Return type:

T

property frame_end: ndarray[Any, dtype[number[Any]]]

Get an array of end times for each frame.

property frame_mid: ndarray[Any, dtype[number[Any]]]

Get an array of mid times for each frame.

get_idx_extract_time(start_time, end_time)

Get the start and end indices for extracting a time interval.

Parameters:
  • start_time (int | float | integer[Any] | floating[Any]) – time at which to begin, inclusive

  • end_time (int | float | integer[Any] | floating[Any]) – time at which to stop, inclusive

Returns:

tuple of start index (inclusive) and end index (exclusive) of interval to extract

Raises:

TimingError – extraction times are out of bound

Return type:

tuple[int, int]

get_weights(weight_by=None)

Get weights for each time frame.

Parameters:

weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

Returns:

numeric weights as a vector with num_frames elements

Raises:

ValueError – invalid weights

Return type:

ndarray[Any, dtype[number[Any]]]

has_gaps()

Check if there are any time gaps between frames.

Return type:

bool

property num_elements: int

Get number of elements in each frame.

property num_frames: int

Get number of frames.

overlap_with(other)

Determine temporal overlap with another TemporalObject of same type.

This is an overlap finding problem in a set of line segments. Each frame is a line segment, with start and end of the line segment corresponding to frame start and end times, respectively. For the purpose of defining overlap, these line segments are treated as being closed at the start and open at the end. If there is no overlap, the output will be an empty list.

Parameters:

other (T) – TemporalObject to compare to

Returns:

list of tuples listing frame start and end times.

Return type:

list[tuple[int | float | integer[Any] | floating[Any], int | float | integer[Any] | floating[Any]]]

property shape: tuple[int, ...]

Get shape of dataobj.

split(split_time)

Split into two TemporalObjects, preserving total n of frames.

Parameters:

split_time (int | float | integer[Any] | floating[Any]) – time at which to split

Returns:

first of the two split TemporalObjects, not including split_time second_img: second of the two split TemporalObjects, including split_time

Return type:

first_img

property start_time: float

Get the starting time of first frame.

property total_duration: float

Get total scan duration (including any gaps).

exception dynamicpet.temporalobject.temporalobject.TimingError

Invalid frame timing.

dynamicpet.temporalobject.temporalobject.check_frametiming(frame_start, frame_duration)

Check if frame timing is valid.

Parameters:
  • frame_start (ndarray[Any, dtype[number[Any]]]) – vector of frame start times

  • frame_duration (ndarray[Any, dtype[number[Any]]]) – vector of frame end times

Raises:

TimingError – inconsistent timing info

Return type:

None

TemporalMatrix class.

class dynamicpet.temporalobject.temporalmatrix.TemporalMatrix(dataobj, frame_start, frame_duration, elem_names=None)

Matrix with corresponding time frame information.

Parameters:
  • dataobj (ndarray[Any, dtype[number[Any]]]) – vector or k x num_frames matrix

  • frame_start (ndarray[Any, dtype[number[Any]]]) – vector containing the start times of each frame

  • frame_duration (ndarray[Any, dtype[number[Any]]]) – vector containing the durations of each frame

  • elem_names (list[str] | None) – [optional] list of k element names

_dataobj

1 x num_frames vector or k x num_frames matrix

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

frame_start

vector containing the start times of each frame

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

frame_duration

vector containing the durations of each frame

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

elem_names

list of k element names

concatenate(other)

Concatenate a TemporalMatrix at the end (in time).

Parameters:

other (TemporalMatrix) – TemporalMatrix to concatenate

Returns:

concatenated TemporalMatrix

Raises:
  • TimingError – TemporalMatrices have temporal overlap or TemporalMatrix being concatenated is earlier in time

  • ValueError – TemporalMatrix being concatenated has different element names

Return type:

TemporalMatrix

property dataobj: ndarray[Any, dtype[number[Any]]]

Get data object.

dynamic_mean(weight_by=None, integration_type='rect')

Compute the (weighted) dynamic mean over time.

Parameters:
  • weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

  • integration_type (Literal['rect', 'trapz']) – rect (rectangular) or trapz (trapezoidal).

Returns:

a 1-D array of weighted temporal averages

Return type:

ndarray[Any, dtype[number[Any]]]

extract(start_time, end_time)

Extract a temporally shorter TemporalMatrix from a TemporalMatrix.

Parameters:
  • start_time (int | float | integer[Any] | floating[Any]) – time at which to begin, inclusive

  • end_time (int | float | integer[Any] | floating[Any]) – time at which to stop, inclusive

Returns:

extracted TemporalMatrix

Return type:

TemporalMatrix

get_elem(elem)

Get timeseries data for a specific element.

Parameters:

elem (str)

Return type:

TemporalMatrix

timeseries_in_mask(mask=None)

Get timeseries for each element within a subset of the elements.

Parameters:

mask (ndarray[Any, dtype[number[Any]]] | None) – Binary mask defining the subset, with shape = (num_elements, 1)

Returns:

timeseries (in mask if provided, otherwise a copy of self is returned)

Raises:

ValueError – binary mask is incompatible

Return type:

TemporalMatrix

TemporalImage class.

class dynamicpet.temporalobject.temporalimage.TemporalImage(img, frame_start, frame_duration)

4-D image with corresponding time frame information.

Parameters:
  • img (SpatialImage) – a SpatialImage object with a 3-D or 4-D dataobj

  • frame_start (ndarray[Any, dtype[number[Any]]]) – vector containing the start time of each frame

  • frame_duration (ndarray[Any, dtype[number[Any]]]) – vector containing the duration of each frame

img

SpatialImage storing image data matrix and header

Type:

nibabel.spatialimages.SpatialImage

frame_start

vector containing the start times of each frame

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

frame_duration

vector containing durations of each frame

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

concatenate(other)

Concatenate another TemporalImage at the end (in time).

Parameters:

other (TemporalImage) – TemporalImage to concatenate

Returns:

concatenated temporal image

Raises:

TimingError – TemporalImages have temporal overlap or TemporalImage being concatenated is earlier in time

Return type:

TemporalImage

property dataobj: ndarray[Any, dtype[float64]]

Get dataobj of image.

dynamic_mean(weight_by=None, integration_type='rect')

Compute the (weighted) dynamic mean over time.

Parameters:
  • weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

  • integration_type (Literal['rect', 'trapz']) – rect (rectangular) or trapz (trapezoidal).

Returns:

3-D image that is the weighted temporal average

Return type:

SpatialImage

extract(start_time, end_time)

Extract a temporally shorter TemporalImage from a TemporalImage.

Parameters:
  • start_time (int | float | integer[Any] | floating[Any]) – time at which to begin, inclusive

  • end_time (int | float | integer[Any] | floating[Any]) – time at which to stop, inclusive

Returns:

extracted TemporalImage

Return type:

extracted_img

mean_timeseries_in_mask(mask)

Get mean time activity curve (TAC) within a region of interest.

Parameters:

mask (ndarray[Any, dtype[number[Any]]]) – 3-D binary mask

Returns:

mean time series in mask

Return type:

TemporalMatrix

property num_voxels: int

Get number of voxels in each frame.

timeseries_in_mask(mask=None)

Get time activity curves (TAC) for each voxel within a region of interest.

Parameters:

mask (ndarray[Any, dtype[number[Any]]] | None) – 3-D binary mask

Returns:

timeseries (in mask if provided, otherwise in entire image)

Raises:

ValueError – binary mask is incompatible

Return type:

TemporalMatrix

dynamicpet.temporalobject.temporalimage.image_maker(x, img)

Make image from dataobj.

Parameters:
  • x (ndarray[Any, dtype[number[Any]]]) – data object

  • img (SpatialImage) – image whose class, affine, and header will be used to make x into an image

Returns:

created image

Return type:

SpatialImage

dynamicpet.petbids

PET BIDS json parsing.

Functions that take as input only the json (and not the PET data itself) are defined here.

It might be useful to make this into its own class in the future.

class dynamicpet.petbids.petbidsjson.PetBidsJson

PET-BIDS json dictionary.

clear() None.  Remove all items from D.
copy() a shallow copy of D
fromkeys(value=None, /)

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)

Return the value for key if key is in the dictionary, else default.

items() a set-like object providing a view on D's items
keys() a set-like object providing a view on D's keys
pop(k[, d]) v, remove specified key and return the corresponding value.

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) None.  Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values() an object providing a view on D's values
dynamicpet.petbids.petbidsjson.get_frametiming_in_mins(json_dict)

Get frame timing information, in minutes, from PET-BIDS json.

PET-BIDS json must be in the 2020 format with the following tags: FrameDuration: Time duration of each frame in seconds FrameTimesStart: Start times for each frame relative to TimeZero in seconds ScanStart: Time of start of scan with respect to TimeZero in seconds InjectionStart: Time of start of injection with respect to TimeZero in seconds. This corresponds to DICOM Tag (0018,1042) converted to seconds relative to TimeZero. At least one of ScanStart and InjectionStart should be 0. This method does not check if the FrameTimesStart and FrameDuration entries in the json file are sensible.

Parameters:

json_dict (PetBidsJson) – PET-BIDS json dictionary

Returns:

vector of frame start times relative to injection start, in minutes frame_end: vector of frame end times relative to injection start, in minutes

Return type:

frame_start

Raises:

ValueError – invalid frame timing

dynamicpet.petbids.petbidsjson.get_hhmmss(json_dict, event)

Get event time in HH:MM:SS.

Parameters:
  • json_dict (PetBidsJson) – json dictionary

  • event (Literal['ScanStart', 'InjectionStart', 'ImageDecayCorrectionTime', 'FirstFrameStart', 'TimeZero']) – event whose time to get in HH:MM:SS

Returns:

event time

Raises:

ValueError – image is not decay corrected

Return type:

time

dynamicpet.petbids.petbidsjson.get_radionuclide_halflife(json_dict)

Get halflife of radionuclide from PET BIDS JSON dictionary.

Parameters:

json_dict (PetBidsJson)

Return type:

float

dynamicpet.petbids.petbidsjson.read_json(jsonfilename)

Read PET-BIDS json (no validity checks).

Parameters:

jsonfilename (str | PathLike[str]) – path to csv file containing frame timing information

Returns:

json dictionary

Raises:

FileNotFoundError – jsonfilename was not found

Return type:

PetBidsJson

dynamicpet.petbids.petbidsjson.timediff(firsttime, secondtime)

Get difference in seconds between two datetime.time objects HH:MM:SS.

Parameters:
  • firsttime (time)

  • secondtime (time)

Return type:

float

dynamicpet.petbids.petbidsjson.update_frametiming_from(json_dict, temporal_object)

Update frame timing information in PET-BIDS json from TemporalObject.

Parameters:
  • json_dict (PetBidsJson) – json dictionary to be updated

  • temporal_object (TemporalObject[Any]) – TemporalObject to pull frame timing info from

Returns:

updated json dictionary

Return type:

PetBidsJson

dynamicpet.petbids.petbidsjson.write_json(json_dict, filename)

Write dictionary to a json file.

Parameters:
  • json_dict (PetBidsJson) – PET BIDS json dictionary

  • filename (str | PathLike[str]) – file name for the output

Return type:

None

PETBIDSMatrix class.

class dynamicpet.petbids.petbidsmatrix.PETBIDSMatrix(dataobj, json_dict, elem_names=None)

4-D image data with corresponding PET-BIDS time frame information.

Parameters:
  • dataobj (ndarray[Any, dtype[number[Any]]]) – vector or k x num_frames matrix

  • json_dict (PetBidsJson) – PET-BIDS json dictionary

  • elem_names (list[str] | None) – list of k ROI names

_dataobj

1 x num_frames vector or k x num_frames matrix

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

frame_start

vector containing the start times of each frame, in min

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

frame_duration

vector containing the durations of each frame, in min

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

json_dict

PET-BIDS json dictionary

Type:

dynamicpet.petbids.petbidsjson.PetBidsJson

elem_names

list of k element names

concatenate(other)

Concatenate another PETBIDSMatrix at the end (in time).

Parameters:

other (PETBIDSMatrix) – PETBIDSMatrix to concatenate

Returns:

concatenated PETBIDSMatrix

Return type:

PETBIDSMatrix

cumulative_integral(integration_type='trapz')

Cumulative integration starting at t=0 and ending at each frame_end.

If start_time > 0, the triangular area between (t=0, 0) and (t=start_time, dataobj value at 0th frame) will be added to each cumulative integral.

Parameters:

integration_type (Literal['rect', 'trapz']) – rect (rectangular) or trapz (trapezoidal).

Returns:

cumulative integral, with same shape as dataobj

Raises:

ValueError – invalid integration type

Return type:

ndarray[Any, dtype[number[Any]]]

property dataobj: ndarray[Any, dtype[number[Any]]]

Get data object.

decay_correct(decaycorrecttime=0)

Return decay corrected PETBIDSMatrix.

Parameters:

decaycorrecttime (float) – time to decay correct to, relative to time zero

Returns:

decay corrected TACs

Return type:

PETBIDSMatrix

decay_uncorrect()

Return decay uncorrected PETBIDSMatrix.

Return type:

PETBIDSMatrix

dynamic_mean(weight_by=None, integration_type='rect')

Compute the (weighted) dynamic mean over time.

Parameters:
  • weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

  • integration_type (Literal['rect', 'trapz']) – rect (rectangular) or trapz (trapezoidal).

Returns:

a 1-D array of weighted temporal averages

Return type:

ndarray[Any, dtype[number[Any]]]

property end_time: float

Get the ending time of last frame.

extract(start_time, end_time)

Extract a temporally shorter PETBIDSMatrix from a PETBIDSMatrix.

Parameters:
  • start_time (int | float | integer[Any] | floating[Any]) – time (min) at which to begin relative to TimeZero, incl.

  • end_time (int | float | integer[Any] | floating[Any]) – time (min) at which to stop relative to TimeZero, incl.

Returns:

extracted PETBIDSMatrix

Return type:

extracted_img

property frame_end: ndarray[Any, dtype[number[Any]]]

Get an array of end times for each frame.

property frame_mid: ndarray[Any, dtype[number[Any]]]

Get an array of mid times for each frame.

get_decay_corrected_tacs(decaycorrecttime=0)

Decay correct time activity curves (TACs).

Parameters:

decaycorrecttime (float) – new time offset (in seconds) to decay correct to, relative to TimeZero

Returns:

decay corrected TACs

Return type:

ndarray[Any, dtype[number[Any]]]

get_decay_correction_factor(decaycorrecttime=0)

Get radionuclide decay correction factor.

Parameters:

decaycorrecttime (float) – time offset (in seconds) relative to TimeZero for decay correction factor calculation

Returns:

decay correction factors

Return type:

ndarray[Any, dtype[number[Any]]]

get_decay_uncorrected_tacs()

Decay uncorrect time activity curves (TACs).

Return type:

ndarray[Any, dtype[number[Any]]]

get_elem(elem)

Get timeseries data for a specific element.

Parameters:

elem (str)

Return type:

TemporalMatrix

get_idx_extract_time(start_time, end_time)

Get the start and end indices for extracting a time interval.

Parameters:
  • start_time (int | float | integer[Any] | floating[Any]) – time at which to begin, inclusive

  • end_time (int | float | integer[Any] | floating[Any]) – time at which to stop, inclusive

Returns:

tuple of start index (inclusive) and end index (exclusive) of interval to extract

Raises:

TimingError – extraction times are out of bound

Return type:

tuple[int, int]

get_weights(weight_by=None)

Get weights for each time frame.

Parameters:

weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

Returns:

numeric weights as a vector with num_frames elements

Raises:

ValueError – invalid weights

Return type:

ndarray[Any, dtype[number[Any]]]

has_gaps()

Check if there are any time gaps between frames.

Return type:

bool

property num_elements: int

Get number of elements in each frame.

property num_frames: int

Get number of frames.

overlap_with(other)

Determine temporal overlap with another TemporalObject of same type.

This is an overlap finding problem in a set of line segments. Each frame is a line segment, with start and end of the line segment corresponding to frame start and end times, respectively. For the purpose of defining overlap, these line segments are treated as being closed at the start and open at the end. If there is no overlap, the output will be an empty list.

Parameters:

other (T) – TemporalObject to compare to

Returns:

list of tuples listing frame start and end times.

Return type:

list[tuple[int | float | integer[Any] | floating[Any], int | float | integer[Any] | floating[Any]]]

set_timezero(anchor='InjectionStart')

Modify time tags and frame time start to specified anchor.

Parameters:

anchor (Literal['InjectionStart', 'ScanStart'])

Return type:

None

property shape: tuple[int, ...]

Get shape of dataobj.

split(split_time)

Split into two TemporalObjects, preserving total n of frames.

Parameters:

split_time (int | float | integer[Any] | floating[Any]) – time at which to split

Returns:

first of the two split TemporalObjects, not including split_time second_img: second of the two split TemporalObjects, including split_time

Return type:

first_img

property start_time: float

Get the starting time of first frame.

timeseries_in_mask(mask=None)

Get timeseries for each element within a subset of the elements.

Parameters:

mask (ndarray[Any, dtype[number[Any]]] | None) – Binary mask defining the subset, with shape = (num_elements, 1)

Returns:

timeseries (in mask if provided, otherwise a copy of self is returned)

Raises:

ValueError – binary mask is incompatible

Return type:

TemporalMatrix

to_filename(filename, save_json=False, anchor='InjectionStart')

Save to file.

Parameters:
  • filename (str | PathLike[str]) – file name for the tabular TAC tsv output

  • save_json (bool) – whether the PET-BIDS json side car should be saved

  • anchor (Literal['InjectionStart', 'ScanStart']) – time anchor. The corresponding tag in the PET-BIDS json will be set to zero (with appropriate offsets applied to other tags).

Raises:

ValueError – file is not a tsv file

Return type:

None

property total_duration: float

Get total scan duration (including any gaps).

dynamicpet.petbids.petbidsmatrix.load(filename, jsonfilename=None)

Read a tsv file containing temporal entries.

Each column of the tsv file should be a time activity curve.

Parameters:
  • filename (str | PathLike[str]) – path to the tsv file

  • jsonfilename (str | PathLike[str] | None) – path to the PET BIDS json file

Returns:

PETBIDSMatrix created from tsv file

Raises:

ValueError – file is not a tsv file

Return type:

PETBIDSMatrix

PETBIDSImage class.

class dynamicpet.petbids.petbidsimage.PETBIDSImage(img, json_dict)

4-D image data with corresponding PET-BIDS time frame information.

Parameters:
  • img (SpatialImage) – a SpatialImage object with a 3-D or 4-D dataobj

  • json_dict (PetBidsJson) – PET-BIDS json dictionary

img

SpatialImage storing image data matrix and header

Type:

nibabel.spatialimages.SpatialImage

frame_start

vector containing the start times of each frame, in min

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

frame_duration

vector containing the durations of each frame, in min

Type:

numpy.ndarray[Any, numpy.dtype[numpy.number[Any]]]

json_dict

PET-BIDS json dictionary

Type:

dynamicpet.petbids.petbidsjson.PetBidsJson

concatenate(other)

Concatenate another PETBIDSImage at the end (in time).

Parameters:

other (PETBIDSImage) – PETBIDSImage to concatenate

Returns:

concatenated PETBIDSImage

Return type:

PETBIDSImage

cumulative_integral(integration_type='trapz')

Cumulative integration starting at t=0 and ending at each frame_end.

If start_time > 0, the triangular area between (t=0, 0) and (t=start_time, dataobj value at 0th frame) will be added to each cumulative integral.

Parameters:

integration_type (Literal['rect', 'trapz']) – rect (rectangular) or trapz (trapezoidal).

Returns:

cumulative integral, with same shape as dataobj

Raises:

ValueError – invalid integration type

Return type:

ndarray[Any, dtype[number[Any]]]

property dataobj: ndarray[Any, dtype[float64]]

Get dataobj of image.

decay_correct(decaycorrecttime=0)

Return decay corrected PETBIDSImage.

This code is written to work with both ScanStart and InjectionStart as TimeZero anchors, even though the internal representation is always with an InjectionStart anchor.

Parameters:

decaycorrecttime (float) – time to decay correct to, relative to time zero

Returns:

decay corrected PET image

Return type:

PETBIDSImage

decay_uncorrect()

Return decay uncorrected PETBIDSImage.

Return type:

PETBIDSImage

dynamic_mean(weight_by=None, integration_type='rect')

Compute the (weighted) dynamic mean over time.

Parameters:
  • weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

  • integration_type (Literal['rect', 'trapz']) – rect (rectangular) or trapz (trapezoidal).

Returns:

3-D image that is the weighted temporal average

Return type:

SpatialImage

property end_time: float

Get the ending time of last frame.

extract(start_time, end_time)

Extract a temporally shorter PETBIDSImage from a PETBIDSImage.

Parameters:
  • start_time (int | float | integer[Any] | floating[Any]) – time (min) at which to begin relative to TimeZero, incl.

  • end_time (int | float | integer[Any] | floating[Any]) – time (min) at which to stop relative to TimeZero, incl.

Returns:

extracted PETBIDSImage

Return type:

extracted_img

property frame_end: ndarray[Any, dtype[number[Any]]]

Get an array of end times for each frame.

property frame_mid: ndarray[Any, dtype[number[Any]]]

Get an array of mid times for each frame.

get_decay_corrected_tacs(decaycorrecttime=0)

Decay correct time activity curves (TACs).

Parameters:

decaycorrecttime (float) – new time offset (in seconds) to decay correct to, relative to TimeZero

Returns:

decay corrected TACs

Return type:

ndarray[Any, dtype[number[Any]]]

get_decay_correction_factor(decaycorrecttime=0)

Get radionuclide decay correction factor.

Parameters:

decaycorrecttime (float) – time offset (in seconds) relative to TimeZero for decay correction factor calculation

Returns:

decay correction factors

Return type:

ndarray[Any, dtype[number[Any]]]

get_decay_uncorrected_tacs()

Decay uncorrect time activity curves (TACs).

Return type:

ndarray[Any, dtype[number[Any]]]

get_idx_extract_time(start_time, end_time)

Get the start and end indices for extracting a time interval.

Parameters:
  • start_time (int | float | integer[Any] | floating[Any]) – time at which to begin, inclusive

  • end_time (int | float | integer[Any] | floating[Any]) – time at which to stop, inclusive

Returns:

tuple of start index (inclusive) and end index (exclusive) of interval to extract

Raises:

TimingError – extraction times are out of bound

Return type:

tuple[int, int]

get_weights(weight_by=None)

Get weights for each time frame.

Parameters:

weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

Returns:

numeric weights as a vector with num_frames elements

Raises:

ValueError – invalid weights

Return type:

ndarray[Any, dtype[number[Any]]]

has_gaps()

Check if there are any time gaps between frames.

Return type:

bool

mean_timeseries_in_mask(mask)

Get mean time activity curve (TAC) within a region of interest.

Parameters:

mask (ndarray[Any, dtype[number[Any]]]) – 3-D binary mask

Returns:

mean time series in mask

Return type:

TemporalMatrix

property num_elements: int

Get number of elements in each frame.

property num_frames: int

Get number of frames.

property num_voxels: int

Get number of voxels in each frame.

overlap_with(other)

Determine temporal overlap with another TemporalObject of same type.

This is an overlap finding problem in a set of line segments. Each frame is a line segment, with start and end of the line segment corresponding to frame start and end times, respectively. For the purpose of defining overlap, these line segments are treated as being closed at the start and open at the end. If there is no overlap, the output will be an empty list.

Parameters:

other (T) – TemporalObject to compare to

Returns:

list of tuples listing frame start and end times.

Return type:

list[tuple[int | float | integer[Any] | floating[Any], int | float | integer[Any] | floating[Any]]]

set_timezero(anchor='InjectionStart')

Modify time tags and frame time start to specified anchor.

Parameters:

anchor (Literal['InjectionStart', 'ScanStart'])

Return type:

None

property shape: tuple[int, ...]

Get shape of dataobj.

split(split_time)

Split into two TemporalObjects, preserving total n of frames.

Parameters:

split_time (int | float | integer[Any] | floating[Any]) – time at which to split

Returns:

first of the two split TemporalObjects, not including split_time second_img: second of the two split TemporalObjects, including split_time

Return type:

first_img

property start_time: float

Get the starting time of first frame.

timeseries_in_mask(mask=None)

Get time activity curves (TAC) for each voxel within a region of interest.

Parameters:

mask (ndarray[Any, dtype[number[Any]]] | None) – 3-D binary mask

Returns:

timeseries (in mask if provided, otherwise in entire image)

Raises:

ValueError – binary mask is incompatible

Return type:

TemporalMatrix

to_filename(filename, save_json=False, anchor='InjectionStart')

Save to file.

Parameters:
  • filename (str | PathLike[str]) – file name for the PET image output

  • save_json (bool) – whether the PET-BIDS json side car should be saved

  • anchor (Literal['InjectionStart', 'ScanStart']) – time anchor. The corresponding tag in the PET-BIDS json will be set to zero (with appropriate offsets applied to other tags).

Return type:

None

property total_duration: float

Get total scan duration (including any gaps).

dynamicpet.petbids.petbidsimage.load(filename, jsonfilename=None, **kwargs)

Load a PET image and accompanying BIDS json.

Parameters:
  • filename (str | PathLike[str]) – path to 4-D image file to load

  • jsonfilename (str | PathLike[str] | None) – path to PET-BIDS json file with frame timing info

  • kwargs (Any) – keyword arguments to format-specific load (see nibabel.load)

Returns:

loaded image

Raises:

FileNotFoundError – filename or jsonfilename was not found

Return type:

PETBIDSImage

dynamicpet.denoise

HYPR denoising.

dynamicpet.denoise.hypr.hypr_lr(ti, fwhm)

HYPR-LR denoising for dynamic PET.

HYPR-LR is short for HighlY constrained backPRojection for Local Reconstruction.

Reference: Christian, B. T., Vandehey, N. T., Floberg, J. M., Mistretta, C. A. (2010). Dynamic PET denoising with HYPR processing. Journal of Nuclear Medicine, 51(7), 1147-1154. https://doi.org/10.2967/jnumed.109.073999

Parameters:
  • ti (PETBIDSImage) – dynamic PET

  • fwhm (float) – full width at half max (in mm) of the Gaussian smoothing filter

Returns:

HYPR-LR denoised dynamic PET

Return type:

PETBIDSImage

dynamicpet.kineticmodel

These kinetic model implementations use the entire temporal extent of the TAC object provided for modeling. If you’d like to use a specific time interval for modeling, first extract this time interval and then fit the kinetic model.

Standardized update value ratio (SUVR).

class dynamicpet.kineticmodel.suvr.SUVR(reftac, tacs)

Standardized uptake value ratio (SUVR).

SUVR = SUV (target) / SUV (reference)
= frame duration weighted sum of target TAC /

frame duration weighted sum of reference TAC

Parameters:
fit(mask=None)

Calculate SUVR.

Parameters:

mask (ndarray[Any, dtype[number[Any]]] | None) – [optional] A 1-D (for TemporalMatrix TACs) or 3-D (for TemporalImage TACs) binary mask that defines where to fit the kinetic model. Elements outside the mask will be set to to 0 in parametric estimate outputs.

Return type:

None

Example

>>> import numpy as np
>>> from dynamicpet.temporalobject import TemporalMatrix
>>> from dynamicpet.kineticmodel.suvr import SUVR
>>> frame_start = [60, 70]
>>> frame_duration = [10, 10]
>>> reftac = TemporalMatrix(dataobj=np.array([2, 2]),
                            frame_start=frame_start,
                            frame_duration=frame_duration)
>>> tacs = TemporalMatrix(dataobj=np.array([[3, 3], [6, 6]]),
                          frame_start=frame_start,
                          frame_duration=frame_duration)
>>> km = SUVR(reftac, tacs)
>>> km.fit()
>>> km.get_parameter('SUVR')
array([1.5, 3. ])
fitted_tacs()

Get fitted TACs based on estimated model parameters.

Return type:

TemporalMatrix | TemporalImage

classmethod get_param_names()

Get names of kinetic model parameters.

Return type:

list[str]

get_parameter(param_name)

Get a fitted parameter.

If the input (tacs) is an image, parameter will be returned as an image. Otherwise, it will be a matrix.

Parameters:

param_name (str) – name of parameter

Returns:

parameter matrix or image

Raises:

AttributeError – no estimate is available (kinetic model has not been fitted) or this model doesn’t have such a parameter

Return type:

SpatialImage | ndarray[Any, dtype[number[Any]]]

set_parameter(param_name, param, mask=None)

Set kinetic model parameter.

Parameters:
  • param_name (str) – name of parameter to set

  • param (ndarray[Any, dtype[number[Any]]]) – parameter estimate

  • mask (ndarray[Any, dtype[number[Any]]] | None) – [optional] A 1-D (for TemporalMatrix TACs) or 3-D (for TemporalImage TACs) binary mask that defines where the kinetic model was fitted. Elements outside the mask will be set to to 0 in parametric outputs.

Return type:

None

Simplified reference tissue model (SRTM).

class dynamicpet.kineticmodel.srtm.SRTMLammertsma1996(reftac, tacs)

Simplified reference tissue model (SRTM).

Reference: Lammertsma AA, Hume SP. Simplified reference tissue model for PET receptor studies. NeuroImage. 1996 Dec;4(3 Pt 1):153-8.

Parameters:
fit(mask=None, weight_by=None)

Estimate model parameters.

Parameters:
  • weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – [optional] frame weights used in model fitting. If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

  • mask (ndarray[Any, dtype[number[Any]]] | None) – [optional] A 1-D (for TemporalMatrix TACs) or 3-D (for TemporalImage TACs) binary mask that defines where to fit the kinetic model. Elements outside the mask will be set to to 0 in parametric estimate outputs.

Return type:

None

fitted_tacs()

Get fitted TACs based on estimated model parameters.

Return type:

TemporalMatrix | TemporalImage

classmethod get_param_names()

Get names of kinetic model parameters.

Return type:

list[str]

get_parameter(param_name)

Get a fitted parameter.

If the input (tacs) is an image, parameter will be returned as an image. Otherwise, it will be a matrix.

Parameters:

param_name (str) – name of parameter

Returns:

parameter matrix or image

Raises:

AttributeError – no estimate is available (kinetic model has not been fitted) or this model doesn’t have such a parameter

Return type:

SpatialImage | ndarray[Any, dtype[number[Any]]]

set_parameter(param_name, param, mask=None)

Set kinetic model parameter.

Parameters:
  • param_name (str) – name of parameter to set

  • param (ndarray[Any, dtype[number[Any]]]) – parameter estimate

  • mask (ndarray[Any, dtype[number[Any]]] | None) – [optional] A 1-D (for TemporalMatrix TACs) or 3-D (for TemporalImage TACs) binary mask that defines where the kinetic model was fitted. Elements outside the mask will be set to to 0 in parametric outputs.

Return type:

None

class dynamicpet.kineticmodel.srtm.SRTMZhou2003(reftac, tacs)

Simplified reference tissue model (SRTM) with linear spatial constraint.

Reference: Zhou Y, Endres CJ, Brašić JR, Huang S-C, Wong DF. Linear regression with spatial constraint to generate parametric images of ligand-receptor dynamic PET studies with a simplified reference tissue model. Neuroimage. 2003;18:975-989.

Parameters:
fit(mask=None, integration_type='trapz', weight_by='frame_duration', fwhm=None)

Estimate model parameters.

Parameters:
  • integration_type (Literal['rect', 'trapz']) – If ‘rect’, rectangular integration is used for TACs. If ‘trapz’, trapezoidal integration is used based on middle timepoint of each frame.

  • weight_by (Literal['frame_duration'] | ~numpy.ndarray[~typing.Any, ~numpy.dtype[~numpy.number[~typing.Any]]] | None) – [optional] frame weights used in model fitting. If weight_by == None, each frame is weighted equally. If weight_by == ‘frame_duration’, each frame is weighted proportionally to its duration (inverse variance weighting). If weight_by is a 1-D array, then specified values are used.

  • mask (ndarray[Any, dtype[number[Any]]] | None) – [optional] A 1-D (for TemporalMatrix TACs) or 3-D (for TemporalImage TACs) binary mask that defines where to fit the kinetic model. Elements outside the mask will be set to to 0 in parametric estimate outputs.

  • fwhm (int | float | integer[Any] | floating[Any] | list[int | float | integer[Any] | floating[Any]] | None) – scalar or length 3 sequence, FWHM in mm over which to smooth

Return type:

None

fitted_tacs()

Get fitted TACs based on estimated model parameters.

Return type:

TemporalMatrix | TemporalImage

classmethod get_param_names()

Get names of kinetic model parameters.

Return type:

list[str]

get_parameter(param_name)

Get a fitted parameter.

If the input (tacs) is an image, parameter will be returned as an image. Otherwise, it will be a matrix.

Parameters:

param_name (str) – name of parameter

Returns:

parameter matrix or image

Raises:

AttributeError – no estimate is available (kinetic model has not been fitted) or this model doesn’t have such a parameter

Return type:

SpatialImage | ndarray[Any, dtype[number[Any]]]

prep_refine_r1(mask=None, fwhm=None)

Refine R1.

Parameters:
  • mask (ndarray[Any, dtype[number[Any]]] | None) – [optional] A 1-D (for TemporalMatrix TACs) or 3-D (for TemporalImage TACs) binary mask that defines where to fit the kinetic model. Elements outside the mask will be set to to 0 in parametric estimate outputs.

  • fwhm (int | float | integer[Any] | floating[Any] | list[int | float | integer[Any] | floating[Any]] | None) – scalar or length 3 sequence, FWHM in mm over which to smooth

Returns:

flattened matrix (according to mask) of smoothed r1 smooth_k2_mat: flattened matrix (according to mask) of smoothed k2 smooth_k2a_mat: flattened matrix (according to mask) of smoothed k2a h: matrix as described in Zhou et al.

Return type:

smooth_r1_mat

set_parameter(param_name, param, mask=None)

Set kinetic model parameter.

Parameters:
  • param_name (str) – name of parameter to set

  • param (ndarray[Any, dtype[number[Any]]]) – parameter estimate

  • mask (ndarray[Any, dtype[number[Any]]] | None) – [optional] A 1-D (for TemporalMatrix TACs) or 3-D (for TemporalImage TACs) binary mask that defines where the kinetic model was fitted. Elements outside the mask will be set to to 0 in parametric outputs.

Return type:

None

dynamicpet.kineticmodel.srtm.srtm_model(reftac, bp_nd, r1, k2)

SRTM model to generate a target TAC.

Parameters:
  • reftac (TemporalMatrix) – reference TAC

  • bp_nd (float) – binding potential

  • r1 (float) – relative radiotracer delivery parameter, R1

  • k2 (float) – k2

Returns:

target TAC

Return type:

ndarray[Any, dtype[number[Any]]]