diff --git a/pyproject.toml b/pyproject.toml index bf5b60e..3936422 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ requires-python = ">=3.11" [project.optional-dependencies] dev = [ - "blueapi>=1.3.1", + "blueapi>=1.12.0", "copier", "pipdeptree", "pre-commit", diff --git a/src/test_rig_bluesky/pandabrick_baseline.yaml b/src/test_rig_bluesky/pandabrick_baseline.yaml new file mode 100644 index 0000000..f820ddf --- /dev/null +++ b/src/test_rig_bluesky/pandabrick_baseline.yaml @@ -0,0 +1,781 @@ +absenc.1.bits: 0 +absenc.1.clk: TTLIN1.VAL +absenc.1.clk_delay: 0 +absenc.1.clk_period: 0.0 +absenc.1.clk_period_units: min +absenc.1.clk_src: Internally Generated +absenc.1.conn_capture: false +absenc.1.data_capture: false +absenc.1.encoding: Unsigned Binary +absenc.1.frame_period: 0.0 +absenc.1.frame_period_units: min +absenc.1.lsb_discard: 0 +absenc.1.msb_discard: 0 +absenc.1.protocol: SSI +absenc.1.val_capture: "No" +absenc.1.val_dataset: "" +absenc.1.val_offset: 0.0 +absenc.1.val_scale: 0.0 +absenc.2.bits: 0 +absenc.2.clk: TTLIN1.VAL +absenc.2.clk_delay: 0 +absenc.2.clk_period: 0.0 +absenc.2.clk_period_units: min +absenc.2.clk_src: Internally Generated +absenc.2.conn_capture: false +absenc.2.data_capture: false +absenc.2.encoding: Unsigned Binary +absenc.2.frame_period: 0.0 +absenc.2.frame_period_units: min +absenc.2.lsb_discard: 0 +absenc.2.msb_discard: 0 +absenc.2.protocol: SSI +absenc.2.val_capture: "No" +absenc.2.val_dataset: "" +absenc.2.val_offset: 0.0 +absenc.2.val_scale: 0.0 +absenc.3.bits: 0 +absenc.3.clk: TTLIN1.VAL +absenc.3.clk_delay: 0 +absenc.3.clk_period: 0.0 +absenc.3.clk_period_units: min +absenc.3.clk_src: Internally Generated +absenc.3.conn_capture: false +absenc.3.data_capture: false +absenc.3.encoding: Unsigned Binary +absenc.3.frame_period: 0.0 +absenc.3.frame_period_units: min +absenc.3.lsb_discard: 0 +absenc.3.msb_discard: 0 +absenc.3.protocol: SSI +absenc.3.val_capture: "No" +absenc.3.val_dataset: "" +absenc.3.val_offset: 0.0 +absenc.3.val_scale: 0.0 +absenc.4.bits: 0 +absenc.4.clk: TTLIN1.VAL +absenc.4.clk_delay: 0 +absenc.4.clk_period: 0.0 +absenc.4.clk_period_units: min +absenc.4.clk_src: Internally Generated +absenc.4.conn_capture: false +absenc.4.data_capture: false +absenc.4.encoding: Unsigned Binary +absenc.4.frame_period: 0.0 +absenc.4.frame_period_units: min +absenc.4.lsb_discard: 0 +absenc.4.msb_discard: 0 +absenc.4.protocol: SSI +absenc.4.val_capture: "No" +absenc.4.val_dataset: "" +absenc.4.val_offset: 0.0 +absenc.4.val_scale: 0.0 +absenc.5.bits: 0 +absenc.5.clk: TTLIN1.VAL +absenc.5.clk_delay: 0 +absenc.5.clk_period: 0.0 +absenc.5.clk_period_units: min +absenc.5.clk_src: Internally Generated +absenc.5.conn_capture: false +absenc.5.data_capture: false +absenc.5.encoding: Unsigned Binary +absenc.5.frame_period: 0.0 +absenc.5.frame_period_units: min +absenc.5.lsb_discard: 0 +absenc.5.msb_discard: 0 +absenc.5.protocol: SSI +absenc.5.val_capture: "No" +absenc.5.val_dataset: "" +absenc.5.val_offset: 0.0 +absenc.5.val_scale: 0.0 +absenc.6.bits: 0 +absenc.6.clk: TTLIN1.VAL +absenc.6.clk_delay: 0 +absenc.6.clk_period: 0.0 +absenc.6.clk_period_units: min +absenc.6.clk_src: Internally Generated +absenc.6.conn_capture: false +absenc.6.data_capture: false +absenc.6.encoding: Unsigned Binary +absenc.6.frame_period: 0.0 +absenc.6.frame_period_units: min +absenc.6.lsb_discard: 0 +absenc.6.msb_discard: 0 +absenc.6.protocol: SSI +absenc.6.val_capture: "No" +absenc.6.val_dataset: "" +absenc.6.val_offset: 0.0 +absenc.6.val_scale: 0.0 +absenc.7.bits: 0 +absenc.7.clk: TTLIN1.VAL +absenc.7.clk_delay: 0 +absenc.7.clk_period: 0.0 +absenc.7.clk_period_units: min +absenc.7.clk_src: Internally Generated +absenc.7.conn_capture: false +absenc.7.data_capture: false +absenc.7.encoding: Unsigned Binary +absenc.7.frame_period: 0.0 +absenc.7.frame_period_units: min +absenc.7.lsb_discard: 0 +absenc.7.msb_discard: 0 +absenc.7.protocol: SSI +absenc.7.val_capture: "No" +absenc.7.val_dataset: "" +absenc.7.val_offset: 0.0 +absenc.7.val_scale: 0.0 +absenc.8.bits: 0 +absenc.8.clk: TTLIN1.VAL +absenc.8.clk_delay: 0 +absenc.8.clk_period: 0.0 +absenc.8.clk_period_units: min +absenc.8.clk_src: Internally Generated +absenc.8.conn_capture: false +absenc.8.data_capture: false +absenc.8.encoding: Unsigned Binary +absenc.8.frame_period: 0.0 +absenc.8.frame_period_units: min +absenc.8.lsb_discard: 0 +absenc.8.msb_discard: 0 +absenc.8.protocol: SSI +absenc.8.val_capture: "No" +absenc.8.val_dataset: "" +absenc.8.val_offset: 0.0 +absenc.8.val_scale: 0.0 +bits.a: false +bits.b: false +bits.c: false +bits.d: false +bits.outa_capture: false +bits.outb_capture: false +bits.outc_capture: false +bits.outd_capture: false +calc.1.inpa: ABSENC1.VAL +calc.1.inpb: ABSENC1.VAL +calc.1.inpc: ABSENC1.VAL +calc.1.inpd: ABSENC1.VAL +calc.1.out_capture: "No" +calc.1.out_dataset: "" +calc.1.out_offset: 0.0 +calc.1.out_scale: 0.0 +calc.1.shift: 0 +calc.1.typea: Value +calc.1.typeb: Value +calc.1.typec: Value +calc.1.typed: Value +calc.2.inpa: ABSENC1.VAL +calc.2.inpb: ABSENC1.VAL +calc.2.inpc: ABSENC1.VAL +calc.2.inpd: ABSENC1.VAL +calc.2.out_capture: "No" +calc.2.out_dataset: "" +calc.2.out_offset: 0.0 +calc.2.out_scale: 0.0 +calc.2.shift: 0 +calc.2.typea: Value +calc.2.typeb: Value +calc.2.typec: Value +calc.2.typed: Value +clock.1.enable: TTLIN1.VAL +clock.1.enable_delay: 0 +clock.1.out_capture: false +clock.1.period: 0.0 +clock.1.period_units: min +clock.1.width: 0.0 +clock.1.width_units: min +clock.2.enable: TTLIN1.VAL +clock.2.enable_delay: 0 +clock.2.out_capture: false +clock.2.period: 0.0 +clock.2.period_units: min +clock.2.width: 0.0 +clock.2.width_units: min +counter.1.carry_capture: false +counter.1.dir: TTLIN1.VAL +counter.1.dir_delay: 0 +counter.1.enable: TTLIN1.VAL +counter.1.enable_delay: 0 +counter.1.max: 0 +counter.1.min: 0 +counter.1.out_capture: "No" +counter.1.out_dataset: "" +counter.1.out_mode: On-Change +counter.1.out_offset: 0.0 +counter.1.out_scale: 0.0 +counter.1.set: 0 +counter.1.start: 0 +counter.1.step: 0 +counter.1.trig: TTLIN1.VAL +counter.1.trig_delay: 0 +counter.1.trig_edge: Rising +counter.2.carry_capture: false +counter.2.dir: TTLIN1.VAL +counter.2.dir_delay: 0 +counter.2.enable: TTLIN1.VAL +counter.2.enable_delay: 0 +counter.2.max: 0 +counter.2.min: 0 +counter.2.out_capture: "No" +counter.2.out_dataset: "" +counter.2.out_mode: On-Change +counter.2.out_offset: 0.0 +counter.2.out_scale: 0.0 +counter.2.set: 0 +counter.2.start: 0 +counter.2.step: 0 +counter.2.trig: TTLIN1.VAL +counter.2.trig_delay: 0 +counter.2.trig_edge: Rising +counter.3.carry_capture: false +counter.3.dir: TTLIN1.VAL +counter.3.dir_delay: 0 +counter.3.enable: TTLIN1.VAL +counter.3.enable_delay: 0 +counter.3.max: 0 +counter.3.min: 0 +counter.3.out_capture: "No" +counter.3.out_dataset: "" +counter.3.out_mode: On-Change +counter.3.out_offset: 0.0 +counter.3.out_scale: 0.0 +counter.3.set: 0 +counter.3.start: 0 +counter.3.step: 0 +counter.3.trig: TTLIN1.VAL +counter.3.trig_delay: 0 +counter.3.trig_edge: Rising +counter.4.carry_capture: false +counter.4.dir: TTLIN1.VAL +counter.4.dir_delay: 0 +counter.4.enable: TTLIN1.VAL +counter.4.enable_delay: 0 +counter.4.max: 0 +counter.4.min: 0 +counter.4.out_capture: "No" +counter.4.out_dataset: "" +counter.4.out_mode: On-Change +counter.4.out_offset: 0.0 +counter.4.out_scale: 0.0 +counter.4.set: 0 +counter.4.start: 0 +counter.4.step: 0 +counter.4.trig: TTLIN1.VAL +counter.4.trig_delay: 0 +counter.4.trig_edge: Rising +data.capture: false +data.capture_mode: FOREVER +data.create_directory: 0 +data.flush_period: 0.0 +data.hdf_directory: /dls/b01-1/data/2026/cm44191-1/spool +data.hdf_file_name: b01-1-981-pandabrick.h5 +data.num_capture: 0 +div.1.divisor: 0 +div.1.enable: TTLIN1.VAL +div.1.enable_delay: 0 +div.1.first_pulse: OutN +div.1.inp: TTLIN1.VAL +div.1.inp_delay: 0 +div.1.outd_capture: false +div.1.outn_capture: false +div.2.divisor: 0 +div.2.enable: TTLIN1.VAL +div.2.enable_delay: 0 +div.2.first_pulse: OutN +div.2.inp: TTLIN1.VAL +div.2.inp_delay: 0 +div.2.outd_capture: false +div.2.outn_capture: false +equ.1.val_capture: false +equ.2.val_capture: false +equ.3.val_capture: false +equ.4.val_capture: false +equ.5.val_capture: false +equ.6.val_capture: false +equ.7.val_capture: false +equ.8.val_capture: false +filter.1.enable: TTLIN1.VAL +filter.1.enable_delay: 0 +filter.1.inp: ABSENC1.VAL +filter.1.mode: difference +filter.1.out_capture: "No" +filter.1.out_dataset: "" +filter.1.out_offset: 0.0 +filter.1.out_scale: 0.0 +filter.1.ready_capture: false +filter.1.trig: TTLIN1.VAL +filter.1.trig_delay: 0 +filter.2.enable: TTLIN1.VAL +filter.2.enable_delay: 0 +filter.2.inp: ABSENC1.VAL +filter.2.mode: difference +filter.2.out_capture: "No" +filter.2.out_dataset: "" +filter.2.out_offset: 0.0 +filter.2.out_scale: 0.0 +filter.2.ready_capture: false +filter.2.trig: TTLIN1.VAL +filter.2.trig_delay: 0 +incenc.1.conn_capture: false +incenc.1.protocol: Quadrature +incenc.1.rst_on_z: false +incenc.1.val_capture: "No" +incenc.1.val_dataset: "" +incenc.1.val_offset: 0.0 +incenc.1.val_scale: 0.0 +incenc.2.conn_capture: false +incenc.2.protocol: Quadrature +incenc.2.rst_on_z: false +incenc.2.val_capture: "No" +incenc.2.val_dataset: X +incenc.2.val_offset: 0.0 +incenc.2.val_scale: 0.0 +incenc.3.conn_capture: false +incenc.3.protocol: Quadrature +incenc.3.rst_on_z: false +incenc.3.val_capture: "No" +incenc.3.val_dataset: Y +incenc.3.val_offset: 0.0 +incenc.3.val_scale: 0.0 +incenc.4.conn_capture: false +incenc.4.protocol: Quadrature +incenc.4.rst_on_z: false +incenc.4.val_capture: "No" +incenc.4.val_dataset: "" +incenc.4.val_offset: 0.0 +incenc.4.val_scale: 0.0 +incenc.5.conn_capture: false +incenc.5.protocol: Quadrature +incenc.5.rst_on_z: false +incenc.5.val_capture: "No" +incenc.5.val_dataset: "" +incenc.5.val_offset: 0.0 +incenc.5.val_scale: 0.0 +incenc.6.conn_capture: false +incenc.6.protocol: Quadrature +incenc.6.rst_on_z: false +incenc.6.val_capture: "No" +incenc.6.val_dataset: "" +incenc.6.val_offset: 0.0 +incenc.6.val_scale: 0.0 +incenc.7.conn_capture: false +incenc.7.protocol: Quadrature +incenc.7.rst_on_z: false +incenc.7.val_capture: "No" +incenc.7.val_dataset: "" +incenc.7.val_offset: 0.0 +incenc.7.val_scale: 0.0 +incenc.8.conn_capture: false +incenc.8.protocol: Quadrature +incenc.8.rst_on_z: false +incenc.8.val_capture: "No" +incenc.8.val_dataset: "" +incenc.8.val_offset: 0.0 +incenc.8.val_scale: 0.0 +lut.1.func: "" +lut.1.inpa: TTLIN1.VAL +lut.1.inpa_delay: 0 +lut.1.inpb: TTLIN1.VAL +lut.1.inpb_delay: 0 +lut.1.inpc: TTLIN1.VAL +lut.1.inpc_delay: 0 +lut.1.inpd: TTLIN1.VAL +lut.1.inpd_delay: 0 +lut.1.inpe: TTLIN1.VAL +lut.1.inpe_delay: 0 +lut.1.out_capture: false +lut.1.typea: Input-Level +lut.1.typeb: Input-Level +lut.1.typec: Input-Level +lut.1.typed: Input-Level +lut.1.typee: Input-Level +lut.2.func: "" +lut.2.inpa: TTLIN1.VAL +lut.2.inpa_delay: 0 +lut.2.inpb: TTLIN1.VAL +lut.2.inpb_delay: 0 +lut.2.inpc: TTLIN1.VAL +lut.2.inpc_delay: 0 +lut.2.inpd: TTLIN1.VAL +lut.2.inpd_delay: 0 +lut.2.inpe: TTLIN1.VAL +lut.2.inpe_delay: 0 +lut.2.out_capture: false +lut.2.typea: Input-Level +lut.2.typeb: Input-Level +lut.2.typec: Input-Level +lut.2.typed: Input-Level +lut.2.typee: Input-Level +lut.3.func: "" +lut.3.inpa: TTLIN1.VAL +lut.3.inpa_delay: 0 +lut.3.inpb: TTLIN1.VAL +lut.3.inpb_delay: 0 +lut.3.inpc: TTLIN1.VAL +lut.3.inpc_delay: 0 +lut.3.inpd: TTLIN1.VAL +lut.3.inpd_delay: 0 +lut.3.inpe: TTLIN1.VAL +lut.3.inpe_delay: 0 +lut.3.out_capture: false +lut.3.typea: Input-Level +lut.3.typeb: Input-Level +lut.3.typec: Input-Level +lut.3.typed: Input-Level +lut.3.typee: Input-Level +lut.4.func: "" +lut.4.inpa: TTLIN1.VAL +lut.4.inpa_delay: 0 +lut.4.inpb: TTLIN1.VAL +lut.4.inpb_delay: 0 +lut.4.inpc: TTLIN1.VAL +lut.4.inpc_delay: 0 +lut.4.inpd: TTLIN1.VAL +lut.4.inpd_delay: 0 +lut.4.inpe: TTLIN1.VAL +lut.4.inpe_delay: 0 +lut.4.out_capture: false +lut.4.typea: Input-Level +lut.4.typeb: Input-Level +lut.4.typec: Input-Level +lut.4.typed: Input-Level +lut.4.typee: Input-Level +lut.5.func: "" +lut.5.inpa: TTLIN1.VAL +lut.5.inpa_delay: 0 +lut.5.inpb: TTLIN1.VAL +lut.5.inpb_delay: 0 +lut.5.inpc: TTLIN1.VAL +lut.5.inpc_delay: 0 +lut.5.inpd: TTLIN1.VAL +lut.5.inpd_delay: 0 +lut.5.inpe: TTLIN1.VAL +lut.5.inpe_delay: 0 +lut.5.out_capture: false +lut.5.typea: Input-Level +lut.5.typeb: Input-Level +lut.5.typec: Input-Level +lut.5.typed: Input-Level +lut.5.typee: Input-Level +lut.6.func: "" +lut.6.inpa: TTLIN1.VAL +lut.6.inpa_delay: 0 +lut.6.inpb: TTLIN1.VAL +lut.6.inpb_delay: 0 +lut.6.inpc: TTLIN1.VAL +lut.6.inpc_delay: 0 +lut.6.inpd: TTLIN1.VAL +lut.6.inpd_delay: 0 +lut.6.inpe: TTLIN1.VAL +lut.6.inpe_delay: 0 +lut.6.out_capture: false +lut.6.typea: Input-Level +lut.6.typeb: Input-Level +lut.6.typec: Input-Level +lut.6.typed: Input-Level +lut.6.typee: Input-Level +lut.7.func: "" +lut.7.inpa: TTLIN1.VAL +lut.7.inpa_delay: 0 +lut.7.inpb: TTLIN1.VAL +lut.7.inpb_delay: 0 +lut.7.inpc: TTLIN1.VAL +lut.7.inpc_delay: 0 +lut.7.inpd: TTLIN1.VAL +lut.7.inpd_delay: 0 +lut.7.inpe: TTLIN1.VAL +lut.7.inpe_delay: 0 +lut.7.out_capture: false +lut.7.typea: Input-Level +lut.7.typeb: Input-Level +lut.7.typec: Input-Level +lut.7.typed: Input-Level +lut.7.typee: Input-Level +lut.8.func: "" +lut.8.inpa: TTLIN1.VAL +lut.8.inpa_delay: 0 +lut.8.inpb: TTLIN1.VAL +lut.8.inpb_delay: 0 +lut.8.inpc: TTLIN1.VAL +lut.8.inpc_delay: 0 +lut.8.inpd: TTLIN1.VAL +lut.8.inpd_delay: 0 +lut.8.inpe: TTLIN1.VAL +lut.8.inpe_delay: 0 +lut.8.out_capture: false +lut.8.typea: Input-Level +lut.8.typeb: Input-Level +lut.8.typec: Input-Level +lut.8.typed: Input-Level +lut.8.typee: Input-Level +pcap.active_capture: false +pcap.arm: false +pcap.bits0_capture: "No" +pcap.bits0_dataset: "" +pcap.bits1_capture: "No" +pcap.bits1_dataset: "" +pcap.bits2_capture: "No" +pcap.bits2_dataset: "" +pcap.bits3_capture: "No" +pcap.bits3_dataset: "" +pcap.enable: TTLIN1.VAL +pcap.enable_delay: 0 +pcap.gate: TTLIN1.VAL +pcap.gate_delay: 0 +pcap.gate_duration_capture: "No" +pcap.gate_duration_dataset: "" +pcap.shift_sum: 0 +pcap.trig: TTLIN1.VAL +pcap.trig_delay: 0 +pcap.trig_edge: Rising +pcap.ts_end_capture: "No" +pcap.ts_end_dataset: "" +pcap.ts_start_capture: "No" +pcap.ts_start_dataset: "" +pcap.ts_trig_capture: "No" +pcap.ts_trig_dataset: "" +pcomp.1.active_capture: false +pcomp.1.dir: Positive +pcomp.1.enable: TTLIN1.VAL +pcomp.1.enable_delay: 0 +pcomp.1.inp: ABSENC1.VAL +pcomp.1.out_capture: false +pcomp.1.pre_start: 0 +pcomp.1.pulses: 0 +pcomp.1.relative: Absolute +pcomp.1.start: 0 +pcomp.1.step: 0 +pcomp.1.width: 0 +pcomp.2.active_capture: false +pcomp.2.dir: Positive +pcomp.2.enable: TTLIN1.VAL +pcomp.2.enable_delay: 0 +pcomp.2.inp: ABSENC1.VAL +pcomp.2.out_capture: false +pcomp.2.pre_start: 0 +pcomp.2.pulses: 0 +pcomp.2.relative: Absolute +pcomp.2.start: 0 +pcomp.2.step: 0 +pcomp.2.width: 0 +pmacenc.1.bits: 0 +pmacenc.1.clk_capture: false +pmacenc.1.data: TTLIN1.VAL +pmacenc.1.data_delay: 0 +pmacenc.1.enable: TTLIN1.VAL +pmacenc.1.enable_delay: 0 +pmacenc.1.encoding: Unsigned Binary +pmacenc.1.generator_error: "No" +pmacenc.1.protocol: Passthrough - UVWT +pmacenc.1.val: ABSENC1.VAL +pmacenc.2.bits: 0 +pmacenc.2.clk_capture: false +pmacenc.2.data: TTLIN1.VAL +pmacenc.2.data_delay: 0 +pmacenc.2.enable: TTLIN1.VAL +pmacenc.2.enable_delay: 0 +pmacenc.2.encoding: Unsigned Binary +pmacenc.2.generator_error: "No" +pmacenc.2.protocol: Passthrough - UVWT +pmacenc.2.val: ABSENC1.VAL +pmacenc.3.bits: 0 +pmacenc.3.clk_capture: false +pmacenc.3.data: TTLIN1.VAL +pmacenc.3.data_delay: 0 +pmacenc.3.enable: TTLIN1.VAL +pmacenc.3.enable_delay: 0 +pmacenc.3.encoding: Unsigned Binary +pmacenc.3.generator_error: "No" +pmacenc.3.protocol: Passthrough - UVWT +pmacenc.3.val: ABSENC1.VAL +pmacenc.4.bits: 0 +pmacenc.4.clk_capture: false +pmacenc.4.data: TTLIN1.VAL +pmacenc.4.data_delay: 0 +pmacenc.4.enable: TTLIN1.VAL +pmacenc.4.enable_delay: 0 +pmacenc.4.encoding: Unsigned Binary +pmacenc.4.generator_error: "No" +pmacenc.4.protocol: Passthrough - UVWT +pmacenc.4.val: ABSENC1.VAL +pmacenc.5.bits: 0 +pmacenc.5.clk_capture: false +pmacenc.5.data: TTLIN1.VAL +pmacenc.5.data_delay: 0 +pmacenc.5.enable: TTLIN1.VAL +pmacenc.5.enable_delay: 0 +pmacenc.5.encoding: Unsigned Binary +pmacenc.5.generator_error: "No" +pmacenc.5.protocol: Passthrough - UVWT +pmacenc.5.val: ABSENC1.VAL +pmacenc.6.bits: 0 +pmacenc.6.clk_capture: false +pmacenc.6.data: TTLIN1.VAL +pmacenc.6.data_delay: 0 +pmacenc.6.enable: TTLIN1.VAL +pmacenc.6.enable_delay: 0 +pmacenc.6.encoding: Unsigned Binary +pmacenc.6.generator_error: "No" +pmacenc.6.protocol: Passthrough - UVWT +pmacenc.6.val: ABSENC1.VAL +pmacenc.7.bits: 0 +pmacenc.7.clk_capture: false +pmacenc.7.data: TTLIN1.VAL +pmacenc.7.data_delay: 0 +pmacenc.7.enable: TTLIN1.VAL +pmacenc.7.enable_delay: 0 +pmacenc.7.encoding: Unsigned Binary +pmacenc.7.generator_error: "No" +pmacenc.7.protocol: Passthrough - UVWT +pmacenc.7.val: ABSENC1.VAL +pmacenc.8.bits: 0 +pmacenc.8.clk_capture: false +pmacenc.8.data: TTLIN1.VAL +pmacenc.8.data_delay: 0 +pmacenc.8.enable: TTLIN1.VAL +pmacenc.8.enable_delay: 0 +pmacenc.8.encoding: Unsigned Binary +pmacenc.8.generator_error: "No" +pmacenc.8.protocol: Passthrough - UVWT +pmacenc.8.val: ABSENC1.VAL +pulse.1.delay: 0.0 +pulse.1.delay_units: min +pulse.1.enable: TTLIN1.VAL +pulse.1.enable_delay: 0 +pulse.1.out_capture: false +pulse.1.pulses: 0 +pulse.1.step: 0.0 +pulse.1.step_units: min +pulse.1.trig: TTLIN1.VAL +pulse.1.trig_delay: 0 +pulse.1.trig_edge: Rising +pulse.1.width: 0.0 +pulse.1.width_units: min +pulse.2.delay: 0.0 +pulse.2.delay_units: min +pulse.2.enable: TTLIN1.VAL +pulse.2.enable_delay: 0 +pulse.2.out_capture: false +pulse.2.pulses: 0 +pulse.2.step: 0.0 +pulse.2.step_units: min +pulse.2.trig: TTLIN1.VAL +pulse.2.trig_delay: 0 +pulse.2.trig_edge: Rising +pulse.2.width: 0.0 +pulse.2.width_units: min +pulse.3.delay: 0.0 +pulse.3.delay_units: min +pulse.3.enable: TTLIN1.VAL +pulse.3.enable_delay: 0 +pulse.3.out_capture: false +pulse.3.pulses: 0 +pulse.3.step: 0.0 +pulse.3.step_units: min +pulse.3.trig: TTLIN1.VAL +pulse.3.trig_delay: 0 +pulse.3.trig_edge: Rising +pulse.3.width: 0.0 +pulse.3.width_units: min +pulse.4.delay: 0.0 +pulse.4.delay_units: min +pulse.4.enable: TTLIN1.VAL +pulse.4.enable_delay: 0 +pulse.4.out_capture: false +pulse.4.pulses: 0 +pulse.4.step: 0.0 +pulse.4.step_units: min +pulse.4.trig: TTLIN1.VAL +pulse.4.trig_delay: 0 +pulse.4.trig_edge: Rising +pulse.4.width: 0.0 +pulse.4.width_units: min +seq.1.active_capture: false +seq.1.bita: TTLIN1.VAL +seq.1.bita_delay: 0 +seq.1.bitb: TTLIN1.VAL +seq.1.bitb_delay: 0 +seq.1.bitc: TTLIN1.VAL +seq.1.bitc_delay: 0 +seq.1.enable: ZERO +seq.1.enable_delay: 0 +seq.1.outa_capture: false +seq.1.outb_capture: false +seq.1.outc_capture: false +seq.1.outd_capture: false +seq.1.oute_capture: false +seq.1.outf_capture: false +seq.1.posa: ZERO +seq.1.posb: ABSENC1.VAL +seq.1.posc: ABSENC1.VAL +seq.1.prescale: 1.0 +seq.1.prescale_units: us +seq.1.repeats: 1 +seq.2.active_capture: false +seq.2.bita: TTLIN1.VAL +seq.2.bita_delay: 0 +seq.2.bitb: TTLIN1.VAL +seq.2.bitb_delay: 0 +seq.2.bitc: TTLIN1.VAL +seq.2.bitc_delay: 0 +seq.2.enable: ZERO +seq.2.enable_delay: 0 +seq.2.outa_capture: false +seq.2.outb_capture: false +seq.2.outc_capture: false +seq.2.outd_capture: false +seq.2.oute_capture: false +seq.2.outf_capture: false +seq.2.posa: ZERO +seq.2.posb: ABSENC1.VAL +seq.2.posc: ABSENC1.VAL +seq.2.prescale: 0.0 +seq.2.prescale_units: us +seq.2.repeats: 1 +srgate.1.enable: TTLIN1.VAL +srgate.1.enable_delay: 0 +srgate.1.out_capture: false +srgate.1.rst: TTLIN1.VAL +srgate.1.rst_delay: 0 +srgate.1.rst_edge: Rising +srgate.1.set: TTLIN1.VAL +srgate.1.set_delay: 0 +srgate.1.set_edge: Rising +srgate.1.when_disabled: Set output low +srgate.2.enable: TTLIN1.VAL +srgate.2.enable_delay: 0 +srgate.2.out_capture: false +srgate.2.rst: TTLIN1.VAL +srgate.2.rst_delay: 0 +srgate.2.rst_edge: Rising +srgate.2.set: TTLIN1.VAL +srgate.2.set_delay: 0 +srgate.2.set_edge: Rising +srgate.2.when_disabled: Set output low +srgate.3.enable: TTLIN1.VAL +srgate.3.enable_delay: 0 +srgate.3.out_capture: false +srgate.3.rst: TTLIN1.VAL +srgate.3.rst_delay: 0 +srgate.3.rst_edge: Rising +srgate.3.set: TTLIN1.VAL +srgate.3.set_delay: 0 +srgate.3.set_edge: Rising +srgate.3.when_disabled: Set output low +srgate.4.enable: TTLIN1.VAL +srgate.4.enable_delay: 0 +srgate.4.out_capture: false +srgate.4.rst: TTLIN1.VAL +srgate.4.rst_delay: 0 +srgate.4.rst_edge: Rising +srgate.4.set: TTLIN1.VAL +srgate.4.set_delay: 0 +srgate.4.set_edge: Rising +srgate.4.when_disabled: Set output low +ttlin.1.term: High-Z +ttlin.1.val_capture: false +ttlin.2.term: High-Z +ttlin.2.val_capture: false +ttlout.1.val: TTLIN1.VAL +ttlout.1.val_delay: 0 +ttlout.2.val: TTLIN1.VAL +ttlout.2.val_delay: 0 diff --git a/src/test_rig_bluesky/plans.py b/src/test_rig_bluesky/plans.py index 2008ed5..8ffc5ea 100644 --- a/src/test_rig_bluesky/plans.py +++ b/src/test_rig_bluesky/plans.py @@ -1,8 +1,10 @@ +import logging import math from pathlib import Path from typing import Any -from bluesky import plan_stubs as bps +import bluesky.plan_stubs as bps +import bluesky.preprocessors as bpp from bluesky.plans import count from bluesky.protocols import Movable from bluesky.utils import MsgGenerator @@ -10,25 +12,46 @@ from dodal.devices.motors import XYZStage from dodal.plan_stubs.data_session import attach_data_session_metadata_decorator from dodal.plans import spec_scan -from ophyd_async.core import Device, Settings, SettingsProvider, YamlSettingsProvider +from ophyd_async.core import ( + DetectorTrigger, + Device, + Settings, + SettingsProvider, + StandardFlyer, + TriggerInfo, + YamlSettingsProvider, +) from ophyd_async.epics.adaravis import AravisDetector from ophyd_async.epics.adcore import ( NDAttributeDataType, NDAttributeParam, + NDROIStatNIO, + setup_ndattributes, +) +from ophyd_async.epics.pmac import PmacIO, PmacTrajectoryTriggerLogic +from ophyd_async.fastcs.panda import ( + HDFPanda, + ScanSpecInfo, + ScanSpecSeqTableTriggerLogic, + SeqBlock, + apply_panda_settings, ) -from ophyd_async.epics.adcore._core_io import NDROIStatNIO from ophyd_async.plan_stubs import ( apply_settings, apply_settings_if_different, retrieve_settings, - setup_ndattributes, store_settings, ) -from scanspec.specs import Line, Spec +from scanspec.specs import Fly, Line, Spec + +LOGGER = logging.getLogger(__name__) -imaging_detector = inject("imaging_detector") +# imaging_detector = inject("imaging_detector") spectroscopy_detector = inject("spectroscopy_detector") sample_stage = inject("sample_stage") +pmac = inject("pmac") +pandabrick = inject("pandabrick") +# pmac_trigger_logic = inject("pmac_trigger_logic") def save_settings( @@ -58,6 +81,25 @@ def load_settings( yield from apply_settings_if_different(settings_to_set, apply_settings) +def load_panda_settings( + panda: HDFPanda, + design_name: str, + whitelist_pvs: list[str] | None = None, +) -> MsgGenerator[None]: + provider = _settings_provider() + settings = yield from retrieve_settings(provider, design_name, panda) + if whitelist_pvs is None: + settings_to_set = settings + else: + signal_values = { + signal: value + for signal, value in settings.items() + if signal.name.replace(f"{panda.name}-", "") in whitelist_pvs + } + settings_to_set = Settings(settings.device, signal_values) + yield from apply_settings_if_different(settings_to_set, apply_panda_settings) + + def _settings_provider() -> SettingsProvider: this_directory = Path(__file__).parent return YamlSettingsProvider(this_directory) @@ -65,7 +107,7 @@ def _settings_provider() -> SettingsProvider: @attach_data_session_metadata_decorator() def snapshot( - imaging_detector: AravisDetector = imaging_detector, + imaging_detector: AravisDetector, spectroscopy_detector: AravisDetector = spectroscopy_detector, sample_stage: XYZStage = sample_stage, ) -> MsgGenerator[None]: @@ -76,8 +118,12 @@ def snapshot( def spectroscopy( spectroscopy_detector: AravisDetector = spectroscopy_detector, sample_stage: XYZStage = sample_stage, + pmac: PmacIO = pmac, + pandabrick: HDFPanda = pandabrick, + num_points: int = 25, spec: Spec[Movable] | None = None, exposure_time: float = 0.1, + fly: bool = True, metadata: dict[str, Any] | None = None, ) -> MsgGenerator[None]: """Do a spectroscopy scan.""" @@ -123,7 +169,7 @@ def spectroscopy( yield from bps.mv( *(spectroscopy_detector.driver.acquire_time, exposure_time), *(spectroscopy_detector.driver.acquire_period, exposure_time + 1961e-6), - wait=True, + group="spectroscopy_detector_aquire", ) params: list[NDAttributeParam] = [] @@ -156,14 +202,181 @@ def spectroscopy( ], ) - spec = spec or Line(sample_stage.x, 0, 5, 5) + # yield from load_panda_settings( + # panda=pandabrick, + # design_name="pandabrick_baseline", + # whitelist_pvs=["incenc-__3-val_dataset", "incenc-__2-val_dataset"], + # ) + + LOGGER.info("Panda Children: %s", list(pandabrick.absenc.children())) # type: ignore + + spec = spec or Line(sample_stage.x, 0, 5, 5) # type: ignore + + # NOTE: replace with spec_serialized = spec.serialize() when this merges: https://github.com/bluesky/scanspec/pull/208 + from typing import Any + + from pydantic import TypeAdapter + from scanspec.specs import Spec + + spec_serialzied = TypeAdapter(Spec[Any]).dump_python( + spec, mode="json", fallback=repr + ) + + # write json-serializable form of spec into metadata + if metadata is None: + metadata = {} + # spec.serialize() when https://github.com/bluesky/scanspec/pull/208 merges + metadata["spec"] = spec_serialzied + + if fly: + LOGGER.info("Performing a fly scan.") + yield from fly_scan( + spec, + spectroscopy_detector, + sample_stage, + pmac, + pandabrick, + num_points, # type: ignore + exposure_time, + metadata, + ) + else: + LOGGER.info("Performing a step scan.") + yield from spec_scan( + {spectroscopy_detector, sample_stage}, + spec, # type: ignore + metadata=metadata, + ) + + +def fly_scan( + spec: Spec[Movable], + spectroscopy_detector: AravisDetector = spectroscopy_detector, + sample_stage: XYZStage = sample_stage, + pmac: PmacIO = pmac, + pandabrick: HDFPanda = pandabrick, + num_points: int = 1_000, + exposure_time: float = 0.1, + metadata: dict[str, Any] | None = None, +): + # yield from load_panda_settings(panda=pandabrick,design_name="pandabrick_baseline") + + yield from load_panda_settings( + panda=pandabrick, + design_name="pandabrick_baseline", + whitelist_pvs=["incenc-3-val_dataset", "incenc-2-val_dataset"], + ) + + scan_frame_duration = exposure_time + fly_spec = Fly(scan_frame_duration @ spec) # type: ignore + detector_deadtime = 2e-3 * 1.01 + + trigger_logic = fly_spec + pmac_trigger_logic = PmacTrajectoryTriggerLogic(pmac) + table: SeqBlock = pandabrick.seq[1] # type: ignore # noqa: SLF001 + + scan_spec_info = ScanSpecInfo(spec=fly_spec, deadtime=detector_deadtime) # type: ignore + + # motor_pos_out = { + # sample_stage.x: PosOutScaleOffset.from_inenc(pandabrick, 2), + # sample_stage.y: PosOutScaleOffset.from_inenc(pandabrick, 3) + # } + + panda_trigger_logic = StandardFlyer( + ScanSpecSeqTableTriggerLogic( + table, + # motor_pos_out + ) + ) + + scan_frame_livetime = scan_frame_duration - detector_deadtime + + # Reproduce metadata present in spec_scan + _md = { + "plan_args": { + "detectors": {det.name for det in [pandabrick, spectroscopy_detector]}, + "spec": repr(fly_spec), + }, + "plan_name": "fly_scan", + "shape": fly_spec.shape(), + **(metadata or {}), + } + + # Prepare Panda file writer trigger info + panda_hdf_info = TriggerInfo( + number_of_events=num_points, + trigger=DetectorTrigger.EXTERNAL_LEVEL, + livetime=scan_frame_livetime, + deadtime=detector_deadtime, + ) + + # Prepare Panda file writer trigger info + detector_info = TriggerInfo( + number_of_events=num_points, + trigger=DetectorTrigger.EXTERNAL_EDGE, + livetime=scan_frame_livetime, + deadtime=detector_deadtime, + ) + + @attach_data_session_metadata_decorator() + @bpp.run_decorator(md=_md) + @bpp.stage_decorator( + [pandabrick, panda_trigger_logic, spectroscopy_detector, pmac_trigger_logic] + ) + def inner_plan(): + # create a group that is waited for + # Hashable prepare_group = ["pmac_trigger_logic", "trigger_logic"] + + # Prepare pmac with the trajectory + yield from bps.prepare(pmac_trigger_logic, trigger_logic) + # prepare sequencer table + yield from bps.prepare(panda_trigger_logic, scan_spec_info) + # prepare panda and hdf writer once, at start of scan + yield from bps.prepare(pandabrick, panda_hdf_info) + # prepare spectroscopy_detector and info + # waiting for this last prepare means all prepare functions will be complete + yield from bps.prepare(spectroscopy_detector, detector_info, wait=True) + + # Need to run this after detectors are prepared + yield from bps.declare_stream( + pandabrick, spectroscopy_detector, name="primary", collect=True + ) + + # Start the detectors and hdf writers acquiring. + # Configure the panda (seq table triggering). + # create a group that is waited for before pmac_trigger_logic kicked off on + # its own with wait=true. + yield from bps.kickoff(pandabrick) + yield from bps.kickoff(panda_trigger_logic) + yield from bps.kickoff(spectroscopy_detector, wait=True) + + # Start the trajectory. + yield from bps.kickoff(pmac_trigger_logic, wait=True) + + # Wait for the scan to complete whilst continuously collecting the data. + yield from bps.collect_while_completing( + flyers=( + pmac_trigger_logic, + panda_trigger_logic, + pandabrick, + spectroscopy_detector, + ), + dets=( + pandabrick, + spectroscopy_detector, + ), + stream_name="primary", + flush_period=0.5, + ) - yield from spec_scan({spectroscopy_detector, sample_stage}, spec, metadata=metadata) + yield from inner_plan() def demo_spectroscopy( spectroscopy_detector: AravisDetector = spectroscopy_detector, sample_stage: XYZStage = sample_stage, + pmac: PmacIO = pmac, + pandabrick: HDFPanda = pandabrick, total_number_of_scan_points: int = 25, grid_size: float = 5.0, grid_origin_x: float = 0.0, @@ -180,13 +393,41 @@ def demo_spectroscopy( xmax = grid_origin_x + grid_size ymin = grid_origin_y ymax = grid_origin_y + grid_size - grid = Line(sample_stage.y, ymin, ymax, ysteps) * Line( - sample_stage.x, xmin, xmax, xsteps + + velomax = grid_size / (xsteps * exposure_time) + if velomax <= 10 * 0.98: + fly = True + LOGGER.info("test-rig-bluesky") + LOGGER.info( + f"Estimated velocity is {velomax:.2f} mm/sec, performing a fly scan." + ) + else: + fly = False + LOGGER.info( + f"Estimated velocity is {velomax:.2f} mm/sec, performing a step scan." + ) + + # Move to the start point + # pmac should handle premove + yield from bps.mv( + *(sample_stage.x, xmin), *(sample_stage.y, ymin), group="initial_move" + ) + + grid = Line(sample_stage.y, ymin, ymax, ysteps) * ~Line( # type: ignore + sample_stage.x, # type: ignore + xmin, + xmax, + xsteps, ) + # fly = False yield from spectroscopy( spectroscopy_detector=spectroscopy_detector, sample_stage=sample_stage, + pmac=pmac, + pandabrick=pandabrick, + num_points=total_number_of_scan_points, spec=grid, exposure_time=exposure_time, + fly=fly, metadata=metadata, ) diff --git a/src/test_rig_bluesky/spectroscopy_detector_baseline.yaml b/src/test_rig_bluesky/spectroscopy_detector_baseline.yaml index 79e8280..e701ef0 100644 --- a/src/test_rig_bluesky/spectroscopy_detector_baseline.yaml +++ b/src/test_rig_bluesky/spectroscopy_detector_baseline.yaml @@ -3,69 +3,68 @@ driver.acquire_period: 0.021815 driver.acquire_time: 0.10000 driver.array_counter: 3 driver.image_mode: Multiple -driver.nd_attributes_file: '' +driver.nd_attributes_file: "" driver.num_images: 1 -driver.trigger_mode: 'Off' +driver.trigger_mode: "Off" driver.trigger_source: Freerun driver.wait_for_plugins: false -fileio.acquire: false -fileio.array_counter: 3 -fileio.auto_increment: true -fileio.capture: false -fileio.chunk_size_auto: true -fileio.compression: None -fileio.create_directory: 0 -fileio.enable_callbacks: Enable -fileio.file_name: 5073260b-9688-4283-84d1-204955e423aa -fileio.file_number: 1 -fileio.file_path: /tmp/ -fileio.file_template: '%s%s.h5' -fileio.file_write_mode: Stream -fileio.flush_now: false -fileio.lazy_open: true -fileio.nd_array_address: 0 -fileio.nd_array_port: D2.roistat -fileio.nd_attributes_file: '' -fileio.num_capture: 0 -fileio.num_extra_dims: 0 -fileio.num_frames_chunks: 1 -fileio.position_mode: false -fileio.queue_size: 2 -fileio.swmr_mode: true -fileio.wait_for_plugins: false -fileio.xml_file_name: '' -roistat.acquire: false +writer.array_counter: 3 +writer.auto_increment: true +writer.capture: false +writer.chunk_size_auto: true +writer.compression: None +writer.create_directory: 0 +writer.enable_callbacks: Enable +writer.file_name: 5073260b-9688-4283-84d1-204955e423aa +writer.file_number: 1 +writer.file_path: /tmp/ +writer.file_template: "%s%s.h5" +writer.file_write_mode: Stream +writer.flush_now: false +writer.lazy_open: true +writer.nd_array_address: 0 +writer.nd_array_port: D2.ROISTAT +writer.nd_attributes_file: "" +writer.num_capture: 0 +writer.num_extra_dims: 0 +writer.num_frames_chunks: 1 +writer.position_mode: false +writer.queue_size: 2 +writer.swmr_mode: true +writer.xml_file_name: "" roistat.array_counter: 3 -roistat.channels.1.min_x: 95 -roistat.channels.1.min_y: 610 -roistat.channels.1.name_: Red +roistat.channels.1.min_x: 295 +roistat.channels.1.min_y: 114 +roistat.channels.1.name_: Blue roistat.channels.1.size_x: 150 roistat.channels.1.size_y: 150 roistat.channels.1.use: true -roistat.channels.2.min_x: 880 -roistat.channels.2.min_y: 605 +roistat.channels.2.min_x: 907 +roistat.channels.2.min_y: 108 roistat.channels.2.name_: Green roistat.channels.2.size_x: 150 roistat.channels.2.size_y: 150 roistat.channels.2.use: true -roistat.channels.3.min_x: 1665 -roistat.channels.3.min_y: 600 -roistat.channels.3.name_: Blue +roistat.channels.3.min_x: 1511 +roistat.channels.3.min_y: 104 +roistat.channels.3.name_: Red roistat.channels.3.size_x: 150 roistat.channels.3.size_y: 150 roistat.channels.3.use: true roistat.enable_callbacks: Enable roistat.nd_array_address: 0 -roistat.nd_array_port: D2.CAM -roistat.nd_attributes_file: +roistat.nd_array_port: D2.DRV +roistat.nd_attributes_file: roistat.queue_size: 2 -roistat.wait_for_plugins: false