diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 9cf0a2ae2..053f238b5 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -21,7 +21,7 @@ definitions: - apt-get update - python -m venv venv - source venv/bin/activate - - pip install -r requirements-ram.txt + - pip install -r requirements-dev.txt - pip freeze artifacts: - venv/** @@ -247,6 +247,7 @@ definitions: - apt-get update - apt-get -y install curl - curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin + - pip freeze # we want to dump this to file regardless of fail status so we can inspect if needed - grype dir:. --only-fixed -o json > grype_results.json - grype dir:. --only-fixed --fail-on high @@ -305,13 +306,6 @@ pipelines: - step: *vmat-tests - step: *winston-lutz-tests - step: *core-module-tests - - step: - <<: *grype-scanning - condition: - changesets: - includePaths: - - "requirements.txt" - - "requirements-ram.txt" branches: release*: diff --git a/docs/source/conf.py b/docs/source/conf.py index 346713be5..8b84e3578 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -34,7 +34,6 @@ "sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.mathjax", - "sphinx.ext.napoleon", "matplotlib.sphinxext.plot_directive", "sphinx_copybutton", ] @@ -43,13 +42,12 @@ autodoc_mock_imports = ["_tkinter", "tkinter"] autoclass_content = "both" -autodoc_default_flags = [ - "show-inheritance", - "members", -] # See: http://sphinx-doc.org/latest/ext/autodoc.html#confval-autodoc_default_flags -autodoc_member_order = "bysource" - -napoleon_include_special_with_doc = False +autodoc_default_options = { + "show-inheritance": True, + "members": True, + "member-order": "bysource", + "ignore-module-all": True, +} # Add any paths that contain templates here, relative to this directory. @@ -158,7 +156,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +# html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied diff --git a/docs/source/core_modules.rst b/docs/source/core_modules.rst index d53770a80..a993cd82c 100644 --- a/docs/source/core_modules.rst +++ b/docs/source/core_modules.rst @@ -22,8 +22,7 @@ Geometry Module Profile Module -------------- -.. automodule:: pylinac.core.profile - :members: +See :ref:`profiles`. I/O Module ---------- diff --git a/docs/source/field_analysis.rst b/docs/source/field_analysis.rst index e17c670de..a0870eecb 100644 --- a/docs/source/field_analysis.rst +++ b/docs/source/field_analysis.rst @@ -264,8 +264,8 @@ The inflection point via the Hill function is useful for both flat and FFF beams The fitting of the function is best for low-resolution data, and is thus the default for ``DeviceFieldAnalysis``. The Hill function, the sigmoid function, and 4-point non-linear regression belong to a family of logistic equations to fit a dual-curved value. Since these fit a function to the data the resolution problems are eliminated. Some examples can be -seen `here `_. The generalized logistic function has helpful visuals as well -`here `_. +seen `here `__. The generalized logistic function has helpful visuals as well +`here `__. The function used here is: @@ -737,9 +737,6 @@ These are the classes a typical user may interface with. .. autoclass:: pylinac.field_analysis.Interpolation :members: -.. autoclass:: pylinac.field_analysis.Normalization - :members: - .. autoclass:: pylinac.field_analysis.Edge :members: diff --git a/docs/source/log_analyzer.rst b/docs/source/log_analyzer.rst index 9d8b27ec4..65aa19df7 100644 --- a/docs/source/log_analyzer.rst +++ b/docs/source/log_analyzer.rst @@ -516,10 +516,10 @@ Trajectory logs in a MachineLogs instance can also be converted to CSV, just as API Documentation ----------------- -Main classes -^^^^^^^^^^^^ +Main interface +^^^^^^^^^^^^^^ -These are the classes a typical user may interface with. +These are the classes and functions a typical user may interface with. .. autofunction:: pylinac.log_analyzer.load_log diff --git a/docs/source/winston_lutz.rst b/docs/source/winston_lutz.rst index 2c30065af..4fd74862f 100644 --- a/docs/source/winston_lutz.rst +++ b/docs/source/winston_lutz.rst @@ -351,7 +351,7 @@ the radiation iso is not of interest. For large-field WL images, you may need to parameter to True. This is because the automatic inversion of the WL module assumes a small field is being delivered. For large field deliveries, kV or MV, see about flipping this parameter if the analysis fails. -.. wl_cbct: +.. _wl_cbct: CBCT Analysis ------------- diff --git a/docs/source/winston_lutz_multi.rst b/docs/source/winston_lutz_multi.rst index 284cfec22..a022aa115 100644 --- a/docs/source/winston_lutz_multi.rst +++ b/docs/source/winston_lutz_multi.rst @@ -468,26 +468,13 @@ with an output of:: API Documentation ----------------- -.. autoclass:: pylinac.winston_lutz.WinstonLutz - :members: .. autoclass:: pylinac.winston_lutz.WinstonLutzMultiTargetMultiField :members: -.. autoclass:: pylinac.winston_lutz.WinstonLutz2D - :members: - .. autoclass:: pylinac.winston_lutz.WinstonLutz2DMultiTarget :members: -.. autoclass:: pylinac.winston_lutz.WinstonLutzResult - :members: - :inherited-members: - -.. autoclass:: pylinac.winston_lutz.WinstonLutz2DResult - :members: - :inherited-members: - .. autoclass:: pylinac.winston_lutz.WinstonLutzMultiTargetMultiFieldResult :members: :inherited-members: diff --git a/noxfile.py b/noxfile.py index ee940d81a..c948d7a8d 100644 --- a/noxfile.py +++ b/noxfile.py @@ -24,7 +24,21 @@ def serve_docs(session): @nox.session(python=False) def build_docs(session): - session.run("sphinx-build", "docs/source", "docs/build") + """Build the docs; used in CI pipelines to test the build. Will always rebuild and will always fail if there are any warnings""" + session.run( + "sphinx-build", + "docs/source", + "docs/build", + "-W", + "--keep-going", + "-j", + "auto", + "-a", + "-E", + "-b", + "html", + "-q", + ) @nox.session(python=False) diff --git a/pylinac/cheese.py b/pylinac/cheese.py index 4c2dee6ba..6145db7b2 100644 --- a/pylinac/cheese.py +++ b/pylinac/cheese.py @@ -77,7 +77,8 @@ def plot_rois(self, axis: plt.Axes) -> None: class TomoCheeseModule(CheeseModule): """The pluggable module with user-accessible holes. - The ROIs of the inner circle are ~45 degrees apart. The ROIs of the outer circle are ~30 degrees apart + The ROIs of the inner circle are ~45 degrees apart. The ROIs of the outer circle are ~30 degrees apart. + """ common_name = "Tomo Cheese" diff --git a/pylinac/core/image.py b/pylinac/core/image.py index 06b9fe312..2b7e80226 100644 --- a/pylinac/core/image.py +++ b/pylinac/core/image.py @@ -90,8 +90,9 @@ def equate_images(image1: ImageLike, image2: ImageLike) -> tuple[ImageLike, Imag Returns ------- image1 : :class:`~pylinac.core.image.ArrayImage` + The first image equated. image2 : :class:`~pylinac.core.image.ArrayImage` - The returns are new instances of Images. + The second image equated. """ image1 = copy.deepcopy(image1) image2 = copy.deepcopy(image2) diff --git a/pylinac/core/io.py b/pylinac/core/io.py index f2c3066ea..74e95a962 100644 --- a/pylinac/core/io.py +++ b/pylinac/core/io.py @@ -243,9 +243,13 @@ def __init__( path : str 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. """ diff --git a/pylinac/ct.py b/pylinac/ct.py index e998428f3..36ecc8016 100644 --- a/pylinac/ct.py +++ b/pylinac/ct.py @@ -241,7 +241,9 @@ def __init__( """ Parameters ---------- - catphan : `~pylinac.cbct.CatPhanBase` instance. + + catphan : :class:`~pylinac.cbct.CatPhanBase` instance. + The catphan instance. slice_num : int The slice number of the DICOM array desired. If None, will use the ``slice_num`` property of subclass. combine : bool @@ -1001,8 +1003,10 @@ class CTP528CP504(CatPhanModule): Attributes ---------- + radius2linepairs_mm : float The radius in mm to the line pairs. + """ attr_name: str = "ctp528" @@ -2068,11 +2072,12 @@ def analyze( low_contrast_tolerance : int The number of low-contrast bubbles needed to be "seen" to pass. cnr_threshold : float, int + The threshold for "detecting" low-contrast image. See RTD for calculation info. .. deprecated:: 3.0 + Use visibility parameter instead. - The threshold for "detecting" low-contrast image. See RTD for calculation info. zip_after : bool If the CT images were not compressed before analysis and this is set to true, pylinac will compress the analyzed images into a ZIP archive. @@ -2090,9 +2095,11 @@ def analyze( values are 0, 1, and 2. .. warning:: This is the padding **on either side**. So a value of 1 => 3 slices, 2 => 5 slices, 3 => 7 slices, etc. + expected_hu_values An optional dictionary of the expected HU values for the HU linearity module. The keys are the ROI names and the values are the expected HU values. If a key is not present or the parameter is None, the default values will be used. + """ self.localize() ctp404, offset = self._get_module(CTP404CP504, raise_empty=True) diff --git a/pylinac/log_analyzer.py b/pylinac/log_analyzer.py index 6348b3217..0d8a34c2b 100644 --- a/pylinac/log_analyzer.py +++ b/pylinac/log_analyzer.py @@ -491,12 +491,12 @@ def calc_map( equal_aspect : bool If True, make the y-direction the same resolution as x. If False, the y-axis will be equal to the number of leaves. - Returns - ------- - numpy.ndarray - A numpy array reconstructing the actual fluence of the log. The size will - be the number of MLC pairs by 400 / resolution since the MLCs can move anywhere within the - 40cm-wide linac head opening. + Returns + ------- + numpy.ndarray + A numpy array reconstructing the actual fluence of the log. The size will + be the number of MLC pairs by 400 / resolution since the MLCs can move anywhere within the + 40cm-wide linac head opening. """ height = MLC_FOV_HEIGHT_MM if not self._mlc.hdmlc else HDMLC_FOV_HEIGHT_MM if equal_aspect: @@ -852,16 +852,20 @@ def __init__( """ Parameters ---------- - log_type: Dynalog, TrajectoryLog + + log_type: :class:`~pylinac.log_analyzer.Dynalog`, :class:`~pylinac.log_analyzer.TrajectoryLog` + The log type. snapshot_idx : array, list The snapshots to be considered for RMS and error calculations (can be all snapshots or just when beam was on). - jaw_struct : Jaw_Struct + jaw_struct : :class:`~pylinac.log_analyzer.JawStruct` + The jaw structure. hdmlc : boolean If False (default), indicates a regular MLC model (e.g. Millennium 120). If True, indicates an HD MLC model (e.g. Millennium 120 HD). Attributes ---------- + leaf_axes : dict containing :class:`~pylinac.log_analyzer.Axis` The dictionary is keyed by the leaf number, with the Axis as the value. @@ -2174,9 +2178,9 @@ class TrajectoryLogAxisData: Collimator data in degrees. gantry : :class:`~pylinac.log_analyzer.Axis` Gantry data in degrees. - jaws : :class:`~pylinac.log_analyzer.Jaw_Struct` + jaws : :class:`~pylinac.log_analyzer.JawStruct` Jaw data structure. Data in cm. - couch : :class:`~pylinac.log_analyzer.Couch_Struct` + couch : :class:`~pylinac.log_analyzer.CouchStruct` Couch data structure. Data in cm. mu : :class:`~pylinac.log_analyzer.Axis` MU data in MU. diff --git a/pylinac/picketfence.py b/pylinac/picketfence.py index a2571783f..2f5f20e4a 100644 --- a/pylinac/picketfence.py +++ b/pylinac/picketfence.py @@ -62,9 +62,11 @@ def __init__(self, leaf_arrangement: list[tuple[int, float]], offset: float = 0) Parameters ---------- - leaf_arrangement: Description of the leaf arrangement. List of tuples containing the number of leaves and leaf width. + leaf_arrangement + Description of the leaf arrangement. List of tuples containing the number of leaves and leaf width. E.g. (10, 5) is 10 leaves with 5mm widths. - offset: The offset in mm of the leaves. Used for asymmetric arrangements. E.g. -2.5mm will shift the arrangement 2.5mm to the left. + offset + The offset in mm of the leaves. Used for asymmetric arrangements. E.g. -2.5mm will shift the arrangement 2.5mm to the left. """ self.centers = [] self.widths = [] diff --git a/pylinac/winston_lutz.py b/pylinac/winston_lutz.py index 936da8cc8..9761464a0 100644 --- a/pylinac/winston_lutz.py +++ b/pylinac/winston_lutz.py @@ -903,7 +903,7 @@ def from_cbct_zip(cls, file: Path | str, raw_pixels: bool = False, **kwargs): ---------- file Path to the archive file. - raw_pixels + raw_pixels If True, uses the raw pixel values of the DICOM files. If False, uses the rescaled Hounsfield units. Generally, this should be true. kwargs @@ -1439,6 +1439,7 @@ def plot_images( Parameters ---------- axis : {'Gantry', 'Collimator', 'Couch', 'GB Combo', 'GBP Combo', 'All'} + The axis to plot. show : bool Whether to show the image. split : bool diff --git a/requirements-dev.txt b/requirements-dev.txt index 5a7a0ff3d..22ff24727 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,8 +1,10 @@ -r requirements.txt black bump2version +furo google-cloud-storage nox +Pillow==10.* pre-commit pytest pytest-cov==3.0.0 diff --git a/requirements-ram.txt b/requirements-ram.txt index b04f7081a..843bd3dfe 100644 --- a/requirements-ram.txt +++ b/requirements-ram.txt @@ -52,7 +52,7 @@ rich==12.4.4 scikit-image==0.19.1 scipy==1.7.3 six==1.16.0 -sphinx==5.* +sphinx==7.* sphinx-autobuild sphinx-copybutton tabulate~=0.9.0