Merge branch 'change-stage-geometry' into 'master'

Change stage geometry

See merge request openflexure/openflexure-microscope-server!73
This commit is contained in:
Joel Collins 2020-10-13 14:00:51 +00:00
commit 0234b20ce3
7 changed files with 197 additions and 19 deletions

View file

@ -129,6 +129,9 @@ labthing.add_view(
)
labthing.add_root_link(views.ConfigurationProperty, "instrumentConfiguration")
# Attach stage resources
labthing.add_view(views.StageTypeProperty, "/instrument/stage/type")
# Attach streams resources
labthing.add_view(views.MjpegStream, f"/streams/mjpeg")

View file

@ -0,0 +1,88 @@
<template>
<div id="stageSettings">
<div>
<h3>Stage settings</h3>
<p>
<label>
Stage Type
<div v-if="this.stageType != 'MissingStage'">
<form @submit.prevent="setStageType">
<div>
<select v-model="stageType" class="uk-select">
<option value="SangaStage">SangaStage (Standard)</option>
<option value= "SangaDeltaStage"> SangaStage (Delta)</option>
</select>
</div>
<div>
<button type="submit" class="uk-button uk-button-primary uk-form-small uk-float-right uk-margin-small uk-width-1-1">
Change stage type
</button>
</div>
</form>
</div>
<div v-else class="uk-text-danger"><b>No stage connected</b></div>
</label>
</p>
</div>
</div>
</template>
<script>
import axios from "axios";
import taskSubmitter from "../../genericComponents/taskSubmitter";
export default {
name: "StageSettings",
components:{
taskSubmitter
},
data: function(){
return {
stageType: "MissingStage",
}
},
computed: {
stageTypeUri: function() {
return `${this.$store.getters.baseUri}/api/v2/properties/stage/type`;
},
},
mounted(){
this.getStageType();
},
methods: {
getStageType: function(){
console.log("Getting stage type")
axios
.get(this.stageTypeUri)
.then(response => {
console.log("Stage type is "+ response.data);
this.stageType = response.data;
})
.catch(error => {
this.modalError(error);
});
},
setStageType: function(){
console.log("Setting stage type")
axios
.put(this.stageTypeUri,this.stageType)
.then(response => {
this.stageType = response.data;
console.log("Stage type set to " + this.stageType);
this.modalNotify("Stage type changed.");
})
.catch(error => {
this.modalError(error);
});
}
}
}
</script>
<style lang="less"></style>

View file

@ -44,6 +44,19 @@
Camera
</tabIcon>
</li>
<li>
<tabIcon
id="settings-stage-icon"
tab-i-d="stage"
:show-title="false"
:show-tooltip="false"
:require-connection="true"
:current-tab="currentTab"
@set-tab="setTab"
>
Stage
</tabIcon>
</li>
<li>
<tabIcon
id="settings-mapping-icon"
@ -104,6 +117,16 @@
</div>
</tabContent>
<tabContent
tab-i-d="stage"
:require-connection="true"
:current-tab="currentTab"
>
<div class="settings-pane uk-padding-small">
<stageSettings />
</div>
</tabContent>
<tabContent
tab-i-d="mapping"
:require-connection="true"
@ -141,7 +164,7 @@ import cameraSettings from "./settingsComponents/cameraSettings.vue";
import appSettings from "./settingsComponents/appSettings.vue";
import featuresSettings from "./settingsComponents/featuresSettings.vue";
import cameraStageMappingSettings from "./settingsComponents/cameraStageMappingSettings.vue";
import stageSettings from "./settingsComponents/stageSettings.vue";
// Import generic components
import tabIcon from "../genericComponents/tabIcon";
import tabContent from "../genericComponents/tabContent";
@ -153,6 +176,7 @@ export default {
components: {
streamSettings,
cameraSettings,
stageSettings,
microscopeSettings,
cameraStageMappingSettings,
appSettings,

View file

@ -2,3 +2,4 @@ from .actions import enabled_root_actions
from .captures import *
from .instrument import *
from .streams import *
from .stage import *

View file

@ -65,3 +65,5 @@ class ZeroStageAPI(ActionView):
# TODO: Make schema for microscope state
return microscope.state["stage"]

View file

@ -0,0 +1,30 @@
from labthings import find_component, fields, schema
from labthings.views import PropertyView
import logging
class StageTypeProperty(PropertyView):
"""The type of the stage"""
schema = fields.String(
missing=None,
example="SangaStage",
OneOf=["SangaStage", "SangaDeltaStage"],
description="The translation stage geometry",
)
def get(self):
"""
Get the stage geometry.
"""
microscope = find_component("org.openflexure.microscope")
return microscope.configuration["stage"]["type"]
def put(self, stage_type):
"""
Set the stage geometry.
"""
microscope = find_component("org.openflexure.microscope")
microscope.set_stage(stage_type=stage_type)
return microscope.configuration["stage"]["type"]

View file

@ -105,24 +105,8 @@ class Microscope:
logging.warning("No compatible camera hardware found.")
### Stage
logging.info("Creating stage")
if configuration.get("stage"):
stage_type = configuration["stage"].get("type")
stage_port = configuration["stage"].get("port")
if stage_type in ("SangaBoard", "SangaStage"):
try:
logging.info("Trying SangaStage")
self.stage = SangaStage(port=stage_port)
except Exception as e:
logging.error(e)
logging.warning("No compatible Sangaboard hardware found.")
elif stage_type in ("SangaDeltaStage"):
try:
logging.info("Trying SangaDeltaStage")
self.stage = SangaDeltaStage(port=stage_port)
except Exception as e:
logging.error(e)
logging.warning("No compatible Sangaboard hardware found.")
self.set_stage(configuration=configuration)
logging.info("Handling fallbacks")
### Fallbacks
@ -138,6 +122,51 @@ class Microscope:
if hasattr(self.stage, "lock"):
self.lock.locks.append(self.stage.lock)
def set_stage(self, configuration=None, stage_type=None):
"""
Set or change the stage geometry
"""
if not configuration:
configuration = self.configuration
if stage_type:
if stage_type == configuration["stage"].get("type"):
logging.info("Stage already set to that stage type")
return
else:
stage_type = configuration["stage"].get("type")
### Close any existing stages
if self.stage:
stage_port = self.stage.port
self.stage.close()
logging.info("Setting stage")
stage_port = configuration["stage"].get("port")
if stage_type in ("SangaBoard", "SangaStage"):
try:
logging.info("Trying SangaStage")
self.stage = SangaStage(port=stage_port)
except Exception as e:
logging.error(e)
logging.warning("No compatible Sangaboard hardware found.")
elif stage_type in ("SangaDeltaStage"):
try:
logging.info("Trying SangaDeltaStage")
self.stage = SangaDeltaStage(port=stage_port)
except Exception as e:
logging.error(e)
logging.warning("No compatible Sangaboard hardware found.")
else:
logging.warning("The stage type is incorrectly defined.")
logging.info("Saving new stage type configuration")
configuration["stage"]["type"] = stage_type
self.configuration_file.save(configuration)
def has_real_stage(self) -> bool:
"""
Check if a real (non-mock) stage is currently attached.
@ -363,6 +392,7 @@ class Microscope:
# Capture to output object
logging.info(f"Starting microscope capture {output.file}")
print(output)
self.camera.capture(
output,
use_video_port=use_video_port,