dls-dodal 1.68.0__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/METADATA +1 -31
- dls_dodal-2.0.0.dist-info/RECORD +354 -0
- {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/WHEEL +1 -1
- dodal/_version.py +2 -2
- dodal/beamlines/__init__.py +10 -17
- dodal/beamlines/adsim.py +40 -33
- dodal/beamlines/b01_1.py +11 -0
- dodal/beamlines/b07.py +17 -21
- dodal/beamlines/b07_1.py +20 -22
- dodal/beamlines/b07_shared.py +12 -0
- dodal/beamlines/b16.py +1 -1
- dodal/beamlines/b21.py +15 -6
- dodal/beamlines/i02_1.py +17 -45
- dodal/beamlines/i02_2.py +6 -12
- dodal/beamlines/i03.py +8 -5
- dodal/beamlines/i03_supervisor.py +19 -0
- dodal/beamlines/i04.py +87 -184
- dodal/beamlines/i05.py +9 -39
- dodal/beamlines/i05_1.py +4 -13
- dodal/beamlines/i05_shared.py +51 -0
- dodal/beamlines/i06_1.py +26 -0
- dodal/beamlines/{i06.py → i06_shared.py} +25 -14
- dodal/beamlines/i07.py +14 -16
- dodal/beamlines/i09.py +76 -29
- dodal/beamlines/i09_1.py +25 -56
- dodal/beamlines/i09_1_shared.py +61 -0
- dodal/beamlines/i09_2.py +6 -100
- dodal/beamlines/i09_2_shared.py +110 -0
- dodal/beamlines/i10.py +60 -54
- dodal/beamlines/i10_1.py +99 -10
- dodal/beamlines/{i10_optics.py → i10_shared.py} +80 -66
- dodal/beamlines/i11.py +31 -18
- dodal/beamlines/i13_1.py +1 -1
- dodal/beamlines/i15.py +6 -6
- dodal/beamlines/i15_1.py +6 -6
- dodal/beamlines/i16.py +11 -0
- dodal/beamlines/i17.py +37 -28
- dodal/beamlines/i18.py +3 -4
- dodal/beamlines/i19_1.py +95 -34
- dodal/beamlines/i19_2.py +68 -52
- dodal/beamlines/i19_optics.py +26 -13
- dodal/beamlines/i20_1.py +17 -11
- dodal/beamlines/i21.py +44 -29
- dodal/beamlines/i22.py +19 -4
- dodal/beamlines/i23.py +20 -27
- dodal/beamlines/i24.py +64 -113
- dodal/beamlines/k07.py +99 -5
- dodal/beamlines/p38.py +3 -3
- dodal/beamlines/p60.py +35 -14
- dodal/beamlines/p99.py +16 -15
- dodal/beamlines/training_rig.py +20 -12
- dodal/cli.py +36 -2
- dodal/common/__init__.py +2 -1
- dodal/common/beamlines/beamline_parameters.py +2 -1
- dodal/common/beamlines/beamline_utils.py +11 -9
- dodal/common/beamlines/commissioning_mode.py +6 -3
- dodal/common/coordination.py +12 -14
- dodal/common/crystal_metadata.py +5 -8
- dodal/common/device_utils.py +4 -3
- dodal/common/maths.py +87 -19
- dodal/common/udc_directory_provider.py +13 -8
- dodal/common/visit.py +18 -21
- dodal/common/watcher_utils.py +13 -12
- dodal/device_manager.py +94 -54
- dodal/devices/aperturescatterguard.py +26 -27
- dodal/devices/areadetector/plugins/cam.py +1 -3
- dodal/devices/areadetector/plugins/mjpg.py +6 -5
- dodal/devices/attenuator/attenuator.py +12 -11
- dodal/devices/beamlines/b07/__init__.py +3 -0
- dodal/devices/{b07_1 → beamlines/b07_1}/__init__.py +2 -2
- dodal/devices/{b07_1 → beamlines/b07_1}/ccmc.py +5 -10
- dodal/devices/{b16 → beamlines/b16}/detector.py +2 -3
- dodal/devices/{i02_1 → beamlines/i02_1}/fast_grid_scan.py +2 -3
- dodal/devices/{i02_1 → beamlines/i02_1}/sample_motors.py +1 -1
- dodal/devices/{i03 → beamlines/i03}/beamsize.py +11 -7
- dodal/devices/{i03 → beamlines/i03}/dcm.py +1 -2
- dodal/devices/{i03 → beamlines/i03}/undulator_dcm.py +4 -5
- dodal/devices/beamlines/i04/beam_centre.py +151 -0
- dodal/devices/{i04 → beamlines/i04}/beamsize.py +11 -7
- dodal/devices/beamlines/i04/max_pixel.py +25 -0
- dodal/devices/{i04 → beamlines/i04}/murko_results.py +23 -8
- dodal/devices/{i04 → beamlines/i04}/transfocator.py +10 -15
- dodal/devices/beamlines/i05/__init__.py +3 -0
- dodal/devices/beamlines/i06_shared/__init__.py +3 -0
- dodal/devices/beamlines/i06_shared/i06_enum.py +7 -0
- dodal/devices/{i07 → beamlines/i07}/dcm.py +2 -3
- dodal/devices/{i07 → beamlines/i07}/id.py +8 -9
- dodal/devices/beamlines/i09/__init__.py +3 -0
- dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/hard_energy.py +5 -6
- dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/hard_undulator_functions.py +19 -16
- dodal/devices/{i10 → beamlines/i10}/diagnostics.py +4 -3
- dodal/devices/{i10 → beamlines/i10}/i10_apple2.py +37 -51
- dodal/devices/{i10 → beamlines/i10}/rasor/rasor_current_amp.py +1 -24
- dodal/devices/{i10 → beamlines/i10}/rasor/rasor_motors.py +2 -2
- dodal/devices/{i10 → beamlines/i10}/slits.py +5 -3
- dodal/devices/beamlines/i10_1/__init__.py +9 -0
- dodal/devices/beamlines/i10_1/electromagnet/magnet.py +16 -0
- dodal/devices/beamlines/i10_1/electromagnet/stages.py +14 -0
- dodal/devices/beamlines/i10_1/scaler_cards.py +13 -0
- dodal/devices/{i11 → beamlines/i11}/cyberstar_blower.py +1 -1
- dodal/devices/{i11 → beamlines/i11}/diff_stages.py +4 -6
- dodal/devices/{i11 → beamlines/i11}/mythen.py +3 -4
- dodal/devices/{i11 → beamlines/i11}/nx100robot.py +6 -6
- dodal/devices/{i11 → beamlines/i11}/spinner.py +1 -1
- dodal/devices/{i13_1 → beamlines/i13_1}/merlin.py +1 -1
- dodal/devices/{i15 → beamlines/i15}/dcm.py +1 -2
- dodal/devices/{i15 → beamlines/i15}/focussing_mirror.py +5 -5
- dodal/devices/{i15 → beamlines/i15}/jack.py +2 -2
- dodal/devices/{i15 → beamlines/i15}/multilayer_mirror.py +1 -1
- dodal/devices/{i17 → beamlines/i17}/i17_apple2.py +16 -22
- dodal/devices/{i18 → beamlines/i18}/diode.py +1 -1
- dodal/devices/{i19 → beamlines/i19}/access_controlled/attenuator_motor_squad.py +12 -8
- dodal/devices/{i19 → beamlines/i19}/access_controlled/blueapi_device.py +16 -15
- dodal/devices/beamlines/i19/access_controlled/piezo_control.py +72 -0
- dodal/devices/{i19 → beamlines/i19}/access_controlled/shutter.py +11 -9
- dodal/devices/{i19 → beamlines/i19}/backlight.py +3 -1
- dodal/devices/{i19 → beamlines/i19}/mapt_configuration.py +2 -1
- dodal/devices/{i19 → beamlines/i19}/pin_col_stages.py +11 -8
- dodal/devices/beamlines/i19/pin_tip.py +32 -0
- dodal/devices/beamlines/i21/__init__.py +3 -0
- dodal/devices/{i22 → beamlines/i22}/dcm.py +1 -2
- dodal/devices/{i22 → beamlines/i22}/fswitch.py +1 -3
- dodal/devices/{i22 → beamlines/i22}/nxsas.py +5 -4
- dodal/devices/{i24 → beamlines/i24}/beam_center.py +1 -1
- dodal/devices/{i24 → beamlines/i24}/beamstop.py +2 -2
- dodal/devices/{i24 → beamlines/i24}/commissioning_jungfrau.py +12 -12
- dodal/devices/{i24 → beamlines/i24}/dcm.py +1 -3
- dodal/devices/{i24 → beamlines/i24}/dual_backlight.py +3 -3
- dodal/devices/{i24 → beamlines/i24}/pmac.py +9 -7
- dodal/devices/{p60 → beamlines/p60}/lab_xray_source.py +1 -1
- dodal/devices/beamlines/p99/__init__.py +0 -0
- dodal/devices/{p99 → beamlines/p99}/andor2_point.py +11 -15
- dodal/devices/bimorph_mirror.py +22 -20
- dodal/devices/collimation_table.py +3 -2
- dodal/devices/common_dcm.py +30 -20
- dodal/devices/controllers.py +2 -2
- dodal/devices/cryostream.py +8 -0
- dodal/devices/current_amplifiers/current_amplifier.py +16 -18
- dodal/devices/current_amplifiers/current_amplifier_detector.py +9 -10
- dodal/devices/current_amplifiers/femto.py +8 -9
- dodal/devices/current_amplifiers/sr570.py +16 -16
- dodal/devices/current_amplifiers/struck_scaler_counter.py +5 -5
- dodal/devices/detector/det_resolution.py +9 -8
- dodal/devices/detector/detector.py +4 -2
- dodal/devices/diamond_filter.py +3 -4
- dodal/devices/eiger.py +32 -17
- dodal/devices/eiger_odin.py +1 -1
- dodal/devices/electron_analyser/base/__init__.py +3 -3
- dodal/devices/electron_analyser/base/base_controller.py +32 -21
- dodal/devices/electron_analyser/base/base_detector.py +15 -20
- dodal/devices/electron_analyser/base/base_driver_io.py +39 -46
- dodal/devices/electron_analyser/base/base_enums.py +0 -5
- dodal/devices/electron_analyser/base/base_region.py +29 -31
- dodal/devices/electron_analyser/base/base_util.py +18 -16
- dodal/devices/electron_analyser/base/energy_sources.py +35 -40
- dodal/devices/electron_analyser/specs/specs_detector.py +7 -6
- dodal/devices/electron_analyser/vgscienta/vgscienta_detector.py +7 -6
- dodal/devices/eurotherm.py +3 -2
- dodal/devices/fast_grid_scan.py +31 -34
- dodal/devices/fast_shutter.py +125 -39
- dodal/devices/flux.py +1 -1
- dodal/devices/focusing_mirror.py +29 -11
- dodal/devices/hutch_shutter.py +6 -6
- dodal/devices/insertion_device/__init__.py +20 -8
- dodal/devices/insertion_device/apple2_controller.py +371 -0
- dodal/devices/insertion_device/apple2_undulator.py +184 -587
- dodal/devices/insertion_device/apple_knot_controller.py +222 -0
- dodal/devices/insertion_device/energy.py +161 -0
- dodal/devices/insertion_device/energy_motor_lookup.py +21 -28
- dodal/devices/insertion_device/lookup_table_models.py +47 -52
- dodal/devices/insertion_device/polarisation.py +36 -0
- dodal/devices/ipin.py +1 -1
- dodal/devices/linkam3.py +7 -5
- dodal/devices/motors.py +107 -19
- dodal/devices/mx_phase1/beamstop.py +2 -4
- dodal/devices/oav/oav_calculations.py +20 -13
- dodal/devices/oav/oav_detector.py +92 -22
- dodal/devices/oav/oav_parameters.py +4 -9
- dodal/devices/oav/oav_to_redis_forwarder.py +22 -18
- dodal/devices/oav/pin_image_recognition/__init__.py +4 -6
- dodal/devices/oav/pin_image_recognition/manual_test.py +1 -2
- dodal/devices/oav/pin_image_recognition/utils.py +30 -32
- dodal/devices/oav/snapshots/grid_overlay.py +10 -9
- dodal/devices/oav/snapshots/snapshot_image_processing.py +15 -13
- dodal/devices/oav/utils.py +20 -6
- dodal/devices/p45.py +3 -9
- dodal/devices/pgm.py +8 -14
- dodal/devices/pressure_jump_cell.py +93 -32
- dodal/devices/qbpm.py +1 -3
- dodal/devices/robot.py +45 -20
- dodal/devices/s4_slit_gaps.py +1 -1
- dodal/devices/selectable_source.py +41 -0
- dodal/devices/slits.py +2 -5
- dodal/devices/smargon.py +2 -3
- dodal/devices/temperture_controller/lakeshore/lakeshore.py +38 -64
- dodal/devices/temperture_controller/lakeshore/lakeshore_io.py +21 -35
- dodal/devices/tetramm.py +7 -7
- dodal/devices/turbo_slit.py +8 -7
- dodal/devices/undulator.py +42 -56
- dodal/devices/util/adjuster_plans.py +2 -3
- dodal/devices/util/epics_util.py +10 -10
- dodal/devices/util/lookup_tables.py +17 -18
- dodal/devices/v2f.py +2 -3
- dodal/devices/watsonmarlow323_pump.py +1 -1
- dodal/devices/xbpm_feedback.py +3 -2
- dodal/devices/xspress3/xspress3.py +8 -11
- dodal/devices/xspress3/xspress3_channel.py +3 -6
- dodal/devices/zebra/zebra.py +21 -7
- dodal/devices/zebra/zebra_constants_mapping.py +12 -7
- dodal/devices/zebra/zebra_controlled_shutter.py +2 -1
- dodal/devices/zocalo/zocalo_interaction.py +14 -14
- dodal/devices/zocalo/zocalo_results.py +33 -33
- dodal/log.py +23 -20
- dodal/plan_stubs/check_topup.py +15 -15
- dodal/plan_stubs/data_session.py +6 -6
- dodal/plan_stubs/motor_utils.py +22 -18
- dodal/plan_stubs/pressure_jump_cell.py +18 -0
- dodal/plan_stubs/wrapped.py +40 -55
- dodal/plans/bimorph.py +63 -52
- dodal/plans/configure_arm_trigger_and_disarm_detector.py +0 -1
- dodal/plans/device_setup_plans/__init__.py +5 -0
- dodal/plans/device_setup_plans/setup_pin_tip_params.py +63 -0
- dodal/plans/preprocessors/verify_undulator_gap.py +10 -8
- dodal/plans/spec_path.py +3 -5
- dodal/plans/verify_undulator_gap.py +1 -2
- dodal/plans/wrapped.py +4 -3
- dodal/testing/__init__.py +0 -0
- dodal/testing/electron_analyser/device_factory.py +5 -7
- dodal/testing/fixtures/devices/apple2.py +38 -0
- dodal/testing/fixtures/run_engine.py +3 -7
- dodal/testing/fixtures/utils.py +1 -2
- dodal/utils.py +60 -58
- dls_dodal-1.68.0.dist-info/RECORD +0 -330
- dodal/beamline_specific_utils/i05_shared.py +0 -14
- dodal/devices/b07/__init__.py +0 -3
- dodal/devices/i04/max_pixel.py +0 -38
- dodal/devices/i05/__init__.py +0 -3
- dodal/devices/i09/__init__.py +0 -3
- dodal/devices/i21/__init__.py +0 -5
- {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/entry_points.txt +0 -0
- {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/licenses/LICENSE +0 -0
- {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/top_level.txt +0 -0
- /dodal/{beamline_specific_utils → devices/beamlines}/__init__.py +0 -0
- /dodal/devices/{b07 → beamlines/b07}/enums.py +0 -0
- /dodal/devices/{b07_1 → beamlines/b07_1}/enums.py +0 -0
- /dodal/devices/{b16 → beamlines/b16}/__init__.py +0 -0
- /dodal/devices/{i02_1 → beamlines/i02_1}/__init__.py +0 -0
- /dodal/devices/{i02_2 → beamlines/i02_2}/__init__.py +0 -0
- /dodal/devices/{i03 → beamlines/i03}/__init__.py +0 -0
- /dodal/devices/{i03 → beamlines/i03}/constants.py +0 -0
- /dodal/devices/{i04 → beamlines/i04}/__init__.py +0 -0
- /dodal/devices/{i04 → beamlines/i04}/constants.py +0 -0
- /dodal/devices/{i05 → beamlines/i05}/enums.py +0 -0
- /dodal/devices/{i07 → beamlines/i07}/__init__.py +0 -0
- /dodal/devices/{i09 → beamlines/i09}/enums.py +0 -0
- /dodal/devices/{i09_1 → beamlines/i09_1}/__init__.py +0 -0
- /dodal/devices/{i09_1 → beamlines/i09_1}/enums.py +0 -0
- /dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/__init__.py +0 -0
- /dodal/devices/{i09_2_shared → beamlines/i09_2_shared}/__init__.py +0 -0
- /dodal/devices/{i09_2_shared → beamlines/i09_2_shared}/i09_apple2.py +0 -0
- /dodal/devices/{i10 → beamlines/i10}/__init__.py +0 -0
- /dodal/devices/{i10 → beamlines/i10}/i10_setting_data.py +0 -0
- /dodal/devices/{i10 → beamlines/i10}/mirrors.py +0 -0
- /dodal/devices/{i10 → beamlines/i10}/rasor/__init__.py +0 -0
- /dodal/devices/{i10 → beamlines/i10}/rasor/rasor_scaler_cards.py +0 -0
- /dodal/devices/{i11 → beamlines/i10_1/electromagnet}/__init__.py +0 -0
- /dodal/devices/{i13_1 → beamlines/i11}/__init__.py +0 -0
- /dodal/devices/{i15 → beamlines/i13_1}/__init__.py +0 -0
- /dodal/devices/{i13_1 → beamlines/i13_1}/merlin_controller.py +0 -0
- /dodal/devices/{i17 → beamlines/i15}/__init__.py +0 -0
- /dodal/devices/{i15 → beamlines/i15}/laue.py +0 -0
- /dodal/devices/{i15 → beamlines/i15}/motors.py +0 -0
- /dodal/devices/{i15 → beamlines/i15}/rail.py +0 -0
- /dodal/devices/{i18 → beamlines/i17}/__init__.py +0 -0
- /dodal/devices/{i19 → beamlines/i18}/__init__.py +0 -0
- /dodal/devices/{i18 → beamlines/i18}/kb_mirror.py +0 -0
- /dodal/devices/{i19/access_controlled → beamlines/i19}/__init__.py +0 -0
- /dodal/devices/{i20_1 → beamlines/i19/access_controlled}/__init__.py +0 -0
- /dodal/devices/{i19 → beamlines/i19}/access_controlled/hutch_access.py +0 -0
- /dodal/devices/{i19 → beamlines/i19}/beamstop.py +0 -0
- /dodal/devices/{i19 → beamlines/i19}/diffractometer.py +0 -0
- /dodal/devices/{i22 → beamlines/i20_1}/__init__.py +0 -0
- /dodal/devices/{i21 → beamlines/i21}/enums.py +0 -0
- /dodal/devices/{i24 → beamlines/i22}/__init__.py +0 -0
- /dodal/devices/{p99 → beamlines/i24}/__init__.py +0 -0
- /dodal/devices/{i24 → beamlines/i24}/aperture.py +0 -0
- /dodal/devices/{i24 → beamlines/i24}/focus_mirrors.py +0 -0
- /dodal/devices/{i24 → beamlines/i24}/vgonio.py +0 -0
- /dodal/devices/{p60 → beamlines/p60}/__init__.py +0 -0
- /dodal/devices/{p60 → beamlines/p60}/enums.py +0 -0
- /dodal/devices/{p99 → beamlines/p99}/sample_stage.py +0 -0
- /dodal/devices/insertion_device/{id_enum.py → enum.py} +0 -0
|
@@ -4,10 +4,12 @@ from ophyd_async.core import AsyncStatus
|
|
|
4
4
|
from pydantic import BaseModel, model_validator
|
|
5
5
|
from pydantic.types import PositiveInt, StringConstraints
|
|
6
6
|
|
|
7
|
-
from dodal.devices.i19.access_controlled.blueapi_device import (
|
|
7
|
+
from dodal.devices.beamlines.i19.access_controlled.blueapi_device import (
|
|
8
8
|
OpticsBlueAPIDevice,
|
|
9
9
|
)
|
|
10
|
-
from dodal.devices.i19.access_controlled.hutch_access import
|
|
10
|
+
from dodal.devices.beamlines.i19.access_controlled.hutch_access import (
|
|
11
|
+
ACCESS_DEVICE_NAME,
|
|
12
|
+
)
|
|
11
13
|
|
|
12
14
|
PermittedKeyStr = Annotated[str, StringConstraints(pattern="^[A-Za-z0-9-_]*$")]
|
|
13
15
|
|
|
@@ -32,18 +34,20 @@ class AttenuatorMotorPositionDemands(BaseModel):
|
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
class AttenuatorMotorSquad(OpticsBlueAPIDevice):
|
|
35
|
-
"""
|
|
37
|
+
"""I19-specific proxy device which requests absorber position changes in the
|
|
38
|
+
x-ray attenuator.
|
|
36
39
|
|
|
37
40
|
Sends REST call to blueapi controlling optics on the I19 cluster.
|
|
38
|
-
|
|
41
|
+
The hutch in use is compared against the hutch which sent the REST call.
|
|
39
42
|
Only the hutch in use will be permitted to execute a plan (requesting motor moves).
|
|
40
|
-
As the two hutches are located in series, checking the hutch in use is necessary to
|
|
41
|
-
avoid accidentally operating optics devices from one hutch while the other has beam
|
|
43
|
+
As the two hutches are located in series, checking the hutch in use is necessary to
|
|
44
|
+
avoid accidentally operating optics devices from one hutch while the other has beam
|
|
45
|
+
time.
|
|
42
46
|
|
|
43
|
-
The name of the hutch that wants to operate the optics device is passed to the
|
|
47
|
+
The name of the hutch that wants to operate the optics device is passed to the
|
|
44
48
|
access controlled device upon instantiation of the latter.
|
|
45
49
|
|
|
46
|
-
For details see the architecture described in
|
|
50
|
+
For details see the architecture described in
|
|
47
51
|
https://github.com/DiamondLightSource/i19-bluesky/issues/30.
|
|
48
52
|
"""
|
|
49
53
|
|
|
@@ -21,11 +21,11 @@ class HutchState(str, Enum):
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class OpticsBlueAPIDevice(StandardReadable, Movable[D]):
|
|
24
|
-
"""General device that a REST call to the blueapi instance controlling the optics
|
|
25
|
-
hutch running on the I19 cluster, which will evaluate the current hutch in use vs
|
|
24
|
+
"""General device that a REST call to the blueapi instance controlling the optics
|
|
25
|
+
hutch running on the I19 cluster, which will evaluate the current hutch in use vs
|
|
26
26
|
the hutch sending the request and decide if the plan will be run or not.
|
|
27
27
|
|
|
28
|
-
For details see the architecture described in
|
|
28
|
+
For details see the architecture described in
|
|
29
29
|
https://github.com/DiamondLightSource/i19-bluesky/issues/30.
|
|
30
30
|
"""
|
|
31
31
|
|
|
@@ -44,22 +44,23 @@ class OpticsBlueAPIDevice(StandardReadable, Movable[D]):
|
|
|
44
44
|
|
|
45
45
|
@AsyncStatus.wrap
|
|
46
46
|
async def set(self, value: D):
|
|
47
|
-
"""
|
|
48
|
-
parameters, gets the generated task_id and then sends a PUT request that runs
|
|
47
|
+
"""On set send a POST request to the optics blueapi with the name and
|
|
48
|
+
parameters, gets the generated task_id and then sends a PUT request that runs
|
|
49
49
|
the plan.
|
|
50
50
|
|
|
51
51
|
Args:
|
|
52
|
-
value (dict): The value passed here should be the parameters for the POST
|
|
53
|
-
request, taking the form
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
value (dict): The value passed here should be the parameters for the POST
|
|
53
|
+
request, taking the form::
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
"name": "plan_name",
|
|
57
|
+
"params": {
|
|
58
|
+
"experiment_hutch": f"{hutch_name}",
|
|
59
|
+
"access_device": "access_control",
|
|
60
|
+
"other_params": "...",
|
|
61
|
+
...
|
|
62
|
+
}
|
|
61
63
|
}
|
|
62
|
-
}
|
|
63
64
|
"""
|
|
64
65
|
# Value here vould be request params dictionary.
|
|
65
66
|
request_params = json.dumps(value)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from enum import StrEnum
|
|
2
|
+
|
|
3
|
+
from ophyd_async.core import AsyncStatus, StandardReadableFormat
|
|
4
|
+
from ophyd_async.epics.core import epics_signal_r
|
|
5
|
+
|
|
6
|
+
from dodal.devices.beamlines.i19.access_controlled.blueapi_device import (
|
|
7
|
+
HutchState,
|
|
8
|
+
OpticsBlueAPIDevice,
|
|
9
|
+
)
|
|
10
|
+
from dodal.devices.beamlines.i19.access_controlled.hutch_access import (
|
|
11
|
+
ACCESS_DEVICE_NAME,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class FocusingMirrorName(StrEnum):
|
|
16
|
+
VFM = "vfm"
|
|
17
|
+
HFM = "hfm"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
PIEZO_CONTROL_PLAN_NAME = "apply_voltage_to_piezo"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# NOTE This device is only meant to control the piezo. There should be a separate device
|
|
24
|
+
# to control the actual focusing mirror motors, as the two operations are often done
|
|
25
|
+
# independently.
|
|
26
|
+
class AccessControlledPiezoActuator(OpticsBlueAPIDevice):
|
|
27
|
+
"""I19-specific device to set a voltage on the focusing mirror piezoelectric
|
|
28
|
+
actuator.
|
|
29
|
+
|
|
30
|
+
This device will send a REST call to the blueapi instance controlling the optics
|
|
31
|
+
hutch running on the I19 cluster, which will evaluate the current hutch in use vs
|
|
32
|
+
the hutch sending the request and decide if the plan will be run or not.
|
|
33
|
+
As the two hutches are located in series, checking the hutch in use is necessary to
|
|
34
|
+
avoid accidentally operating the shutter from one hutch while the other has beamtime.
|
|
35
|
+
|
|
36
|
+
The name of the hutch that wants to operate the shutter, as well as a commissioning
|
|
37
|
+
directory to act as a placehlder for the instrument_session,should be passed to the
|
|
38
|
+
device upon instantiation.
|
|
39
|
+
|
|
40
|
+
A mirror type (vfm or hfm) also needs to be set upon instantiation so that the
|
|
41
|
+
correct plan can be run and the correct optics device is injected.
|
|
42
|
+
|
|
43
|
+
For details see the architecture described in
|
|
44
|
+
https://diamondlightsource.github.io/i19-bluesky/main/explanations/decisions/0004-optics-blueapi-architecture.html
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
prefix: str,
|
|
50
|
+
mirror_type: FocusingMirrorName,
|
|
51
|
+
hutch: HutchState,
|
|
52
|
+
instrument_session: str = "",
|
|
53
|
+
name: str = "",
|
|
54
|
+
):
|
|
55
|
+
with self.add_children_as_readables(StandardReadableFormat.HINTED_SIGNAL):
|
|
56
|
+
self.readback = epics_signal_r(float, f"{prefix}AOFPITCH:RBV")
|
|
57
|
+
self.mirror = mirror_type
|
|
58
|
+
super().__init__(hutch=hutch, instrument_session=instrument_session, name=name)
|
|
59
|
+
|
|
60
|
+
@AsyncStatus.wrap
|
|
61
|
+
async def set(self, value: float):
|
|
62
|
+
request_params = {
|
|
63
|
+
"name": PIEZO_CONTROL_PLAN_NAME,
|
|
64
|
+
"params": {
|
|
65
|
+
"experiment_hutch": self._invoking_hutch,
|
|
66
|
+
"access_device": ACCESS_DEVICE_NAME,
|
|
67
|
+
"voltage_demand": value,
|
|
68
|
+
"focus_mirror": self.mirror.value,
|
|
69
|
+
},
|
|
70
|
+
"instrument_session": self.instrument_session,
|
|
71
|
+
}
|
|
72
|
+
await super().set(request_params)
|
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
from ophyd_async.core import AsyncStatus, StandardReadableFormat
|
|
2
2
|
from ophyd_async.epics.core import epics_signal_r
|
|
3
3
|
|
|
4
|
-
from dodal.devices.
|
|
5
|
-
from dodal.devices.i19.access_controlled.blueapi_device import (
|
|
4
|
+
from dodal.devices.beamlines.i19.access_controlled.blueapi_device import (
|
|
6
5
|
HutchState,
|
|
7
6
|
OpticsBlueAPIDevice,
|
|
8
7
|
)
|
|
9
|
-
from dodal.devices.i19.access_controlled.hutch_access import
|
|
8
|
+
from dodal.devices.beamlines.i19.access_controlled.hutch_access import (
|
|
9
|
+
ACCESS_DEVICE_NAME,
|
|
10
|
+
)
|
|
11
|
+
from dodal.devices.hutch_shutter import ShutterDemand, ShutterState
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class AccessControlledShutter(OpticsBlueAPIDevice):
|
|
13
|
-
"""
|
|
15
|
+
"""I19-specific device to operate the hutch shutter.
|
|
14
16
|
|
|
15
|
-
This device will send a REST call to the blueapi instance controlling the optics
|
|
16
|
-
hutch running on the I19 cluster, which will evaluate the current hutch in use vs
|
|
17
|
+
This device will send a REST call to the blueapi instance controlling the optics
|
|
18
|
+
hutch running on the I19 cluster, which will evaluate the current hutch in use vs
|
|
17
19
|
the hutch sending the request and decide if the plan will be run or not.
|
|
18
|
-
As the two hutches are located in series, checking the hutch in use is necessary to
|
|
20
|
+
As the two hutches are located in series, checking the hutch in use is necessary to
|
|
19
21
|
avoid accidentally operating the shutter from one hutch while the other has beamtime.
|
|
20
22
|
|
|
21
|
-
The name of the hutch that wants to operate the shutter should be passed to the
|
|
23
|
+
The name of the hutch that wants to operate the shutter should be passed to the
|
|
22
24
|
device upon instantiation.
|
|
23
25
|
|
|
24
|
-
For details see the architecture described in
|
|
26
|
+
For details see the architecture described in
|
|
25
27
|
https://github.com/DiamondLightSource/i19-bluesky/issues/30.
|
|
26
28
|
"""
|
|
27
29
|
|
|
@@ -6,7 +6,9 @@ from dodal.common.enums import InOutUpper
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class BacklightPosition(StandardReadable, Movable[InOutUpper]):
|
|
9
|
-
"""Device moves backlight to the IN or OUT position since controls side manages
|
|
9
|
+
"""Device moves backlight to the IN or OUT position since controls side manages
|
|
10
|
+
switching the light on/off.
|
|
11
|
+
"""
|
|
10
12
|
|
|
11
13
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
12
14
|
self.position = epics_signal_rw(InOutUpper, f"{prefix}AD1:choiceButton")
|
|
@@ -27,7 +27,8 @@ class MAPTConfigurationTable(StandardReadable):
|
|
|
27
27
|
class MAPTConfigurationControl(StandardReadable):
|
|
28
28
|
"""A device to control the MAPT (Mini Aperture) configuration. It provides a signal
|
|
29
29
|
to set the configuration PV to the requested value and a triggerable signal that
|
|
30
|
-
will move all the motors to the correct position.
|
|
30
|
+
will move all the motors to the correct position.
|
|
31
|
+
"""
|
|
31
32
|
|
|
32
33
|
def __init__(
|
|
33
34
|
self, prefix: str, aperture_request: type[SubsetEnum], name: str = ""
|
|
@@ -6,7 +6,7 @@ from ophyd_async.core import AsyncStatus, StandardReadable, SubsetEnum
|
|
|
6
6
|
from ophyd_async.epics.core import epics_signal_r
|
|
7
7
|
from pydantic import BaseModel
|
|
8
8
|
|
|
9
|
-
from dodal.devices.i19.mapt_configuration import (
|
|
9
|
+
from dodal.devices.beamlines.i19.mapt_configuration import (
|
|
10
10
|
MAPTConfigurationControl,
|
|
11
11
|
MAPTConfigurationTable,
|
|
12
12
|
)
|
|
@@ -45,10 +45,10 @@ class AperturePosition(BaseModel):
|
|
|
45
45
|
one of the available apertures.
|
|
46
46
|
|
|
47
47
|
Attributes:
|
|
48
|
-
pinhole_x: The position of the x motor on the pinhole stage
|
|
49
|
-
pinhole_y: The position of the y motor on the pinhole stage
|
|
50
|
-
collimator_x: The position of the x motor on the collimator stage
|
|
51
|
-
collimator_y: The position of the y motor on the collimator stage
|
|
48
|
+
pinhole_x (float): The position of the x motor on the pinhole stage.
|
|
49
|
+
pinhole_y (float): The position of the y motor on the pinhole stage.
|
|
50
|
+
collimator_x (float): The position of the x motor on the collimator stage.
|
|
51
|
+
collimator_y (float): The position of the y motor on the collimator stage.
|
|
52
52
|
"""
|
|
53
53
|
|
|
54
54
|
pinhole_x: float
|
|
@@ -59,7 +59,8 @@ class AperturePosition(BaseModel):
|
|
|
59
59
|
|
|
60
60
|
class PinColConfiguration(StandardReadable):
|
|
61
61
|
"""Full MAPT configuration table, including out positions and selection for the
|
|
62
|
-
Pinhole and Collimator control.
|
|
62
|
+
Pinhole and Collimator control.
|
|
63
|
+
"""
|
|
63
64
|
|
|
64
65
|
def __init__(self, prefix: str, apertures: list[int], name: str = "") -> None:
|
|
65
66
|
with self.add_children_as_readables():
|
|
@@ -75,7 +76,8 @@ class PinColConfiguration(StandardReadable):
|
|
|
75
76
|
|
|
76
77
|
class PinholeCollimatorControl(StandardReadable, Movable[str]):
|
|
77
78
|
"""Device to control the Pinhole and Collimator stages moves on I19-2, using the
|
|
78
|
-
MAPT configuration table to look up the positions.
|
|
79
|
+
MAPT configuration table to look up the positions.
|
|
80
|
+
"""
|
|
79
81
|
|
|
80
82
|
def __init__(
|
|
81
83
|
self,
|
|
@@ -130,7 +132,8 @@ class PinholeCollimatorControl(StandardReadable, Movable[str]):
|
|
|
130
132
|
async def _safe_move_in(self, value: _PinColPosition):
|
|
131
133
|
"""Move the pinhole and collimator stages safely to the in position.
|
|
132
134
|
In order to avoid a collision, we have to make sure that the pinhole stage is
|
|
133
|
-
always moved in before the collimator stage.
|
|
135
|
+
always moved in before the collimator stage.
|
|
136
|
+
"""
|
|
134
137
|
LOGGER.info(
|
|
135
138
|
f"Moving pinhole and collimator stages to in position: {value.value}"
|
|
136
139
|
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from ophyd_async.core import StandardReadable
|
|
2
|
+
from ophyd_async.epics.core import epics_signal_rw
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class PinTipCentreHolder(StandardReadable):
|
|
6
|
+
"""Temporary device to hold the pin tip x,y positions for centring.
|
|
7
|
+
It uses the CenterX and CenterY PVs in the overlay plugin for the OAV device to
|
|
8
|
+
save and read the pit tip location.
|
|
9
|
+
|
|
10
|
+
Attributes:
|
|
11
|
+
pin_tip_i (SignalRW): x position of the pin tip, in pixels.
|
|
12
|
+
pin_tip_j (SignalRW): y position of the pin tip, in pixels.
|
|
13
|
+
|
|
14
|
+
This workaround is necessary because it's not yet possible to get these values back
|
|
15
|
+
from a plan in blueapi. It will be removed once this is completed
|
|
16
|
+
https://github.com/DiamondLightSource/blueapi/issues/1349
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
prefix: str,
|
|
22
|
+
name: str = "",
|
|
23
|
+
overlay_channel: int = 1,
|
|
24
|
+
):
|
|
25
|
+
with self.add_children_as_readables():
|
|
26
|
+
self.pin_tip_i = epics_signal_rw(
|
|
27
|
+
int, prefix + f"OVER:{overlay_channel}:CenterX"
|
|
28
|
+
)
|
|
29
|
+
self.pin_tip_j = epics_signal_rw(
|
|
30
|
+
int, prefix + f"OVER:{overlay_channel}:CenterY"
|
|
31
|
+
)
|
|
32
|
+
super().__init__(name)
|
|
@@ -24,8 +24,7 @@ _CONVERSION_CONSTANT = 12.3984
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class DCM(DoubleCrystalMonochromatorWithDSpacing[RollCrystal, PitchAndRollCrystal]):
|
|
27
|
-
"""
|
|
28
|
-
A double crystal monochromator (DCM), used to select the energy of the beam.
|
|
27
|
+
"""A double crystal monochromator (DCM), used to select the energy of the beam.
|
|
29
28
|
|
|
30
29
|
perp describes the gap between the 2 DCM crystals which has to change as you alter
|
|
31
30
|
the angle to select the requested energy.
|
|
@@ -15,8 +15,7 @@ from dodal.common.enums import InOutUpper
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class FSwitch(StandardReadable):
|
|
18
|
-
"""
|
|
19
|
-
Device for i22's fswitch. A filter switch for manipulating
|
|
18
|
+
"""Device for i22's fswitch. A filter switch for manipulating
|
|
20
19
|
compound refractive lenses. Also referred to as a transfocator.
|
|
21
20
|
|
|
22
21
|
This currently only implements the minimum
|
|
@@ -25,7 +24,6 @@ class FSwitch(StandardReadable):
|
|
|
25
24
|
Eventually this should be combined with the transfocator device in the i04
|
|
26
25
|
module but is currently incompatible as the Epics interfaces are different.
|
|
27
26
|
See https://github.com/DiamondLightSource/dodal/issues/399
|
|
28
|
-
|
|
29
27
|
"""
|
|
30
28
|
|
|
31
29
|
NUM_FILTERS = 128
|
|
@@ -57,8 +57,7 @@ class MetadataHolder:
|
|
|
57
57
|
|
|
58
58
|
@dataclass
|
|
59
59
|
class NXSasMetadataHolder(MetadataHolder):
|
|
60
|
-
"""
|
|
61
|
-
Required fields for NXDetectors that are used in an NXsas application definition.
|
|
60
|
+
"""Required fields for NXDetectors that are used in an NXsas application definition.
|
|
62
61
|
All fields are Configuration and read once per run only.
|
|
63
62
|
"""
|
|
64
63
|
|
|
@@ -94,7 +93,8 @@ class NXSasPilatus(PilatusDetector):
|
|
|
94
93
|
to comply with the NXsas application definition.
|
|
95
94
|
Adds all values in the NXSasMetadataHolder's configuration fields
|
|
96
95
|
to the configuration of the parent device.
|
|
97
|
-
Writes hdf5 files.
|
|
96
|
+
Writes hdf5 files.
|
|
97
|
+
"""
|
|
98
98
|
super().__init__(
|
|
99
99
|
prefix,
|
|
100
100
|
path_provider,
|
|
@@ -137,7 +137,8 @@ class NXSasOAV(AravisDetector):
|
|
|
137
137
|
to comply with the NXsas application definition.
|
|
138
138
|
Adds all values in the NXSasMetadataHolder's configuration fields
|
|
139
139
|
to the configuration of the parent device.
|
|
140
|
-
Writes hdf5 files.
|
|
140
|
+
Writes hdf5 files.
|
|
141
|
+
"""
|
|
141
142
|
super().__init__(
|
|
142
143
|
prefix,
|
|
143
144
|
path_provider,
|
|
@@ -21,8 +21,8 @@ class Beamstop(XYZStage):
|
|
|
21
21
|
The additional y_rotation motor is independent of the positioner and can to be moved
|
|
22
22
|
on its own as needed.
|
|
23
23
|
|
|
24
|
-
WARNING. Before moving the y_rotation motor away from 0, it is important to make
|
|
25
|
-
that the backlight is in the "OUT" position to avoid a collision.
|
|
24
|
+
WARNING. Before moving the y_rotation motor away from 0, it is important to make
|
|
25
|
+
sure that the backlight is in the "OUT" position to avoid a collision.
|
|
26
26
|
See also https://github.com/DiamondLightSource/dodal/issues/646.
|
|
27
27
|
"""
|
|
28
28
|
|
|
@@ -6,11 +6,10 @@ from bluesky.protocols import StreamAsset
|
|
|
6
6
|
from event_model import DataKey # type: ignore
|
|
7
7
|
from ophyd_async.core import (
|
|
8
8
|
AsyncStatus,
|
|
9
|
-
AutoIncrementingPathProvider,
|
|
10
9
|
DetectorWriter,
|
|
10
|
+
PathProvider,
|
|
11
11
|
StandardDetector,
|
|
12
12
|
StandardReadable,
|
|
13
|
-
StaticPathProvider,
|
|
14
13
|
TriggerInfo,
|
|
15
14
|
observe_value,
|
|
16
15
|
wait_for_value,
|
|
@@ -22,22 +21,22 @@ from ophyd_async.fastcs.jungfrau._signals import JungfrauDriverIO
|
|
|
22
21
|
from dodal.log import LOGGER
|
|
23
22
|
|
|
24
23
|
|
|
25
|
-
class
|
|
24
|
+
class JungfrauCommissioningWriter(DetectorWriter, StandardReadable):
|
|
26
25
|
"""Implementation of the temporary filewriter used for Jungfrau commissioning on i24.
|
|
27
26
|
|
|
28
27
|
The PVs on this device are responsible for writing files of a specified name
|
|
29
28
|
to a specified path, marking itself as "ready to write", and having a counter of
|
|
30
|
-
frames written, which must be zero'd at the ophyd level
|
|
29
|
+
frames written, which must be zero'd at the ophyd level.
|
|
31
30
|
"""
|
|
32
31
|
|
|
33
32
|
def __init__(
|
|
34
33
|
self,
|
|
35
34
|
prefix,
|
|
36
|
-
path_provider:
|
|
35
|
+
path_provider: PathProvider,
|
|
37
36
|
name="",
|
|
38
37
|
) -> None:
|
|
39
38
|
with self.add_children_as_readables():
|
|
40
|
-
self.
|
|
39
|
+
self._path_provider = path_provider
|
|
41
40
|
self.frame_counter = epics_signal_rw(int, f"{prefix}NumCaptured")
|
|
42
41
|
self.file_name = epics_signal_rw_rbv(str, f"{prefix}FileName")
|
|
43
42
|
self.file_path = epics_signal_rw_rbv(str, f"{prefix}FilePath")
|
|
@@ -47,9 +46,8 @@ class JunfrauCommissioningWriter(DetectorWriter, StandardReadable):
|
|
|
47
46
|
|
|
48
47
|
async def open(self, name: str, exposures_per_event: int = 1) -> dict[str, DataKey]:
|
|
49
48
|
self._exposures_per_event = exposures_per_event
|
|
50
|
-
_path_info = self.
|
|
49
|
+
_path_info = self._path_provider()
|
|
51
50
|
|
|
52
|
-
# Commissioning Jungfrau plans allow you to override path, so check to see if file exists
|
|
53
51
|
requested_filepath = Path(_path_info.directory_path) / _path_info.filename
|
|
54
52
|
if requested_filepath.exists():
|
|
55
53
|
raise FileExistsError(
|
|
@@ -65,6 +63,7 @@ class JunfrauCommissioningWriter(DetectorWriter, StandardReadable):
|
|
|
65
63
|
f"Jungfrau writing to folder {_path_info.directory_path} with filename {_path_info.filename}"
|
|
66
64
|
)
|
|
67
65
|
await wait_for_value(self.writer_ready, 1, timeout=10)
|
|
66
|
+
self.final_path = requested_filepath
|
|
68
67
|
return await self._describe()
|
|
69
68
|
|
|
70
69
|
async def _describe(self) -> dict[str, DataKey]:
|
|
@@ -99,20 +98,21 @@ class JunfrauCommissioningWriter(DetectorWriter, StandardReadable):
|
|
|
99
98
|
|
|
100
99
|
|
|
101
100
|
class CommissioningJungfrau(
|
|
102
|
-
StandardDetector[JungfrauController,
|
|
101
|
+
StandardDetector[JungfrauController, JungfrauCommissioningWriter]
|
|
103
102
|
):
|
|
104
103
|
"""Ophyd-async implementation of a Jungfrau 9M Detector, using a temporary
|
|
105
|
-
filewriter in place of Odin
|
|
104
|
+
filewriter in place of Odin.
|
|
105
|
+
"""
|
|
106
106
|
|
|
107
107
|
def __init__(
|
|
108
108
|
self,
|
|
109
109
|
prefix: str,
|
|
110
110
|
writer_prefix: str,
|
|
111
|
-
path_provider:
|
|
111
|
+
path_provider: PathProvider,
|
|
112
112
|
name="",
|
|
113
113
|
):
|
|
114
114
|
self.drv = JungfrauDriverIO(prefix)
|
|
115
|
-
writer =
|
|
115
|
+
writer = JungfrauCommissioningWriter(writer_prefix, path_provider)
|
|
116
116
|
controller = JungfrauController(self.drv)
|
|
117
117
|
super().__init__(controller, writer, name=name)
|
|
118
118
|
|
|
@@ -8,9 +8,7 @@ from dodal.devices.common_dcm import (
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class DCM(DoubleCrystalMonochromatorWithDSpacing[RollCrystal, PitchAndRollCrystal]):
|
|
11
|
-
"""
|
|
12
|
-
A double crystal monocromator device, used to select the beam energy.
|
|
13
|
-
"""
|
|
11
|
+
"""A double crystal monocromator device, used to select the beam energy."""
|
|
14
12
|
|
|
15
13
|
def __init__(self, prefix: str, motion_prefix: str, name: str = "") -> None:
|
|
16
14
|
with self.add_children_as_readables():
|
|
@@ -27,13 +27,13 @@ class BacklightPositioner(StandardReadable):
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class DualBacklight(StandardReadable):
|
|
30
|
-
"""
|
|
31
|
-
Device to trigger the dual backlight on I24.
|
|
30
|
+
"""Device to trigger the dual backlight on I24.
|
|
32
31
|
This device is made up by two LEDs:
|
|
33
32
|
- LED1 is the "backlight", can be moved to 5 different positions.
|
|
34
33
|
- LED2 is a "frontlight", it does not move, just switches on and off.
|
|
35
34
|
|
|
36
|
-
To set the position for LED1
|
|
35
|
+
To set the position for LED1::
|
|
36
|
+
|
|
37
37
|
b = DualBacklight(name="backlight)
|
|
38
38
|
b.backlight_position.set("OAV2")
|
|
39
39
|
|
|
@@ -45,9 +45,11 @@ class LaserSettings(str, Enum):
|
|
|
45
45
|
class EncReset(str, Enum):
|
|
46
46
|
"""PMAC strings for position compare on encoder channels in the controller.
|
|
47
47
|
|
|
48
|
-
For example, for ENC5
|
|
48
|
+
For example, for ENC5::
|
|
49
|
+
|
|
49
50
|
m508 sets position A to be compared with value in Channel5 in the controller.
|
|
50
51
|
m509 sets position B to be compared with value in Channel5 in the controller.
|
|
52
|
+
|
|
51
53
|
Note. These settings are usually used for initialisation.
|
|
52
54
|
"""
|
|
53
55
|
|
|
@@ -141,8 +143,8 @@ class ProgramRunner(Device, Flyable):
|
|
|
141
143
|
|
|
142
144
|
@AsyncStatus.wrap
|
|
143
145
|
async def kickoff(self):
|
|
144
|
-
"""Kick off the collection by sending a program number to the pmac_string and
|
|
145
|
-
|
|
146
|
+
"""Kick off the collection by sending a program number to the pmac_string and
|
|
147
|
+
wait for the scan status PV to go to 1.
|
|
146
148
|
"""
|
|
147
149
|
prog_num_str = await self._get_prog_number_string()
|
|
148
150
|
await self._signal_ref().set(prog_num_str, wait=True)
|
|
@@ -154,8 +156,8 @@ class ProgramRunner(Device, Flyable):
|
|
|
154
156
|
|
|
155
157
|
@AsyncStatus.wrap
|
|
156
158
|
async def complete(self):
|
|
157
|
-
"""Stop collecting when the scan status PV goes to 0 or when counter PV hasn't
|
|
158
|
-
|
|
159
|
+
"""Stop collecting when the scan status PV goes to 0 or when counter PV hasn't
|
|
160
|
+
updated for 30 seconds.
|
|
159
161
|
"""
|
|
160
162
|
counter_time = await self._counter_time_ref().get_value()
|
|
161
163
|
async for signal, value in observe_signals_value(
|
|
@@ -169,8 +171,8 @@ class ProgramRunner(Device, Flyable):
|
|
|
169
171
|
|
|
170
172
|
|
|
171
173
|
class ProgramAbort(Triggerable):
|
|
172
|
-
"""Abort a data collection by setting the PMAC string and then wait for the
|
|
173
|
-
|
|
174
|
+
"""Abort a data collection by setting the PMAC string and then wait for the
|
|
175
|
+
status value to go back to 0.
|
|
174
176
|
"""
|
|
175
177
|
|
|
176
178
|
def __init__(
|
|
@@ -12,7 +12,7 @@ class LabXraySource(float, Enum):
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class LabXraySourceReadable(StandardReadable):
|
|
15
|
-
"""Simple device to get the laboratory x-ray tube energy reading"""
|
|
15
|
+
"""Simple device to get the laboratory x-ray tube energy reading."""
|
|
16
16
|
|
|
17
17
|
def __init__(self, xraysource: LabXraySource, name: str = "") -> None:
|
|
18
18
|
with self.add_children_as_readables():
|
|
File without changes
|
|
@@ -8,7 +8,17 @@ from ophyd_async.epics.core import epics_signal_r
|
|
|
8
8
|
|
|
9
9
|
class Andor2Point(SingleTriggerDetector):
|
|
10
10
|
"""Using the andor2 as if it is a massive point detector, read the read uncached
|
|
11
|
-
value after a picture is taken.
|
|
11
|
+
value after a picture is taken.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
prefix (str): Beamline camera PV.
|
|
15
|
+
drv_suffix (str): Camera PV suffix.
|
|
16
|
+
read_uncached (dict[str,str]): A dictionary contains the name and the PV
|
|
17
|
+
suffix for the statistic plugin.
|
|
18
|
+
name (str): Name of the device.
|
|
19
|
+
plugins ([dict[str, NDPluginBaseIO], optional): Dictionary containing
|
|
20
|
+
plugin that are forward to the base class.
|
|
21
|
+
"""
|
|
12
22
|
|
|
13
23
|
def __init__(
|
|
14
24
|
self,
|
|
@@ -18,20 +28,6 @@ class Andor2Point(SingleTriggerDetector):
|
|
|
18
28
|
name: str = "",
|
|
19
29
|
plugins: dict[str, NDPluginBaseIO] | None = None,
|
|
20
30
|
) -> None:
|
|
21
|
-
"""
|
|
22
|
-
Parameters
|
|
23
|
-
----------
|
|
24
|
-
prefix: str,
|
|
25
|
-
Beamline camera pv
|
|
26
|
-
drv_suffix : str,
|
|
27
|
-
Camera pv suffix
|
|
28
|
-
read_uncached: dict[str,str]
|
|
29
|
-
A dictionary contains the name and the pv suffix for the statistic plugin.
|
|
30
|
-
name: str:
|
|
31
|
-
Name of the device.
|
|
32
|
-
plugins:: Optional[dict[str, NDPluginBaseIO] | None
|
|
33
|
-
Dictionary containing plugin that are forward to the base class.
|
|
34
|
-
"""
|
|
35
31
|
with self.add_children_as_readables(StandardReadableFormat.HINTED_SIGNAL):
|
|
36
32
|
for k, v in read_uncached.items():
|
|
37
33
|
setattr(self, k, epics_signal_r(float, prefix + v))
|