ophyd-async 0.8.0a5__py3-none-any.whl → 0.9.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.
- ophyd_async/_version.py +2 -2
- ophyd_async/core/__init__.py +17 -46
- ophyd_async/core/_detector.py +68 -44
- ophyd_async/core/_device.py +120 -79
- ophyd_async/core/_device_filler.py +17 -8
- ophyd_async/core/_flyer.py +2 -2
- ophyd_async/core/_protocol.py +0 -28
- ophyd_async/core/_readable.py +30 -23
- ophyd_async/core/_settings.py +104 -0
- ophyd_async/core/_signal.py +164 -151
- ophyd_async/core/_signal_backend.py +4 -1
- ophyd_async/core/_soft_signal_backend.py +2 -1
- ophyd_async/core/_table.py +27 -14
- ophyd_async/core/_utils.py +30 -5
- ophyd_async/core/_yaml_settings.py +64 -0
- ophyd_async/epics/adandor/__init__.py +9 -0
- ophyd_async/epics/adandor/_andor.py +45 -0
- ophyd_async/epics/adandor/_andor_controller.py +49 -0
- ophyd_async/epics/adandor/_andor_io.py +36 -0
- ophyd_async/epics/adaravis/__init__.py +3 -1
- ophyd_async/epics/adaravis/_aravis.py +23 -37
- ophyd_async/epics/adaravis/_aravis_controller.py +21 -30
- ophyd_async/epics/adaravis/_aravis_io.py +4 -4
- ophyd_async/epics/adcore/__init__.py +15 -8
- ophyd_async/epics/adcore/_core_detector.py +41 -0
- ophyd_async/epics/adcore/_core_io.py +56 -31
- ophyd_async/epics/adcore/_core_logic.py +99 -84
- ophyd_async/epics/adcore/_core_writer.py +219 -0
- ophyd_async/epics/adcore/_hdf_writer.py +33 -59
- ophyd_async/epics/adcore/_jpeg_writer.py +26 -0
- ophyd_async/epics/adcore/_single_trigger.py +5 -4
- ophyd_async/epics/adcore/_tiff_writer.py +26 -0
- ophyd_async/epics/adcore/_utils.py +37 -36
- ophyd_async/epics/adkinetix/_kinetix.py +29 -24
- ophyd_async/epics/adkinetix/_kinetix_controller.py +15 -27
- ophyd_async/epics/adkinetix/_kinetix_io.py +7 -7
- ophyd_async/epics/adpilatus/__init__.py +2 -2
- ophyd_async/epics/adpilatus/_pilatus.py +28 -40
- ophyd_async/epics/adpilatus/_pilatus_controller.py +47 -25
- ophyd_async/epics/adpilatus/_pilatus_io.py +5 -5
- ophyd_async/epics/adsimdetector/__init__.py +3 -3
- ophyd_async/epics/adsimdetector/_sim.py +33 -17
- ophyd_async/epics/advimba/_vimba.py +23 -23
- ophyd_async/epics/advimba/_vimba_controller.py +21 -35
- ophyd_async/epics/advimba/_vimba_io.py +23 -23
- ophyd_async/epics/core/_aioca.py +52 -21
- ophyd_async/epics/core/_p4p.py +59 -16
- ophyd_async/epics/core/_pvi_connector.py +4 -2
- ophyd_async/epics/core/_signal.py +9 -2
- ophyd_async/epics/core/_util.py +10 -1
- ophyd_async/epics/eiger/_eiger_controller.py +10 -5
- ophyd_async/epics/eiger/_eiger_io.py +3 -3
- ophyd_async/epics/motor.py +26 -15
- ophyd_async/epics/sim/_ioc.py +29 -0
- ophyd_async/epics/{demo → sim}/_mover.py +12 -6
- ophyd_async/epics/{demo → sim}/_sensor.py +2 -2
- ophyd_async/epics/testing/__init__.py +24 -0
- ophyd_async/epics/testing/_example_ioc.py +91 -0
- ophyd_async/epics/testing/_utils.py +50 -0
- ophyd_async/epics/testing/test_records.db +174 -0
- ophyd_async/epics/testing/test_records_pva.db +177 -0
- ophyd_async/fastcs/core.py +2 -2
- ophyd_async/fastcs/panda/__init__.py +0 -2
- ophyd_async/fastcs/panda/_block.py +9 -9
- ophyd_async/fastcs/panda/_control.py +9 -4
- ophyd_async/fastcs/panda/_hdf_panda.py +7 -2
- ophyd_async/fastcs/panda/_table.py +4 -1
- ophyd_async/fastcs/panda/_trigger.py +7 -7
- ophyd_async/plan_stubs/__init__.py +14 -0
- ophyd_async/plan_stubs/_ensure_connected.py +11 -17
- ophyd_async/plan_stubs/_fly.py +2 -2
- ophyd_async/plan_stubs/_nd_attributes.py +7 -5
- ophyd_async/plan_stubs/_panda.py +13 -0
- ophyd_async/plan_stubs/_settings.py +125 -0
- ophyd_async/plan_stubs/_wait_for_awaitable.py +13 -0
- ophyd_async/sim/__init__.py +19 -0
- ophyd_async/sim/{demo/_pattern_detector → _pattern_detector}/_pattern_detector_controller.py +9 -2
- ophyd_async/sim/{demo/_pattern_detector → _pattern_detector}/_pattern_generator.py +13 -6
- ophyd_async/sim/{demo/_sim_motor.py → _sim_motor.py} +34 -32
- ophyd_async/tango/__init__.py +0 -43
- ophyd_async/tango/{signal → core}/__init__.py +7 -2
- ophyd_async/tango/{base_devices → core}/_base_device.py +38 -64
- ophyd_async/tango/{signal → core}/_signal.py +16 -4
- ophyd_async/tango/{base_devices → core}/_tango_readable.py +3 -4
- ophyd_async/tango/{signal → core}/_tango_transport.py +13 -15
- ophyd_async/tango/{demo → sim}/_counter.py +6 -7
- ophyd_async/tango/{demo → sim}/_mover.py +13 -9
- ophyd_async/testing/__init__.py +52 -0
- ophyd_async/testing/__pytest_assert_rewrite.py +4 -0
- ophyd_async/testing/_assert.py +176 -0
- ophyd_async/{core → testing}/_mock_signal_utils.py +15 -11
- ophyd_async/testing/_one_of_everything.py +126 -0
- ophyd_async/testing/_wait_for_pending.py +22 -0
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.9.0.dist-info}/METADATA +50 -48
- ophyd_async-0.9.0.dist-info/RECORD +129 -0
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.9.0.dist-info}/WHEEL +1 -1
- ophyd_async/core/_device_save_loader.py +0 -274
- ophyd_async/epics/adsimdetector/_sim_controller.py +0 -51
- ophyd_async/fastcs/panda/_utils.py +0 -16
- ophyd_async/sim/demo/__init__.py +0 -19
- ophyd_async/sim/testing/__init__.py +0 -0
- ophyd_async/tango/base_devices/__init__.py +0 -4
- ophyd_async-0.8.0a5.dist-info/RECORD +0 -112
- ophyd_async-0.8.0a5.dist-info/entry_points.txt +0 -2
- /ophyd_async/epics/{demo → sim}/__init__.py +0 -0
- /ophyd_async/epics/{demo → sim}/mover.db +0 -0
- /ophyd_async/epics/{demo → sim}/sensor.db +0 -0
- /ophyd_async/sim/{demo/_pattern_detector → _pattern_detector}/__init__.py +0 -0
- /ophyd_async/sim/{demo/_pattern_detector → _pattern_detector}/_pattern_detector.py +0 -0
- /ophyd_async/sim/{demo/_pattern_detector → _pattern_detector}/_pattern_detector_writer.py +0 -0
- /ophyd_async/tango/{demo → sim}/__init__.py +0 -0
- /ophyd_async/tango/{demo → sim}/_detector.py +0 -0
- /ophyd_async/tango/{demo → sim}/_tango/__init__.py +0 -0
- /ophyd_async/tango/{demo → sim}/_tango/_servers.py +0 -0
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.9.0.dist-info}/LICENSE +0 -0
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.9.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
record(bo, "$(device)bool") {
|
|
2
|
+
field(ZNAM, "No")
|
|
3
|
+
field(ONAM, "Yes")
|
|
4
|
+
field(VAL, "1")
|
|
5
|
+
field(PINI, "YES")
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
record(bo, "$(device)bool_unnamed") {
|
|
9
|
+
field(VAL, "1")
|
|
10
|
+
field(PINI, "YES")
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
record(longout, "$(device)int") {
|
|
14
|
+
field(LLSV, "MAJOR") # LOLO is alarm
|
|
15
|
+
field(LSV, "MINOR") # LOW is warning
|
|
16
|
+
field(HSV, "MINOR") # HIGH is warning
|
|
17
|
+
field(HHSV, "MAJOR") # HIHI is alarm
|
|
18
|
+
field(HOPR, "100")
|
|
19
|
+
field(HIHI, "98")
|
|
20
|
+
field(HIGH, "96")
|
|
21
|
+
field(DRVH, "90")
|
|
22
|
+
field(DRVL, "10")
|
|
23
|
+
field(LOW, "5")
|
|
24
|
+
field(LOLO, "2")
|
|
25
|
+
field(LOPR, "0")
|
|
26
|
+
field(VAL, "42")
|
|
27
|
+
field(PINI, "YES")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
record(longout, "$(device)partialint") {
|
|
31
|
+
field(LLSV, "MAJOR") # LOLO is alarm
|
|
32
|
+
field(HHSV, "MAJOR") # HIHI is alarm
|
|
33
|
+
field(HOPR, "100")
|
|
34
|
+
field(HIHI, "98")
|
|
35
|
+
field(DRVH, "90")
|
|
36
|
+
field(DRVL, "10")
|
|
37
|
+
field(LOLO, "2")
|
|
38
|
+
field(LOPR, "0")
|
|
39
|
+
field(VAL, "42")
|
|
40
|
+
field(PINI, "YES")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
record(longout, "$(device)lessint") {
|
|
44
|
+
field(HSV, "MINOR") # LOW is warning
|
|
45
|
+
field(LSV, "MINOR") # HIGH is warning
|
|
46
|
+
field(HOPR, "100")
|
|
47
|
+
field(HIGH, "98")
|
|
48
|
+
field(LOW, "2")
|
|
49
|
+
field(LOPR, "0")
|
|
50
|
+
field(VAL, "42")
|
|
51
|
+
field(PINI, "YES")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
record(ao, "$(device)float") {
|
|
55
|
+
field(PREC, "1")
|
|
56
|
+
field(EGU, "mm")
|
|
57
|
+
field(VAL, "3.141")
|
|
58
|
+
field(PINI, "YES")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
record(ao, "$(device)float_prec_0") {
|
|
62
|
+
field(PREC, "0")
|
|
63
|
+
field(EGU, "mm")
|
|
64
|
+
field(VAL, "3")
|
|
65
|
+
field(PINI, "YES")
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
record(ao, "$(device)float_prec_1") {
|
|
69
|
+
field(PREC, "1")
|
|
70
|
+
field(EGU, "mm")
|
|
71
|
+
field(VAL, "3")
|
|
72
|
+
field(PINI, "YES")
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
record(stringout, "$(device)str") {
|
|
76
|
+
field(VAL, "hello")
|
|
77
|
+
field(PINI, "YES")
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
record(mbbo, "$(device)enum") {
|
|
81
|
+
field(ZRST, "Aaa")
|
|
82
|
+
field(ZRVL, "5")
|
|
83
|
+
field(ONST, "Bbb")
|
|
84
|
+
field(ONVL, "6")
|
|
85
|
+
field(TWST, "Ccc")
|
|
86
|
+
field(TWVL, "7")
|
|
87
|
+
field(VAL, "1")
|
|
88
|
+
field(PINI, "YES")
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
record(mbbo, "$(device)enum2") {
|
|
92
|
+
field(ZRST, "Aaa")
|
|
93
|
+
field(ONST, "Bbb")
|
|
94
|
+
field(TWST, "Ccc")
|
|
95
|
+
field(VAL, "1")
|
|
96
|
+
field(PINI, "YES")
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
record(mbbo, "$(device)subset_enum") {
|
|
100
|
+
field(ZRST, "Aaa")
|
|
101
|
+
field(ONST, "Bbb")
|
|
102
|
+
field(TWST, "Ccc")
|
|
103
|
+
field(VAL, "1")
|
|
104
|
+
field(PINI, "YES")
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
record(mbbo, "$(device)enum_str_fallback") {
|
|
108
|
+
field(ZRST, "Aaa")
|
|
109
|
+
field(ONST, "Bbb")
|
|
110
|
+
field(TWST, "Ccc")
|
|
111
|
+
field(VAL, "1")
|
|
112
|
+
field(PINI, "YES")
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
record(waveform, "$(device)uint8a") {
|
|
116
|
+
field(NELM, "3")
|
|
117
|
+
field(FTVL, "UCHAR")
|
|
118
|
+
field(INP, {const:[0, 255]})
|
|
119
|
+
field(PINI, "YES")
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
record(waveform, "$(device)int16a") {
|
|
123
|
+
field(NELM, "3")
|
|
124
|
+
field(FTVL, "SHORT")
|
|
125
|
+
field(INP, {const:[-32768, 32767]})
|
|
126
|
+
field(PINI, "YES")
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
record(waveform, "$(device)int32a") {
|
|
130
|
+
field(NELM, "3")
|
|
131
|
+
field(FTVL, "LONG")
|
|
132
|
+
field(INP, {const:[-2147483648, 2147483647]})
|
|
133
|
+
field(PINI, "YES")
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
record(waveform, "$(device)float32a") {
|
|
137
|
+
field(NELM, "3")
|
|
138
|
+
field(FTVL, "FLOAT")
|
|
139
|
+
field(INP, {const:[0.000002, -123.123]})
|
|
140
|
+
field(PINI, "YES")
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
record(waveform, "$(device)float64a") {
|
|
144
|
+
field(NELM, "3")
|
|
145
|
+
field(FTVL, "DOUBLE")
|
|
146
|
+
field(INP, {const:[0.1, -12345678.123]})
|
|
147
|
+
field(PINI, "YES")
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
record(waveform, "$(device)stra") {
|
|
151
|
+
field(NELM, "3")
|
|
152
|
+
field(FTVL, "STRING")
|
|
153
|
+
field(INP, {const:["five", "six", "seven"]})
|
|
154
|
+
field(PINI, "YES")
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
record(waveform, "$(device)longstr") {
|
|
158
|
+
field(NELM, "80")
|
|
159
|
+
field(FTVL, "CHAR")
|
|
160
|
+
field(INP, {const:"a string that is just longer than forty characters"})
|
|
161
|
+
field(PINI, "YES")
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
record(lsi, "$(device)longstr2") {
|
|
165
|
+
field(SIZV, "80")
|
|
166
|
+
field(INP, {const:"a string that is just longer than forty characters"})
|
|
167
|
+
field(PINI, "YES")
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
record(calc, "$(device)ticking") {
|
|
171
|
+
field(INPA, "$(device)ticking")
|
|
172
|
+
field(CALC, "A+1")
|
|
173
|
+
field(SCAN, ".1 second")
|
|
174
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
record(waveform, "$(device)int8a") {
|
|
2
|
+
field(NELM, "3")
|
|
3
|
+
field(FTVL, "CHAR")
|
|
4
|
+
field(INP, {const:[-128, 127]})
|
|
5
|
+
field(PINI, "YES")
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
record(waveform, "$(device)uint16a") {
|
|
9
|
+
field(NELM, "3")
|
|
10
|
+
field(FTVL, "USHORT")
|
|
11
|
+
field(INP, {const:[0, 65535]})
|
|
12
|
+
field(PINI, "YES")
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
record(waveform, "$(device)uint32a") {
|
|
16
|
+
field(NELM, "3")
|
|
17
|
+
field(FTVL, "ULONG")
|
|
18
|
+
field(INP, {const:[0, 4294967295]})
|
|
19
|
+
field(PINI, "YES")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
record(waveform, "$(device)int64a") {
|
|
23
|
+
field(NELM, "3")
|
|
24
|
+
field(FTVL, "INT64")
|
|
25
|
+
# Can't do 64-bit int with JSON numbers in a const link...
|
|
26
|
+
field(INP, {const:[-2147483649, 2147483648]})
|
|
27
|
+
field(PINI, "YES")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
record(waveform, "$(device)uint64a") {
|
|
31
|
+
field(NELM, "3")
|
|
32
|
+
field(FTVL, "UINT64")
|
|
33
|
+
field(INP, {const:[0, 4294967297]})
|
|
34
|
+
field(PINI, "YES")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
record(waveform, "$(device)table:labels") {
|
|
38
|
+
field(FTVL, "STRING")
|
|
39
|
+
field(NELM, "5")
|
|
40
|
+
field(INP, {const:["Bool", "Int", "Float", "Str", "Enum"]})
|
|
41
|
+
field(PINI, "YES")
|
|
42
|
+
info(Q:group, {
|
|
43
|
+
"$(device)table": {
|
|
44
|
+
"+id": "epics:nt/NTTable:1.0",
|
|
45
|
+
"labels": {
|
|
46
|
+
"+type": "plain",
|
|
47
|
+
"+channel": "VAL"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
record(waveform, "$(device)table:bool")
|
|
54
|
+
{
|
|
55
|
+
field(FTVL, "UCHAR")
|
|
56
|
+
field(NELM, "4096")
|
|
57
|
+
field(INP, {const:[false, false, true, true]})
|
|
58
|
+
field(PINI, "YES")
|
|
59
|
+
info(Q:group, {
|
|
60
|
+
"$(device)table": {
|
|
61
|
+
"value.bool": {
|
|
62
|
+
"+type": "plain",
|
|
63
|
+
"+channel": "VAL",
|
|
64
|
+
"+putorder": 1
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
record(waveform, "$(device)table:int")
|
|
71
|
+
{
|
|
72
|
+
field(FTVL, "LONG")
|
|
73
|
+
field(NELM, "4096")
|
|
74
|
+
field(INP, {const:[1, 8, -9, 32]})
|
|
75
|
+
field(PINI, "YES")
|
|
76
|
+
info(Q:group, {
|
|
77
|
+
"$(device)table": {
|
|
78
|
+
"value.int": {
|
|
79
|
+
"+type": "plain",
|
|
80
|
+
"+channel": "VAL",
|
|
81
|
+
"+putorder": 2
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
record(waveform, "$(device)table:float")
|
|
88
|
+
{
|
|
89
|
+
field(FTVL, "DOUBLE")
|
|
90
|
+
field(NELM, "4096")
|
|
91
|
+
field(INP, {const:[1.8, 8.2, -6, 32.9887]})
|
|
92
|
+
field(PINI, "YES")
|
|
93
|
+
info(Q:group, {
|
|
94
|
+
"$(device)table": {
|
|
95
|
+
"value.float": {
|
|
96
|
+
"+type": "plain",
|
|
97
|
+
"+channel": "VAL",
|
|
98
|
+
"+putorder": 3
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
record(waveform, "$(device)table:str")
|
|
105
|
+
{
|
|
106
|
+
field(FTVL, "STRING")
|
|
107
|
+
field(NELM, "4096")
|
|
108
|
+
field(INP, {const:["Hello", "World", "Foo", "Bar"]})
|
|
109
|
+
field(PINI, "YES")
|
|
110
|
+
info(Q:group, {
|
|
111
|
+
"$(device)table": {
|
|
112
|
+
"value.str": {
|
|
113
|
+
"+type": "plain",
|
|
114
|
+
"+channel": "VAL",
|
|
115
|
+
"+putorder": 4
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
record(waveform, "$(device)table:enum")
|
|
122
|
+
{
|
|
123
|
+
field(FTVL, "STRING")
|
|
124
|
+
field(NELM, "4096")
|
|
125
|
+
field(INP, {const:["Aaa", "Bbb", "Aaa", "Ccc"]})
|
|
126
|
+
field(PINI, "YES")
|
|
127
|
+
info(Q:group, {
|
|
128
|
+
"$(device)table": {
|
|
129
|
+
"value.enum": {
|
|
130
|
+
"+type": "plain",
|
|
131
|
+
"+channel": "VAL",
|
|
132
|
+
"+putorder": 5,
|
|
133
|
+
"+trigger": "*",
|
|
134
|
+
},
|
|
135
|
+
"": {"+type": "meta", "+channel": "VAL"}
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
record(longout, "$(device)ntndarray:ArraySize0_RBV") {
|
|
141
|
+
field(VAL, "3")
|
|
142
|
+
field(PINI, "YES")
|
|
143
|
+
info(Q:group, {
|
|
144
|
+
"$(device)ntndarray":{
|
|
145
|
+
"dimension[0].size":{+channel:"VAL", +type:"plain", +putorder:0}
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
record(longout, "$(device)ntndarray:ArraySize1_RBV") {
|
|
151
|
+
field(VAL, "2")
|
|
152
|
+
field(PINI, "YES")
|
|
153
|
+
info(Q:group, {
|
|
154
|
+
"$(device)ntndarray":{
|
|
155
|
+
"dimension[1].size":{+channel:"VAL", +type:"plain", +putorder:0}
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
record(waveform, "$(device)ntndarray:data")
|
|
161
|
+
{
|
|
162
|
+
field(FTVL, "INT64")
|
|
163
|
+
field(NELM, "6")
|
|
164
|
+
field(INP, {const:[0, 0, 0, 0, 0, 0]})
|
|
165
|
+
field(PINI, "YES")
|
|
166
|
+
info(Q:group, {
|
|
167
|
+
"$(device)ntndarray":{
|
|
168
|
+
+id:"epics:nt/NTNDArray:1.0",
|
|
169
|
+
"value":{
|
|
170
|
+
+type:"any",
|
|
171
|
+
+channel:"VAL",
|
|
172
|
+
+trigger:"*",
|
|
173
|
+
},
|
|
174
|
+
"": {+type:"meta", +channel:"SEVR"}
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
}
|
ophyd_async/fastcs/core.py
CHANGED
|
@@ -2,8 +2,8 @@ from ophyd_async.core import Device, DeviceConnector
|
|
|
2
2
|
from ophyd_async.epics.core import PviDeviceConnector
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
def fastcs_connector(device: Device, uri: str) -> DeviceConnector:
|
|
5
|
+
def fastcs_connector(device: Device, uri: str, error_hint: str = "") -> DeviceConnector:
|
|
6
6
|
# TODO: add Tango support based on uri scheme
|
|
7
|
-
connector = PviDeviceConnector(uri)
|
|
7
|
+
connector = PviDeviceConnector(uri, error_hint)
|
|
8
8
|
connector.create_children_from_annotations(device)
|
|
9
9
|
return connector
|
|
@@ -23,7 +23,6 @@ from ._trigger import (
|
|
|
23
23
|
StaticPcompTriggerLogic,
|
|
24
24
|
StaticSeqTableTriggerLogic,
|
|
25
25
|
)
|
|
26
|
-
from ._utils import phase_sorter
|
|
27
26
|
from ._writer import PandaHDFWriter
|
|
28
27
|
|
|
29
28
|
__all__ = [
|
|
@@ -47,5 +46,4 @@ __all__ = [
|
|
|
47
46
|
"SeqTableInfo",
|
|
48
47
|
"StaticPcompTriggerLogic",
|
|
49
48
|
"StaticSeqTableTriggerLogic",
|
|
50
|
-
"phase_sorter",
|
|
51
49
|
]
|
|
@@ -36,14 +36,14 @@ class PulseBlock(Device):
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class PcompDirection(StrictEnum):
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
POSITIVE = "Positive"
|
|
40
|
+
NEGATIVE = "Negative"
|
|
41
|
+
EITHER = "Either"
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class BitMux(SubsetEnum):
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
ZERO = "ZERO"
|
|
46
|
+
ONE = "ONE"
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
class PcompBlock(Device):
|
|
@@ -57,10 +57,10 @@ class PcompBlock(Device):
|
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
class TimeUnits(StrictEnum):
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
MIN = "min"
|
|
61
|
+
S = "s"
|
|
62
|
+
MS = "ms"
|
|
63
|
+
US = "us"
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
class SeqBlock(Device):
|
|
@@ -18,10 +18,15 @@ class PandaPcapController(DetectorController):
|
|
|
18
18
|
return 0.000000008
|
|
19
19
|
|
|
20
20
|
async def prepare(self, trigger_info: TriggerInfo):
|
|
21
|
-
|
|
22
|
-
DetectorTrigger.
|
|
23
|
-
DetectorTrigger.
|
|
24
|
-
)
|
|
21
|
+
if trigger_info.trigger not in (
|
|
22
|
+
DetectorTrigger.CONSTANT_GATE,
|
|
23
|
+
DetectorTrigger.VARIABLE_GATE,
|
|
24
|
+
):
|
|
25
|
+
msg = (
|
|
26
|
+
"Only constant_gate and variable_gate triggering is supported on "
|
|
27
|
+
"the PandA",
|
|
28
|
+
)
|
|
29
|
+
raise TypeError(msg)
|
|
25
30
|
|
|
26
31
|
async def arm(self):
|
|
27
32
|
self._arm_status = self.pcap.arm.set(True)
|
|
@@ -9,8 +9,12 @@ from ._block import CommonPandaBlocks
|
|
|
9
9
|
from ._control import PandaPcapController
|
|
10
10
|
from ._writer import PandaHDFWriter
|
|
11
11
|
|
|
12
|
+
MINIMUM_PANDA_IOC = "0.11.4"
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
|
|
15
|
+
class HDFPanda(
|
|
16
|
+
CommonPandaBlocks, StandardDetector[PandaPcapController, PandaHDFWriter]
|
|
17
|
+
):
|
|
14
18
|
def __init__(
|
|
15
19
|
self,
|
|
16
20
|
prefix: str,
|
|
@@ -18,8 +22,9 @@ class HDFPanda(CommonPandaBlocks, StandardDetector):
|
|
|
18
22
|
config_sigs: Sequence[SignalR] = (),
|
|
19
23
|
name: str = "",
|
|
20
24
|
):
|
|
25
|
+
error_hint = f"Is PandABlocks-ioc at least version {MINIMUM_PANDA_IOC}?"
|
|
21
26
|
# This has to be first so we make self.pcap
|
|
22
|
-
connector = fastcs_connector(self, prefix)
|
|
27
|
+
connector = fastcs_connector(self, prefix, error_hint)
|
|
23
28
|
controller = PandaPcapController(pcap=self.pcap)
|
|
24
29
|
writer = PandaHDFWriter(
|
|
25
30
|
path_provider=path_provider,
|
|
@@ -83,5 +83,8 @@ class SeqTable(Table):
|
|
|
83
83
|
"""
|
|
84
84
|
|
|
85
85
|
first_length = len(self)
|
|
86
|
-
|
|
86
|
+
max_length = 4096
|
|
87
|
+
if first_length > max_length:
|
|
88
|
+
msg = f"Length {first_length} is too long"
|
|
89
|
+
raise ValueError(msg)
|
|
87
90
|
return self
|
|
@@ -20,8 +20,8 @@ class StaticSeqTableTriggerLogic(FlyerController[SeqTableInfo]):
|
|
|
20
20
|
|
|
21
21
|
async def prepare(self, value: SeqTableInfo):
|
|
22
22
|
await asyncio.gather(
|
|
23
|
-
self.seq.prescale_units.set(TimeUnits.
|
|
24
|
-
self.seq.enable.set(BitMux.
|
|
23
|
+
self.seq.prescale_units.set(TimeUnits.US),
|
|
24
|
+
self.seq.enable.set(BitMux.ZERO),
|
|
25
25
|
)
|
|
26
26
|
await asyncio.gather(
|
|
27
27
|
self.seq.prescale.set(value.prescale_as_us),
|
|
@@ -30,14 +30,14 @@ class StaticSeqTableTriggerLogic(FlyerController[SeqTableInfo]):
|
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
async def kickoff(self) -> None:
|
|
33
|
-
await self.seq.enable.set(BitMux.
|
|
33
|
+
await self.seq.enable.set(BitMux.ONE)
|
|
34
34
|
await wait_for_value(self.seq.active, True, timeout=1)
|
|
35
35
|
|
|
36
36
|
async def complete(self) -> None:
|
|
37
37
|
await wait_for_value(self.seq.active, False, timeout=None)
|
|
38
38
|
|
|
39
39
|
async def stop(self):
|
|
40
|
-
await self.seq.enable.set(BitMux.
|
|
40
|
+
await self.seq.enable.set(BitMux.ZERO)
|
|
41
41
|
await wait_for_value(self.seq.active, False, timeout=1)
|
|
42
42
|
|
|
43
43
|
|
|
@@ -68,7 +68,7 @@ class StaticPcompTriggerLogic(FlyerController[PcompInfo]):
|
|
|
68
68
|
self.pcomp = pcomp
|
|
69
69
|
|
|
70
70
|
async def prepare(self, value: PcompInfo):
|
|
71
|
-
await self.pcomp.enable.set(BitMux.
|
|
71
|
+
await self.pcomp.enable.set(BitMux.ZERO)
|
|
72
72
|
await asyncio.gather(
|
|
73
73
|
self.pcomp.start.set(value.start_postion),
|
|
74
74
|
self.pcomp.width.set(value.pulse_width),
|
|
@@ -78,12 +78,12 @@ class StaticPcompTriggerLogic(FlyerController[PcompInfo]):
|
|
|
78
78
|
)
|
|
79
79
|
|
|
80
80
|
async def kickoff(self) -> None:
|
|
81
|
-
await self.pcomp.enable.set(BitMux.
|
|
81
|
+
await self.pcomp.enable.set(BitMux.ONE)
|
|
82
82
|
await wait_for_value(self.pcomp.active, True, timeout=1)
|
|
83
83
|
|
|
84
84
|
async def complete(self, timeout: float | None = None) -> None:
|
|
85
85
|
await wait_for_value(self.pcomp.active, False, timeout=timeout)
|
|
86
86
|
|
|
87
87
|
async def stop(self):
|
|
88
|
-
await self.pcomp.enable.set(BitMux.
|
|
88
|
+
await self.pcomp.enable.set(BitMux.ZERO)
|
|
89
89
|
await wait_for_value(self.pcomp.active, False, timeout=1)
|
|
@@ -5,6 +5,14 @@ from ._fly import (
|
|
|
5
5
|
time_resolved_fly_and_collect_with_static_seq_table,
|
|
6
6
|
)
|
|
7
7
|
from ._nd_attributes import setup_ndattributes, setup_ndstats_sum
|
|
8
|
+
from ._panda import apply_panda_settings
|
|
9
|
+
from ._settings import (
|
|
10
|
+
apply_settings,
|
|
11
|
+
apply_settings_if_different,
|
|
12
|
+
get_current_settings,
|
|
13
|
+
retrieve_settings,
|
|
14
|
+
store_settings,
|
|
15
|
+
)
|
|
8
16
|
|
|
9
17
|
__all__ = [
|
|
10
18
|
"fly_and_collect",
|
|
@@ -13,4 +21,10 @@ __all__ = [
|
|
|
13
21
|
"ensure_connected",
|
|
14
22
|
"setup_ndattributes",
|
|
15
23
|
"setup_ndstats_sum",
|
|
24
|
+
"apply_panda_settings",
|
|
25
|
+
"apply_settings",
|
|
26
|
+
"apply_settings_if_different",
|
|
27
|
+
"get_current_settings",
|
|
28
|
+
"retrieve_settings",
|
|
29
|
+
"store_settings",
|
|
16
30
|
]
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
import bluesky.plan_stubs as bps
|
|
1
|
+
from bluesky.utils import plan
|
|
4
2
|
|
|
5
3
|
from ophyd_async.core import DEFAULT_TIMEOUT, Device, LazyMock, wait_for_connection
|
|
6
4
|
|
|
5
|
+
from ._wait_for_awaitable import wait_for_awaitable
|
|
6
|
+
|
|
7
7
|
|
|
8
|
+
@plan
|
|
8
9
|
def ensure_connected(
|
|
9
10
|
*devices: Device,
|
|
10
11
|
mock: bool | LazyMock = False,
|
|
@@ -17,17 +18,10 @@ def ensure_connected(
|
|
|
17
18
|
}
|
|
18
19
|
if non_unique:
|
|
19
20
|
raise ValueError(f"Devices do not have unique names {non_unique}")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
return wait_for_connection(**coros)
|
|
29
|
-
|
|
30
|
-
(connect_task,) = yield from bps.wait_for([connect_devices])
|
|
31
|
-
|
|
32
|
-
if connect_task and connect_task.exception() is not None:
|
|
33
|
-
raise connect_task.exception()
|
|
21
|
+
coros = {
|
|
22
|
+
device.name: device.connect(
|
|
23
|
+
mock=mock, timeout=timeout, force_reconnect=force_reconnect
|
|
24
|
+
)
|
|
25
|
+
for device in devices
|
|
26
|
+
}
|
|
27
|
+
yield from wait_for_awaitable(wait_for_connection(**coros))
|
ophyd_async/plan_stubs/_fly.py
CHANGED
|
@@ -58,11 +58,11 @@ def prepare_static_seq_table_flyer_and_detectors_with_same_trigger(
|
|
|
58
58
|
if not detectors:
|
|
59
59
|
raise ValueError("No detectors provided. There must be at least one.")
|
|
60
60
|
|
|
61
|
-
deadtime = max(det.
|
|
61
|
+
deadtime = max(det._controller.get_deadtime(exposure) for det in detectors) # noqa: SLF001
|
|
62
62
|
|
|
63
63
|
trigger_info = TriggerInfo(
|
|
64
64
|
number_of_triggers=number_of_frames * repeats,
|
|
65
|
-
trigger=DetectorTrigger.
|
|
65
|
+
trigger=DetectorTrigger.CONSTANT_GATE,
|
|
66
66
|
deadtime=deadtime,
|
|
67
67
|
livetime=exposure,
|
|
68
68
|
frame_timeout=frame_timeout,
|
|
@@ -50,11 +50,13 @@ def setup_ndattributes(
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def setup_ndstats_sum(detector: Device):
|
|
53
|
-
hdf = getattr(detector, "
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
hdf = getattr(detector, "fileio", None)
|
|
54
|
+
if not isinstance(hdf, NDFileHDFIO):
|
|
55
|
+
msg = (
|
|
56
|
+
f"Expected {detector.name} to have 'fileio' attribute that is an "
|
|
57
|
+
f"NDFileHDFIO, got {hdf}"
|
|
58
|
+
)
|
|
59
|
+
raise TypeError(msg)
|
|
58
60
|
yield from (
|
|
59
61
|
setup_ndattributes(
|
|
60
62
|
hdf,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from bluesky.utils import MsgGenerator, plan
|
|
2
|
+
|
|
3
|
+
from ophyd_async.core import Settings
|
|
4
|
+
from ophyd_async.fastcs import panda
|
|
5
|
+
|
|
6
|
+
from ._settings import apply_settings
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@plan
|
|
10
|
+
def apply_panda_settings(settings: Settings[panda.HDFPanda]) -> MsgGenerator[None]:
|
|
11
|
+
units, others = settings.partition(lambda signal: signal.name.endswith("_units"))
|
|
12
|
+
yield from apply_settings(units)
|
|
13
|
+
yield from apply_settings(others)
|