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
|
@@ -30,8 +30,7 @@ class InvalidPinError(Exception):
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class PinTipDetection(StandardReadable):
|
|
33
|
-
"""
|
|
34
|
-
A device which will read from an on-axis view and calculate the location of the
|
|
33
|
+
"""A device which will read from an on-axis view and calculate the location of the
|
|
35
34
|
pin-tip (in pixels) of that frame.
|
|
36
35
|
|
|
37
36
|
Used for pin tip centring workflow.
|
|
@@ -42,7 +41,8 @@ class PinTipDetection(StandardReadable):
|
|
|
42
41
|
If no tip is found it will return {INVALID_POSITION}. However, it will also
|
|
43
42
|
occasionally give incorrect data. Therefore, it is recommended that you trigger
|
|
44
43
|
this device, which will attempt to find a pin within {validity_timeout} seconds if
|
|
45
|
-
no tip is found after this time it will not error but instead return
|
|
44
|
+
no tip is found after this time it will not error but instead return
|
|
45
|
+
{INVALID_POSITION}.
|
|
46
46
|
"""
|
|
47
47
|
|
|
48
48
|
INVALID_POSITION = np.array([np.iinfo(np.int32).min, np.iinfo(np.int32).min])
|
|
@@ -98,9 +98,7 @@ class PinTipDetection(StandardReadable):
|
|
|
98
98
|
self._bottom_edge_setter(results.edge_bottom)
|
|
99
99
|
|
|
100
100
|
async def _get_tip_and_edge_data(self, array_data: np.ndarray) -> SampleLocation:
|
|
101
|
-
"""
|
|
102
|
-
Gets the location of the pin tip and the top and bottom edges.
|
|
103
|
-
"""
|
|
101
|
+
"""Gets the location of the pin tip and the top and bottom edges."""
|
|
104
102
|
preprocess_key = await self.preprocess_operation.get_value()
|
|
105
103
|
preprocess_iter = await self.preprocess_iterations.get_value()
|
|
106
104
|
preprocess_ksize = await self.preprocess_ksize.get_value()
|
|
@@ -100,9 +100,7 @@ NONE_VALUE: Final[int] = -1
|
|
|
100
100
|
|
|
101
101
|
@dataclass
|
|
102
102
|
class SampleLocation:
|
|
103
|
-
"""
|
|
104
|
-
Holder type for results from sample detection.
|
|
105
|
-
"""
|
|
103
|
+
"""Holder type for results from sample detection."""
|
|
106
104
|
|
|
107
105
|
tip_x: int | None
|
|
108
106
|
tip_y: int | None
|
|
@@ -111,6 +109,28 @@ class SampleLocation:
|
|
|
111
109
|
|
|
112
110
|
|
|
113
111
|
class MxSampleDetect:
|
|
112
|
+
"""Configures sample detection parameters.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
preprocess (Callable): A preprocessing function applied to the array after
|
|
116
|
+
conversion to grayscale. See implementations of common functions above
|
|
117
|
+
for predefined conversions. Defaults to a no-op (i.e. no preprocessing).
|
|
118
|
+
|
|
119
|
+
for open and close operations, please read:
|
|
120
|
+
https://docs.opencv.org/4.x/d9/d61/tutorial_py_morphological_ops.html
|
|
121
|
+
|
|
122
|
+
open_ksize (int, optional): Kernel size for "open" operation, if set to zero
|
|
123
|
+
then ignore "open" operation.
|
|
124
|
+
open_iterations (int, optional): Number of iterations for "open" operation.
|
|
125
|
+
canny_upper (int, optional): Upper threshold for canny edge detection.
|
|
126
|
+
canny_lower (int, optional): Lower threshold for canny edge detection.
|
|
127
|
+
close_ksize (int, optional): Kernel size for "close" operation.
|
|
128
|
+
close_iterations (int, optional): Number of iterations for "close" operation.
|
|
129
|
+
scan_direction (ScanDirections, optional): ScanDirections.FORWARD for
|
|
130
|
+
left-to-right, ScanDirections.REVERSE for right-to-left.
|
|
131
|
+
min_tip_height (int, optional): Minimum height of pin tip.
|
|
132
|
+
"""
|
|
133
|
+
|
|
114
134
|
def __init__(
|
|
115
135
|
self,
|
|
116
136
|
*,
|
|
@@ -124,27 +144,6 @@ class MxSampleDetect:
|
|
|
124
144
|
scan_direction: ScanDirections = ScanDirections.FORWARD,
|
|
125
145
|
min_tip_height: int = 5,
|
|
126
146
|
):
|
|
127
|
-
"""
|
|
128
|
-
Configures sample detection parameters.
|
|
129
|
-
|
|
130
|
-
Args:
|
|
131
|
-
preprocess: A preprocessing function applied to the array after conversion to grayscale.
|
|
132
|
-
See implementations of common functions above for predefined conversions
|
|
133
|
-
Defaults to a no-op (i.e. no preprocessing)
|
|
134
|
-
|
|
135
|
-
for open and close operations, please read:
|
|
136
|
-
https://docs.opencv.org/4.x/d9/d61/tutorial_py_morphological_ops.html
|
|
137
|
-
|
|
138
|
-
open_ksize: kernel size for "open" operation, if set to zero then ignore "open" operation
|
|
139
|
-
open_iterations: number of iterations for "open" operation
|
|
140
|
-
canny_upper: upper threshold for canny edge detection
|
|
141
|
-
canny_lower: lower threshold for canny edge detection
|
|
142
|
-
close_ksize: kernel size for "close" operation
|
|
143
|
-
close_iterations: number of iterations for "close" operation
|
|
144
|
-
scan_direction: ScanDirections.FORWARD for left-to-right, ScanDirections.REVERSE for right-to-left
|
|
145
|
-
min_tip_height: minimum height of pin tip
|
|
146
|
-
"""
|
|
147
|
-
|
|
148
147
|
self.preprocess = preprocess
|
|
149
148
|
self.open_ksize = open_ksize
|
|
150
149
|
self.open_iterations = open_iterations
|
|
@@ -185,17 +184,16 @@ class MxSampleDetect:
|
|
|
185
184
|
def _first_and_last_nonzero_by_columns(
|
|
186
185
|
arr: np.ndarray,
|
|
187
186
|
) -> tuple[np.ndarray, np.ndarray]:
|
|
188
|
-
"""
|
|
189
|
-
Finds the indexes of the first & last non-zero values by column in a 2d array.
|
|
187
|
+
"""Finds the indexes of the first & last non-zero values by column in a 2d array.
|
|
190
188
|
|
|
191
189
|
Outputs will contain NONE_VALUE if no non-zero values exist in a column.
|
|
192
190
|
|
|
193
|
-
i.e. for input
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
191
|
+
i.e. for input::
|
|
192
|
+
[
|
|
193
|
+
[0, 0, 0, 1],
|
|
194
|
+
[1, 1, 0, 0],
|
|
195
|
+
[0, 1, 0, 1],
|
|
196
|
+
]
|
|
199
197
|
|
|
200
198
|
first_nonzero will be: [1, 1, NONE_VALUE, 0]
|
|
201
199
|
last_nonzero will be [1, 2, NONE_VALUE, 2]
|
|
@@ -19,12 +19,12 @@ def _add_parallel_lines_to_image(
|
|
|
19
19
|
orientation=Orientation.horizontal,
|
|
20
20
|
):
|
|
21
21
|
"""Draws horizontal or vertical parallel lines on a given image.
|
|
22
|
-
Draws a line of a given length and orientation starting from a given point; then
|
|
23
|
-
draws a given number of parallel lines equally spaced with a given spacing.
|
|
24
|
-
If the line is horizontal, the start point corresponds to left end of the initial
|
|
25
|
-
line and the other parallel lines will be drawn below the initial line; if
|
|
26
|
-
vertical, the start point corresponds to the top end of the initial line and the
|
|
27
|
-
other parallel lines will be drawn to the right of the initial line. (0,0) is the
|
|
22
|
+
Draws a line of a given length and orientation starting from a given point; then
|
|
23
|
+
draws a given number of parallel lines equally spaced with a given spacing.
|
|
24
|
+
If the line is horizontal, the start point corresponds to left end of the initial
|
|
25
|
+
line and the other parallel lines will be drawn below the initial line; if
|
|
26
|
+
vertical, the start point corresponds to the top end of the initial line and the
|
|
27
|
+
other parallel lines will be drawn to the right of the initial line. (0,0) is the
|
|
28
28
|
top left of the image.
|
|
29
29
|
|
|
30
30
|
Args:
|
|
@@ -32,11 +32,12 @@ def _add_parallel_lines_to_image(
|
|
|
32
32
|
start_x (int): The x coordinate (in pixels) of the start of the initial line.
|
|
33
33
|
start_y (int): The y coordinate (in pixels) of the start of the initial line.
|
|
34
34
|
line_length (int): The length of each of the parallel lines in pixels.
|
|
35
|
-
spacing (float): The spacing, in pixels, between each parallel line. Strictly,
|
|
35
|
+
spacing (float): The spacing, in pixels, between each parallel line. Strictly,
|
|
36
36
|
there are spacing-1 pixels between each line
|
|
37
37
|
num_lines (int): The total number of parallel lines to draw.
|
|
38
|
-
orientation (Orientation): The orientation (horizontal or vertical) of the
|
|
39
|
-
parallel lines to draw.
|
|
38
|
+
orientation (Orientation): The orientation (horizontal or vertical) of the
|
|
39
|
+
parallel lines to draw.
|
|
40
|
+
"""
|
|
40
41
|
lines = [
|
|
41
42
|
(
|
|
42
43
|
(
|
|
@@ -8,12 +8,12 @@ CROSSHAIR_FILL_COLOUR = "White"
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def draw_crosshair(image: Image.Image, beam_x: int, beam_y: int):
|
|
11
|
-
"""
|
|
12
|
-
|
|
11
|
+
"""Draw a crosshair at the beam centre coordinates specified.
|
|
12
|
+
|
|
13
13
|
Args:
|
|
14
|
-
image: The image to draw the crosshair onto. This is mutated.
|
|
15
|
-
beam_x: The x-coordinate of the crosshair (pixels)
|
|
16
|
-
beam_y: The y-coordinate of the crosshair (pixels)
|
|
14
|
+
image (Image): The image to draw the crosshair onto. This is mutated.
|
|
15
|
+
beam_x (int): The x-coordinate of the crosshair (pixels).
|
|
16
|
+
beam_y (int): The y-coordinate of the crosshair (pixels).
|
|
17
17
|
"""
|
|
18
18
|
draw = ImageDraw.Draw(image)
|
|
19
19
|
outline_width = 1
|
|
@@ -51,16 +51,18 @@ def compute_beam_centre_pixel_xy_for_mm_position(
|
|
|
51
51
|
beam_pos_at_origin_px: Pixel,
|
|
52
52
|
microns_per_pixel: tuple[float, float],
|
|
53
53
|
) -> Pixel:
|
|
54
|
-
"""
|
|
55
|
-
|
|
54
|
+
"""Compute the location of the beam centre in pixels on a reference image.
|
|
55
|
+
|
|
56
56
|
Args:
|
|
57
|
-
sample_pos_mm: x, y location of the sample in mm relative
|
|
58
|
-
was taken.
|
|
59
|
-
beam_pos_at_origin_px: x, y position of the beam centre in the reference
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
sample_pos_mm (tuple[float, float]): x, y location of the sample in mm relative
|
|
58
|
+
to when the reference image was taken.
|
|
59
|
+
beam_pos_at_origin_px (Pixel): x, y position of the beam centre in the reference
|
|
60
|
+
image (pixels).
|
|
61
|
+
microns_per_pixel (tuple[float, float]): x, y scaling factor relating the sample
|
|
62
|
+
position to the position in the image.
|
|
63
63
|
|
|
64
|
+
Returns:
|
|
65
|
+
Pixel: x, y location of the beam centre (pixels).
|
|
64
66
|
"""
|
|
65
67
|
|
|
66
68
|
def centre(sample_pos, beam_pos, um_per_px) -> int:
|
dodal/devices/oav/utils.py
CHANGED
|
@@ -2,6 +2,7 @@ from collections.abc import Generator
|
|
|
2
2
|
from enum import IntEnum
|
|
3
3
|
|
|
4
4
|
import bluesky.plan_stubs as bps
|
|
5
|
+
import cv2
|
|
5
6
|
import numpy as np
|
|
6
7
|
from bluesky.utils import Msg
|
|
7
8
|
|
|
@@ -40,9 +41,7 @@ def bottom_right_from_top_left(
|
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
class EdgeOutputArrayImageType(IntEnum):
|
|
43
|
-
"""
|
|
44
|
-
Enum to store the types of image to tweak the output array. We use Original.
|
|
45
|
-
"""
|
|
44
|
+
"""Enum to store the types of image to tweak the output array. We use Original."""
|
|
46
45
|
|
|
47
46
|
ORIGINAL = 0
|
|
48
47
|
GREYSCALE = 1
|
|
@@ -56,8 +55,9 @@ def get_move_required_so_that_beam_is_at_pixel(
|
|
|
56
55
|
pixel: Pixel,
|
|
57
56
|
oav: OAV,
|
|
58
57
|
) -> Generator[Msg, None, np.ndarray]:
|
|
59
|
-
"""Calculate the required move so that the given pixel is in the centre of the
|
|
60
|
-
|
|
58
|
+
"""Calculate the required move so that the given pixel is in the centre of the
|
|
59
|
+
beam.
|
|
60
|
+
"""
|
|
61
61
|
current_motor_xyz = np.array(
|
|
62
62
|
[
|
|
63
63
|
(yield from bps.rd(gonio.x)),
|
|
@@ -94,7 +94,7 @@ def calculate_x_y_z_of_pixel(
|
|
|
94
94
|
microns_per_pixel: tuple[float, float],
|
|
95
95
|
xyz_direction: tuple[int, int, int],
|
|
96
96
|
) -> np.ndarray:
|
|
97
|
-
"""Get the x, y, z position of a pixel in mm"""
|
|
97
|
+
"""Get the x, y, z position of a pixel in mm."""
|
|
98
98
|
beam_distance_px: Pixel = calculate_beam_distance(beam_centre, *pixel)
|
|
99
99
|
|
|
100
100
|
return current_x_y_z + camera_coordinates_to_xyz_mm(
|
|
@@ -119,3 +119,17 @@ def wait_for_tip_to_be_found(
|
|
|
119
119
|
raise PinNotFoundError(f"No pin found after {timeout} seconds")
|
|
120
120
|
|
|
121
121
|
return Pixel((int(found_tip[0]), int(found_tip[1])))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def convert_to_gray_and_blur(data: cv2.typing.MatLike) -> cv2.typing.MatLike:
|
|
125
|
+
"""Preprocess the image array data (convert to grayscale and apply a gaussian blur)
|
|
126
|
+
Image is converted to grayscale (using a weighted mean as green contributes more to
|
|
127
|
+
brightness) as we aren't interested in data relating to colour. A blur is then
|
|
128
|
+
applied to mitigate errors due to rogue hot pixels.
|
|
129
|
+
"""
|
|
130
|
+
# kernel size describes how many of the neighbouring pixels are used for the blur,
|
|
131
|
+
# higher kernal size means more of a blur effect
|
|
132
|
+
kernel_size = (7, 7)
|
|
133
|
+
|
|
134
|
+
gray_arr = cv2.cvtColor(data, cv2.COLOR_BGR2GRAY)
|
|
135
|
+
return cv2.GaussianBlur(gray_arr, kernel_size, 0)
|
dodal/devices/p45.py
CHANGED
|
@@ -3,9 +3,7 @@ from ophyd_async.epics.motor import Motor
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class SampleY(StandardReadable):
|
|
6
|
-
"""
|
|
7
|
-
Motors for controlling the sample's y position and stretch in the y axis.
|
|
8
|
-
"""
|
|
6
|
+
"""Motors for controlling the sample's y position and stretch in the y axis."""
|
|
9
7
|
|
|
10
8
|
def __init__(self, prefix: str, name: str = ""):
|
|
11
9
|
with self.add_children_as_readables():
|
|
@@ -17,9 +15,7 @@ class SampleY(StandardReadable):
|
|
|
17
15
|
|
|
18
16
|
|
|
19
17
|
class SampleTheta(StandardReadable):
|
|
20
|
-
"""
|
|
21
|
-
Motors for controlling the sample's theta position and skew
|
|
22
|
-
"""
|
|
18
|
+
"""Motors for controlling the sample's theta position and skew."""
|
|
23
19
|
|
|
24
20
|
def __init__(self, prefix: str, name: str = ""):
|
|
25
21
|
with self.add_children_as_readables():
|
|
@@ -31,9 +27,7 @@ class SampleTheta(StandardReadable):
|
|
|
31
27
|
|
|
32
28
|
|
|
33
29
|
class TomoStageWithStretchAndSkew(StandardReadable):
|
|
34
|
-
"""
|
|
35
|
-
Grouping of motors for the P45 tomography stage
|
|
36
|
-
"""
|
|
30
|
+
"""Grouping of motors for the P45 tomography stage."""
|
|
37
31
|
|
|
38
32
|
def __init__(self, prefix: str, name: str = ""):
|
|
39
33
|
with self.add_children_as_readables():
|
dodal/devices/pgm.py
CHANGED
|
@@ -8,8 +8,14 @@ from ophyd_async.epics.motor import Motor
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class PlaneGratingMonochromator(StandardReadable):
|
|
11
|
-
"""
|
|
12
|
-
|
|
11
|
+
"""Plane grating monochromator, it is use in soft x-ray beamline to generate
|
|
12
|
+
monochromic beam.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
prefix (str): Beamline specific part of the PV.
|
|
16
|
+
grating (type[StrictEnum]): The Enum for the grating table.
|
|
17
|
+
grating_pv (str): The suffix PV part of grating PV.
|
|
18
|
+
name (str, optional): Name of the device.
|
|
13
19
|
"""
|
|
14
20
|
|
|
15
21
|
def __init__(
|
|
@@ -19,18 +25,6 @@ class PlaneGratingMonochromator(StandardReadable):
|
|
|
19
25
|
grating_pv: str = "GRATINGSELECT:SELECT",
|
|
20
26
|
name: str = "",
|
|
21
27
|
) -> None:
|
|
22
|
-
"""
|
|
23
|
-
Parameters
|
|
24
|
-
----------
|
|
25
|
-
prefix:
|
|
26
|
-
Beamline specific part of the PV
|
|
27
|
-
grating:
|
|
28
|
-
The Enum for the grating table.
|
|
29
|
-
grating_pv:
|
|
30
|
-
The suffix pv part of grating Pv
|
|
31
|
-
name:
|
|
32
|
-
Name of the device
|
|
33
|
-
"""
|
|
34
28
|
with self.add_children_as_readables():
|
|
35
29
|
self.energy = Motor(prefix + "ENERGY")
|
|
36
30
|
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
|
|
@@ -2,14 +2,21 @@ import asyncio
|
|
|
2
2
|
from enum import IntEnum
|
|
3
3
|
from typing import Generic, TypeVar
|
|
4
4
|
|
|
5
|
-
from bluesky.protocols import Movable
|
|
5
|
+
from bluesky.protocols import Movable, Stoppable, Triggerable
|
|
6
6
|
from ophyd_async.core import (
|
|
7
7
|
AsyncStatus,
|
|
8
|
+
DeviceMock,
|
|
8
9
|
DeviceVector,
|
|
10
|
+
Reference,
|
|
9
11
|
SignalR,
|
|
10
12
|
StandardReadable,
|
|
11
13
|
StandardReadableFormat,
|
|
12
14
|
StrictEnum,
|
|
15
|
+
callback_on_mock_put,
|
|
16
|
+
default_mock_class,
|
|
17
|
+
set_and_wait_for_other_value,
|
|
18
|
+
set_mock_value,
|
|
19
|
+
wait_for_value,
|
|
13
20
|
)
|
|
14
21
|
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
|
|
15
22
|
|
|
@@ -22,11 +29,6 @@ class PumpState(StrictEnum):
|
|
|
22
29
|
AUTO_POSITION = "Auto Position"
|
|
23
30
|
|
|
24
31
|
|
|
25
|
-
class StopState(StrictEnum):
|
|
26
|
-
CONTINUE = "CONTINUE"
|
|
27
|
-
STOP = "STOP"
|
|
28
|
-
|
|
29
|
-
|
|
30
32
|
class ValveControlRequest(StrictEnum):
|
|
31
33
|
OPEN = "Open"
|
|
32
34
|
CLOSE = "Close"
|
|
@@ -99,10 +101,8 @@ class ValveControl(
|
|
|
99
101
|
|
|
100
102
|
|
|
101
103
|
class AllValvesControl(StandardReadable):
|
|
102
|
-
"""
|
|
103
|
-
|
|
104
|
-
specific valves. Other valves are under manual
|
|
105
|
-
control.
|
|
104
|
+
"""The default IOC for this device only controls specific valves. Other valves are
|
|
105
|
+
under manual control.
|
|
106
106
|
"""
|
|
107
107
|
|
|
108
108
|
def __init__(
|
|
@@ -163,12 +163,10 @@ class Pump(StandardReadable):
|
|
|
163
163
|
|
|
164
164
|
|
|
165
165
|
class PressureTransducer(StandardReadable):
|
|
166
|
-
"""
|
|
167
|
-
Pressure transducer for a high pressure X-ray cell.
|
|
166
|
+
"""Pressure transducer for a high pressure X-ray cell.
|
|
168
167
|
This is the chamber and there are three of them.
|
|
169
168
|
1 is the start, 3 is where the sample is.
|
|
170
169
|
NOTE: the distinction between the adc prefix and the cell prefix is kept here.
|
|
171
|
-
|
|
172
170
|
"""
|
|
173
171
|
|
|
174
172
|
def __init__(
|
|
@@ -201,34 +199,99 @@ class PressureTransducer(StandardReadable):
|
|
|
201
199
|
super().__init__(name)
|
|
202
200
|
|
|
203
201
|
|
|
204
|
-
class
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
202
|
+
class DoJump(StandardReadable, Triggerable):
|
|
203
|
+
def __init__(
|
|
204
|
+
self,
|
|
205
|
+
prefix: str,
|
|
206
|
+
busy_signal: Reference,
|
|
207
|
+
timeout_signal: Reference,
|
|
208
|
+
name: str = "",
|
|
209
|
+
):
|
|
210
|
+
self._busy_signal = busy_signal
|
|
211
|
+
self._timeout_signal = timeout_signal
|
|
208
212
|
|
|
209
|
-
def __init__(self, prefix: str, name: str = "") -> None:
|
|
210
213
|
with self.add_children_as_readables():
|
|
211
|
-
self.
|
|
214
|
+
self.set_jump = epics_signal_rw(bool, f"{prefix}SETJUMP")
|
|
215
|
+
|
|
216
|
+
self._name = name
|
|
217
|
+
super().__init__(name)
|
|
218
|
+
|
|
219
|
+
@AsyncStatus.wrap
|
|
220
|
+
async def trigger(self):
|
|
221
|
+
await set_and_wait_for_other_value(
|
|
222
|
+
self.set_jump, True, self._busy_signal(), True
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
timeout_value = await self._timeout_signal().get_value()
|
|
226
|
+
await wait_for_value(self._busy_signal(), False, timeout_value)
|
|
212
227
|
|
|
213
|
-
self.target_pressure = epics_signal_rw(float, f"{prefix}TARGET")
|
|
214
|
-
self.timeout = epics_signal_rw(float, f"{prefix}TIMER.HIGH")
|
|
215
|
-
self.go = epics_signal_rw(bool, f"{prefix}GO")
|
|
216
228
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
self.jump_ready = epics_signal_rw(bool, f"{prefix}SETJUMP")
|
|
229
|
+
class PressureJumpCellController(StandardReadable, Movable, Stoppable):
|
|
230
|
+
"""Top-level control for a fixed pressure or pressure jumps."""
|
|
220
231
|
|
|
232
|
+
def __init__(self, prefix: str, name: str = "") -> None:
|
|
233
|
+
with self.add_children_as_readables():
|
|
234
|
+
# Common
|
|
235
|
+
self.busy = epics_signal_r(bool, f"{prefix}GOTOBUSY")
|
|
221
236
|
self.result = epics_signal_r(str, f"{prefix}RESULT")
|
|
237
|
+
self.timeout = epics_signal_rw(float, f"{prefix}TIMER.HIGH")
|
|
222
238
|
|
|
239
|
+
# Constant pressure
|
|
240
|
+
self.target_pressure = epics_signal_rw(int, f"{prefix}TARGET")
|
|
241
|
+
self.go = epics_signal_rw(bool, f"{prefix}GO")
|
|
242
|
+
|
|
243
|
+
# Pressure jump
|
|
244
|
+
self.from_pressure = epics_signal_rw(int, f"{prefix}JUMPF")
|
|
245
|
+
self.to_pressure = epics_signal_rw(int, f"{prefix}JUMPT")
|
|
246
|
+
self.do_jump = DoJump(
|
|
247
|
+
prefix, Reference(self.busy), Reference(self.timeout), name
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
# Internal
|
|
251
|
+
self._stop = epics_signal_rw(bool, f"{prefix}STOP")
|
|
223
252
|
self._name = name
|
|
253
|
+
|
|
224
254
|
super().__init__(name)
|
|
225
255
|
|
|
256
|
+
@AsyncStatus.wrap
|
|
257
|
+
async def set(self, value: int):
|
|
258
|
+
"""Sets the desired pressure waiting for the device to complete the
|
|
259
|
+
operation.
|
|
260
|
+
"""
|
|
261
|
+
timeout = await self.timeout.get_value()
|
|
262
|
+
|
|
263
|
+
await self.target_pressure.set(value)
|
|
264
|
+
await set_and_wait_for_other_value(self.go, True, self.busy, True)
|
|
265
|
+
|
|
266
|
+
await wait_for_value(self.busy, False, timeout) # Change complete
|
|
226
267
|
|
|
268
|
+
@AsyncStatus.wrap
|
|
269
|
+
async def stop(self, success=True):
|
|
270
|
+
await self._stop.set(True)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class BusyMock(DeviceMock["PressureJumpCell"]):
|
|
274
|
+
async def connect(self, device) -> None:
|
|
275
|
+
async def busy(*_, **__):
|
|
276
|
+
async def busy_idle():
|
|
277
|
+
await asyncio.sleep(0)
|
|
278
|
+
set_mock_value(device.control.busy, True)
|
|
279
|
+
await asyncio.sleep(0)
|
|
280
|
+
set_mock_value(device.control.busy, False)
|
|
281
|
+
|
|
282
|
+
asyncio.create_task(busy_idle())
|
|
283
|
+
|
|
284
|
+
callback_on_mock_put(device.control.go, busy)
|
|
285
|
+
callback_on_mock_put(device.control.do_jump.set_jump, busy)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
@default_mock_class(BusyMock)
|
|
227
289
|
class PressureJumpCell(StandardReadable):
|
|
228
|
-
"""
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
The prefix of beamline - SPECIAL - unusual that the cell prefix is
|
|
290
|
+
"""High pressure X-ray cell, used to apply pressure or pressure jumps to a sample.
|
|
291
|
+
|
|
292
|
+
Args:
|
|
293
|
+
prefix (str): The prefix of beamline - SPECIAL - unusual that the cell prefix is
|
|
294
|
+
computed separately.
|
|
232
295
|
"""
|
|
233
296
|
|
|
234
297
|
def __init__(
|
|
@@ -241,9 +304,7 @@ class PressureJumpCell(StandardReadable):
|
|
|
241
304
|
self.all_valves_control = AllValvesControl(f"{prefix}{cell_prefix}", name)
|
|
242
305
|
self.pump = Pump(f"{prefix}{cell_prefix}", name)
|
|
243
306
|
|
|
244
|
-
self.
|
|
245
|
-
f"{prefix}{cell_prefix}CTRL:", name
|
|
246
|
-
)
|
|
307
|
+
self.control = PressureJumpCellController(f"{prefix}{cell_prefix}CTRL:", name)
|
|
247
308
|
|
|
248
309
|
with self.add_children_as_readables():
|
|
249
310
|
self.pressure_transducers: DeviceVector[PressureTransducer] = DeviceVector(
|
dodal/devices/qbpm.py
CHANGED
|
@@ -3,9 +3,7 @@ from ophyd_async.epics.core import epics_signal_r
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class QBPM(StandardReadable):
|
|
6
|
-
"""
|
|
7
|
-
A beam position monitor that gives a position and intensity of the beam.
|
|
8
|
-
"""
|
|
6
|
+
"""A beam position monitor that gives a position and intensity of the beam."""
|
|
9
7
|
|
|
10
8
|
def __init__(
|
|
11
9
|
self,
|