Skip to content

Commit

Permalink
Merge pull request #162 from bbean23/160-clean-up-abstractspotanalysi…
Browse files Browse the repository at this point in the history
…simageprocessor

160 clean up abstractspotanalysisimageprocessor
  • Loading branch information
e10harvey authored Nov 11, 2024
2 parents e765fd3 + fe3cd68 commit 7fc448f
Show file tree
Hide file tree
Showing 12 changed files with 1,649 additions and 419 deletions.
592 changes: 547 additions & 45 deletions opencsp/common/lib/cv/CacheableImage.py

Large diffs are not rendered by default.

11 changes: 1 addition & 10 deletions opencsp/common/lib/cv/SpotAnalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,6 @@ def set_image_processors(self, image_processors: list[asaip.AbstractSpotAnalysis
self.visualization_coordinator.clear()
self.visualization_coordinator.register_visualization_processors(image_processors)

# limit the amount of memory that image processors utilize
from opencsp.common.lib.cv.spot_analysis.image_processor.AbstractSpotAnalysisImageProcessorLeger import (
image_processors_persistant_memory_total,
)

mem_per_image_processor = image_processors_persistant_memory_total / len(self.image_processors)
for image_processor in self.image_processors:
image_processor._allowed_memory_footprint = mem_per_image_processor

# assign the input stream to the first image processor
if self.input_stream != None:
self._assign_inputs(self.input_stream)
Expand Down Expand Up @@ -263,7 +254,7 @@ def process_next(self):

# Release memory from the previous result
if self._prev_result is not None:
self.image_processors[-1].cache_image_to_disk_as_necessary(self._prev_result)
self.image_processors[-1].cache_images_to_disk_as_necessary()
self._prev_result = None

# Attempt to get the next image. Raises StopIteration if there are no
Expand Down
69 changes: 53 additions & 16 deletions opencsp/common/lib/cv/spot_analysis/SpotAnalysisOperable.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,13 @@ def __post_init__(self):
requires_update = True

# record the primary image source, if not available already
if primary_image_source_path == None:
if primary_image.source_path != None:
if primary_image_source_path is None:
if primary_image.source_path is not None:
primary_image_source_path = primary_image.source_path
else:
primary_image_source_path = primary_image.cache_path
requires_update = True

# set the source path on the cacheable instance of the primary image
if primary_image.source_path == None:
if primary_image_source_path != None:
primary_image.source_path = primary_image_source_path
if primary_image_source_path is not None:
requires_update = True

if requires_update:
# use __init__ to update frozen values
Expand All @@ -114,8 +110,41 @@ def __post_init__(self):
self.image_processor_notes,
)

def __sizeof__(self) -> int:
return sys.getsizeof(self.primary_image) + sum([sys.getsizeof(im) for im in self.supporting_images.values()])
def get_all_images(self, primary=True, supporting=True, visualization=True, algorithm=True) -> list[CacheableImage]:
"""
Get a list of all images tracked by this operable including all primary
images, supporting images, visualization, and algorithm images.
Parameters
----------
primary : bool, optional
True to include the primary image in the list of returned images. By
default True.
supporting : bool, optional
True to include the supporting images, if any, in the list of
returned images. By default True.
visualization : bool, optional
True to include the visualization images in the list of returned
images. By default True.
algorithm : bool, optional
True to include the algorithm images, if any, in the list of
returned images. By default True.
Returns
-------
list[CacheableImage]
The images tracked by this operable.
"""
ret: list[CacheableImage] = []

if primary:
ret.append(self.primary_image)

if supporting:
for image_type in self.supporting_images:
ret.append(self.supporting_images[image_type])

return ret

def replace_use_default_values(
self, supporting_images: dict[ImageType, CacheableImage] = None, data: 'SpotAnalysisOperable' = None
Expand All @@ -125,13 +154,13 @@ def replace_use_default_values(
values."""
ret = self

if supporting_images != None:
if supporting_images is not None:
for image_type in supporting_images:
if (image_type in ret.supporting_images) and (ret.supporting_images[image_type] != None):
if (image_type in ret.supporting_images) and (ret.supporting_images[image_type] is not None):
supporting_images[image_type] = ret.supporting_images[image_type]
ret = replace(ret, supporting_images=supporting_images)

if data != None:
if data is not None:
given_fiducials = data.given_fiducials if len(self.given_fiducials) == 0 else self.given_fiducials
found_fiducials = data.found_fiducials if len(self.found_fiducials) == 0 else self.found_fiducials
annotations = data.annotations if len(self.annotations) == 0 else self.annotations
Expand Down Expand Up @@ -180,7 +209,7 @@ def get_primary_path_nameext(self) -> tuple[str, str]:
if image_name is not None and image_name != "":
break

if image_name == None or image_name == "":
if image_name is None or image_name == "":
ret_path, ret_name_ext = "unknown_path", "unknown_image"
else:
ret_path, name, ext = ft.path_components(image_name)
Expand All @@ -202,7 +231,7 @@ def best_primary_pathnameext(self) -> str:
def max_popf(self) -> npt.NDArray[np.float_]:
"""Returns the maximum population float value, if it exists. Otherwise
returns the maximum value for this instance's primary image."""
if self.population_statistics != None:
if self.population_statistics is not None:
return self.population_statistics.maxf
else:
return np.max(self.primary_image.nparray)
Expand All @@ -211,7 +240,7 @@ def max_popf(self) -> npt.NDArray[np.float_]:
def min_popf(self) -> npt.NDArray[np.float_]:
"""Returns the minimum population float value, if it exists. Otherwise
returns the minimum value for this instance's primary image."""
if self.population_statistics != None:
if self.population_statistics is not None:
return self.population_statistics.minf
else:
return np.min(self.primary_image.nparray)
Expand All @@ -233,3 +262,11 @@ def get_fiducials_by_type(
+ f"found 0 fiducials matching type {fiducial_type.__name__} for image {self.best_primary_pathnameext}"
)
return ret

def __sizeof__(self) -> int:
"""
Get the size of this operable in memory including all primary images,
supporting images, and visualization images.
"""
all_images_size = sum([sys.getsizeof(img) for img in self.get_all_images()])
return all_images_size
Loading

0 comments on commit 7fc448f

Please sign in to comment.