Code cleanup
This commit is contained in:
parent
2bfb988460
commit
994e83dbeb
46 changed files with 261 additions and 318 deletions
|
|
@ -8,9 +8,11 @@ def handle_extension_error(extension_name):
|
|||
"""'gracefully' log an error if an extension fails to load."""
|
||||
try:
|
||||
yield
|
||||
except Exception as e:
|
||||
except Exception: # pylint: disable=W0703
|
||||
logging.error(
|
||||
f"Exception loading builtin extension {extension_name}: \n{traceback.format_exc()}"
|
||||
"Exception loading builtin extension %s: \n%s",
|
||||
extension_name,
|
||||
traceback.format_exc(),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ from threading import Event, Thread
|
|||
import numpy as np
|
||||
from labthings import current_action, fields, find_component
|
||||
from labthings.extensions import BaseExtension
|
||||
from labthings.views import ActionView, PropertyView, View
|
||||
from labthings.views import ActionView, View
|
||||
from scipy import ndimage
|
||||
|
||||
from openflexure_microscope.devel import JsonResponse, abort, request
|
||||
from openflexure_microscope.devel import abort
|
||||
from openflexure_microscope.utilities import set_properties
|
||||
|
||||
### Autofocus utilities
|
||||
|
|
@ -36,19 +36,15 @@ class JPEGSharpnessMonitor:
|
|||
return self.background_thread.is_alive()
|
||||
|
||||
def should_stop(self):
|
||||
import time
|
||||
|
||||
return time.time() - self.kept_alive > self.timeout
|
||||
|
||||
def keep_alive(self):
|
||||
import time
|
||||
|
||||
self.kept_alive = time.time()
|
||||
|
||||
def start(self):
|
||||
"Start monitoring sharpness by looking at JPEG size"
|
||||
if not self.camera.stream_active:
|
||||
logging.warn(
|
||||
logging.warning(
|
||||
"Autofocus sharpness monitor was started but the camera isn't streaming. Attempting to start the stream..."
|
||||
)
|
||||
self.camera.start_stream_recording()
|
||||
|
|
@ -66,7 +62,7 @@ class JPEGSharpnessMonitor:
|
|||
"Function that runs in a background thread to record sharpness"
|
||||
logging.debug("Starting sharpness measurement in background thread")
|
||||
self.keep_alive()
|
||||
logging.debug(f"_measure_jpegs stop_event: {self.stop_event.is_set()}")
|
||||
logging.debug("_measure_jpegs stop_event: %s", self.stop_event.is_set())
|
||||
while not self.stop_event.is_set() and not self.should_stop():
|
||||
size_now = self.jpeg_size()
|
||||
time_now = time.time()
|
||||
|
|
@ -107,7 +103,7 @@ class JPEGSharpnessMonitor:
|
|||
if np.sum(jpeg_times > stage_times[0]) == 0:
|
||||
raise ValueError(
|
||||
"No images were captured during the move of the stage. Perhaps the camera is not streaming images?"
|
||||
)
|
||||
) from e
|
||||
else:
|
||||
raise e
|
||||
if stop < 1:
|
||||
|
|
@ -119,7 +115,7 @@ class JPEGSharpnessMonitor:
|
|||
|
||||
def sharpest_z_on_move(self, index):
|
||||
"""Return the z position of the sharpest image on a given move"""
|
||||
jt, jz, js = self.move_data(index)
|
||||
_, jz, js = self.move_data(index)
|
||||
if len(js) == 0:
|
||||
raise ValueError(
|
||||
"No images were captured during the move of the stage. Perhaps the camera is not streaming images?"
|
||||
|
|
@ -226,7 +222,7 @@ def fast_autofocus(microscope, dz=2000, backlash=None):
|
|||
"""Perform a down-up-down-up autofocus"""
|
||||
with monitor_sharpness(
|
||||
microscope
|
||||
) as m, microscope.camera.lock, microscope.stage.lock:
|
||||
) as m, microscope.camera.lock as _, microscope.stage.lock as _:
|
||||
i, z = m.focus_rel(-dz / 2)
|
||||
i, z = m.focus_rel(dz)
|
||||
fz = m.sharpest_z_on_move(i)
|
||||
|
|
@ -278,7 +274,7 @@ def fast_up_down_up_autofocus(
|
|||
"""
|
||||
with monitor_sharpness(
|
||||
microscope
|
||||
) as m, microscope.camera.lock, microscope.stage.lock:
|
||||
) as m, microscope.camera.lock as _, microscope.stage.lock as _:
|
||||
# Ensure the MJPEG stream has started
|
||||
microscope.camera.start_stream_recording()
|
||||
|
||||
|
|
@ -291,12 +287,8 @@ def fast_up_down_up_autofocus(
|
|||
i, z = m.focus_rel(-df)
|
||||
# now inspect where the sharpest point is, and estimate the sharpness
|
||||
# (JPEG size) that we should find at the start of the Z stack
|
||||
logging.debug("Get target_s")
|
||||
jt, jz, js = m.move_data(i)
|
||||
_, jz, js = m.move_data(i)
|
||||
best_z = jz[np.argmax(js)]
|
||||
target_s = np.interp(
|
||||
[best_z + target_z], jz[::-1], js[::-1]
|
||||
) # NB jz is decreasing
|
||||
|
||||
# now move to the start of the z stack
|
||||
logging.debug("Move to the start of the z stack")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import logging
|
||||
import os
|
||||
from sys import platform
|
||||
|
||||
import psutil
|
||||
from flask import abort
|
||||
|
|
@ -9,9 +8,7 @@ from labthings.extensions import BaseExtension
|
|||
from labthings.views import PropertyView, View
|
||||
|
||||
from openflexure_microscope.api.utilities.gui import build_gui
|
||||
from openflexure_microscope.captures.capture import build_captures_from_exif
|
||||
from openflexure_microscope.captures.capture_manager import BASE_CAPTURE_PATH
|
||||
from openflexure_microscope.config import OpenflexureSettingsFile
|
||||
from openflexure_microscope.paths import check_rw, settings_file_path
|
||||
|
||||
AS_SETTINGS_PATH = settings_file_path("autostorage_settings.json")
|
||||
|
|
@ -97,10 +94,10 @@ class AutostorageExtension(BaseExtension):
|
|||
|
||||
def on_microscope(self, microscope_obj):
|
||||
"""Function to automatically call when the parent LabThing has a microscope attached."""
|
||||
logging.debug(f"Autostorage extension found microscope {microscope_obj}")
|
||||
logging.debug("Autostorage extension found microscope %s", microscope_obj)
|
||||
if hasattr(microscope_obj, "captures"):
|
||||
logging.debug(
|
||||
f"Autostorage extension bound to CaptureManager {self.capture_manager}"
|
||||
"Autostorage extension bound to CaptureManager %s", self.capture_manager
|
||||
)
|
||||
|
||||
# Store a reference to the CaptureManager
|
||||
|
|
@ -119,7 +116,8 @@ class AutostorageExtension(BaseExtension):
|
|||
# If preferred path does not exist, or cannot be written to
|
||||
if not (os.path.isdir(location) and check_rw(location)):
|
||||
logging.error(
|
||||
f"Preferred capture path {location} is missing or cannot be written to. Restoring defaults."
|
||||
"Preferred capture path %s is missing or cannot be written to. Restoring defaults.",
|
||||
location,
|
||||
)
|
||||
# Reset the storage location to default
|
||||
set_current_location(self.capture_manager, get_default_location())
|
||||
|
|
@ -187,8 +185,6 @@ autostorage_extension_v2 = AutostorageExtension()
|
|||
|
||||
class GetLocationsView(PropertyView):
|
||||
def get(self):
|
||||
global autostorage_extension_v2
|
||||
|
||||
autostorage_extension_v2.check_location()
|
||||
return autostorage_extension_v2.get_locations()
|
||||
|
||||
|
|
@ -197,13 +193,10 @@ class PreferredLocationView(PropertyView):
|
|||
schema = fields.String(required=True, example="Default")
|
||||
|
||||
def get(self):
|
||||
global autostorage_extension_v2
|
||||
|
||||
autostorage_extension_v2.check_location()
|
||||
return autostorage_extension_v2.get_preferred_key()
|
||||
|
||||
def post(self, new_path_key):
|
||||
global autostorage_extension_v2
|
||||
microscope = find_component("org.openflexure.microscope")
|
||||
|
||||
if not microscope:
|
||||
|
|
@ -218,13 +211,11 @@ class PreferredLocationGUIView(View):
|
|||
args = {"new_path_title": fields.String(required=True)}
|
||||
|
||||
def post(self, args):
|
||||
global autostorage_extension_v2
|
||||
|
||||
new_path_title = args.get("new_path_title")
|
||||
logging.debug(new_path_title)
|
||||
|
||||
new_path_key = autostorage_extension_v2.title_to_key(new_path_title)
|
||||
logging.debug(f"{new_path_key}")
|
||||
logging.debug(new_path_key)
|
||||
|
||||
autostorage_extension_v2.check_location()
|
||||
autostorage_extension_v2.set_preferred_key(new_path_key)
|
||||
|
|
@ -233,7 +224,6 @@ class PreferredLocationGUIView(View):
|
|||
|
||||
|
||||
def dynamic_form():
|
||||
global autostorage_extension_v2
|
||||
autostorage_extension_v2.check_location()
|
||||
return {
|
||||
"icon": "sd_storage",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from typing import Tuple
|
|||
from flask import abort
|
||||
from labthings import find_component
|
||||
from labthings.extensions import BaseExtension
|
||||
from labthings.views import ActionView, View
|
||||
from labthings.views import ActionView
|
||||
|
||||
from .recalibrate_utils import (
|
||||
auto_expose_and_freeze_settings,
|
||||
|
|
@ -78,17 +78,10 @@ class FlattenLSTView(ActionView):
|
|||
"No microscope connected. Unable to flatten the lens shading table.",
|
||||
)
|
||||
|
||||
try:
|
||||
with pause_stream(microscope.camera) as scamera:
|
||||
flat_lst = flat_lens_shading_table(scamera.camera)
|
||||
scamera.camera.lens_shading_table = flat_lst
|
||||
microscope.save_settings()
|
||||
except:
|
||||
logging.exception("Error flattening the lens shading table.")
|
||||
abort(
|
||||
503,
|
||||
"Couldn't flatten the lens shading table - do you have the forked PiCamera library installed?",
|
||||
)
|
||||
with pause_stream(microscope.camera) as scamera:
|
||||
flat_lst = flat_lens_shading_table(scamera.camera)
|
||||
scamera.camera.lens_shading_table = flat_lst
|
||||
microscope.save_settings()
|
||||
|
||||
|
||||
class DeleteLSTView(ActionView):
|
||||
|
|
@ -101,16 +94,9 @@ class DeleteLSTView(ActionView):
|
|||
"No microscope connected. Unable to flatten the lens shading table.",
|
||||
)
|
||||
|
||||
try:
|
||||
with pause_stream(microscope.camera) as scamera:
|
||||
scamera.camera.lens_shading_table = None
|
||||
microscope.save_settings()
|
||||
except:
|
||||
logging.exception("Error deleting the lens shading table.")
|
||||
abort(
|
||||
503,
|
||||
"Couldn't flatten the lens shading table - do you have the forked PiCamera library installed?",
|
||||
)
|
||||
with pause_stream(microscope.camera) as scamera:
|
||||
scamera.camera.lens_shading_table = None
|
||||
microscope.save_settings()
|
||||
|
||||
|
||||
lst_extension_v2 = BaseExtension(
|
||||
|
|
|
|||
|
|
@ -24,13 +24,15 @@ def flat_lens_shading_table(camera):
|
|||
raise ImportError(
|
||||
"This program requires the forked picamera library with lens shading support"
|
||||
)
|
||||
return np.zeros(camera._lens_shading_table_shape(), dtype=np.uint8) + 32
|
||||
return (
|
||||
np.zeros(camera._lens_shading_table_shape(), dtype=np.uint8) + 32
|
||||
) # pylint: disable=W0212
|
||||
|
||||
|
||||
def adjust_exposure_to_setpoint(camera, setpoint):
|
||||
"""Adjust the camera's exposure time until the maximum pixel value is <setpoint>."""
|
||||
print("Adjusting shutter speed to hit setpoint {}".format(setpoint), end="")
|
||||
for i in range(3):
|
||||
for _ in range(3):
|
||||
print(".", end="")
|
||||
camera.shutter_speed = int(
|
||||
camera.shutter_speed * setpoint / np.max(rgb_image(camera))
|
||||
|
|
@ -50,9 +52,9 @@ def auto_expose_and_freeze_settings(camera):
|
|||
camera.awb_mode = "auto"
|
||||
camera.exposure_mode = "auto"
|
||||
camera.iso = (
|
||||
0
|
||||
) # This is important, if it's on a fixed ISO, gain might not set properly.
|
||||
for i in range(6):
|
||||
0 # This is important, if it's on a fixed ISO, gain might not set properly.
|
||||
)
|
||||
for _ in range(6):
|
||||
print(".", end="")
|
||||
time.sleep(0.5)
|
||||
logging.info("done")
|
||||
|
|
@ -188,10 +190,10 @@ def recalibrate_camera(camera):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with PiCamera() as camera:
|
||||
camera.start_preview()
|
||||
with PiCamera() as main_camera:
|
||||
main_camera.start_preview()
|
||||
time.sleep(3)
|
||||
logging.info("Recalibrating...")
|
||||
recalibrate_camera(camera)
|
||||
recalibrate_camera(main_camera)
|
||||
logging.info("Done.")
|
||||
time.sleep(2)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from labthings import (
|
|||
update_action_progress,
|
||||
)
|
||||
from labthings.extensions import BaseExtension
|
||||
from labthings.views import ActionView, View
|
||||
from labthings.views import ActionView
|
||||
|
||||
from openflexure_microscope.captures.capture_manager import generate_basename
|
||||
from openflexure_microscope.devel import abort
|
||||
|
|
@ -74,10 +74,13 @@ class ScanExtension(BaseExtension):
|
|||
use_video_port: bool = False,
|
||||
resize: Tuple[int, int] = None,
|
||||
bayer: bool = False,
|
||||
metadata: dict = {},
|
||||
annotations: dict = {},
|
||||
tags: list = [],
|
||||
metadata: dict = None,
|
||||
annotations: dict = None,
|
||||
tags: list = None,
|
||||
):
|
||||
metadata = metadata or {}
|
||||
annotations = annotations or {}
|
||||
tags = tags or []
|
||||
|
||||
# Construct a tile filename
|
||||
if namemode == "coordinates":
|
||||
|
|
@ -117,18 +120,22 @@ class ScanExtension(BaseExtension):
|
|||
basename: str = None,
|
||||
namemode: str = "coordinates",
|
||||
temporary: bool = False,
|
||||
stride_size: int = [2000, 1500, 100],
|
||||
grid: list = [3, 3, 5],
|
||||
stride_size: list = (2000, 1500, 100),
|
||||
grid: list = (3, 3, 5),
|
||||
style="raster",
|
||||
autofocus_dz: int = 50,
|
||||
use_video_port: bool = False,
|
||||
resize: Tuple[int, int] = None,
|
||||
bayer: bool = False,
|
||||
fast_autofocus=False,
|
||||
metadata: dict = {},
|
||||
annotations: dict = {},
|
||||
tags: list = [],
|
||||
metadata: dict = None,
|
||||
annotations: dict = None,
|
||||
tags: list = None,
|
||||
):
|
||||
metadata = metadata or {}
|
||||
annotations = annotations or {}
|
||||
tags = tags or []
|
||||
|
||||
start = time.time()
|
||||
|
||||
# Keep task progress
|
||||
|
|
@ -210,7 +217,7 @@ class ScanExtension(BaseExtension):
|
|||
|
||||
# If we're not doing a z-stack, just capture
|
||||
if grid[2] <= 1:
|
||||
capture(
|
||||
self.capture(
|
||||
microscope,
|
||||
basename,
|
||||
namemode=namemode,
|
||||
|
|
@ -250,7 +257,7 @@ class ScanExtension(BaseExtension):
|
|||
microscope.stage.move_abs(initial_position)
|
||||
|
||||
end = time.time()
|
||||
logging.info(f"Scan took {end - start} seconds")
|
||||
logging.info("Scan took %s seconds", end - start)
|
||||
|
||||
def stack(
|
||||
self,
|
||||
|
|
@ -264,24 +271,27 @@ class ScanExtension(BaseExtension):
|
|||
use_video_port: bool = False,
|
||||
resize: Tuple[int, int] = None,
|
||||
bayer: bool = False,
|
||||
metadata: dict = {},
|
||||
annotations: dict = {},
|
||||
tags: list = [],
|
||||
metadata: dict = None,
|
||||
annotations: dict = None,
|
||||
tags: list = None,
|
||||
):
|
||||
metadata = metadata or {}
|
||||
annotations = annotations or {}
|
||||
tags = tags or []
|
||||
|
||||
# Store initial position
|
||||
initial_position = microscope.stage.position
|
||||
logging.debug(f"Starting z-stack from position {microscope.stage.position}")
|
||||
logging.debug("Starting z-stack from position %s", microscope.stage.position)
|
||||
|
||||
with microscope.lock:
|
||||
# Move to center scan
|
||||
logging.debug("Moving to z-stack starting position")
|
||||
microscope.stage.move_rel([0, 0, int((-step_size * steps) / 2)])
|
||||
logging.debug(f"Starting scan from position {microscope.stage.position}")
|
||||
logging.debug("Starting scan from position %s", microscope.stage.position)
|
||||
|
||||
for i in range(steps):
|
||||
time.sleep(0.1)
|
||||
logging.debug(f"Capturing from position {microscope.stage.position}")
|
||||
logging.debug("Capturing from position %s", microscope.stage.position)
|
||||
self.capture(
|
||||
microscope,
|
||||
basename,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class ZipObjectSchema(Schema):
|
|||
links = fields.Dict()
|
||||
|
||||
@pre_dump
|
||||
def generate_links(self, data, **kwargs):
|
||||
def generate_links(self, data, **_):
|
||||
data.links = {
|
||||
"download": {
|
||||
"href": url_for(
|
||||
|
|
@ -34,8 +34,8 @@ class ZipObjectSchema(Schema):
|
|||
|
||||
|
||||
class ZipObjectDescription:
|
||||
def __init__(self, id, file_pointer, data_size=None):
|
||||
self.id = id
|
||||
def __init__(self, id_, file_pointer, data_size=None):
|
||||
self.id = id_
|
||||
self.fp = file_pointer
|
||||
self.data_size = data_size
|
||||
self.zip_size = os.path.getsize(self.fp.name) * 1e-6
|
||||
|
|
@ -155,7 +155,7 @@ class ZipGetterAPIView(View):
|
|||
if not session_id in default_zip_manager.session_zips:
|
||||
return abort(404) # 404 Not Found
|
||||
|
||||
logging.info(f"Session ID: {session_id}")
|
||||
logging.info("Session ID: %s", session_id)
|
||||
|
||||
return send_file(
|
||||
default_zip_manager.zip_fp_from_id(session_id).name,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue