Acquire microscope lock for state and settings IO

This commit is contained in:
Joel Collins 2020-06-15 16:19:33 +01:00
parent 5d70d5f7fe
commit 1c1dcdbe1a

View file

@ -153,39 +153,41 @@ class Microscope:
Return: Return:
dict: Dictionary containing complete microscope state dict: Dictionary containing complete microscope state
""" """
state = {"camera": self.camera.state, "stage": self.stage.state} with self.lock:
return state state = {"camera": self.camera.state, "stage": self.stage.state}
return state
def update_settings(self, settings: dict): def update_settings(self, settings: dict):
""" """
Applies a settings dictionary to the microscope. Missing parameters will be left untouched. Applies a settings dictionary to the microscope. Missing parameters will be left untouched.
""" """
logging.debug("Microscope: Applying settings: {}".format(settings)) with self.lock:
logging.debug("Microscope: Applying settings: {}".format(settings))
# If attached to a camera # If attached to a camera
if ("camera" in settings) and self.camera: if ("camera" in settings) and self.camera:
self.camera.update_settings(settings.get("camera", {})) self.camera.update_settings(settings.get("camera", {}))
# If attached to a stage # If attached to a stage
if ("stage" in settings) and self.stage: if ("stage" in settings) and self.stage:
self.stage.update_settings(settings.get("stage", {})) self.stage.update_settings(settings.get("stage", {}))
# Capture manager # Capture manager
self.captures.update_settings(settings.get("captures", {})) self.captures.update_settings(settings.get("captures", {}))
# Microscope settings # Microscope settings
if "id" in settings: if "id" in settings:
self.id = settings["id"] self.id = settings["id"]
if "name" in settings: if "name" in settings:
self.name = settings["name"] self.name = settings["name"]
if "fov" in settings: if "fov" in settings:
self.fov = settings["fov"] self.fov = settings["fov"]
# Extension settings # Extension settings
if "extensions" in settings: if "extensions" in settings:
self.extension_settings.update(settings["extensions"]) self.extension_settings.update(settings["extensions"])
# TODO: warn if there are settings that we silently ignore # TODO: warn if there are settings that we silently ignore
def read_settings(self, full: bool = True): def read_settings(self, full: bool = True):
""" """
@ -197,49 +199,50 @@ class Microscope:
This is to ensure that settings for currently disconnected hardware This is to ensure that settings for currently disconnected hardware
don't get removed from the settings file. don't get removed from the settings file.
""" """
with self.lock:
settings_current = { settings_current = {
"id": self.id, "id": self.id,
"name": self.name, "name": self.name,
"fov": self.fov, "fov": self.fov,
"extensions": self.extension_settings, "extensions": self.extension_settings,
} }
# If attached to a camera # If attached to a camera
if self.camera: if self.camera:
settings_current_camera = self.camera.read_settings() settings_current_camera = self.camera.read_settings()
settings_current["camera"] = settings_current_camera settings_current["camera"] = settings_current_camera
# Store an encoded copy of the PiCamera lens shading table, if it exists # Store an encoded copy of the PiCamera lens shading table, if it exists
if hasattr(self.camera, "read_lens_shading_table"): if hasattr(self.camera, "read_lens_shading_table"):
# Read LST. Returns None if no LST is active # Read LST. Returns None if no LST is active
lst_arr = self.camera.read_lens_shading_table() lst_arr = self.camera.read_lens_shading_table()
if lst_arr is not None: if lst_arr is not None:
b64_string, dtype, shape = serialise_array_b64(lst_arr) b64_string, dtype, shape = serialise_array_b64(lst_arr)
settings_current["camera"]["lens_shading_table"] = { settings_current["camera"]["lens_shading_table"] = {
"@type": "ndarray", "@type": "ndarray",
"b64_string": b64_string, "b64_string": b64_string,
"dtype": dtype, "dtype": dtype,
"shape": shape, "shape": shape,
} }
# If attached to a stage # If attached to a stage
if self.stage: if self.stage:
settings_current_stage = self.stage.read_settings() settings_current_stage = self.stage.read_settings()
settings_current["stage"] = settings_current_stage settings_current["stage"] = settings_current_stage
# Capture manager # Capture manager
settings_current_captures = self.captures.read_settings() settings_current_captures = self.captures.read_settings()
settings_current["captures"] = settings_current_captures settings_current["captures"] = settings_current_captures
settings_full = self.settings_file.merge(settings_current) settings_full = self.settings_file.merge(settings_current)
if full: if full:
return settings_full return settings_full
else: else:
return settings_current return settings_current
def save_settings(self): def save_settings(self):
""" """
@ -341,7 +344,7 @@ class Microscope:
) )
# Gether metadata from hardware in a greenlet # Gether metadata from hardware in a greenlet
gevent.spawn(self.add_metadata_to_capture, output, metadata, annotations, tags) gevent.get_hub().threadpool.spawn(self.add_metadata_to_capture, output, metadata, annotations, tags)
logging.info(f"Finished capture to {output.file}") logging.info(f"Finished capture to {output.file}")