{"title": "AutofocusThing", "properties": {"stack_dz": {"title": "stack_dz", "type": "integer", "forms": [{"href": "/autofocus/stack_dz", "op": ["readproperty", "writeproperty"]}]}, "stack_images_to_save": {"title": "stack_images_to_save", "type": "integer", "forms": [{"href": "/autofocus/stack_images_to_save", "op": ["readproperty", "writeproperty"]}]}, "stack_min_images_to_test": {"title": "stack_min_images_to_test", "type": "integer", "forms": [{"href": "/autofocus/stack_min_images_to_test", "op": ["readproperty", "writeproperty"]}]}}, "actions": {"fast_autofocus": {"description": "This method will will move down by dz/2, sweep up by dz, and then evaluate\nthe position where the image was sharpest. We'll then move back down, and\nfinally up to the sharpest point.", "title": "Sweep the stage up and down, then move to the sharpest point.", "forms": [{"href": "/autofocus/fast_autofocus", "op": ["invokeaction"]}], "input": {"title": "fast_autofocus_input", "type": "object", "properties": {"dz": {"title": "Dz", "default": 2000, "type": "integer"}, "start": {"title": "Start", "default": "centre", "type": "string"}}}, "output": {"description": "A BaseModel with the position and sharpness data from JPEGSharpnessMonitor.\n\nEach JPEG Size (representing a sharpness metric) has an associated timestamp,\nas does each stage position. The stage positions need to be interpolated so\nthey correspond with the image timestamps.", "title": "fast_autofocus_output", "type": "object", "properties": {"jpeg_times": {"description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.", "title": "NestedListOfNumbersModel", "oneOf": [{"type": "integer"}, {"type": "number"}, {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}, {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {}}}}}}}}]}, "jpeg_sizes": {"description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.", "title": "NestedListOfNumbersModel", "oneOf": [{"type": "integer"}, {"type": "number"}, {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}, {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {}}}}}}}}]}, "stage_times": {"description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.", "title": "NestedListOfNumbersModel", "oneOf": [{"type": "integer"}, {"type": "number"}, {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}, {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {}}}}}}}}]}, "stage_positions": {"title": "Stage Positions", "type": "array", "items": {"type": "object"}}}, "required": ["jpeg_times", "jpeg_sizes", "stage_times", "stage_positions"]}}, "looping_autofocus": {"description": "This action will run the ``fast_autofocus`` action until it settles on a point\nin the middle 3/5 of its range. Such logic can be helpful if the microscope\nis close to focus, but not quite within ``dz/2``. It will attempt to autofocus\nup to 10 times.", "title": "Repeatedly autofocus the stage until it looks focused.", "forms": [{"href": "/autofocus/looping_autofocus", "op": ["invokeaction"]}], "input": {"title": "looping_autofocus_input", "type": "object", "properties": {"dz": {"title": "Dz", "default": 2000}, "start": {"title": "Start", "default": "centre"}}}, "output": {"title": "looping_autofocus_output"}}, "run_smart_stack": {"description": "A smart stack captures images offset in z, testing whether the sharpest image\nis towards the centre of the stack.\n\nThe sharpest image, and optionally images around the sharpest, will be saved\nto the images_dir with their coordinates in the filename.\n\n\n:param cam: Camera Dependency supplied by LabThings dependency injection\n:param stage: Stage Dependency supplied by LabThings dependency injection\n:param sharpness_monitor: Sharpness Monitor Dependency (for focus detection)\n    supplied by LabThings dependency injection\n:param images_dir: the folder to save all images\n:param autofocus_dz: the range to autofocus over if a stack fails\n:param save_resolution: The resolution the images should be saved at, the\n    images will be resampled if this doesn't match the camera's capture\n    resolution\n\n:returns: A tuple containing:\n\n    * A boolean, True if stack was successfully\n    * The z position of the sharpest image", "title": "Run a smart stack.", "forms": [{"href": "/autofocus/run_smart_stack", "op": ["invokeaction"]}], "input": {"title": "run_smart_stack_input", "type": "object", "properties": {"images_dir": {"title": "Images Dir", "type": "string"}, "autofocus_dz": {"title": "Autofocus Dz", "type": "integer"}, "save_resolution": {"title": "Save Resolution", "type": "array", "items": [{"type": "integer"}, {"type": "integer"}], "maxItems": 2, "minItems": 2}}, "required": ["images_dir", "autofocus_dz", "save_resolution"]}, "output": {"title": "run_smart_stack_output", "type": "array", "items": [{"type": "boolean"}, {"type": "integer"}], "maxItems": 2, "minItems": 2}}, "z_move_and_measure_sharpness": {"description": "This method will will make a series of relative moves in z, and\nreturn the sharpness (JPEG size) vs time, along with timestamps\nfor the moves. This can be used to calibrate autofocus.\n\nEach move is relative to the last one, i.e. we will finish at\n``sum(dz)`` relative to the starting position.\n\nIf ``wait`` is specified, we will wait for that many seconds\nbetween moves.", "title": "Make a move (or a series of moves) and monitor sharpness.", "forms": [{"href": "/autofocus/z_move_and_measure_sharpness", "op": ["invokeaction"]}], "input": {"title": "z_move_and_measure_sharpness_input", "type": "object", "properties": {"dz": {"title": "Dz", "type": "array", "items": {"type": "integer"}}, "wait": {"title": "Wait", "default": 0, "type": "number"}}, "required": ["dz"]}, "output": {"description": "A BaseModel with the position and sharpness data from JPEGSharpnessMonitor.\n\nEach JPEG Size (representing a sharpness metric) has an associated timestamp,\nas does each stage position. The stage positions need to be interpolated so\nthey correspond with the image timestamps.", "title": "z_move_and_measure_sharpness_output", "type": "object", "properties": {"jpeg_times": {"description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.", "title": "NestedListOfNumbersModel", "oneOf": [{"type": "integer"}, {"type": "number"}, {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}, {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {}}}}}}}}]}, "jpeg_sizes": {"description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.", "title": "NestedListOfNumbersModel", "oneOf": [{"type": "integer"}, {"type": "number"}, {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}, {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {}}}}}}}}]}, "stage_times": {"description": "A RootModel describing a list-of-lists up to 7 deep.\n\nThis is used to generate a JSONSchema description of a `numpy.ndarray`\nserialised to a list. It is used in the annotated `.NDArray` type.", "title": "NestedListOfNumbersModel", "oneOf": [{"type": "integer"}, {"type": "number"}, {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}, {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "number"}]}}}}}}}, {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {"type": "array", "items": {}}}}}}}}]}, "stage_positions": {"title": "Stage Positions", "type": "array", "items": {"type": "object"}}}, "required": ["jpeg_times", "jpeg_sizes", "stage_times", "stage_positions"]}}}, "base": "http://testserver/", "securityDefinitions": {"no_security": {"description": "No security", "scheme": "nosec"}}, "security": "no_security", "@context": "https://www.w3.org/2022/wot/td/v1.1"}