From 97e0f6832778ef428c0e8cc90d7a567acf76116f Mon Sep 17 00:00:00 2001 From: Henry Pinkard <7969470+henrypinkard@users.noreply.github.com> Date: Sat, 13 Jul 2024 18:42:30 +0200 Subject: [PATCH 1/2] reorganization and cleanup --- src/mmpycorex/__init__.py | 2 +- src/mmpycorex/core.py | 2 +- src/mmpycorex/{headless.py => launcher.py} | 71 +++++++++++----------- src/mmpycorex/main.py | 5 -- src/mmpycorex/test.py | 4 -- 5 files changed, 38 insertions(+), 46 deletions(-) rename src/mmpycorex/{headless.py => launcher.py} (81%) delete mode 100644 src/mmpycorex/main.py delete mode 100644 src/mmpycorex/test.py diff --git a/src/mmpycorex/__init__.py b/src/mmpycorex/__init__.py index 3e7f577..4912d1d 100644 --- a/src/mmpycorex/__init__.py +++ b/src/mmpycorex/__init__.py @@ -6,6 +6,6 @@ """ from ._version import __version__, version_info -from .headless import create_core_instance, terminate_core_instances +from .launcher import create_core_instance, terminate_core_instances from .core import Core from .install import download_and_install_mm, find_existing_mm_install diff --git a/src/mmpycorex/core.py b/src/mmpycorex/core.py index afb025c..6aeece0 100644 --- a/src/mmpycorex/core.py +++ b/src/mmpycorex/core.py @@ -1,7 +1,7 @@ import threading from pyjavaz import JavaObject, PullSocket, DEFAULT_BRIDGE_PORT -from .headless import _PYMMCORES +from .launcher import _PYMMCORES class _CoreCallback: """ diff --git a/src/mmpycorex/headless.py b/src/mmpycorex/launcher.py similarity index 81% rename from src/mmpycorex/headless.py rename to src/mmpycorex/launcher.py index 52c8114..249cf56 100644 --- a/src/mmpycorex/headless.py +++ b/src/mmpycorex/launcher.py @@ -14,12 +14,41 @@ logger = logging.getLogger(__name__) + +#### Some functions to normalize the API between the Java and Python backends + class TaggedImage: def __init__(self, tags, pix): self.tags = tags self.pix = pix +def pop_next_tagged_image(self): + md = pymmcore.Metadata() + pix = self.pop_next_image_md(0, 0, md) + tags = {key: md.GetSingleTag(key).GetValue() for key in md.GetKeys()} + return TaggedImage(tags, pix) + +def get_tagged_image(core, cam_index, camera, height, width, binning=None, pixel_type=None, roi_x_start=None, + roi_y_start=None): + """ + Different signature than the Java version because of difference in metadata handling in the swig layers + """ + pix = core.get_image() + md = pymmcore.Metadata() + # most of the same tags from pop_next_tagged_image, which may not be the same as the MMCoreJ version of this function + tags = {'Camera': camera, 'Height': height, 'Width': width, 'PixelType': pixel_type, + 'CameraChannelIndex': cam_index} + # Could optionally add these for completeness but there might be a performance hit + if binning is not None: + tags['Binning'] = binning + if roi_x_start is not None: + tags['ROI-X-start'] = roi_x_start + if roi_y_start is not None: + tags['ROI-Y-start'] = roi_y_start + + return TaggedImage(tags, pix) + def _camel_to_snake(name): """ Convert camelCase string to snake_case @@ -29,10 +58,7 @@ def _camel_to_snake(name): def _create_pymmcore_instance(): """ - Make a subclass of CMMCore with two differences: - - 1. All methods are converted to snake_case - 2. add convenience methods to match the MMCoreJ API: + Make a subclass of CMMCore with all methods converted to snake_case """ # Create a new dictionary for the class attributes @@ -53,37 +79,6 @@ def _create_pymmcore_instance(): instance = clz() - def pop_next_tagged_image(self): - md = pymmcore.Metadata() - pix = self.pop_next_image_md(0, 0, md) - tags = {key: md.GetSingleTag(key).GetValue() for key in md.GetKeys()} - return TaggedImage(tags, pix) - - def get_tagged_image(core, cam_index, camera, height, width, binning=None, pixel_type=None, roi_x_start=None, - roi_y_start=None): - """ - Different signature than the Java version because of difference in metadata handling in the swig layers - """ - pix = core.get_image() - md = pymmcore.Metadata() - # most of the same tags from pop_next_tagged_image, which may not be the same as the MMCoreJ version of this function - tags = {'Camera': camera, 'Height': height, 'Width': width, 'PixelType': pixel_type, - 'CameraChannelIndex': cam_index} - # Could optionally add these for completeness but there might be a performance hit - if binning is not None: - tags['Binning'] = binning - if roi_x_start is not None: - tags['ROI-X-start'] = roi_x_start - if roi_y_start is not None: - tags['ROI-Y-start'] = roi_y_start - - return TaggedImage(tags, pix) - - instance.get_tagged_image = types.MethodType(get_tagged_image, instance) - instance.pop_next_tagged_image = types.MethodType(pop_next_tagged_image, instance) - - # attach TaggedImage class - instance.TaggedImage = TaggedImage return instance @@ -166,6 +161,12 @@ def create_core_instance( mmc.load_system_configuration(config_file) mmc.set_circular_buffer_memory_footprint(buffer_size_mb) _PYMMCORES.append(mmc) # Store so it doesn't get garbage collected + + ## Some hacks to somewhat mimic the MMCoreJ API + mmc.get_tagged_image = types.MethodType(get_tagged_image, mmc) + mmc.pop_next_tagged_image = types.MethodType(pop_next_tagged_image, mmc) + # attach TaggedImage class + mmc.TaggedImage = TaggedImage else: classpath = mm_app_path + '/plugins/Micro-Manager/*' if java_loc is None: diff --git a/src/mmpycorex/main.py b/src/mmpycorex/main.py deleted file mode 100644 index 29b8476..0000000 --- a/src/mmpycorex/main.py +++ /dev/null @@ -1,5 +0,0 @@ - -name = "mmpycorex" -from mmpycorex.headless import create_core_instance, terminate_core_instances -from mmpycorex.core import Core -from mmpycorex.install import download_and_install_mm, find_existing_mm_install diff --git a/src/mmpycorex/test.py b/src/mmpycorex/test.py deleted file mode 100644 index e0798d3..0000000 --- a/src/mmpycorex/test.py +++ /dev/null @@ -1,4 +0,0 @@ -from mmpycorex import create_core_instance - - -create_core_instance( mm_app_path= '/Users/henrypinkard/Micro-Manager', python_backend=True, debug=True) \ No newline at end of file From 3591a720694a09bd90c64ae80b4ea615d8aefd7e Mon Sep 17 00:00:00 2001 From: Henry Pinkard <7969470+henrypinkard@users.noreply.github.com> Date: Sat, 13 Jul 2024 18:43:06 +0200 Subject: [PATCH 2/2] cleanup and finalizing --- src/mmpycorex/_version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmpycorex/_version.py b/src/mmpycorex/_version.py index 3c15861..e2626c8 100644 --- a/src/mmpycorex/_version.py +++ b/src/mmpycorex/_version.py @@ -1,2 +1,2 @@ -version_info = (0, 1, 2) -__version__ = ".".join(map(str, version_info)) \ No newline at end of file +version_info = (0, 1, 3) +__version__ = ".".join(map(str, version_info))