Core Modules¶
The following is the API documentation for the core modules of pylinac. These can be used directly, or as the base for mixin classes or methods.
Image Module¶
This module holds classes for image loading and manipulation.
- pylinac.core.image.equate_images(image1: DicomImage | ArrayImage | FileImage | LinacDicomImage, image2: DicomImage | ArrayImage | FileImage | LinacDicomImage) tuple[DicomImage | ArrayImage | FileImage | LinacDicomImage, DicomImage | ArrayImage | FileImage | LinacDicomImage] [source]¶
- Crop and resize two images to make them:
The same pixel dimensions
The same DPI
The usefulness of the function comes when trying to compare images from different sources. The best example is calculating gamma on a machine log fluence and EPID image. The physical and pixel dimensions must be normalized, the SID normalized
Parameters¶
- image1{
ArrayImage
,DicomImage
,FileImage
} Must have DPI and SID.
- image2{
ArrayImage
,DicomImage
,FileImage
} Must have DPI and SID.
Returns¶
- image1
ArrayImage
The first image equated.
- image2
ArrayImage
The second image equated.
- pylinac.core.image.is_image(path: str | io.BytesIO | ImageLike | np.ndarray) bool [source]¶
Determine whether the path is a valid image file.
Returns¶
bool
- pylinac.core.image.retrieve_image_files(path: str) list[str] [source]¶
Retrieve the file names of all the valid image files in the path.
Returns¶
- list
Contains strings pointing to valid image paths.
- pylinac.core.image.load(path: str | Path | ImageLike | np.ndarray | BinaryIO, **kwargs) ImageLike [source]¶
Load a DICOM image, JPG/TIF/BMP image, or numpy 2D array.
Parameters¶
- pathstr, file-object
The path to the image file or data stream or array.
- kwargs
See
FileImage
,DicomImage
, orArrayImage
for keyword arguments.
Returns¶
- :
FileImage
,ArrayImage
, orDicomImage
Return type depends on input image.
Examples¶
Load an image from a file and then apply a filter:
>>> from pylinac.core.image import load >>> my_image = r"C:\QA\image.tif" >>> img = load(my_image) # returns a FileImage >>> img.filter(5)
Loading from an array is just like loading from a file:
>>> arr = np.arange(36).reshape(6, 6) >>> img = load(arr) # returns an ArrayImage
- pylinac.core.image.load_url(url: str, progress_bar: bool = True, **kwargs) DicomImage | ArrayImage | FileImage | LinacDicomImage [source]¶
Load an image from a URL.
Parameters¶
- urlstr
A string pointing to a valid URL that points to a file.
Note
For some images (e.g. Github), the raw binary URL must be used, not simply the basic link.
- progress_bar: bool
Whether to display a progress bar of download status.
- pylinac.core.image.load_multiples(image_file_list: Sequence, method: str = 'mean', stretch_each: bool = True, **kwargs) DicomImage | ArrayImage | FileImage | LinacDicomImage [source]¶
Combine multiple image files into one superimposed image.
Parameters¶
- image_file_listlist
A list of the files to be superimposed.
- method{‘mean’, ‘max’, ‘sum’}
A string specifying how the image values should be combined.
- stretch_eachbool
Whether to normalize the images being combined by stretching their high/low values to the same values across images.
- kwargs :
Further keyword arguments are passed to the load function and stretch function.
Examples¶
Load multiple images:
>>> from pylinac.core.image import load_multiples >>> paths = ['starshot1.tif', 'starshot2.tif'] >>> superimposed_img = load_multiples(paths)
- class pylinac.core.image.BaseImage(path: str | Path | BytesIO | ImageLike | np.ndarray | BufferedReader)[source]¶
Bases:
object
Base class for the Image classes.
Attributes¶
- pathstr
The path to the image file.
- arraynumpy.ndarray
The actual image pixel array.
Parameters¶
- pathstr
The path to the image.
- classmethod from_multiples(filelist: list[str], method: str = 'mean', stretch: bool = True, **kwargs) DicomImage | ArrayImage | FileImage | LinacDicomImage [source]¶
Load an instance from multiple image items. See
load_multiples()
.
- property center: Point¶
Return the center position of the image array as a Point. Even-length arrays will return the midpoint between central two indices. Odd will return the central index.
- property physical_shape: float, float¶
The physical size of the image in mm.
- date_created(format: str = '%A, %B %d, %Y') str [source]¶
The date the file was created. Tries DICOM data before falling back on OS timestamp. The method use one or more inputs of formatted code, where % means a placeholder and the letter the time unit of interest. For a full description of the several formatting codes see strftime() documentation.
Parameters¶
- formatstr
%A means weekday full name, %B month full name, %d day of the month as a zero-padded decimal number and %Y year with century as a decimal number.
Returns¶
- str
The date the file was created.
- plot(ax: Axes | None = None, show: bool = True, clear_fig: bool = False, **kwargs) Axes [source]¶
Plot the image.
Parameters¶
- axmatplotlib.Axes instance
The axis to plot the image to. If None, creates a new figure.
- showbool
Whether to actually show the image. Set to false when plotting multiple items.
- clear_figbool
Whether to clear the prior items on the figure before plotting.
- kwargs
kwargs passed to plt.imshow()
- plot_metrics(show: bool = True) list[figure] [source]¶
Plot any additional figures from the metrics.
Returns a list of figures of the metrics. These metrics are not drawn on the original image but rather are something complete separate. E.g. a profile plot or a histogram of the metric.
- filter(size: float | int = 0.05, kind: str = 'median') None [source]¶
Filter the profile in place.
Parameters¶
- sizeint, float
Size of the median filter to apply. If a float, the size is the ratio of the length. Must be in the range 0-1. E.g. if size=0.1 for a 1000-element array, the filter will be 100 elements. If an int, the filter is the size passed.
- kind{‘median’, ‘gaussian’}
The kind of filter to apply. If gaussian, size is the sigma value.
- crop(pixels: int = 15, edges: tuple[str, ...] = ('top', 'bottom', 'left', 'right')) None [source]¶
Removes pixels on all edges of the image in-place.
Parameters¶
- pixelsint
Number of pixels to cut off all sides of the image.
- edgestuple
Which edges to remove from. Can be any combination of the four edges.
- roll(direction: str = 'x', amount: int = 1) None [source]¶
Roll the image array around in-place. Wrapper for np.roll().
Parameters¶
- direction{‘x’, ‘y’}
The axis to roll over.
- amountint
The amount of elements to roll over.
- rot90(n: int = 1) None [source]¶
Wrapper for numpy.rot90; rotate the array by 90 degrees CCW n times.
- rotate(angle: float, mode: str = 'edge', *args, **kwargs)[source]¶
Rotate the image counter-clockwise. Simple wrapper for scikit-image. See https://scikit-image.org/docs/stable/api/skimage.transform.html#skimage.transform.rotate. All parameters are passed to that function.
- threshold(threshold: float, kind: str = 'high') None [source]¶
Apply a high- or low-pass threshold filter.
Parameters¶
- thresholdint
The cutoff value.
- kindstr
If
high
(default), will apply a high-pass threshold. All values above the cutoff are left as-is. Remaining points are set to 0. Iflow
, will apply a low-pass threshold.
- as_binary(threshold: int) DicomImage | ArrayImage | FileImage | LinacDicomImage [source]¶
Return a binary (black & white) image based on the given threshold.
Parameters¶
- thresholdint, float
The threshold value. If the value is above or equal to the threshold it is set to 1, otherwise to 0.
Returns¶
ArrayImage
- dist2edge_min(point: Point | tuple) float [source]¶
Calculates distance from given point to the closest edge.
Parameters¶
point : geometry.Point, tuple
Returns¶
float
- ground() float [source]¶
Ground the profile in place such that the lowest value is 0.
Note
This will also “ground” profiles that are negative or partially-negative. For such profiles, be careful that this is the behavior you desire.
Returns¶
- float
The amount subtracted from the image.
- normalize(norm_val: str | float | None = None) None [source]¶
Normalize the profile to the given value.
Parameters¶
- valuenumber or None
If a number, normalize the array to that number. If None, normalizes to the maximum value.
- check_inversion(box_size: int = 20, position: float, float = (0.0, 0.0)) None [source]¶
Check the image for inversion by sampling the 4 image corners. If the average value of the four corners is above the average pixel value, then it is very likely inverted.
Parameters¶
- box_sizeint
The size in pixels of the corner box to detect inversion.
- position2-element sequence
The location of the sampling boxes.
- check_inversion_by_histogram(percentiles: float, float, float = (5, 50, 95)) bool [source]¶
Check the inversion of the image using histogram analysis. The assumption is that the image is mostly background-like values and that there is a relatively small amount of dose getting to the image (e.g. a picket fence image). This function looks at the distance from one percentile to another to determine if the image should be inverted.
Parameters¶
- percentiles3-element tuple
The 3 percentiles to compare. Default is (5, 50, 95). Recommend using (x, 50, y). To invert the other way (where pixel value is decreasing with dose, reverse the percentiles, e.g. (95, 50, 5).
Returns¶
bool: Whether an inversion was performed.
- gamma(comparison_image: DicomImage | ArrayImage | FileImage | LinacDicomImage, doseTA: float = 1, distTA: float = 1, threshold: float = 0.1, ground: bool = True, normalize: bool = True) ndarray [source]¶
Calculate the gamma between the current image (reference) and a comparison image.
Added in version 1.2.
The gamma calculation is based on Bakai et al eq.6, which is a quicker alternative to the standard Low gamma equation.
Parameters¶
- comparison_image{
ArrayImage
,DicomImage
, orFileImage
} The comparison image. The image must have the same DPI/DPMM to be comparable. The size of the images must also be the same.
- doseTAint, float
Dose-to-agreement in percent; e.g. 2 is 2%.
- distTAint, float
Distance-to-agreement in mm.
- thresholdfloat
The dose threshold percentage of the maximum dose, below which is not analyzed. Must be between 0 and 1.
- groundbool
Whether to “ground” the image values. If true, this sets both datasets to have the minimum value at 0. This can fix offset errors in the data.
- normalizebool
Whether to normalize the images. This sets the max value of each image to the same value.
Returns¶
- gamma_mapnumpy.ndarray
The calculated gamma map.
See Also¶
- comparison_image{
- compute(metrics: list[MetricBase] | MetricBase) Any | dict[str, Any] [source]¶
Compute the given metrics on the image.
This can be called multiple times to compute different metrics. Metrics are appended on each call. This allows for modification of the image between metric calls as well as the ability to compute different metrics on the same image that might depend on earlier metrics.
Metrics are both returned and stored in the
metrics
attribute. Themetrics
attribute will store all metrics every calculated. The metrics returned are only those passed in themetrics
argument.Parameters¶
- metricslist[MetricBase] | MetricBase
The metric(s) to compute.
- class pylinac.core.image.XIM(file_path: str | Path, read_pixels: bool = True)[source]¶
Bases:
BaseImage
A class to open, read, and/or export an .xim image, Varian’s custom image format which is 99.999% PNG
This had inspiration from a number of places: - https://gist.github.com/1328/7da697c71f9c4ef12e1e - https://medium.com/@duhroach/how-png-works-f1174e3cc7b7 - https://www.mathworks.com/matlabcentral/answers/419228-how-to-write-for-loop-and-execute-data - https://www.w3.org/TR/PNG-Filters.html - https://bitbucket.org/dmoderesearchtools/ximreader/src/master/
Parameters¶
- file_path
The path to the file of interest.
- read_pixels
Whether to read and parse the pixel information. Doing so is quite slow. Set this to false if, e.g., you are searching for images only via tags or doing a pre-filtering of image selection.
- array: np.ndarray¶
- properties: dict¶
- property dpmm: float¶
The dots/mm value of the XIM images. The value appears to be in cm in the file.
- save_as(file: str, format: str | None = None) None [source]¶
Save the image to a NORMAL format. PNG is highly suggested. Accepts any format supported by Pillow. Ironically, an equivalent PNG image (w/ metadata) is ~50% smaller than an .xim image.
Warning
Any format other than PNG will not include the properties included in the .xim image!
Parameters¶
- file
The file to save the image to. E.g. my_xim.png
- format
The format to save the image as. Uses the Pillow logic, which will infer the format if the file name has one.
- class pylinac.core.image.DicomImage(path: str | Path | BytesIO | BufferedReader, *, dtype: np.dtype | None = None, dpi: float = None, sid: float = None, sad: float = 1000, raw_pixels: bool = False)[source]¶
Bases:
BaseImage
An image from a DICOM RTImage file.
Attributes¶
- metadatapydicom Dataset
The dataset of the file as returned by pydicom without pixel data.
Parameters¶
- pathstr, file-object
The path to the file or the data stream.
- dtypedtype, None, optional
The data type to cast the image data as. If None, will use whatever raw image format is.
- dpiint, float
The dots-per-inch of the image, defined at isocenter.
Note
If a DPI tag is found in the image, that value will override the parameter, otherwise this one will be used.
- sidint, float
The Source-to-Image distance in mm.
- sadfloat
The Source-to-Axis distance in mm.
- raw_pixelsbool
Whether to apply pixel intensity correction to the DICOM data. Typically, Rescale Slope, Rescale Intercept, and other tags are included and meant to be applied to the raw pixel data, which is potentially compressed. If True, no correction will be applied. This is typically used for scenarios when you want to match behavior to older or different software.
- classmethod from_dataset(dataset: Dataset)[source]¶
Create a DICOM image instance from a pydicom Dataset.
- save(filename: str | Path) str | Path [source]¶
Save the image instance back out to a .dcm file.
Parameters¶
- filenamestr, Path
The filename to save the DICOM file as.
Returns¶
A string pointing to the new filename.
- property z_position: float¶
The z-position of the slice. Relevant for CT and MR images.
- property slice_spacing: float¶
Determine the distance between slices. The spacing can be greater than the slice thickness (i.e. gaps). Uses the absolute version as it can apparently be negative: https://dicom.innolitics.com/ciods/nm-image/nm-reconstruction/00180088
This attempts to use the slice spacing attr and if it doesn’t exist, use the slice thickness attr
- property sid: float¶
The Source-to-Image in mm.
- property sad: float¶
The source to axis (iso) in mm
- property dpi: float¶
The dots-per-inch of the image, defined at isocenter.
- property dpmm: float¶
The Dots-per-mm of the image, defined at isocenter. E.g. if an EPID image is taken at 150cm SID, the dpmm will scale back to 100cm.
- property cax: Point¶
The position of the beam central axis. If no DICOM translation tags are found then the center is returned. Uses this tag: https://dicom.innolitics.com/ciods/rt-beams-delivery-instruction/rt-beams-delivery-instruction/00741020/00741030/3002000d
- class pylinac.core.image.LinacDicomImage(path: str | Path | BinaryIO, use_filenames: bool = False, axes_precision: int | None = None, **kwargs)[source]¶
Bases:
DicomImage
DICOM image taken on a linac. Also allows passing of gantry/coll/couch values via the filename.
Parameters¶
- pathstr, file-object
The path to the file or the data stream.
- dtypedtype, None, optional
The data type to cast the image data as. If None, will use whatever raw image format is.
- dpiint, float
The dots-per-inch of the image, defined at isocenter.
Note
If a DPI tag is found in the image, that value will override the parameter, otherwise this one will be used.
- sidint, float
The Source-to-Image distance in mm.
- sadfloat
The Source-to-Axis distance in mm.
- raw_pixelsbool
Whether to apply pixel intensity correction to the DICOM data. Typically, Rescale Slope, Rescale Intercept, and other tags are included and meant to be applied to the raw pixel data, which is potentially compressed. If True, no correction will be applied. This is typically used for scenarios when you want to match behavior to older or different software.
- property gantry_angle: float¶
Gantry angle of the irradiation.
- property collimator_angle: float¶
Collimator angle of the irradiation.
- property couch_angle: float¶
Couch angle of the irradiation.
- class pylinac.core.image.FileImage(path: str | Path | BinaryIO, *, dpi: float | None = None, sid: float | None = None, dtype: np.dtype | None = None)[source]¶
Bases:
BaseImage
An image from a “regular” file (.tif, .jpg, .bmp).
Attributes¶
- infodict
The info dictionary as generated by Pillow.
- sidfloat
The SID value as passed in upon construction.
Parameters¶
- pathstr, file-object
The path to the file or a data stream.
- dpiint, float
The dots-per-inch of the image, defined at isocenter.
Note
If a DPI tag is found in the image, that value will override the parameter, otherwise this one will be used.
- sidint, float
The Source-to-Image distance in mm.
- dtypenumpy.dtype
The data type to cast the array as. If None, will use the datatype stored in the file. If the file is multi-channel (e.g. RGB), it will be converted to int32
- property dpi: float | None¶
The dots-per-inch of the image, defined at isocenter.
- property dpmm: float | None¶
The Dots-per-mm of the image, defined at isocenter. E.g. if an EPID image is taken at 150cm SID, the dpmm will scale back to 100cm.
- class pylinac.core.image.ArrayImage(array: ndarray, *, dpi: float | None = None, sid: float | None = None, dtype=None)[source]¶
Bases:
BaseImage
An image constructed solely from a numpy array.
Parameters¶
- arraynumpy.ndarray
The image array.
- dpiint, float
The dots-per-inch of the image, defined at isocenter.
Note
If a DPI tag is found in the image, that value will override the parameter, otherwise this one will be used.
- sidint, float
The Source-to-Image distance in mm.
- dtypedtype, None, optional
The data type to cast the image data as. If None, will use whatever raw image format is.
- property dpmm: float | None¶
The Dots-per-mm of the image, defined at isocenter. E.g. if an EPID image is taken at 150cm SID, the dpmm will scale back to 100cm.
- property dpi: float | None¶
The dots-per-inch of the image, defined at isocenter.
- class pylinac.core.image.DicomImageStack(folder: str | Path, dtype: np.dtype | None = None, min_number: int = 39, check_uid: bool = True, raw_pixels: bool = False)[source]¶
Bases:
object
A class that loads and holds a stack of DICOM images (e.g. a CT dataset). The class can take a folder or zip file and will read CT images. The images must all be the same size. Supports indexing to individual images.
Attributes¶
- imageslist
Holds instances of
DicomImage
. Can be accessed via index; i.e. self[0] == self.images[0].
Examples¶
Load a folder of Dicom images >>> from pylinac import image >>> img_folder = r”folder/qa/cbct/june” >>> dcm_stack = image.DicomImageStack(img_folder) # loads and sorts the images >>> dcm_stack.plot(3) # plot the 3rd image
Load a zip archive >>> img_folder_zip = r”archive/qa/cbct/june.zip” # save space and zip your CBCTs >>> dcm_stack = image.DicomImageStack.from_zip(img_folder_zip)
Load as a certain data type >>> dcm_stack_uint32 = image.DicomImageStack(img_folder, dtype=np.uint32)
Load a folder with DICOM CT images.
Parameters¶
- folderstr
Path to the folder.
- dtypedtype, None, optional
The data type to cast the image data as. If None, will use whatever raw image format is.
- classmethod from_zip(zip_path: str | Path, dtype: np.dtype | None = None)[source]¶
Load a DICOM ZIP archive.
Parameters¶
- zip_pathstr
Path to the ZIP archive.
- dtypedtype, None, optional
The data type to cast the image data as. If None, will use whatever raw image format is.
- static is_image_slice(file: str | Path) bool [source]¶
Test if the file is a CT Image storage DICOM file.
- plot(slice: int = 0) None [source]¶
Plot a slice of the DICOM dataset.
Parameters¶
- sliceint
The slice to plot.
- property metadata: FileDataset¶
The metadata of the first image; shortcut attribute. Only attributes that are common throughout the stack should be used, otherwise the individual image metadata should be used.
- pylinac.core.image.tiff_to_dicom(tiff_file: str | Path | BytesIO, sid: float, gantry: float, coll: float, couch: float, dpi: float | None = None) Dataset [source]¶
Converts a TIFF file into a simplistic DICOM file. Not meant to be a full-fledged tool. Used for conversion so that tools that are traditionally oriented towards DICOM have a path to accept TIFF. Currently used to convert files for WL.
Note
This will convert the image into an uint16 datatype to match the native EPID datatype.
Parameters¶
- tiff_file
The TIFF file to be converted.
- sid
The Source-to-Image distance in mm.
- dpi
The dots-per-inch value of the TIFF image.
- gantry
The gantry value that the image was taken at.
- coll
The collimator value that the image was taken at.
- couch
The couch value that the image was taken at.
- pylinac.core.image.gamma_2d(reference: ndarray, evaluation: ndarray, dose_to_agreement: float = 1, distance_to_agreement: int = 1, gamma_cap_value: float = 2, global_dose: bool = True, dose_threshold: float = 5, fill_value: float = nan) ndarray [source]¶
Compute a 2D gamma of two 2D numpy arrays. This does NOT do size or spatial resolution checking. It performs an element-by-element evaluation. It is the responsibility of the caller to ensure the reference and evaluation have comparable spatial resolution.
The algorithm follows Table I of D. Low’s 2004 paper: Evaluation of the gamma dose distribution comparison method: https://aapm.onlinelibrary.wiley.com/doi/epdf/10.1118/1.1598711
This is similar to the gamma_1d function for profiles, except we must search a 2D grid around the reference point.
Parameters¶
- reference
The reference 2D array.
- evaluation
The evaluation 2D array.
- dose_to_agreement
The dose to agreement in %. E.g. 1 is 1% of global reference max dose.
- distance_to_agreement
The distance to agreement in elements. E.g. if the value is 4 this means 4 elements from the reference point under calculation. Must be >0
- gamma_cap_value
The value to cap the gamma at. E.g. a gamma of 5.3 will get capped to 2. Useful for displaying data with a consistent range.
- global_dose
Whether to evaluate the dose to agreement threshold based on the global max or the dose point under evaluation.
- dose_threshold
The dose threshold as a number between 0 and 100 of the % of max dose under which a gamma is not calculated. This is not affected by the global/local dose normalization and the threshold value is evaluated against the global max dose, period.
- fill_value
The value to give pixels that were not calculated because they were under the dose threshold. Default is NaN, but another option would be 0. If NaN, allows the user to calculate mean/median gamma over just the evaluated portion and not be skewed by 0’s that should not be considered.
Geometry Module¶
Module for classes that represent common geometric objects or patterns.
- pylinac.core.geometry.tan(degrees: float) float [source]¶
Calculate the tangent of the given degrees.
- pylinac.core.geometry.atan(x: float, y: float) float [source]¶
Calculate the degrees of a given x/y from the origin
- pylinac.core.geometry.cos(degrees: float) float [source]¶
Calculate the cosine of the given degrees.
- class pylinac.core.geometry.Point(x: float | tuple | Point = 0, y: float = 0, z: float = 0, idx: int | None = None, value: float | None = None, as_int: bool = False)[source]¶
Bases:
object
A geometric point with x, y, and z coordinates/attributes.
Parameters¶
- xnumber-like, Point, iterable
x-coordinate or iterable type containing all coordinates. If iterable, values are assumed to be in order: (x,y,z).
- ynumber-like, optional
y-coordinate
- idxint, optional
Index of point. Useful for sequential coordinates; e.g. a point on a circle profile is sometimes easier to describe in terms of its index rather than x,y coords.
- valuenumber-like, optional
value at point location (e.g. pixel value of an image)
- as_intboolean
If True, coordinates are converted to integers.
- class pylinac.core.geometry.Circle(center_point: Point | Iterable = (0, 0), radius: float = 0)[source]¶
Bases:
object
A geometric circle with center Point, radius, and diameter.
Parameters¶
- center_pointPoint, optional
Center point of the wobble circle.
- radiusfloat, optional
Radius of the wobble circle.
- property diameter: float¶
Get the diameter of the circle.
- plot2axes(axes: Axes, edgecolor: str = 'black', fill: bool = False, text: str = '', fontsize: str = 'medium') None [source]¶
Plot the Circle on the axes.
Parameters¶
- axesmatplotlib.axes.Axes
An MPL axes to plot to.
- edgecolorstr
The color of the circle.
- fillbool
Whether to fill the circle with color or leave hollow.
- text: str
If provided, plots the given text at the center. Useful for identifying ROIs on a plotted image apart.
- fontsize: str
The size of the text, if provided. See https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.text.html for options.
- class pylinac.core.geometry.Vector(x: float = 0, y: float = 0, z: float = 0)[source]¶
Bases:
object
A vector with x, y, and z coordinates.
- pylinac.core.geometry.vector_is_close(vector1: Vector, vector2: Vector, delta: float = 0.1) bool [source]¶
Determine if two vectors are with delta of each other; this is a simple coordinate comparison check.
- class pylinac.core.geometry.Line(point1: Point | tuple[float, float], point2: Point | tuple[float, float])[source]¶
Bases:
object
A line that is represented by two points or by m*x+b.
Notes¶
Calculations of slope, etc are from here: http://en.wikipedia.org/wiki/Linear_equation and here: http://www.mathsisfun.com/algebra/line-equation-2points.html
Parameters¶
- point1Point
One point of the line
- point2Point
Second point along the line.
- property m: float¶
Return the slope of the line.
m = (y1 - y2)/(x1 - x2)
- property b: float¶
Return the y-intercept of the line.
b = y - m*x
- property length: float¶
Return length of the line, if finite.
- distance_to(point: Point) float [source]¶
Calculate the minimum distance from the line to a point.
Equations are from here: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html #14
Parameters¶
- pointPoint, iterable
The point to calculate distance to.
- class pylinac.core.geometry.Rectangle(width: float, height: float, center: Point | tuple, as_int: bool = False)[source]¶
Bases:
object
A rectangle with width, height, center Point, top-left corner Point, and bottom-left corner Point.
Parameters¶
- widthnumber
Width of the rectangle. Must be positive
- heightnumber
Height of the rectangle. Must be positive.
- centerPoint, iterable, optional
Center point of rectangle.
- as_intbool
If False (default), inputs are left as-is. If True, all inputs are converted to integers.
- plot2axes(axes: Axes, edgecolor: str = 'black', angle: float = 0.0, fill: bool = False, alpha: float = 1, facecolor: str = 'g', label=None, text: str = '', fontsize: str = 'medium', text_rotation: float = 0)[source]¶
Plot the Rectangle to the axes.
Parameters¶
- axesmatplotlib.axes.Axes
An MPL axes to plot to.
- edgecolorstr
The color of the circle.
- anglefloat
Angle of the rectangle.
- fillbool
Whether to fill the rectangle with color or leave hollow.
- text: str
If provided, plots the given text at the center. Useful for identifying ROIs on a plotted image apart.
- fontsize: str
The size of the text, if provided. See https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.text.html for options.
- text_rotation: float
The rotation of the text in degrees.
Profile Module¶
See Profiles.
I/O Module¶
I/O helper functions for pylinac.
- pylinac.core.io.is_dicom(file: str | Path) bool [source]¶
Boolean specifying if file is a proper DICOM file.
This function is a pared down version of read_preamble meant for a fast return. The file is read for a proper preamble (‘DICM’), returning True if so, and False otherwise. This is a conservative approach.
Parameters¶
- filestr
The path to the file.
See Also¶
pydicom.filereader.read_preamble pydicom.filereader.read_partial
- pylinac.core.io.is_dicom_image(file: str | Path | BinaryIO) bool [source]¶
Boolean specifying if file is a proper DICOM file with a image
Parameters¶
- filestr
The path to the file.
See Also¶
pydicom.filereader.read_preamble pydicom.filereader.read_partial
- pylinac.core.io.retrieve_dicom_file(file: str | Path | BinaryIO) pydicom.FileDataset [source]¶
Read and return the DICOM dataset.
Parameters¶
- filestr
The path to the file.
- class pylinac.core.io.TemporaryZipDirectory(zfile: str | Path | BinaryIO)[source]¶
Bases:
TemporaryDirectory
Creates a temporary directory that unpacks a ZIP archive. Shockingly useful
Parameters¶
- zfilestr
String that points to a ZIP archive.
- pylinac.core.io.retrieve_filenames(directory: str | Path, func: Callable | None = None, recursive: bool = True, **kwargs) list[str] [source]¶
Retrieve file names in a directory.
Parameters¶
- directorystr
The directory to walk over recursively.
- funcfunction, None
The function that validates if the file name should be kept. If None, no validation will be performed and all file names will be returned.
- recursivebool
Whether to search only the root directory.
- kwargs
Additional arguments passed to the func parameter.
- pylinac.core.io.retrieve_demo_file(name: str, force: bool = False) Path [source]¶
Retrieve the demo file either by getting it from file or from a URL.
If the file is already on disk it returns the file name. If the file isn’t on disk, get the file from the URL and put it at the expected demo file location on disk for lazy loading next time.
Parameters¶
- namestr
The suffix to the url (location within the S3 bucket) pointing to the demo file.
- pylinac.core.io.is_url(url: str) bool [source]¶
Determine whether a given string is a valid URL.
Parameters¶
url : str
Returns¶
bool
- pylinac.core.io.get_url(url: str, destination: str | Path | None = None, progress_bar: bool = True) str [source]¶
Download a URL to a local file.
Parameters¶
- urlstr
The URL to download.
- destinationstr, None
The destination of the file. If None is given the file is saved to a temporary directory.
- progress_barbool
Whether to show a command-line progress bar while downloading.
Returns¶
- filenamestr
The location of the downloaded file.
Notes¶
Progress bar use/example adapted from tqdm documentation: https://github.com/tqdm/tqdm
- class pylinac.core.io.SNCProfiler(path: str, gain_row: int = 20, detector_row: int = 106, bias_row: int = 107, calibration_row: int = 108, data_row: int = -1, data_columns: slice = slice(5, 259, None))[source]¶
Bases:
object
Load a file from a Sun Nuclear Profiler device. This accepts .prs files.
Parameters¶
- pathstr
Path to the .prs file.
- detector_row
The row that contains the detector data.
- bias_row
The row that contains the bias data.
- calibration_row
The row that contains the calibration data.
- data_row
The row that contains the data.
- data_columns
The range of columns that the data is in. Usually, there are some columns before and after the real data.
- to_profiles(n_detectors_row: int = 63, **kwargs) tuple[SingleProfile, SingleProfile, SingleProfile, SingleProfile] [source]¶
Convert the SNC data to SingleProfiles. These can be analyzed directly or passed to other modules like flat/sym.
Parameters¶
- n_detectors_rowint
The number of detectors in a given row. Note that they Y profile includes 2 extra detectors from the other 3.
ROI Module¶
- pylinac.core.roi.bbox_center(region: RegionProperties) Point [source]¶
Return the center of the bounding box of an scikit-image region.
Parameters¶
- region
A scikit-image region as calculated by skimage.measure.regionprops().
Returns¶
point :
Point
- class pylinac.core.roi.DiskROI(array: np.ndarray, angle: float, roi_radius: float, dist_from_center: float, phantom_center: tuple | Point)[source]¶
Bases:
Circle
An class representing a disk-shaped Region of Interest.
Parameters¶
- arrayndarray
The 2D array representing the image the disk is on.
- angleint, float
The angle of the ROI in degrees from the phantom center.
- roi_radiusint, float
The radius of the ROI from the center of the phantom.
- dist_from_centerint, float
The distance of the ROI from the phantom center.
- phantom_centertuple
The location of the phantom center.
- property pixel_value: float¶
The median pixel value of the ROI.
- property std: float¶
The standard deviation of the pixel values.
- plot2axes(axes: plt.Axes | None = None, edgecolor: str = 'black', fill: bool = False, text: str = '', fontsize: str = 'medium') None [source]¶
Plot the Circle on the axes.
Parameters¶
- axesmatplotlib.axes.Axes
An MPL axes to plot to.
- edgecolorstr
The color of the circle.
- fillbool
Whether to fill the circle with color or leave hollow.
- text: str
If provided, plots the given text at the center. Useful for differentiating ROIs on a plotted image.
- fontsize: str
The size of the text, if provided. See https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.text.html for options.
- class pylinac.core.roi.LowContrastDiskROI(array: np.ndarray | ArrayImage, angle: float, roi_radius: float, dist_from_center: float, phantom_center: tuple | Point, contrast_threshold: float | None = None, contrast_reference: float | None = None, cnr_threshold: float | None = None, contrast_method: str = 'Michelson', visibility_threshold: float | None = 0.1)[source]¶
Bases:
DiskROI
A class for analyzing the low-contrast disks.
Parameters¶
- contrast_thresholdfloat, int
The threshold for considering a bubble to be “seen”.
- property signal_to_noise: float¶
The signal-to-noise ratio. Cast to numpy first to use numpy overflow handling.
- property contrast_to_noise: float¶
The contrast to noise ratio of the ROI. Cast to numpy first to use numpy overflow handling.
- property michelson: float¶
The Michelson contrast
- property weber: float¶
The Weber contrast
- property rms: float¶
The root-mean-square contrast
- property ratio: float¶
The ratio contrast
- property contrast: float¶
The contrast of the bubble. Uses the contrast method passed in the constructor. See https://en.wikipedia.org/wiki/Contrast_(vision).
- property cnr_constant: float¶
The contrast-to-noise value times the bubble diameter.
- property visibility: float¶
The visual perception of CNR. Uses the model from A Rose: https://www.osapublishing.org/josa/abstract.cfm?uri=josa-38-2-196. See also here: https://howradiologyworks.com/x-ray-cnr/. Finally, a review paper here: http://xrm.phys.northwestern.edu/research/pdf_papers/1999/burgess_josaa_1999.pdf Importantly, the Rose model is not applicable for high-contrast use cases.
- property contrast_constant: float¶
The contrast value times the bubble diameter.
- property passed: bool¶
Whether the disk ROI contrast passed.
- property passed_visibility: bool¶
Whether the disk ROI’s visibility passed.
- property passed_contrast_constant: bool¶
Boolean specifying if ROI pixel value was within tolerance of the nominal value.
- property passed_cnr_constant: bool¶
Boolean specifying if ROI pixel value was within tolerance of the nominal value.
- property plot_color: str¶
Return one of two colors depending on if ROI passed.
- property plot_color_constant: str¶
Return one of two colors depending on if ROI passed.
- property plot_color_cnr: str¶
Return one of two colors depending on if ROI passed.
- as_dict() dict [source]¶
Dump important data as a dictionary. Useful when exporting a results_data output
- property std: float¶
The std within the ROI.
- property max: float¶
The max pixel value of the ROI.
- property min: float¶
The min pixel value of the ROI.
- class pylinac.core.roi.HighContrastDiskROI(array: np.ndarray, angle: float, roi_radius: float, dist_from_center: float, phantom_center: tuple | Point, contrast_threshold: float)[source]¶
Bases:
DiskROI
A class for analyzing the high-contrast disks.
Parameters¶
- contrast_thresholdfloat, int
The threshold for considering a bubble to be “seen”.
- property max: ndarray¶
The max pixel value of the ROI.
- property min: ndarray¶
The min pixel value of the ROI.
- class pylinac.core.roi.RectangleROI(array, width, height, angle, dist_from_center, phantom_center)[source]¶
Bases:
Rectangle
Class that represents a rectangular ROI.
Parameters¶
- widthnumber
Width of the rectangle. Must be positive
- heightnumber
Height of the rectangle. Must be positive.
- centerPoint, iterable, optional
Center point of rectangle.
- as_intbool
If False (default), inputs are left as-is. If True, all inputs are converted to integers.
- property pixel_array: ndarray¶
The pixel array within the ROI.
- property pixel_value: float¶
The pixel array within the ROI.
- property mean: float¶
The mean value within the ROI.
- property std: float¶
The std within the ROI.
- property min: float¶
The min value within the ROI.
- property max: float¶
The max value within the ROI.
Mask Module¶
Module for processing “masked” arrays, i.e. binary images.
Utilities Module¶
Utility functions for pylinac.
- pylinac.core.utilities.convert_to_enum(value: str | Enum | None, enum: type[Enum]) Enum [source]¶
Convert a value to an enum representation from an enum value if needed
- class pylinac.core.utilities.OptionListMixin[source]¶
Bases:
object
A mixin class that will create a list of the class attributes. Used for enum-like classes
- class pylinac.core.utilities.ResultBase[source]¶
Bases:
object
- pylinac_version: str¶
- date_of_analysis: datetime¶
- pylinac.core.utilities.clear_data_files()[source]¶
Delete all demo files, image classifiers, etc from the demo folder
- pylinac.core.utilities.assign2machine(source_file: str, machine_file: str)[source]¶
Assign a DICOM RT Plan file to a specific machine. The source file is overwritten to contain the machine of the machine file.
Parameters¶
- source_filestr
Path to the DICOM RTPlan file that contains the fields/plan desired (e.g. a Winston Lutz set of fields or Varian’s default PF files).
- machine_filestr
Path to a DICOM RTPlan file that has the desired machine. This is easily obtained from pushing a plan from the TPS for that specific machine. The file must contain at least one valid field.
- pylinac.core.utilities.is_close(val: float, target: float | Sequence, delta: float = 1)[source]¶
Return whether the value is near the target value(s).
Parameters¶
- valnumber
The value being compared against.
- targetnumber, iterable
If a number, the values are simply evaluated. If a sequence, each target is compared to
val
. If any values oftarget
are close, the comparison is considered True.
Returns¶
bool
- pylinac.core.utilities.simple_round(number: float | int, decimals: int | None = 0) float | int [source]¶
Round a number to the given number of decimals. Fixes small floating number errors. If decimals is None, no rounding is performed
- class pylinac.core.utilities.Structure(**kwargs)[source]¶
Bases:
object
A simple structure that assigns the arguments to the object.
- pylinac.core.utilities.decode_binary(file: BinaryIO, dtype: type[int] | type[float] | type[str] | str | np.dtype, num_values: int = 1, cursor_shift: int = 0, strip_empty: bool = True) int | float | str | np.ndarray | list [source]¶
Read in a raw binary file and convert it to given data types.
Parameters¶
- file
The open file object.
- dtype
The expected data type to return. If int or float and num_values > 1, will return numpy array.
- num_values
The expected number of dtype to return
Note
This is not the same as the number of bytes.
- cursor_shiftint
The number of bytes to move the cursor forward after decoding. This is used if there is a reserved section after the read-in segment.
- strip_emptybool
Whether to strip trailing empty/null values for strings.
Contrast Module¶
- class pylinac.core.contrast.Contrast[source]¶
Bases:
OptionListMixin
Contrast calculation technique. See Visibility
- MICHELSON = 'Michelson'¶
- WEBER = 'Weber'¶
- RATIO = 'Ratio'¶
- RMS = 'Root Mean Square'¶
- DIFFERENCE = 'Difference'¶
- pylinac.core.contrast.visibility(array: ndarray, radius: float, std: float, algorithm: str) float [source]¶
The visual perception of CNR. Uses the model from A Rose: https://www.osapublishing.org/josa/abstract.cfm?uri=josa-38-2-196. See also here: https://howradiologyworks.com/x-ray-cnr/. Finally, a review paper here: http://xrm.phys.northwestern.edu/research/pdf_papers/1999/burgess_josaa_1999.pdf Importantly, the Rose model is not applicable for high-contrast use cases.
This uses the
contrast
function under the hood. Consult before using.Parameters¶
- array
The numpy array of the contrast ROI or a 2-element array containing the individual inputs. See
contrast
for more.- radius
The radius of the contrast ROI
- std
Standard deviation of the array. This can sometimes be obtained from another ROI, so it is a separate parameter.
- algorithm
The contrast method. See
Contrast
for options.
- pylinac.core.contrast.contrast(array: ndarray, algorithm: str) float [source]¶
Generic contrast function. Different algorithms have different inputs, so caution is advised. When possible, the exact contrast function is preferred.
For Michelson and RMS algorithms, the input array can be any ordinary numpy array. For Weber and Ratio algorithms, the array is assumed to be a 2-element array.
Parameters¶
- array
The numpy array of the ROI or 2-element input array. This is used in combination with the method.
- algorithm
The contrast method. See
Contrast
for options.
- pylinac.core.contrast.rms(array: ndarray) float [source]¶
The root-mean-square contrast. Requires values be within 0 and 1.
- pylinac.core.contrast.difference(feature: float, background: float) float [source]¶
The simple absolute difference between the feature ROI and background ROI. This can be useful if the default CNR formula is desired (since pylinac CNR is based on the contrast algorithm chosen.
- pylinac.core.contrast.michelson(array: ndarray) float [source]¶
The Michelson contrast. Used for sinusoidal patterns. Ranges from 0 to 1.
See also
https://en.wikipedia.org/wiki/Contrast_(vision)#Michelson_contrast
- pylinac.core.contrast.weber(feature: float, background: float) float [source]¶
The Weber contrast. Used for patterns with a small feature within a large background. Ranges from 0 to infinity.
For backwards compatibility with previous versions, the absolute difference is used, making the range 0 to infinity vs -1 to infinity.
See also
https://en.wikipedia.org/wiki/Contrast_(vision)#Weber_contrast
Danger
The default definition does not use the absolute value. We only use it here for backwards compatibility.