Skip to content

Commit

Permalink
fix other java acq types + improve installer
Browse files Browse the repository at this point in the history
  • Loading branch information
henrypinkard committed Jun 23, 2024
1 parent 0a63364 commit 995dbb5
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 28 deletions.
2 changes: 1 addition & 1 deletion pycromanager/_version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version_info = (0, 34, 4)
version_info = (0, 34, 5)
__version__ = ".".join(map(str, version_info))
27 changes: 11 additions & 16 deletions pycromanager/acquisition/java_backend_acquisitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ def _notification_handler_fn(acquisition, notification_push_port, connected_even
if AcqNotification.is_image_saved_notification(notification): # it was saved to RAM, not disk
if not notification.is_data_sink_finished_notification():
# check if NDTiff data storage used
if acquisition._directory is not None:
if acquisition._directory is not None or isinstance(acquisition, MagellanAcquisition) or \
isinstance(acquisition, XYTiledAcquisition):
index_entry = notification.payload.encode('ISO-8859-1')
axes = acquisition._dataset.add_index_entry(index_entry)
# swap the notification.payload from the byte array of index information to axes
Expand Down Expand Up @@ -300,12 +301,7 @@ def __init__(
warnings.warn('Could not create acquisition notification handler. '
'Update Micro-Manager and Pyrcro-Manager to the latest versions to fix this')

# Start remote acquisition
# Acquistition.start is now deprecated, so this can be removed later
# Acquisitions now get started automatically when the first events submitted
# but Magellan acquisitons (and probably others that generate their own events)
# will need some new method to submit events only after image processors etc have been added
self._acq.start()

self._dataset_disk_location = (
self._acq.get_data_sink().get_storage().get_disk_location()
if self._acq.get_data_sink() is not None
Expand All @@ -321,7 +317,7 @@ def __init__(
# when images are written to disk/RAM storage
storage_java_class = data_sink.get_storage()
summary_metadata = storage_java_class.get_summary_metadata()
if directory is not None:
if directory is not None or isinstance(self, MagellanAcquisition) or isinstance(self, XYTiledAcquisition):
# NDTiff dataset saved to disk on Java side
self._dataset = Dataset(dataset_path=self._dataset_disk_location, summary_metadata=summary_metadata)
else:
Expand Down Expand Up @@ -364,10 +360,6 @@ def await_completion(self):
if hasattr(self, '_event_thread'):
self._event_thread.join()

# need to do this so its _Bridge can be garbage collected and a reference to the JavaBackendAcquisition
# does not prevent Bridge cleanup and process exiting
self._remote_acq = None

# Wait on all the other threads to shut down properly
if hasattr(self, '_storage_monitor_thread'):
self._storage_monitor_thread.join()
Expand Down Expand Up @@ -633,6 +625,7 @@ def __init__(
l = locals()
named_args = {arg_name: l[arg_name] for arg_name in arg_names}
super().__init__(**named_args)
self._acq.start()

def _create_remote_acquisition(self, port, **kwargs):
core = ZMQRemoteMMCoreJ(port=self._port, timeout=self._timeout)
Expand All @@ -648,7 +641,7 @@ def _create_remote_acquisition(self, port, **kwargs):
x_overlap = self.tile_overlap
y_overlap = self.tile_overlap

self._remote_acq = acq_factory.create_tiled_acquisition(
self._acq = acq_factory.create_tiled_acquisition(
kwargs['directory'],
kwargs['name'],
show_viewer,
Expand Down Expand Up @@ -710,6 +703,7 @@ def __init__(
l = locals()
named_args = {arg_name: l[arg_name] for arg_name in arg_names}
super().__init__(**named_args)
self._acq.start()

def _create_remote_acquisition(self, port, **kwargs):
if type(self.tile_overlap) is tuple:
Expand All @@ -720,7 +714,7 @@ def _create_remote_acquisition(self, port, **kwargs):

ui_class = JavaClass('org.micromanager.explore.ExploreAcqUIAndStorage')
ui = ui_class.create(kwargs['directory'], kwargs['name'], x_overlap, y_overlap, self.z_step_um, self.channel_group)
self._remote_acq = ui.get_acquisition()
self._acq = ui.get_acquisition()

def _start_events(self, **kwargs):
pass # These come from the user
Expand Down Expand Up @@ -767,6 +761,7 @@ def __init__(
l = locals()
named_args = {arg_name: l[arg_name] for arg_name in arg_names}
super().__init__(**named_args)
self._acq.start()

def _start_events(self, **kwargs):
pass # Magellan handles this on Java side
Expand All @@ -777,7 +772,7 @@ def _create_event_queue(self, **kwargs):
def _create_remote_acquisition(self, **kwargs):
magellan_api = Magellan()
if self.magellan_acq_index is not None:
self._remote_acq = magellan_api.create_acquisition(self.magellan_acq_index, False)
self._acq = magellan_api.create_acquisition(self.magellan_acq_index, False)
elif self.magellan_explore:
self._remote_acq = magellan_api.create_explore_acquisition(False)
self._acq = magellan_api.create_explore_acquisition(False)
self._event_queue = None
41 changes: 30 additions & 11 deletions pycromanager/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@
MM_DOWNLOAD_URL_MAC = MM_DOWNLOAD_URL_BASE + '/nightly/2.0/Mac'
MM_DOWNLOAD_URL_WINDOWS = MM_DOWNLOAD_URL_BASE + '/nightly/2.0/Windows'

def _get_download_url(ci_build=False):
"""
Get the download URL for the latest nightly build of Micro-Manager
Returns
-------
str
The URL to the latest nightly build
"""
platform = _get_platform()
if platform == 'Windows':
url = MM_DOWNLOAD_URL_WINDOWS
elif platform == 'Mac':
url = MM_DOWNLOAD_URL_MAC
else:
raise ValueError(f"Unsupported OS: {platform}")
if ci_build:
url = url.replace('nightly', 'ci')
return url

def _get_platform():
"""
Get the platform of the system
Expand All @@ -30,18 +50,12 @@ def _get_platform():
else:
raise ValueError(f"Unsupported OS: {sys.platform}")

def _find_versions():
def _find_versions(ci_build=False):
"""
Find all available versions of Micro-Manager nightly builds
Find all available versions of Micro-Manager builds
"""
platform = _get_platform()
# Get the webpage
if platform == 'Windows':
webpage = requests.get(MM_DOWNLOAD_URL_WINDOWS)
elif platform == 'Mac':
webpage = requests.get(MM_DOWNLOAD_URL_MAC)
else:
raise ValueError(f"Unsupported OS: {platform}")
webpage = requests.get(_get_download_url(ci_build))
return re.findall(r'class="rowDefault" href="([^"]+)', webpage.text)

def find_existing_mm_install():
Expand All @@ -63,14 +77,18 @@ def find_existing_mm_install():
else:
raise ValueError(f"Unsupported OS: {platform}")

def download_and_install(destination='auto', mm_install_log_path=None):
def download_and_install(destination='auto', mm_install_log_path=None, ci_build=False):
"""
Download and install the latest nightly build of Micro-Manager
Parameters
----------
destination : str
The directory to install Micro-Manager to. If 'auto', it will install to the user's home directory.
mm_install_log_path : str
Path to save the installation log to
ci_build : bool
If True, download the latest CI build instead of nightly build
Returns
-------
Expand All @@ -80,14 +98,15 @@ def download_and_install(destination='auto', mm_install_log_path=None):
windows = _get_platform() == 'Windows'
platform = 'Windows' if windows else 'Mac'
installer = 'mm_installer.exe' if windows else 'mm_installer.dmg'
latest_version = MM_DOWNLOAD_URL_BASE + _find_versions()[0]
latest_version = _get_download_url(ci_build) + os.sep + _find_versions(ci_build)[0].split(os.sep)[-1]
# make a progress bar that updates every 0.5 seconds
def bar(curr, total, width):
if not hasattr(bar, 'last_update'):
bar.last_update = 0
if curr / total*100 - bar.last_update > 0.5:
print(f"\rDownloading installer: {curr / total*100:.2f}%", end='')
bar.last_update = curr / total*100
print('Downloading: ', latest_version)
wget.download(latest_version, out=installer, bar=bar)

if windows:
Expand Down

0 comments on commit 995dbb5

Please sign in to comment.