Skip to content

Commit

Permalink
Merged in feature/RAM-4285-acr-mri-mtf (pull request #495)
Browse files Browse the repository at this point in the history
RAM-4285 Add 10-90% MTF for ACR MRI phantom

Approved-by: Randy Taylor
  • Loading branch information
jrkerns committed Jan 8, 2025
2 parents baa7b58 + e0eec52 commit f16b70a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/source/acr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,8 @@ Interpreting MRI Results
* ``measured_slice_thickness_mm``: The measured slice thickness in mm.
* ``row_mtf_50``: The MTF at 50% for the row-based ROIs.
* ``col_mtf_50``: The MTF at 50% for the column-based ROIs.
* ``row_mtf_lp_mm``: The MTF:lp/mm for the row-based ROIs from 10-90% in 10% increments.
* ``col_mtf_lp_mm``: The MTF:lp/mm for the column-based ROIs from 10-90% in 10% increments.
* ``rois``: A dictionary of the analyzed MTF ROIs. The key is the name of the
ROI; e.g. ``Row 1.1`` and the key is a dictionary of the following items:

Expand Down
2 changes: 2 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ ACR MRI
* :bdg-warning:`Fixed` The positive and negative diagonal geometric distortion calculations (``results_data().geometric_distortion_module.profiles["negative diagonal"]['width (mm)']``) for the ACR Large MRI phantom were not scaled correctly.
Since the pixel distance is diagonal the physical spacing between pixels is actually :math:`\sqrt{2}` times the pixel spacing.
This is now fixed. Prior values can be scaled by :math:`\sqrt{2}` to get the correct values.
* :bdg-success:`Feature` MTF is now provided in 10% increments from 10-90% in the ``results_data`` return object
for both row and column MTFs as ``row_mtf_lp_mm`` and ``col_mtf_lp_mm``. This is to match CT-like MTF outputs.

v 3.30.0
--------
Expand Down
19 changes: 19 additions & 0 deletions pylinac/acr.py
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,14 @@ class MRSlice1ModuleOutput(BaseModel):
description="The MTF at 50% for the column-based ROIs.",
title="Column-wise 50% MTF (lp/mm)",
)
row_mtf_lp_mm: dict[int, float] = Field(
description="A key-value pair of the MTF. The key is the relative resolution in % and the value is the lp/mm at that resolution",
title="MTF (lp/mm)",
)
col_mtf_lp_mm: dict[int, float] = Field(
description="A key-value pair of the MTF. The key is the relative resolution in % and the value is the lp/mm at that resolution",
title="MTF (lp/mm)",
)


class MRUniformityModule(CatPhanModule):
Expand Down Expand Up @@ -1636,6 +1644,15 @@ def results(self, as_str: bool = True) -> str | tuple:
return string

def _generate_results_data(self) -> ACRMRIResult:
resolutions = range(10, 91, 10) # 10-90% in 10% increments
row_mtfs = {
resolution: self.slice1.row_mtf.relative_resolution(resolution)
for resolution in resolutions
}
col_mtfs = {
resolution: self.slice1.col_mtf.relative_resolution(resolution)
for resolution in resolutions
}
return ACRMRIResult(
phantom_model=self._model,
phantom_roll_deg=self.catphan_roll,
Expand All @@ -1650,6 +1667,8 @@ def _generate_results_data(self) -> ACRMRIResult:
measured_slice_thickness_mm=self.slice1.measured_slice_thickness_mm,
row_mtf_50=self.slice1.row_mtf.relative_resolution(50),
col_mtf_50=self.slice1.col_mtf.relative_resolution(50),
row_mtf_lp_mm=row_mtfs,
col_mtf_lp_mm=col_mtfs,
),
slice11=MRSlice11ModuleOutput(
offset=MR_SLICE11_MODULE_OFFSET_MM,
Expand Down
12 changes: 12 additions & 0 deletions tests_basic/test_acr.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,18 @@ def construct_analyzed_instance(self):
mri.analyze()
return mri

def test_row_mtf_keys(self):
phantom = self.construct_analyzed_instance()
data = phantom.results_data()
for key, value in {10: 1.13, 80: 0.564}.items():
self.assertAlmostEqual(data.slice1.row_mtf_lp_mm[key], value, delta=0.01)

def test_col_mtf_keys(self):
phantom = self.construct_analyzed_instance()
data = phantom.results_data()
for key, value in {10: 1.11, 80: 0.826}.items():
self.assertAlmostEqual(data.slice1.col_mtf_lp_mm[key], value, delta=0.01)


class TestMRGeneral(TestCase):
def setUp(self):
Expand Down

0 comments on commit f16b70a

Please sign in to comment.