Blackened
This commit is contained in:
parent
0907d013cd
commit
76af0891e9
14 changed files with 95 additions and 63 deletions
|
|
@ -132,11 +132,11 @@ class ListAPI(MicroscopeView):
|
|||
|
||||
# Inject system metadata
|
||||
system_metadata = {
|
||||
"microscope_settings": self.microscope.read_settings(),
|
||||
"microscope_state": self.microscope.state,
|
||||
"microscope_id": self.microscope.id,
|
||||
"microscope_name": self.microscope.name,
|
||||
}
|
||||
"microscope_settings": self.microscope.read_settings(),
|
||||
"microscope_state": self.microscope.state,
|
||||
"microscope_id": self.microscope.id,
|
||||
"microscope_name": self.microscope.name,
|
||||
}
|
||||
output.system_metadata.update(system_metadata)
|
||||
|
||||
# Insert custom metadata
|
||||
|
|
|
|||
|
|
@ -8,38 +8,38 @@ _actions = {
|
|||
"rule": "/camera/capture/",
|
||||
"view_class": camera.CaptureAPI,
|
||||
"description": "Take a single still capture",
|
||||
"conditions": True
|
||||
"conditions": True,
|
||||
},
|
||||
"preview_start": {
|
||||
"rule": "/camera/preview/start",
|
||||
"view_class": camera.GPUPreviewStartAPI,
|
||||
"description": "Start the on-board GPU preview",
|
||||
"conditions": True
|
||||
"conditions": True,
|
||||
},
|
||||
"preview_stop": {
|
||||
"rule": "/camera/preview/stop",
|
||||
"view_class": camera.GPUPreviewStopAPI,
|
||||
"description": "Stop the on-board GPU preview",
|
||||
"conditions": True
|
||||
"conditions": True,
|
||||
},
|
||||
"move": {
|
||||
"rule": "/stage/move/",
|
||||
"view_class": stage.MoveStageAPI,
|
||||
"description": "Move the microscope stage",
|
||||
"conditions": True
|
||||
"conditions": True,
|
||||
},
|
||||
"shutdown": {
|
||||
"rule": "/system/shutdown/",
|
||||
"view_class": system.ShutdownAPI,
|
||||
"description": "Shutdown the device",
|
||||
"conditions": (platform == "linux")
|
||||
"conditions": (platform == "linux"),
|
||||
},
|
||||
"reboot": {
|
||||
"rule": "/system/reboot/",
|
||||
"view_class": system.RebootAPI,
|
||||
"description": "Reboot the device",
|
||||
"conditions": (platform == "linux")
|
||||
}
|
||||
"conditions": (platform == "linux"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ def actions_representation():
|
|||
"links": {"self": url_for(f".{name}")},
|
||||
"description": action["description"],
|
||||
"rule": action["rule"],
|
||||
"view_class": str(action["view_class"])
|
||||
"view_class": str(action["view_class"]),
|
||||
}
|
||||
|
||||
actions[name] = d
|
||||
|
|
|
|||
|
|
@ -84,11 +84,11 @@ class CaptureAPI(MicroscopeView):
|
|||
|
||||
# Inject system metadata
|
||||
system_metadata = {
|
||||
"microscope_settings": self.microscope.read_settings(),
|
||||
"microscope_state": self.microscope.state,
|
||||
"microscope_id": self.microscope.id,
|
||||
"microscope_name": self.microscope.name,
|
||||
}
|
||||
"microscope_settings": self.microscope.read_settings(),
|
||||
"microscope_state": self.microscope.state,
|
||||
"microscope_id": self.microscope.id,
|
||||
"microscope_name": self.microscope.name,
|
||||
}
|
||||
output.system_metadata.update(system_metadata)
|
||||
|
||||
# Insert custom metadata
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class ShutdownAPI(MicroscopeView):
|
|||
.. :quickref: Actions; Shutdown
|
||||
|
||||
"""
|
||||
subprocess.Popen(['shutdown', '-h', 'now'])
|
||||
subprocess.Popen(["shutdown", "-h", "now"])
|
||||
|
||||
return "{}", 201
|
||||
|
||||
|
|
@ -24,6 +24,6 @@ class RebootAPI(MicroscopeView):
|
|||
.. :quickref: Actions; Shutdown
|
||||
|
||||
"""
|
||||
subprocess.Popen(['sudo', 'shutdown', '-r', 'now'])
|
||||
subprocess.Popen(["sudo", "shutdown", "-r", "now"])
|
||||
|
||||
return "{}", 201
|
||||
|
|
|
|||
|
|
@ -20,14 +20,22 @@ def captures_representation(capture_list: list, include_unavailable: bool = Fals
|
|||
if include_unavailable:
|
||||
captures = {image.id: image.state for image in capture_list}
|
||||
else:
|
||||
captures = {image.id: image.state for image in capture_list if image.state["available"]}
|
||||
captures = {
|
||||
image.id: image.state for image in capture_list if image.state["available"]
|
||||
}
|
||||
|
||||
for capture_key, capture_repr in captures.items():
|
||||
# Add API routes to returned representations
|
||||
extra_state = {
|
||||
"links": {
|
||||
"self": "{}".format(url_for(".capture", capture_id=capture_key)),
|
||||
"download": "{}".format(url_for(".capture_download", capture_id=capture_key, filename=capture_repr["filename"])),
|
||||
"download": "{}".format(
|
||||
url_for(
|
||||
".capture_download",
|
||||
capture_id=capture_key,
|
||||
filename=capture_repr["filename"],
|
||||
)
|
||||
),
|
||||
"tags": "{}".format(url_for(".capture_tags", capture_id=capture_key)),
|
||||
}
|
||||
}
|
||||
|
|
@ -131,7 +139,9 @@ class CaptureAPI(MicroscopeView):
|
|||
"""
|
||||
|
||||
try:
|
||||
representation = captures_representation(self.microscope.camera.images)[capture_id]
|
||||
representation = captures_representation(self.microscope.camera.images)[
|
||||
capture_id
|
||||
]
|
||||
except KeyError:
|
||||
return abort(404) # 404 Not Found
|
||||
|
||||
|
|
@ -379,9 +389,7 @@ def construct_blueprint(microscope_obj):
|
|||
# Capture routes
|
||||
blueprint.add_url_rule(
|
||||
"/<capture_id>/download/<filename>",
|
||||
view_func=DownloadAPI.as_view(
|
||||
"capture_download", microscope=microscope_obj
|
||||
),
|
||||
view_func=DownloadAPI.as_view("capture_download", microscope=microscope_obj),
|
||||
)
|
||||
|
||||
blueprint.add_url_rule(
|
||||
|
|
@ -397,7 +405,6 @@ def construct_blueprint(microscope_obj):
|
|||
)
|
||||
|
||||
blueprint.add_url_rule(
|
||||
"/",
|
||||
view_func=ListAPI.as_view("capture_list", microscope=microscope_obj),
|
||||
"/", view_func=ListAPI.as_view("capture_list", microscope=microscope_obj)
|
||||
)
|
||||
return blueprint
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ def plugins_representation(plugin_loader_object: PluginLoader):
|
|||
"name": plugin["name"],
|
||||
"plugin": str(plugin["plugin"]),
|
||||
"routes": plugin["routes"],
|
||||
"form": plugin["form"]
|
||||
"form": plugin["form"],
|
||||
}
|
||||
plugins.append(d)
|
||||
|
||||
|
|
@ -55,8 +55,7 @@ def construct_blueprint(microscope_obj):
|
|||
|
||||
# Create a base route to return plugin API forms, if any exist
|
||||
blueprint.add_url_rule(
|
||||
"/",
|
||||
view_func=PluginFormAPI.as_view("plugins", microscope=microscope_obj),
|
||||
"/", view_func=PluginFormAPI.as_view("plugins", microscope=microscope_obj)
|
||||
)
|
||||
|
||||
all_routes = []
|
||||
|
|
|
|||
|
|
@ -16,9 +16,7 @@ def tasks_representation():
|
|||
for task_key, task_repr in tasks_dict.items():
|
||||
# Add API routes to returned representations
|
||||
extra_state = {
|
||||
"links": {
|
||||
"self": "{}".format(url_for(".task", task_id=task_key)),
|
||||
}
|
||||
"links": {"self": "{}".format(url_for(".task", task_id=task_key))}
|
||||
}
|
||||
|
||||
tasks_dict[task_key].update(extra_state)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,9 @@ def pull_usercomment_dict(filepath):
|
|||
return json.loads(exif_dict["Exif"][37510].decode())
|
||||
except json.decoder.JSONDecodeError:
|
||||
# TODO: Remove YAML support in a later version
|
||||
logging.warning(f"Capture {filepath} has metadata stored in YAML format. This is now deprecated in favour of JSON.")
|
||||
logging.warning(
|
||||
f"Capture {filepath} has metadata stored in YAML format. This is now deprecated in favour of JSON."
|
||||
)
|
||||
return yaml.load(exif_dict["Exif"][37510].decode())
|
||||
else:
|
||||
return None
|
||||
|
|
@ -227,7 +229,6 @@ class CaptureObject(object):
|
|||
# Insert exif into file
|
||||
piexif.insert(exif_bytes, self.file)
|
||||
|
||||
|
||||
@property
|
||||
def metadata(self) -> dict:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class PiCameraStreamer(BaseCamera):
|
|||
"sharpness",
|
||||
"annotate_text",
|
||||
"annotate_text_size",
|
||||
"zoom"
|
||||
"zoom",
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
|
|
@ -93,13 +93,23 @@ class PiCameraStreamer(BaseCamera):
|
|||
self.set_zoom(1.0)
|
||||
|
||||
# Set default settings
|
||||
self.image_resolution = tuple(self.camera.MAX_RESOLUTION) #: tuple: Resolution for image captures
|
||||
self.stream_resolution = (832, 624) #: tuple: Resolution for stream and video captures
|
||||
self.numpy_resolution = (1312, 976) #: tuple: Resolution for numpy array captures
|
||||
self.image_resolution = tuple(
|
||||
self.camera.MAX_RESOLUTION
|
||||
) #: tuple: Resolution for image captures
|
||||
self.stream_resolution = (
|
||||
832,
|
||||
624,
|
||||
) #: tuple: Resolution for stream and video captures
|
||||
self.numpy_resolution = (
|
||||
1312,
|
||||
976,
|
||||
) #: tuple: Resolution for numpy array captures
|
||||
self.jpeg_quality = 75 #: int: JPEG quality
|
||||
|
||||
# Set default lens shading table path
|
||||
self.picamera_lst_path = settings_file_path("picamera_lst.npy") #: str: Path of .npy lens shading table file
|
||||
self.picamera_lst_path = settings_file_path(
|
||||
"picamera_lst.npy"
|
||||
) #: str: Path of .npy lens shading table file
|
||||
|
||||
# Update board identifier
|
||||
self.status.update({})
|
||||
|
|
@ -138,7 +148,9 @@ class PiCameraStreamer(BaseCamera):
|
|||
"image_resolution": self.image_resolution,
|
||||
"numpy_resolution": self.numpy_resolution,
|
||||
"jpeg_quality": self.jpeg_quality,
|
||||
"picamera_lst_path": self.picamera_lst_path if os.path.isfile(self.picamera_lst_path) else None,
|
||||
"picamera_lst_path": self.picamera_lst_path
|
||||
if os.path.isfile(self.picamera_lst_path)
|
||||
else None,
|
||||
"picamera_settings": {},
|
||||
}
|
||||
)
|
||||
|
|
@ -273,7 +285,7 @@ class PiCameraStreamer(BaseCamera):
|
|||
"""
|
||||
Read the current lens shading table as a numpy array, if it exists. Return None otherwise.
|
||||
"""
|
||||
if hasattr(self.camera, 'lens_shading_table'):
|
||||
if hasattr(self.camera, "lens_shading_table"):
|
||||
return self.camera.lens_shading_table
|
||||
else:
|
||||
return None
|
||||
|
|
@ -297,13 +309,17 @@ class PiCameraStreamer(BaseCamera):
|
|||
elif (type(lst_array_or_path) == str) and os.path.isfile(lst_array_or_path):
|
||||
self.camera.lens_shading_table = np.load(lst_array_or_path)
|
||||
else:
|
||||
logging.error("Unsupported or missing data for camera lens_shading_table. Must be numpy ndarray, or .npy file path string. Skipping.")
|
||||
logging.error(
|
||||
"Unsupported or missing data for camera lens_shading_table. Must be numpy ndarray, or .npy file path string. Skipping."
|
||||
)
|
||||
|
||||
def set_zoom(self, zoom_value: float = 1.0) -> None:
|
||||
"""
|
||||
Change the camera zoom, handling re-centering and scaling.
|
||||
"""
|
||||
logging.warning("set_zoom is deprecated. Please use the 'zoom' property in picamera_settings.")
|
||||
logging.warning(
|
||||
"set_zoom is deprecated. Please use the 'zoom' property in picamera_settings."
|
||||
)
|
||||
with self.lock:
|
||||
self.status["zoom_value"] = float(zoom_value)
|
||||
if self.status["zoom_value"] < 1:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class JSONEncoder(json.JSONEncoder):
|
|||
"""
|
||||
A custom JSON encoder, with type conversions for PiCamera fractions, Numpy integers, and Numpy arrays
|
||||
"""
|
||||
|
||||
def default(self, o, markers=None):
|
||||
# PiCamera fractions
|
||||
if isinstance(o, Fraction):
|
||||
|
|
@ -39,6 +40,7 @@ class JSONEncoder(json.JSONEncoder):
|
|||
|
||||
# MAIN CONFIG CLASS
|
||||
|
||||
|
||||
class OpenflexureSettingsFile:
|
||||
"""
|
||||
An object to handle expansion, conversion, and saving of the microscope configuration.
|
||||
|
|
@ -164,6 +166,7 @@ class OpenflexureSettingsFile:
|
|||
|
||||
# HANDLE BASIC LOADING AND SAVING OF SETTINGS FILES
|
||||
|
||||
|
||||
def load_json_file(config_path) -> dict:
|
||||
"""
|
||||
Open a .json config file
|
||||
|
|
|
|||
|
|
@ -160,7 +160,9 @@ class Microscope:
|
|||
and :py:attr:`openflexure_microscope.camera.base.BaseCamera.status`
|
||||
"""
|
||||
# DEPRECATED
|
||||
logging.warning("Microscope.state is deprecated. Use Microscope.status instead. State will be removed in a future version.")
|
||||
logging.warning(
|
||||
"Microscope.state is deprecated. Use Microscope.status instead. State will be removed in a future version."
|
||||
)
|
||||
state = {
|
||||
"camera": self.camera.status,
|
||||
"stage": self.stage.status,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class AutofocusAPI(MicroscopeViewPlugin):
|
|||
return jsonify(task.state), 202
|
||||
|
||||
else:
|
||||
abort(503, 'No stage connected. Unable to autofocus.')
|
||||
abort(503, "No stage connected. Unable to autofocus.")
|
||||
|
||||
|
||||
class FastAutofocusAPI(MicroscopeViewPlugin):
|
||||
|
|
@ -53,4 +53,4 @@ class FastAutofocusAPI(MicroscopeViewPlugin):
|
|||
return jsonify(task.state), 202
|
||||
|
||||
else:
|
||||
abort(503, 'No stage connected. Unable to autofocus.')
|
||||
abort(503, "No stage connected. Unable to autofocus.")
|
||||
|
|
|
|||
|
|
@ -147,14 +147,16 @@ class ScanPlugin(MicroscopePlugin):
|
|||
if "time" not in metadata:
|
||||
metadata["time"] = generate_basename()
|
||||
|
||||
metadata.update({
|
||||
"scan_parameters": {
|
||||
"step_size": step_size,
|
||||
"grid": grid,
|
||||
"style": style,
|
||||
"autofocus_dz": autofocus_dz
|
||||
metadata.update(
|
||||
{
|
||||
"scan_parameters": {
|
||||
"step_size": step_size,
|
||||
"grid": grid,
|
||||
"style": style,
|
||||
"autofocus_dz": autofocus_dz,
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
# Check if autofocus is enabled
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -154,7 +154,9 @@ class PluginLoader(object):
|
|||
@property
|
||||
def state(self):
|
||||
# DEPRECATED
|
||||
logging.warning("PluginMount.state is deprecated. Use PluginMount.active instead. State will be removed in a future version.")
|
||||
logging.warning(
|
||||
"PluginMount.state is deprecated. Use PluginMount.active instead. State will be removed in a future version."
|
||||
)
|
||||
return [m["python_name"] for m in self._plugins]
|
||||
|
||||
@property
|
||||
|
|
@ -195,13 +197,15 @@ class PluginLoader(object):
|
|||
setattr(self, pythonsafe_plugin_name, plugin_object)
|
||||
|
||||
# Store the plugin object, and it's properties
|
||||
self._plugins.append({
|
||||
"name": plugin_name,
|
||||
"python_name": pythonsafe_plugin_name,
|
||||
"plugin": plugin_object,
|
||||
"routes": [],
|
||||
"form": None
|
||||
})
|
||||
self._plugins.append(
|
||||
{
|
||||
"name": plugin_name,
|
||||
"python_name": pythonsafe_plugin_name,
|
||||
"plugin": plugin_object,
|
||||
"routes": [],
|
||||
"form": None,
|
||||
}
|
||||
)
|
||||
|
||||
# Grant plugin access to the hardware
|
||||
plugin_object.microscope = self.parent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue