Skip to content

Commit 509b9f3

Browse files
Moved all remaining beamline routes to BeamlineAdapter
1 parent b072c83 commit 509b9f3

File tree

9 files changed

+91
-154
lines changed

9 files changed

+91
-154
lines changed

mxcubeweb/core/adapter/adapter_manager.py

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from mxcubecore.utils.conversion import make_table
99

1010
from mxcubeweb.core.adapter.adapter_base import AdapterBase
11-
from mxcubeweb.core.adapter.beamline_adapter import BeamlineAdapter
1211

1312

1413
class HardwareObjectAdapterManager:
@@ -44,7 +43,6 @@ def init(self) -> None:
4443
done when one wishes.
4544
"""
4645
try:
47-
self.beamline = BeamlineAdapter(HWR.beamline, self.app)
4846
self.adapt_hardware_objects()
4947
except Exception: # noqa: BLE001
5048
msg = (
@@ -124,32 +122,44 @@ def find_best_adapter(self, ho):
124122
logging.getLogger("MX3.HWR").error(msg)
125123
raise RuntimeError(msg)
126124

125+
def adapt_hardware_object(self, ho, _id):
126+
adapter_cls = self.find_best_adapter(ho)
127+
128+
if adapter_cls:
129+
try:
130+
adapter_instance = adapter_cls(ho, _id, self.app)
131+
msg = f"Added adapter for {_id}"
132+
logging.getLogger("MX3.HWR").info(msg)
133+
except Exception:
134+
msg = f"Could not add adapter for {_id}"
135+
logging.getLogger("MX3.HWR").exception(msg)
136+
adapter_cls = AdapterBase
137+
adapter_instance = AdapterBase(ho, _id, self.app)
138+
139+
self._add_adapter(_id, adapter_cls, ho, adapter_instance)
140+
else:
141+
msg = f"No adapter for {_id}"
142+
logging.getLogger("MX3.HWR").info(msg)
143+
127144
def adapt_hardware_objects(self):
128145
_hwr = HWR.get_hardware_repository()
129146

147+
# Beamline is not added to the list of hardware objects
148+
# returned by _hwr.hardware_objects as its considered a
149+
# special object root object for all other hardware objects
150+
# so we add it manually here. We give it the id 'beamline'
151+
# so that it can be retrieved by the adapter manager but
152+
# in reality has no id.
153+
self.adapt_hardware_object(HWR.beamline, "beamline")
154+
130155
for ho_name in _hwr.hardware_objects:
131156
ho = _hwr.get_hardware_object(ho_name)
132157
if not ho:
133158
continue
134159

135-
_id = ho.id
136-
adapter_cls = self.find_best_adapter(ho)
137-
138-
if adapter_cls:
139-
try:
140-
adapter_instance = adapter_cls(ho, _id, self.app)
141-
msg = f"Added adapter for {_id}"
142-
logging.getLogger("MX3.HWR").info(msg)
143-
except Exception:
144-
msg = f"Could not add adapter for {_id}"
145-
logging.getLogger("MX3.HWR").exception(msg)
146-
adapter_cls = AdapterBase
147-
adapter_instance = AdapterBase(ho, _id, self.app)
148-
149-
self._add_adapter(_id, adapter_cls, ho, adapter_instance)
150-
else:
151-
msg = f"No adapter for {_id}"
152-
logging.getLogger("MX3.HWR").info(msg)
160+
_id = ho.id or "beamline"
161+
162+
self.adapt_hardware_object(ho, _id)
153163

154164
self._print_adapter_table()
155165

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,72 @@
11
import logging
2+
from typing import ClassVar
23

34
import pydantic
5+
from mxcubecore import HardwareRepository as HWR
6+
from mxcubecore.HardwareObjects.Beamline import Beamline
47

5-
BEAMLINE_ADAPTER = None
8+
from mxcubeweb.core.adapter.adapter_base import ActuatorAdapterBase
9+
from mxcubeweb.core.models.configmodels import ResourceHandlerConfigModel
610

7-
# Singleton like interface is needed to keep the same reference to the
8-
# adapter object and its corresponding hardware objects, so that the signal
9-
# system won't clean up signal handlers. (PyDispatcher removes signal handlers
10-
# when an object is garbage collected)
11+
resource_handler_config = ResourceHandlerConfigModel(
12+
commands=["prepare_beamline_for_sample"],
13+
attributes=["data", "get_value"],
14+
)
1115

1216

13-
def BeamlineAdapter(*args):
14-
global BEAMLINE_ADAPTER
15-
16-
if BEAMLINE_ADAPTER is None:
17-
BEAMLINE_ADAPTER = _BeamlineAdapter(*args)
18-
19-
return BEAMLINE_ADAPTER
20-
21-
22-
class _BeamlineAdapter:
17+
class BeamlineAdapter(ActuatorAdapterBase):
2318
"""
2419
Adapter between Beamline route and Beamline hardware object.
2520
"""
2621

27-
def __init__(self, beamline_hwobj, app):
22+
SUPPORTED_TYPES: ClassVar[list[object]] = [Beamline]
23+
24+
def __init__(self, ho, role, app):
25+
super().__init__(ho, role, app, resource_handler_config)
2826
self.app = app
29-
self._bl = beamline_hwobj
3027
self.adapter_dict = {}
3128

32-
workflow = self._bl.workflow
29+
workflow = self._ho.workflow
3330
if workflow:
34-
workflow.connect("parametersNeeded", self.wf_parameters_needed)
31+
workflow.connect("parametersNeeded", self._wf_parameters_needed)
3532

36-
gphl_workflow = self._bl.gphl_workflow
33+
gphl_workflow = self._ho.gphl_workflow
3734
if gphl_workflow:
3835
gphl_workflow.connect(
39-
"GphlJsonParametersNeeded", self.gphl_json_wf_parameters_needed
36+
"GphlJsonParametersNeeded", self._gphl_json_wf_parameters_needed
4037
)
4138
gphl_workflow.connect(
42-
"GphlUpdateUiParameters", self.gphl_json_wf_update_ui_parameters
39+
"GphlUpdateUiParameters", self._gphl_json_wf_update_ui_parameters
4340
)
4441

45-
def wf_parameters_needed(self, params):
42+
from mxcubeweb.routes import signals
43+
44+
if HWR.beamline.xrf_spectrum:
45+
HWR.beamline.xrf_spectrum.connect(
46+
HWR.beamline.xrf_spectrum,
47+
"xrf_task_progress",
48+
signals.xrf_task_progress,
49+
)
50+
51+
def _wf_parameters_needed(self, params):
4652
self.app.server.emit("workflowParametersDialog", params, namespace="/hwr")
4753

48-
def gphl_json_wf_parameters_needed(self, schema, ui_schema):
54+
def _gphl_json_wf_parameters_needed(self, schema, ui_schema):
4955
params = {}
5056
params["schema"] = schema
5157
params["ui_schema"] = ui_schema
5258
self.app.server.emit("gphlWorkflowParametersDialog", params, namespace="/hwr")
5359

54-
def gphl_json_wf_update_ui_parameters(self, update_dict):
60+
def _gphl_json_wf_update_ui_parameters(self, update_dict):
5561
self.app.server.emit(
5662
"gphlWorkflowUpdateUiParametersDialog", update_dict, namespace="/hwr"
5763
)
5864

59-
def get_object(self, name):
60-
return self._ho.get_hardware_object(name)
65+
def _get_available_elements(self):
66+
escan = self._ho.energy_scan
67+
return escan.get_elements() if escan else []
6168

62-
def dict(self):
69+
def get_value(self) -> dict:
6370
"""
6471
Build dictionary value-representation for each beamline attribute
6572
Returns:
@@ -68,6 +75,10 @@ def dict(self):
6875
attributes = {}
6976

7077
for attr_name in self.app.mxcubecore.adapter_dict:
78+
# We skip the beamline attribute to avoid endless recursion
79+
if attr_name == "beamline":
80+
continue
81+
7182
try:
7283
_d = self.app.mxcubecore.get_adapter(attr_name).data().dict()
7384
except pydantic.ValidationError:
@@ -76,13 +87,15 @@ def dict(self):
7687

7788
attributes.update({attr_name: _d})
7889

79-
return {"hardwareObjects": attributes}
80-
81-
def get_available_elements(self):
82-
escan = self._bl.energy_scan
83-
elements = []
90+
return {
91+
"energyScanElements": self._get_available_elements(),
92+
"path": HWR.beamline.session.get_base_image_directory(),
93+
"actionsList": [],
94+
"hardwareObjects": attributes,
95+
}
8496

85-
if escan:
86-
elements = escan.get_elements()
97+
def prepare_beamline_for_sample(self) -> dict:
98+
if hasattr(HWR.beamline.collect, "prepare_for_new_sample"):
99+
HWR.beamline.collect.prepare_for_new_sample()
87100

88-
return {"elements": elements}
101+
return {}

mxcubeweb/core/components/beamline.py

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from mxcubecore import HardwareRepository as HWR
22

3-
from mxcubeweb.core.adapter.beamline_adapter import BeamlineAdapter
43
from mxcubeweb.core.components.component_base import ComponentBase
54

65

@@ -9,28 +8,7 @@ def __init__(self, app, config):
98
super().__init__(app, config)
109

1110
def init_signals(self):
12-
from mxcubeweb.routes import signals
13-
14-
if HWR.beamline.xrf_spectrum:
15-
HWR.beamline.xrf_spectrum.connect(
16-
HWR.beamline.xrf_spectrum,
17-
"xrf_task_progress",
18-
signals.xrf_task_progress,
19-
)
20-
21-
def get_aperture(self):
22-
"""
23-
Returns list of apertures and the one currently used.
24-
25-
:return: Tuple, (list of apertures, current aperture)
26-
:rtype: tuple
27-
"""
28-
beam = HWR.beamline.beam
29-
30-
aperture_list = beam.get_available_size()["values"]
31-
current_aperture = beam.get_value()[-1]
32-
33-
return aperture_list, current_aperture
11+
pass
3412

3513
def get_viewport_info(self):
3614
"""
@@ -76,25 +54,3 @@ def get_viewport_info(self):
7654
"videoHash": HWR.beamline.sample_view.camera.stream_hash,
7755
"videoURL": self.app.CONFIG.app.VIDEO_STREAM_URL,
7856
}
79-
80-
def beamline_get_all_attributes(self):
81-
ho = BeamlineAdapter(HWR.beamline)
82-
data = ho.dict()
83-
actions = []
84-
85-
data.update(
86-
{
87-
"path": HWR.beamline.session.get_base_image_directory(),
88-
"actionsList": actions,
89-
}
90-
)
91-
92-
data.update(
93-
{"energyScanElements": ho.get_available_elements().get("elements", [])}
94-
)
95-
96-
return data
97-
98-
def prepare_beamline_for_sample(self):
99-
if hasattr(HWR.beamline.collect, "prepare_for_new_sample"):
100-
HWR.beamline.collect.prepare_for_new_sample()

mxcubeweb/routes/beamline.py

Lines changed: 0 additions & 33 deletions
This file was deleted.

mxcubeweb/server.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ def register_routes(mxcube):
117117
Server.flask, Server.user_datastore, register_blueprint=False
118118
)
119119

120-
from mxcubeweb.routes.beamline import init_route as init_beamline_route
121120
from mxcubeweb.routes.csp_report import init_route as init_csp_route
122121
from mxcubeweb.routes.harvester import init_route as init_harvester_route
123122
from mxcubeweb.routes.lims import init_route as init_lims_route
@@ -133,9 +132,6 @@ def register_routes(mxcube):
133132

134133
url_root_prefix = "/mxcube/api/v0.1"
135134

136-
Server._register_route(
137-
init_beamline_route, mxcube, f"{url_root_prefix}/beamline"
138-
)
139135
Server._register_route(init_csp_route, mxcube, f"{url_root_prefix}/csp")
140136

141137
Server._register_route(init_lims_route, mxcube, f"{url_root_prefix}/lims")

test/test_beamline_routes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ def test_beamline_get_all_attribute(client):
66
Checks that the data returned has the right structure and if "all"
77
beamline attributes are at least present
88
"""
9-
resp = client.get("/mxcube/api/v0.1/beamline/")
9+
resp = client.get(
10+
"/mxcube/api/v0.1/hwobj/beamline/beamline/get_value",
11+
)
1012
data = json.loads(resp.data)
1113

1214
actual = list(data.get("hardwareObjects").keys())

ui/src/actions/beamline.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { sendPrepareBeamlineForNewSample } from '../api/beamline';
21
import { sendExecuteCommand, sendSetValue } from '../api/hardware-object';
32
import { sendLogFrontEndTraceBack } from '../api/log';
43

@@ -51,7 +50,13 @@ export function executeCommand(object_type, object_id, name, args) {
5150
}
5251

5352
export function prepareBeamlineForNewSample() {
54-
return () => sendPrepareBeamlineForNewSample();
53+
return () =>
54+
sendExecuteCommand(
55+
'beamline',
56+
'beamline',
57+
'prepare_beamline_for_sample',
58+
{},
59+
);
5560
}
5661

5762
export function logFrontEndTraceBack(stack) {

ui/src/actions/login.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable promise/prefer-await-to-then */
2-
import { fetchBeamlineSetup } from '../api/beamline';
32
import { fetchValue } from '../api/hardware-object';
43
import { fetchHarvesterInitialState } from '../api/harvester';
54
import { sendSelectProposal } from '../api/lims';
@@ -96,7 +95,7 @@ export function getInitialState() {
9695
fetchValue('beam', 'beam')
9796
.then((beamInfo) => ({ beamInfo: beamInfo.value }))
9897
.catch(notify),
99-
fetchBeamlineSetup()
98+
fetchValue('beamline', 'beamline')
10099
.then((beamlineSetup) => ({
101100
beamlineSetup,
102101
datapath: beamlineSetup.path,

ui/src/api/beamline.js

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)