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
|
@@ -5,15 +5,14 @@ from dodal.devices.electron_analyser.base.base_controller import (
|
|
|
5
5
|
)
|
|
6
6
|
from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector
|
|
7
7
|
from dodal.devices.electron_analyser.base.base_region import TLensMode, TPsuMode
|
|
8
|
-
from dodal.devices.electron_analyser.base.energy_sources import
|
|
9
|
-
DualEnergySource,
|
|
10
|
-
EnergySource,
|
|
11
|
-
)
|
|
8
|
+
from dodal.devices.electron_analyser.base.energy_sources import AbstractEnergySource
|
|
12
9
|
from dodal.devices.electron_analyser.specs.specs_driver_io import SpecsAnalyserDriverIO
|
|
13
10
|
from dodal.devices.electron_analyser.specs.specs_region import (
|
|
14
11
|
SpecsRegion,
|
|
15
12
|
SpecsSequence,
|
|
16
13
|
)
|
|
14
|
+
from dodal.devices.fast_shutter import FastShutter
|
|
15
|
+
from dodal.devices.selectable_source import SourceSelector
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
class SpecsDetector(
|
|
@@ -29,7 +28,9 @@ class SpecsDetector(
|
|
|
29
28
|
prefix: str,
|
|
30
29
|
lens_mode_type: type[TLensMode],
|
|
31
30
|
psu_mode_type: type[TPsuMode],
|
|
32
|
-
energy_source:
|
|
31
|
+
energy_source: AbstractEnergySource,
|
|
32
|
+
shutter: FastShutter | None = None,
|
|
33
|
+
source_selector: SourceSelector | None = None,
|
|
33
34
|
name: str = "",
|
|
34
35
|
):
|
|
35
36
|
# Save to class so takes part with connect()
|
|
@@ -39,7 +40,7 @@ class SpecsDetector(
|
|
|
39
40
|
|
|
40
41
|
controller = ElectronAnalyserController[
|
|
41
42
|
SpecsAnalyserDriverIO[TLensMode, TPsuMode], SpecsRegion[TLensMode, TPsuMode]
|
|
42
|
-
](self.driver, energy_source,
|
|
43
|
+
](self.driver, energy_source, shutter, source_selector)
|
|
43
44
|
|
|
44
45
|
sequence_class = SpecsSequence[lens_mode_type, psu_mode_type]
|
|
45
46
|
|
|
@@ -5,10 +5,7 @@ from dodal.devices.electron_analyser.base.base_controller import (
|
|
|
5
5
|
)
|
|
6
6
|
from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector
|
|
7
7
|
from dodal.devices.electron_analyser.base.base_region import TLensMode, TPsuMode
|
|
8
|
-
from dodal.devices.electron_analyser.base.energy_sources import
|
|
9
|
-
DualEnergySource,
|
|
10
|
-
EnergySource,
|
|
11
|
-
)
|
|
8
|
+
from dodal.devices.electron_analyser.base.energy_sources import AbstractEnergySource
|
|
12
9
|
from dodal.devices.electron_analyser.vgscienta.vgscienta_driver_io import (
|
|
13
10
|
VGScientaAnalyserDriverIO,
|
|
14
11
|
)
|
|
@@ -17,6 +14,8 @@ from dodal.devices.electron_analyser.vgscienta.vgscienta_region import (
|
|
|
17
14
|
VGScientaRegion,
|
|
18
15
|
VGScientaSequence,
|
|
19
16
|
)
|
|
17
|
+
from dodal.devices.fast_shutter import FastShutter
|
|
18
|
+
from dodal.devices.selectable_source import SourceSelector
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
class VGScientaDetector(
|
|
@@ -33,7 +32,9 @@ class VGScientaDetector(
|
|
|
33
32
|
lens_mode_type: type[TLensMode],
|
|
34
33
|
psu_mode_type: type[TPsuMode],
|
|
35
34
|
pass_energy_type: type[TPassEnergyEnum],
|
|
36
|
-
energy_source:
|
|
35
|
+
energy_source: AbstractEnergySource,
|
|
36
|
+
shutter: FastShutter | None = None,
|
|
37
|
+
source_selector: SourceSelector | None = None,
|
|
37
38
|
name: str = "",
|
|
38
39
|
):
|
|
39
40
|
# Save to class so takes part with connect()
|
|
@@ -44,7 +45,7 @@ class VGScientaDetector(
|
|
|
44
45
|
controller = ElectronAnalyserController[
|
|
45
46
|
VGScientaAnalyserDriverIO[TLensMode, TPsuMode, TPassEnergyEnum],
|
|
46
47
|
VGScientaRegion[TLensMode, TPassEnergyEnum],
|
|
47
|
-
](self.driver, energy_source,
|
|
48
|
+
](self.driver, energy_source, shutter, source_selector)
|
|
48
49
|
|
|
49
50
|
sequence_class = VGScientaSequence[
|
|
50
51
|
lens_mode_type, psu_mode_type, pass_energy_type
|
dodal/devices/eurotherm.py
CHANGED
|
@@ -37,7 +37,7 @@ _EUROTHERM_RBV: str = ":RBV"
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class EurothermPID(StandardReadable):
|
|
40
|
-
"""The class for the Eurotherm PID values"""
|
|
40
|
+
"""The class for the Eurotherm PID values."""
|
|
41
41
|
|
|
42
42
|
def __init__(
|
|
43
43
|
self,
|
|
@@ -111,7 +111,8 @@ class UpdatingEurothermGeneral(EurothermGeneral):
|
|
|
111
111
|
|
|
112
112
|
class EurothermAutotune(StandardReadable):
|
|
113
113
|
"""Newer versions of Eurotherm controllers have the ability to Autotune the
|
|
114
|
-
PID values, and this is the device
|
|
114
|
+
PID values, and this is the device.
|
|
115
|
+
"""
|
|
115
116
|
|
|
116
117
|
def __init__(
|
|
117
118
|
self,
|
dodal/devices/fast_grid_scan.py
CHANGED
|
@@ -44,34 +44,32 @@ class GridAxis:
|
|
|
44
44
|
full_steps: int
|
|
45
45
|
|
|
46
46
|
def steps_to_motor_position(self, steps):
|
|
47
|
-
"""Gives the motor position based on steps, where steps are 0 indexed"""
|
|
47
|
+
"""Gives the motor position based on steps, where steps are 0 indexed."""
|
|
48
48
|
return self.start + self.step_size_mm * steps
|
|
49
49
|
|
|
50
50
|
@property
|
|
51
51
|
def end(self):
|
|
52
|
-
"""Gives the point where the final frame is taken"""
|
|
52
|
+
"""Gives the point where the final frame is taken."""
|
|
53
53
|
# Note that full_steps is one indexed e.g. if there is one step then the end is
|
|
54
54
|
# refering to the first position
|
|
55
55
|
return self.steps_to_motor_position(self.full_steps - 1)
|
|
56
56
|
|
|
57
57
|
def is_within(self, steps: float):
|
|
58
|
-
"""
|
|
59
|
-
Determine whether a single axis coordinate is within the grid.
|
|
58
|
+
"""Determine whether a single axis coordinate is within the grid.
|
|
60
59
|
The coordinate is from a continuous coordinate space based on the
|
|
61
60
|
XRC grid where the origin corresponds to the centre of the first grid box.
|
|
62
61
|
|
|
63
62
|
Args:
|
|
64
|
-
steps: The coordinate to check
|
|
63
|
+
steps (float): The coordinate to check.
|
|
65
64
|
|
|
66
65
|
Returns:
|
|
67
|
-
True if the coordinate falls within the grid.
|
|
66
|
+
bool: True if the coordinate falls within the grid.
|
|
68
67
|
"""
|
|
69
68
|
return -0.5 <= steps <= self.full_steps - 0.5
|
|
70
69
|
|
|
71
70
|
|
|
72
71
|
class GridScanParamsCommon(AbstractExperimentWithBeamParams):
|
|
73
|
-
"""
|
|
74
|
-
Common holder class for the parameters of a grid scan in a similar
|
|
72
|
+
"""Common holder class for the parameters of a grid scan in a similar
|
|
75
73
|
layout to EPICS. The parameters and functions of this class are common
|
|
76
74
|
to both the zebra and panda triggered fast grid scans in 2d or 3d.
|
|
77
75
|
|
|
@@ -108,10 +106,12 @@ class GridScanParamsCommon(AbstractExperimentWithBeamParams):
|
|
|
108
106
|
to a real motor position.
|
|
109
107
|
|
|
110
108
|
Args:
|
|
111
|
-
grid_position: The x, y, z position in grid steps. The origin is
|
|
112
|
-
centre of the first grid box
|
|
109
|
+
grid_position (ndarray): The x, y, z position in grid steps. The origin is
|
|
110
|
+
at the centre of the first grid box
|
|
111
|
+
|
|
113
112
|
Returns:
|
|
114
|
-
The motor position this corresponds to.
|
|
113
|
+
ndarray: The motor position this corresponds to.
|
|
114
|
+
|
|
115
115
|
Raises:
|
|
116
116
|
IndexError if the desired position is outside the grid.
|
|
117
117
|
"""
|
|
@@ -133,8 +133,8 @@ class GridScanParamsCommon(AbstractExperimentWithBeamParams):
|
|
|
133
133
|
class GridScanParamsThreeD(GridScanParamsCommon):
|
|
134
134
|
"""Additional parameters required to do a 3 dimensional gridscan.
|
|
135
135
|
|
|
136
|
-
A 3D gridscan works by doing two 2D gridscans. The first of these grids is x_steps
|
|
137
|
-
y_steps. The sample is then rotated by 90 degrees, and then the second grid is
|
|
136
|
+
A 3D gridscan works by doing two 2D gridscans. The first of these grids is x_steps
|
|
137
|
+
by y_steps. The sample is then rotated by 90 degrees, and then the second grid is
|
|
138
138
|
x_steps by z_steps.
|
|
139
139
|
"""
|
|
140
140
|
|
|
@@ -173,16 +173,13 @@ class WithDwellTime(BaseModel):
|
|
|
173
173
|
|
|
174
174
|
|
|
175
175
|
class ZebraGridScanParamsThreeD(GridScanParamsThreeD, WithDwellTime):
|
|
176
|
-
"""
|
|
177
|
-
Params for standard Zebra FGS. Adds on the dwell time, which is really the time
|
|
176
|
+
"""Params for standard Zebra FGS. Adds on the dwell time, which is really the time
|
|
178
177
|
between trigger positions.
|
|
179
178
|
"""
|
|
180
179
|
|
|
181
180
|
|
|
182
181
|
class PandAGridScanParams(GridScanParamsThreeD):
|
|
183
|
-
"""
|
|
184
|
-
Params for panda constant-motion scan. Adds on the goniometer run-up distance
|
|
185
|
-
"""
|
|
182
|
+
"""Params for panda constant-motion scan. Adds on the goniometer run-up distance."""
|
|
186
183
|
|
|
187
184
|
run_up_distance_mm: float = 0.17
|
|
188
185
|
|
|
@@ -203,8 +200,8 @@ class FastGridScanCommon(
|
|
|
203
200
|
):
|
|
204
201
|
"""Device containing the minimal signals for a general fast grid scan.
|
|
205
202
|
|
|
206
|
-
When the motion program is started, the goniometer will move in a snake-like grid
|
|
207
|
-
with X as the fast axis and Y as the slow axis.
|
|
203
|
+
When the motion program is started, the goniometer will move in a snake-like grid
|
|
204
|
+
trajectory, with X as the fast axis and Y as the slow axis.
|
|
208
205
|
|
|
209
206
|
See ZebraFastGridScanThreeD as an example of how to implement.
|
|
210
207
|
"""
|
|
@@ -297,14 +294,14 @@ class FastGridScanCommon(
|
|
|
297
294
|
|
|
298
295
|
@AsyncStatus.wrap
|
|
299
296
|
async def prepare(self, value: ParamType):
|
|
300
|
-
"""
|
|
301
|
-
|
|
302
|
-
|
|
297
|
+
"""Submit the gridscan parameters to the device for validation prior to
|
|
298
|
+
gridscan kickoff.
|
|
299
|
+
|
|
303
300
|
Args:
|
|
304
|
-
value:
|
|
301
|
+
value (ParamType): The gridscan parameters.
|
|
305
302
|
|
|
306
303
|
Raises:
|
|
307
|
-
GridScanInvalidError:
|
|
304
|
+
GridScanInvalidError: If the gridscan parameters were not valid.
|
|
308
305
|
"""
|
|
309
306
|
set_statuses = []
|
|
310
307
|
|
|
@@ -426,8 +423,8 @@ class FastGridScanThreeD(FastGridScanCommon[ParamType]):
|
|
|
426
423
|
class ZebraFastGridScanThreeD(FastGridScanThreeD[ZebraGridScanParamsThreeD]):
|
|
427
424
|
"""Device for standard Zebra 3D FGS.
|
|
428
425
|
|
|
429
|
-
In this scan, the goniometer's velocity profile follows a parabolic shape between X
|
|
430
|
-
with the slowest points occuring at each X step.
|
|
426
|
+
In this scan, the goniometer's velocity profile follows a parabolic shape between X
|
|
427
|
+
steps, with the slowest points occuring at each X step.
|
|
431
428
|
"""
|
|
432
429
|
|
|
433
430
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
@@ -448,8 +445,8 @@ class ZebraFastGridScanThreeD(FastGridScanThreeD[ZebraGridScanParamsThreeD]):
|
|
|
448
445
|
class PandAFastGridScan(FastGridScanThreeD[PandAGridScanParams]):
|
|
449
446
|
"""Device for panda constant-motion scan.
|
|
450
447
|
|
|
451
|
-
In this scan, the goniometer's velocity
|
|
452
|
-
|
|
448
|
+
In this scan, the goniometer's velocity is constant through each row. It doesn't
|
|
449
|
+
slow down when going through trigger points.
|
|
453
450
|
"""
|
|
454
451
|
|
|
455
452
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
@@ -475,13 +472,13 @@ class PandAFastGridScan(FastGridScanThreeD[PandAGridScanParams]):
|
|
|
475
472
|
|
|
476
473
|
|
|
477
474
|
def set_fast_grid_scan_params(scan: FastGridScanCommon[ParamType], params: ParamType):
|
|
478
|
-
"""
|
|
479
|
-
|
|
475
|
+
"""Apply the fast grid scan parameters to the grid scan device and validate them.
|
|
476
|
+
|
|
480
477
|
Args:
|
|
481
|
-
scan: The fast grid scan device
|
|
482
|
-
params: The parameters to set
|
|
478
|
+
scan (FastGridScancommon[ParamType]): The fast grid scan device.
|
|
479
|
+
params (ParamType): The parameters to set.
|
|
483
480
|
|
|
484
481
|
Raises:
|
|
485
|
-
GridScanInvalidError: if the grid scan parameters are not valid
|
|
482
|
+
GridScanInvalidError: if the grid scan parameters are not valid.
|
|
486
483
|
"""
|
|
487
484
|
yield from prepare(scan, params, wait=True)
|
dodal/devices/fast_shutter.py
CHANGED
|
@@ -1,69 +1,155 @@
|
|
|
1
|
-
from typing import TypeVar
|
|
1
|
+
from typing import Generic, Protocol, TypeVar
|
|
2
2
|
|
|
3
3
|
from bluesky.protocols import Movable
|
|
4
4
|
from ophyd_async.core import (
|
|
5
5
|
AsyncStatus,
|
|
6
6
|
EnumTypes,
|
|
7
|
+
Reference,
|
|
8
|
+
SignalRW,
|
|
7
9
|
StandardReadable,
|
|
10
|
+
StandardReadableFormat,
|
|
11
|
+
derived_signal_rw,
|
|
12
|
+
soft_signal_r_and_setter,
|
|
8
13
|
)
|
|
9
14
|
from ophyd_async.epics.core import epics_signal_rw
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
from dodal.devices.selectable_source import SelectedSource, get_obj_from_selected_source
|
|
12
17
|
|
|
18
|
+
EnumTypesT = TypeVar("EnumTypesT", bound=EnumTypes)
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
|
|
21
|
+
class FastShutter(Movable[EnumTypesT], Protocol, Generic[EnumTypesT]):
|
|
22
|
+
"""Enum device specialised for a fast shutter with configured open_state and
|
|
17
23
|
close_state so it is generic enough to be used with any device or plan without
|
|
18
24
|
knowing the specific enum to use.
|
|
19
25
|
|
|
20
|
-
For example
|
|
26
|
+
For example::
|
|
27
|
+
|
|
21
28
|
await shutter.set(shutter.open_state)
|
|
22
29
|
await shutter.set(shutter.close_state)
|
|
23
|
-
|
|
30
|
+
|
|
31
|
+
OR::
|
|
32
|
+
|
|
24
33
|
run_engine(bps.mv(shutter, shutter.open_state))
|
|
25
34
|
run_engine(bps.mv(shutter, shutter.close_state))
|
|
26
35
|
"""
|
|
27
36
|
|
|
37
|
+
open_state: EnumTypesT
|
|
38
|
+
close_state: EnumTypesT
|
|
39
|
+
shutter_state: SignalRW[EnumTypesT]
|
|
40
|
+
|
|
41
|
+
@AsyncStatus.wrap
|
|
42
|
+
async def set(self, state: EnumTypesT):
|
|
43
|
+
await self.shutter_state.set(state)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class GenericFastShutter(
|
|
47
|
+
StandardReadable, FastShutter[EnumTypesT], Generic[EnumTypesT]
|
|
48
|
+
):
|
|
49
|
+
"""Implementation of fast shutter that connects to an epics pv. This pv is an enum that
|
|
50
|
+
controls the open and close state of the shutter.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
pv (str): The pv to connect to the shutter device.
|
|
54
|
+
open_state (EnumTypesT): The enum value that corresponds with opening the
|
|
55
|
+
shutter.
|
|
56
|
+
close_state (EnumTypesT): The enum value that corresponds with closing the
|
|
57
|
+
shutter.
|
|
58
|
+
name (str, optional): The name of the shutter.
|
|
59
|
+
"""
|
|
60
|
+
|
|
28
61
|
def __init__(
|
|
29
62
|
self,
|
|
30
63
|
pv: str,
|
|
31
|
-
open_state:
|
|
32
|
-
close_state:
|
|
64
|
+
open_state: EnumTypesT,
|
|
65
|
+
close_state: EnumTypesT,
|
|
33
66
|
name: str = "",
|
|
34
67
|
):
|
|
35
|
-
"""
|
|
36
|
-
Arguments:
|
|
37
|
-
pv: The pv to connect to the shutter device.
|
|
38
|
-
open_state: The enum value that corresponds with opening the shutter.
|
|
39
|
-
close_state: The enum value that corresponds with closing the shutter.
|
|
40
|
-
"""
|
|
41
68
|
self.open_state = open_state
|
|
42
69
|
self.close_state = close_state
|
|
43
70
|
with self.add_children_as_readables():
|
|
44
|
-
self.
|
|
71
|
+
self.shutter_state = epics_signal_rw(type(self.open_state), pv)
|
|
45
72
|
super().__init__(name)
|
|
46
73
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
|
|
75
|
+
class DualFastShutter(StandardReadable, FastShutter[EnumTypesT], Generic[EnumTypesT]):
|
|
76
|
+
"""A fast shutter device that handles the positions of two other fast shutters. The
|
|
77
|
+
"active" shutter is the one that corrosponds to the selected_shutter signal. For
|
|
78
|
+
example, active shutter is shutter1 if selected_source is at SelectedSource.SOURCE1
|
|
79
|
+
and vise versa for shutter2 and SelectedSource.SOURCE2. Whenever a move is done on
|
|
80
|
+
this device, the inactive shutter is always set to the close_state.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
shutter1 (GenericFastShutter): Active shutter that corrosponds to
|
|
84
|
+
SelectedSource.SOURCE1.
|
|
85
|
+
shutter2 (GenericFastShutter): Active shutter that corrosponds to
|
|
86
|
+
SelectedSource.SOURCE2.
|
|
87
|
+
selected_source (SignalRW): Signal that decides the active shutter.
|
|
88
|
+
name (str, optional): Name of this device.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
shutter1: GenericFastShutter[EnumTypesT],
|
|
94
|
+
shutter2: GenericFastShutter[EnumTypesT],
|
|
95
|
+
selected_source: SignalRW[SelectedSource],
|
|
96
|
+
name: str = "",
|
|
97
|
+
):
|
|
98
|
+
self._validate_shutter_states(shutter1.open_state, shutter2.open_state)
|
|
99
|
+
self._validate_shutter_states(shutter1.close_state, shutter2.close_state)
|
|
100
|
+
self.open_state = shutter1.open_state
|
|
101
|
+
self.close_state = shutter1.close_state
|
|
102
|
+
|
|
103
|
+
self._shutter1_ref = Reference(shutter1)
|
|
104
|
+
self._shutter2_ref = Reference(shutter2)
|
|
105
|
+
self._selected_shutter_ref = Reference(selected_source)
|
|
106
|
+
|
|
107
|
+
with self.add_children_as_readables():
|
|
108
|
+
self.shutter_state = derived_signal_rw(
|
|
109
|
+
self._read_shutter_state,
|
|
110
|
+
self._set_shutter_state,
|
|
111
|
+
selected_shutter=selected_source,
|
|
112
|
+
shutter1=shutter1.shutter_state,
|
|
113
|
+
shutter2=shutter2.shutter_state,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
|
|
117
|
+
self.shutter1_device_name, _ = soft_signal_r_and_setter(
|
|
118
|
+
str, initial_value=shutter1.name
|
|
119
|
+
)
|
|
120
|
+
self.shutter2_device_name, _ = soft_signal_r_and_setter(
|
|
121
|
+
str, initial_value=shutter2.name
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
self.add_readables([shutter1, shutter2, selected_source])
|
|
125
|
+
|
|
126
|
+
super().__init__(name)
|
|
127
|
+
|
|
128
|
+
def _validate_shutter_states(self, state1: EnumTypesT, state2: EnumTypesT) -> None:
|
|
129
|
+
if state1 is not state2:
|
|
130
|
+
raise ValueError(
|
|
131
|
+
f"{state1} is not same value as {state2}. They must be the same to be compatible."
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def _read_shutter_state(
|
|
135
|
+
self,
|
|
136
|
+
selected_shutter: SelectedSource,
|
|
137
|
+
shutter1: EnumTypesT,
|
|
138
|
+
shutter2: EnumTypesT,
|
|
139
|
+
) -> EnumTypesT:
|
|
140
|
+
return get_obj_from_selected_source(selected_shutter, shutter1, shutter2)
|
|
141
|
+
|
|
142
|
+
async def _set_shutter_state(self, value: EnumTypesT):
|
|
143
|
+
selected_shutter = await self._selected_shutter_ref().get_value()
|
|
144
|
+
active_shutter = get_obj_from_selected_source(
|
|
145
|
+
selected_shutter,
|
|
146
|
+
self._shutter1_ref(),
|
|
147
|
+
self._shutter2_ref(),
|
|
148
|
+
)
|
|
149
|
+
inactive_shutter = get_obj_from_selected_source(
|
|
150
|
+
selected_shutter,
|
|
151
|
+
self._shutter2_ref(),
|
|
152
|
+
self._shutter1_ref(),
|
|
153
|
+
)
|
|
154
|
+
await inactive_shutter.set(inactive_shutter.close_state)
|
|
155
|
+
await active_shutter.set(value)
|
dodal/devices/flux.py
CHANGED
|
@@ -6,7 +6,7 @@ from ophyd_async.epics.core import epics_signal_r
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class Flux(StandardReadable):
|
|
9
|
-
"""Simple device to get the flux reading"""
|
|
9
|
+
"""Simple device to get the flux reading."""
|
|
10
10
|
|
|
11
11
|
def __init__(self, prefix: str, name="") -> None:
|
|
12
12
|
with self.add_children_as_readables(StandardReadableFormat.HINTED_SIGNAL):
|
dodal/devices/focusing_mirror.py
CHANGED
|
@@ -27,7 +27,7 @@ DEFAULT_SETTLE_TIME_S = 60
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class MirrorType(StrictEnum):
|
|
30
|
-
"""See https://manual.nexusformat.org/classes/base_classes/NXmirror.html"""
|
|
30
|
+
"""See https://manual.nexusformat.org/classes/base_classes/NXmirror.html."""
|
|
31
31
|
|
|
32
32
|
SINGLE = "single"
|
|
33
33
|
MULTI = "multi"
|
|
@@ -53,8 +53,9 @@ class MirrorVoltageDemand(StrictEnum):
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
class SingleMirrorVoltage(Device):
|
|
56
|
-
"""Abstract the bimorph mirror voltage PVs into a single device that can be set
|
|
57
|
-
the demanded voltage setpoint is accepted, without
|
|
56
|
+
"""Abstract the bimorph mirror voltage PVs into a single device that can be set
|
|
57
|
+
asynchronously and returns when the demanded voltage setpoint is accepted, without
|
|
58
|
+
blocking the caller as this process can take significant time.
|
|
58
59
|
"""
|
|
59
60
|
|
|
60
61
|
def __init__(self, prefix: str, name: str = ""):
|
|
@@ -66,11 +67,14 @@ class SingleMirrorVoltage(Device):
|
|
|
66
67
|
@AsyncStatus.wrap
|
|
67
68
|
async def set(self, value, *args, **kwargs):
|
|
68
69
|
"""Combine the following operations into a single set:
|
|
69
|
-
1. apply the value to the setpoint PV
|
|
70
|
-
3. Wait until demand is accepted
|
|
71
|
-
4. When either demand is accepted or DEFAULT_SETTLE_TIME expires, signal the result on the Status
|
|
72
|
-
"""
|
|
73
70
|
|
|
71
|
+
1. apply the value to the setpoint PV.
|
|
72
|
+
|
|
73
|
+
3. Wait until demand is accepted.
|
|
74
|
+
|
|
75
|
+
4. When either demand is accepted or DEFAULT_SETTLE_TIME expires, signal the
|
|
76
|
+
result on the Status.
|
|
77
|
+
""" # noqa D415
|
|
74
78
|
setpoint_v = self._setpoint_v
|
|
75
79
|
demand_accepted = self._demand_accepted
|
|
76
80
|
|
|
@@ -136,7 +140,7 @@ class MirrorVoltages(StandardReadable):
|
|
|
136
140
|
|
|
137
141
|
|
|
138
142
|
class SimpleMirror(XYPitchStage):
|
|
139
|
-
"""Simple Focusing Mirror"""
|
|
143
|
+
"""Simple Focusing Mirror."""
|
|
140
144
|
|
|
141
145
|
def __init__(
|
|
142
146
|
self,
|
|
@@ -165,7 +169,7 @@ class SimpleMirror(XYPitchStage):
|
|
|
165
169
|
|
|
166
170
|
|
|
167
171
|
class FocusingMirror(StandardReadable):
|
|
168
|
-
"""Focusing Mirror"""
|
|
172
|
+
"""Focusing Mirror."""
|
|
169
173
|
|
|
170
174
|
def __init__(
|
|
171
175
|
self,
|
|
@@ -202,7 +206,8 @@ class FocusingMirror(StandardReadable):
|
|
|
202
206
|
|
|
203
207
|
class FocusingMirrorWithStripes(FocusingMirror):
|
|
204
208
|
"""A focusing mirror where the stripe material can be changed. This is usually done
|
|
205
|
-
based on the energy of the beamline.
|
|
209
|
+
based on the energy of the beamline.
|
|
210
|
+
"""
|
|
206
211
|
|
|
207
212
|
def __init__(self, prefix: str, name: str = "", *args, **kwargs):
|
|
208
213
|
self.stripe = epics_signal_rw(MirrorStripe, prefix + "STRP:DVAL")
|
|
@@ -212,9 +217,22 @@ class FocusingMirrorWithStripes(FocusingMirror):
|
|
|
212
217
|
super().__init__(prefix, name, *args, **kwargs)
|
|
213
218
|
|
|
214
219
|
def energy_to_stripe(self, energy_kev) -> MirrorStripeConfiguration:
|
|
215
|
-
"""Return the stripe, yaw angle and lateral position for the specified energy"""
|
|
220
|
+
"""Return the stripe, yaw angle and lateral position for the specified energy."""
|
|
216
221
|
# In future, this should be configurable per-mirror
|
|
217
222
|
if energy_kev < 7:
|
|
218
223
|
return {"stripe": MirrorStripe.BARE, "yaw_mrad": 6.2, "lat_mm": 0.0}
|
|
219
224
|
else:
|
|
220
225
|
return {"stripe": MirrorStripe.RHODIUM, "yaw_mrad": 0.0, "lat_mm": 10.0}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
class FocusingMirrorWithPiezo(FocusingMirror):
|
|
229
|
+
"""A focusing mirror which also has a piezoelectric actuator.
|
|
230
|
+
A voltage can be applied to the piezo to steer the beam by making the material
|
|
231
|
+
shrink or expand.
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
def __init__(self, prefix: str, name: str = "", *args, **kwargs):
|
|
235
|
+
with self.add_children_as_readables():
|
|
236
|
+
self.piezo = epics_signal_rw(float, f"{prefix}AOFPITCH")
|
|
237
|
+
self.piezo_rbv = epics_signal_r(float, f"{prefix}AOFPITCH:RBV")
|
|
238
|
+
super().__init__(prefix, name, *args, **kwargs)
|
dodal/devices/hutch_shutter.py
CHANGED
|
@@ -58,14 +58,14 @@ class HutchInterlock(StandardReadable):
|
|
|
58
58
|
class HutchShutter(StandardReadable, Movable[ShutterDemand]):
|
|
59
59
|
"""Device to operate the hutch shutter.
|
|
60
60
|
|
|
61
|
-
When a demand is sent, the device should first check the hutch status
|
|
62
|
-
and raise an error if it's not interlocked (searched and locked), meaning it's not
|
|
61
|
+
When a demand is sent, the device should first check the hutch status
|
|
62
|
+
and raise an error if it's not interlocked (searched and locked), meaning it's not
|
|
63
63
|
safe to operate the shutter.
|
|
64
64
|
|
|
65
|
-
If the requested shutter position is "Open", the shutter control PV should first
|
|
66
|
-
go to "Reset" and then move to "Open". This is because before opening the hutch
|
|
67
|
-
shutter, the interlock status PV (`-PS-SHTR-01:ILKSTA`) will show as `failed` until
|
|
68
|
-
the hutch shutter is reset. This will set the interlock status to `OK`, allowing
|
|
65
|
+
If the requested shutter position is "Open", the shutter control PV should first
|
|
66
|
+
go to "Reset" and then move to "Open". This is because before opening the hutch
|
|
67
|
+
shutter, the interlock status PV (`-PS-SHTR-01:ILKSTA`) will show as `failed` until
|
|
68
|
+
the hutch shutter is reset. This will set the interlock status to `OK`, allowing
|
|
69
69
|
for shutter operations. Until this step is done, the hutch shutter can't be opened.
|
|
70
70
|
The reset is not needed for closing the shutter.
|
|
71
71
|
"""
|
|
@@ -1,38 +1,48 @@
|
|
|
1
|
-
from .
|
|
2
|
-
DEFAULT_MOTOR_MIN_TIMEOUT,
|
|
1
|
+
from .apple2_controller import (
|
|
3
2
|
MAXIMUM_MOVE_TIME,
|
|
4
|
-
Apple2,
|
|
5
3
|
Apple2Controller,
|
|
6
4
|
Apple2EnforceLHMoveController,
|
|
5
|
+
Apple2Type,
|
|
6
|
+
EnergyMotorConvertor,
|
|
7
|
+
)
|
|
8
|
+
from .apple2_undulator import (
|
|
9
|
+
DEFAULT_MOTOR_MIN_TIMEOUT,
|
|
10
|
+
Apple2,
|
|
7
11
|
Apple2LockedPhasesVal,
|
|
8
12
|
Apple2PhasesVal,
|
|
9
13
|
Apple2Val,
|
|
10
|
-
BeamEnergy,
|
|
11
14
|
EnabledDisabledUpper,
|
|
12
|
-
EnergyMotorConvertor,
|
|
13
|
-
InsertionDeviceEnergy,
|
|
14
|
-
InsertionDevicePolarisation,
|
|
15
15
|
UndulatorGap,
|
|
16
16
|
UndulatorJawPhase,
|
|
17
17
|
UndulatorLockedPhaseAxes,
|
|
18
18
|
UndulatorPhaseAxes,
|
|
19
|
+
UnstoppableMotor,
|
|
20
|
+
)
|
|
21
|
+
from .apple_knot_controller import (
|
|
22
|
+
AppleKnotController,
|
|
23
|
+
AppleKnotPathFinder,
|
|
19
24
|
)
|
|
25
|
+
from .energy import BeamEnergy, InsertionDeviceEnergy, InsertionDeviceEnergyBase
|
|
20
26
|
from .energy_motor_lookup import (
|
|
21
27
|
ConfigServerEnergyMotorLookup,
|
|
22
28
|
EnergyMotorLookup,
|
|
23
29
|
)
|
|
24
|
-
from .
|
|
30
|
+
from .enum import Pol, UndulatorGateStatus
|
|
25
31
|
from .lookup_table_models import (
|
|
26
32
|
EnergyCoverage,
|
|
27
33
|
LookupTable,
|
|
28
34
|
LookupTableColumnConfig,
|
|
29
35
|
convert_csv_to_lookup,
|
|
30
36
|
)
|
|
37
|
+
from .polarisation import InsertionDevicePolarisation
|
|
31
38
|
|
|
32
39
|
__all__ = [
|
|
33
40
|
"Apple2",
|
|
41
|
+
"Apple2Type",
|
|
34
42
|
"Apple2Controller",
|
|
35
43
|
"Apple2EnforceLHMoveController",
|
|
44
|
+
"AppleKnotController",
|
|
45
|
+
"AppleKnotPathFinder",
|
|
36
46
|
"UndulatorGap",
|
|
37
47
|
"UndulatorPhaseAxes",
|
|
38
48
|
"UndulatorJawPhase",
|
|
@@ -55,4 +65,6 @@ __all__ = [
|
|
|
55
65
|
"EnergyMotorLookup",
|
|
56
66
|
"ConfigServerEnergyMotorLookup",
|
|
57
67
|
"EnergyMotorConvertor",
|
|
68
|
+
"UnstoppableMotor",
|
|
69
|
+
"InsertionDeviceEnergyBase",
|
|
58
70
|
]
|