Skip to content

Commit

Permalink
Merged in bugfix/lazystack_acr (pull request #326)
Browse files Browse the repository at this point in the history
fix ACR w/ lazy stack

Approved-by: Randy Taylor
  • Loading branch information
jrkerns committed Jan 8, 2024
2 parents 0fb802e + 78e3dcc commit 027446f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 13 deletions.
26 changes: 14 additions & 12 deletions pylinac/acr.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from .core import pdf
from .core.array_utils import find_nearest_idx
from .core.geometry import Line, Point
from .core.image import DicomImage
from .core.mtf import MTF
from .core.profile import FWXMProfilePhysical
from .core.roi import HighContrastDiskROI, RectangleROI
Expand Down Expand Up @@ -1037,7 +1036,7 @@ def analyze(self, echo_number: int | None = None) -> None:
echo_number:
The echo to analyze. If not passed, uses the minimum echo number found.
"""
self.dicom_stack.images = self._select_echo_images(echo_number)
self._select_echo_images(echo_number)
self.localize()
self.slice1 = self.slice1(self, offset=0)
self.geometric_distortion = self.geometric_distortion(
Expand All @@ -1048,17 +1047,18 @@ def analyze(self, echo_number: int | None = None) -> None:
)
self.slice11 = self.slice11(self, offset=MR_SLICE11_MODULE_OFFSET_MM)

def _select_echo_images(self, echo_number: int | None) -> list[DicomImage]:
"""Get the image indices that match the given echo number"""
def _select_echo_images(self, echo_number: int | None) -> None:
"""Select out the images that match the given echo number"""
# we check for multiple echos. We only pick the first echo found.
# this is probably not the best logic but we somehow have to pick
# Echo Numbers is an int; https://dicom.innolitics.com/ciods/mr-image/mr-image/00180086

# in case EchoNumbers isn't there, return all
# in case EchoNumbers isn't there, use all
try:
all_echos = {int(i.metadata.EchoNumbers) for i in self.dicom_stack.images}
all_echos = {int(i.metadata.EchoNumbers) for i in self.dicom_stack}
except AttributeError:
return self.dicom_stack.images
# no manipulation; use all images
return
if echo_number is None:
echo_number = min(all_echos)
if len(all_echos) > 1:
Expand All @@ -1069,11 +1069,13 @@ def _select_echo_images(self, echo_number: int | None) -> list[DicomImage]:
raise ValueError(
f"Echo number {echo_number} was passed but not found in the dataset. Found echo numbers: {all_echos}. Remove the echo_number parameter or pick a valid echo number."
)
return [
image
for image in self.dicom_stack.images
if int(image.metadata.EchoNumbers) == echo_number
]
# drop images that don't have the same echo number
to_pop = []
for idx, img in enumerate([i for i in self.dicom_stack].copy()):
if int(img.metadata.EchoNumbers) != echo_number:
to_pop.append(idx)
for idx in sorted(to_pop, reverse=True):
del self.dicom_stack[idx]

def plot_analyzed_image(self, show: bool = True, **plt_kwargs) -> plt.Figure:
"""Plot the analyzed image
Expand Down
13 changes: 13 additions & 0 deletions pylinac/core/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,15 @@ def __setitem__(self, key: int, value: DicomImage):
current_path = self._image_path_keys[key]
value.save(current_path)

def __delitem__(self, key):
"""Delete the image from the stack and OS."""
current_path = self._image_path_keys[key]
try:
os.remove(current_path)
except Exception:
pass
del self._image_path_keys[key]

def __len__(self):
return len(self._image_path_keys)

Expand Down Expand Up @@ -1754,6 +1763,10 @@ def __getitem__(self, item) -> DicomImage:
def __setitem__(self, key, value: DicomImage):
self.images[key] = value

def __delitem__(self, key):
"""Delete the image from the stack."""
del self.images[key]

def __len__(self):
return len(self.images)

Expand Down
2 changes: 1 addition & 1 deletion tests_basic/test_acr.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ class ACRMRMixin(CloudFileMixin):
@classmethod
def setUpClass(cls):
filename = cls.get_filename()
cls.mri = ACRMRILarge.from_zip(filename)
cls.mri = ACRMRILarge.from_zip(filename, memory_efficient_mode=True)
cls.mri.analyze()

def test_roll(self):
Expand Down

0 comments on commit 027446f

Please sign in to comment.