hazenlib ACR tasks
hazenlib.tasks.acr_geometric_accuracy task
ACR Geometric Accuracy
https://www.acraccreditation.org/-/media/acraccreditation/documents/mri/largephantomguidance.pdf
Calculates geometric accuracy for slices 1 and 5 of the ACR phantom.
This script calculates the horizontal and vertical lengths of the ACR phantom in Slice 1 in accordance with the ACR Guidance. This script calculates the horizontal, vertical and diagonal lengths of the ACR phantom in Slice 5 in accordance with the ACR Guidance. The average distance measurement error, maximum distance measurement error and coefficient of variation of all distance measurements is reported as recommended by IPEM Report 112, “Quality Control and Artefacts in Magnetic Resonance Imaging”.
This is done by first producing a binary mask for each respective slice. Line profiles are drawn with aid of rotation matrices around the centre of the test object to determine each respective length. The results are also visualised.
Created by Yassine Azma yassine.azma@rmh.nhs.uk
18/11/2022
- class hazenlib.tasks.acr_geometric_accuracy.ACRGeometricAccuracy(**kwargs)[source]
Bases:
HazenTaskGeometric accuracy measurement class for DICOM images of the ACR phantom.
- run() dict[source]
Main function for performing geometric accuracy measurement using the first and fifth slices from the ACR phantom image set.
- Returns
results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation.
- Return type
dict
- get_geometric_accuracy(slice_index)[source]
Measure geometric accuracy for input slice.
Creates a mask over the phantom from the pixel array of the DICOM image. Uses the centre and shape of the mask to determine horizontal and vertical lengths, and also diagonal lengths in slice 5.
- Parameters
slice_index (int) – the index of the slice position, for example slice 5 is at index 4.
- Returns
horizontal and vertical distances.
- Return type
tuple of float
- diagonal_lengths(img, cxy, slice_index)[source]
Measure diagonal lengths.
Rotates the pixel array by 45° and measures the horizontal and vertical distances.
- Parameters
img (np.ndarray) – pixel array of the slice (dcm.pixel_array).
cxy (tuple) – x,y coordinates of the circle centre.
slice_index (int) – index of the slice number.
- Returns
for both the south-east (SE) diagonal length and the south-west (SW) diagonal length:
”start” and “end” indicate the start and end x and y positions of the lengths; “Extent” is the distance (in pixels) of the lengths; “Distance” is “Extent” with factors applied to convert from pixels to mm.
- Return type
tuple of dictionaries
- static get_distortion_metrics(L)[source]
Calculates the mean error, the maximum error and the coefficient of variation between the horizontal and vertical distances measured on slices 1 and 5.
- Parameters
L (tuple) – horizontal and vertical distances from slices 1 and 5.
- Returns
mean_err, max_err, cov_l
- Return type
tuple of floats
hazenlib.tasks.acr_ghosting task
ACR Ghosting
https://www.acraccreditation.org/-/media/acraccreditation/documents/mri/largephantomguidance.pdf
Calculates the percent-signal ghosting for slice 7 of the ACR phantom.
This script calculates the percentage signal ghosting in accordance with the ACR Guidance. This is done by first defining a large 200cm2 ROI before placing 10cm2 elliptical ROIs outside the phantom along the cardinal directions. The results are also visualised.
Created by Yassine Azma yassine.azma@rmh.nhs.uk
14/11/2022
- class hazenlib.tasks.acr_ghosting.ACRGhosting(**kwargs)[source]
Bases:
HazenTaskGhosting measurement class for DICOM images of the ACR phantom.
- run() dict[source]
Main function for performing ghosting measurement using slice 7 from the ACR phantom image set.
- Returns
results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation.
- Return type
dict
- get_signal_ghosting(dcm)[source]
Calculate the percentage signal ghosting (PSG).
Sample signal intensity from ellipses outside the phantom in four directions and calculate the mean signal value within each. Percentage signal ghosting (PSG) is then expressed as the mean signal in these four ROIs as a percentage of the mean signal in a ROI in the centre of the phantom.
- Parameters
dcm (pydicom.Dataset) – DICOM image object.
- Returns
percentage ghosting value.
- Return type
float
hazenlib.tasks.acr_slice_position task
ACR Slice Position
https://www.acraccreditation.org/-/media/acraccreditation/documents/mri/largephantomguidance.pdf
Calculates the bar length difference for slices 1 and 11 of the ACR phantom.
This script calculates the bar length difference in accordance with the ACR Guidance. Line profiles are drawn vertically through the left and right wedges. The right wedge’s line profile is shifted and wrapped round before being subtracted from the left wedge’s line profile, e.g.:
Right line profile: [1, 2, 3, 4, 5]
Right line profile wrapped round by 1: [2, 3, 4, 5, 1]
This wrapping process, from hereon referred to as ‘circular shifting’, is then used for subtractions.
The shift used to produce the minimum difference between the circularly shifted right line profile and the static left one is used to determine the bar length difference, which is twice the slice position displacement.
The results are also visualised.
Created by Yassine Azma yassine.azma@rmh.nhs.uk
28/12/2022
- class hazenlib.tasks.acr_slice_position.ACRSlicePosition(**kwargs)[source]
Bases:
HazenTaskSlice position measurement class for DICOM images of the ACR phantom.
- run() dict[source]
Main function for performing slice position measurement using the first and last slices from the ACR phantom image set.
- Returns
results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation
- Return type
dict
- find_wedges(img, mask)[source]
Find wedges in the pixel array.
Investigates the top half of the phantom to locate where the wedges pass through the slice, and calculates the co-ordinates of these locations.
- Parameters
img (np.ndarray) – dcm.pixel_array
mask (np.ndarray) – dcm.pixel_array of the image mask
- Returns
of x and y coordinates of wedges.
- Return type
tuple of tuples
hazenlib.tasks.acr_slice_thickness task
ACR Slice Thickness
Calculates the slice thickness for slice 1 of the ACR phantom.
The ramps located in the middle of the phantom are located and line profiles are drawn through them. The full-width half-maximum (FWHM) of each ramp is determined to be their length. Using the formula described in the ACR guidance, the slice thickness is then calculated.
Created by Yassine Azma yassine.azma@rmh.nhs.uk
31/01/2022
- class hazenlib.tasks.acr_slice_thickness.ACRSliceThickness(**kwargs)[source]
Bases:
HazenTaskSlice width measurement class for DICOM images of the ACR phantom.
- run() dict[source]
Main function for performing slice width measurement using slice 1 from the ACR phantom image set.
- Returns
results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation.
- Return type
dict
- find_ramps(img, centre)[source]
Find ramps in the pixel array and return the co-ordinates of their location.
- Parameters
img (np.ndarray) – dcm.pixel_array
centre (list) – x,y coordinates of the phantom centre
- Returns
x and y coordinates of ramp.
- Return type
tuple
hazenlib.tasks.acr_snr task
ACR SNR
Calculates the SNR for slice 7 (the uniformity slice) of the ACR phantom.
This script utilises the smoothed subtraction method described in McCann 2013 [1], and a standard subtraction SNR.
Created by Neil Heraghty (Adapted by Yassine Azma, yassine.azma@rmh.nhs.uk)
09/01/2023
[1] McCann, A. J., Workman, A., & McGrath, C. (2013). A quick and robust method for measurement of signal-to-noise ratio in MRI. Physics in Medicine & Biology, 58(11), 3775.
- class hazenlib.tasks.acr_snr.ACRSNR(**kwargs)[source]
Bases:
HazenTaskSignal-to-noise ratio measurement class for DICOM images of the ACR phantom.
- run() dict[source]
Main function for performing SNR measurement using slice 7 from the ACR phantom image set. Performs either smoothing or subtraction method depending on user-provided input.
Notes
Uses the smoothing method by default or the subtraction method if a second set of images are provided (using the –subtract option with dataset in a separate folder).
- Returns
results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation.
- Return type
dict
- get_normalised_snr_factor(dcm, measured_slice_width=None) float[source]
Calculates the normalisation factor to be applied to the SNR in order to obtain the absolute SNR (ASNR). The normalisation factor depends on voxel size, bandwidth, number of averages and number of phase encoding steps.
- Parameters
dcm (pydicom.Dataset) – DICOM image object
measured_slice_width (float, optional) – Provide the true slice width for the set of images. Defaults to None.
- Returns
normalisation factor.
- Return type
float
- filtered_image(dcm: Dataset) array[source]
Apply filtering to a pixel array (image), as per the single image SNR method outlined in McCann et al, 2013.
Notes
Performs a 2D convolution (for filtering images), using uniform_filter (SciPy function).
- Parameters
dcm (pydicom.Dataset) – DICOM image object.
- Returns
pixel array of the filtered image.
- Return type
np.array
- get_noise_image(dcm: Dataset) array[source]
Get a noise image when only one set of DICOM data is available.
Notes
Separates the image noise by smoothing the pixel array and subtracting the smoothed pixel array from the original, leaving only the noise.
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
pixel array representing the image noise.
- Return type
np.array
- get_roi_samples(ax, dcm: Dataset, centre_col: int, centre_row: int) list[source]
Takes the pixel array and divides it into several rectangular regions of interest (ROIs). If ‘ax’ is provided, then a plot of the ROIs is generated.
- Parameters
ax (matplotlib.pyplot.subplots) – matplotlib axis for visualisation.
dcm (pydicom.Dataset or np.ndarray) – DICOM image object, or its pixel array.
centre_col (int) – x coordinate of the centre.
centre_row (int) – y coordinate of the centre.
- Returns
subsets of the original pixel array.
- Return type
list of np.array
- snr_by_smoothing(dcm: Dataset, measured_slice_width=None) float[source]
Obtains a noise image using the single-image smoothing technique. Generates a ROI within the phantom region of the pixel array. Then measures the mean signal within the ROI on the original pixel array, and the standard deviation within the ROI on the noise image. Calculates SNR using these values and multiplies the SNR by the normalisation factor.
- Parameters
dcm (pydicom.Dataset) – DICOM image object.
measured_slice_width (float, optional) – Provide the true slice width for the set of images. Defaults to None.
- Returns
normalised_snr.
- Return type
float
- snr_by_subtraction(dcm1: Dataset, dcm2: Dataset, measured_slice_width=None) float[source]
Calculates signal to noise ratio using the two image subtraction method. Obtains a noise image by subtracting the two pixel arrays. Obtains ROIs within the phantom region of the pixel arrays. Calculates the mean within the ROI on one of the pixel arrays, and the standard deviation within the ROIs on the noise image. Calculates the SNR with these measurements and multiplies by the normalisation factor.
- Parameters
dcm1 (pydicom.Dataset) – DICOM image object to calculate signal.
dcm2 (pydicom.Dataset) – DICOM image object to calculate noise.
measured_slice_width (float, optional) – Provide the true slice width for the set of images. Defaults to None.
- Returns
normalised_snr.
- Return type
float
hazenlib.tasks.acr_spatial_resolution task
ACR Spatial Resolution (MTF)
https://www.acraccreditation.org/-/media/acraccreditation/documents/mri/largephantomguidance.pdf
Calculates the effective resolution (MTF50) for slice 1 for the ACR phantom. This is done in accordance with the methodology described in Section 3 of the following paper:
https://opg.optica.org/oe/fulltext.cfm?uri=oe-22-5-6040&id=281325
WARNING: The phantom must be slanted for valid results to be produced. This test is not within the scope of ACR guidance.
This script first identifies the rotation angle of the ACR phantom using slice 1. It provides a warning if the slanted angle is less than 3 degrees.
The location of the ramps within the slice thickness are identified and a square ROI is selected around the anterior edge of the slice thickness insert.
A rudimentary edge response function is generated based on the edge within the ROI to provide initialisation values for the 2D normal cumulative distribution fit of the ROI.
The edge is then super-sampled in the direction of the bright-dark transition of the edge and binned at right angles based on the edge slope determined from the 2D Normal CDF fit of the ROI to obtain the edge response function.
This super-sampled ERF is then fitted using a weighted sigmoid function. The raw data and this fit are then used to determine the LSF and the subsequent MTF. The MTF50 for both raw and fitted data are reported.
The results are also visualised.
Created by Yassine Azma yassine.azma@rmh.nhs.uk
22/02/2023
- class hazenlib.tasks.acr_spatial_resolution.ACRSpatialResolution(**kwargs)[source]
Bases:
HazenTaskSpatial resolution measurement class for DICOM images of the ACR phantom
Inherits from HazenTask class
- run() dict[source]
Main function for performing spatial resolution measurement using slice 1 from the ACR phantom image set
- Returns
results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation
- Return type
dict
- y_position_for_ramp(img, cxy)[source]
Identify the y coordinate of the ramp
- Parameters
img (np.ndarray) – dcm.pixelarray
cxy (tuple) – x,y coordinates of the object centre
- Returns
y coordinate of the ramp min
- Return type
float
- crop_image(img, x, y, width)[source]
Return a rectangular subset of a pixel array
- Parameters
img (np.ndarray) – dcm.pixelarray
x (int) – x coordinate of centre
y (int) – y coordinate of centre
width (int) – size of the array top subset
- Returns
subset of a pixel array with given width
- Return type
np.ndarray
- get_edge_type(crop_img)[source]
Determine direction of ramp edge
- Parameters
crop_img (np.ndarray) – cropped pixel array ~ subset of the image
- Returns
vertical/horizontal and up/down or left/rigtward
- Return type
tuple of string
- edge_location_for_plot(crop_img, edge_type)[source]
Determine the location of the edge so it can be visualised
- Parameters
crop_img (np.array) – cropped pixel array ~ subset of the image
edge_type (tuple) – vertical/horizontal and up/down or left/rigtward
- Returns
mask array for edge location
- Return type
np.array
- fit_normcdf_surface(crop_img, edge_type, direction)[source]
Fit normalised CDF? to surface
- Parameters
crop_img (np.array) – cropped pixel array ~ subset of the image
edge_type (string) – vertical/horizontal
direction (string) – up/down or left/rigtward
- Returns
slope, surface
- Return type
tuple of floats
- sample_erf(crop_img, slope, edge_type)[source]
_summary_
- Parameters
crop_img (np.array) – cropped pixel array ~ subset of the image
slope (float) – value of slope of edge
edge_type (string) – vertical/horizontal
- Returns
_description_
- Return type
np.array
- fit_erf(erf)[source]
Fit ERF
- Parameters
erf (np.array) – _description_
- Returns
_description_
- Return type
_type_
- calculate_MTF(erf)[source]
Calculate MTF
- Parameters
erf (np.array) – array of ?
- Returns
freq, lsf, MTF
- Return type
tuple
hazenlib.tasks.acr_uniformity task
ACR Uniformity
https://www.acraccreditation.org/-/media/acraccreditation/documents/mri/largephantomguidance.pdf
Calculates the percentage integral uniformity for slice 7 of the ACR phantom.
This script calculates the percentage integral uniformity in accordance with the ACR Guidance. This is done by first defining a large 200cm2 ROI before placing 1cm2 ROIs at every pixel within the large ROI. At each point, the mean of the 1cm2 ROI is calculated. The ROIs with the maximum and minimum mean value are used to calculate the integral uniformity. The results are also visualised.
Created by Yassine Azma yassine.azma@rmh.nhs.uk
13/01/2022
- class hazenlib.tasks.acr_uniformity.ACRUniformity(**kwargs)[source]
Bases:
HazenTaskUniformity measurement class for DICOM images of the ACR phantom.
- run() dict[source]
Main function for performing uniformity measurement using slice 7 from the ACR phantom image set.
- Returns
results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation
- Return type
dict
- get_integral_uniformity(dcm)[source]
Calculates the percent integral uniformity (PIU) of a DICOM pixel array.
Iterates with a ~1 cm^2 ROI through a ~200 cm^2 ROI inside the phantom region, and calculates the mean non-zero pixel value inside each ~1 cm^2 ROI.
The PIU is defined as: PIU = 100 * (1 - (max - min) / (max + min)), where
‘max’ and ‘min’ represent the maximum and minimum of the mean non-zero pixel values of each ~1 cm^2 ROI.
- Parameters
dcm (pydicom.Dataset) – DICOM image object to calculate uniformity from.
- Returns
value of integral uniformity.
- Return type
float