From b80ed2d71c8984ab09edb456f3e8cd311ca3934d Mon Sep 17 00:00:00 2001 From: gac-x05la Date: Tue, 10 Dec 2024 15:48:21 +0100 Subject: [PATCH] Snapshot --- tomcat_bec/Readme.md | 175 +++++++++---------------- tomcat_bec/scans/tutorial_fly_scan.py | 7 +- tomcat_bec/scripts/anotherroundsans.py | 4 +- tomcat_bec/scripts/scans_fede.py | 49 +++++++ 4 files changed, 121 insertions(+), 114 deletions(-) create mode 100644 tomcat_bec/scripts/scans_fede.py diff --git a/tomcat_bec/Readme.md b/tomcat_bec/Readme.md index 811a711..0520800 100644 --- a/tomcat_bec/Readme.md +++ b/tomcat_bec/Readme.md @@ -34,7 +34,7 @@ This is needed whenever you edit the scan or device files. In order to start the BEC console interface, you first need to activate the corresponding venv. This will also start the BEC GUI in a separate process and window: ``` -source /data/test/x05la-test-bec/bec_deployment/bev_venv/bin/activate +source /data/test/x05la-test-bec/test/bec_venv/bin/activate bec ``` @@ -43,16 +43,14 @@ bec The BEC is deployed to a beamline specific network mounted folder that contains the main repositories for the current installation, you can check it by: ``` -[gac-x05la@x05la-bec-001 ~]$ ls -ltr /data/test/x05la-test-bec/bec_deployment/ -total 4 -drwxr-xr-x 7 gac-x05la unx-sls 4096 Aug 20 15:10 ophyd_devices -drwxr-xr-x 8 gac-x05la unx-sls 4096 Aug 20 15:10 bec_widgets -drwxr-xr-x 6 gac-x05la unx-sls 4096 Aug 20 15:11 bec_venv --rw-r--r-- 1 gac-x05la unx-sls 326 Aug 20 15:15 bec_config.yaml --rw-r--r-- 1 gac-x05la unx-sls 289 Aug 20 15:15 bec_client_config.yaml -drwxr-xr-x 15 gac-x05la unx-sls 4096 Aug 29 13:06 bec -drwxr-xr-x 7 gac-x05la unx-sls 4096 Sep 3 13:28 tomcat_bec -drwxr-xr-x 2 gac-x05la unx-sls 4096 Sep 6 11:22 logs +(bec_venv) [gac-x05la@x05la-bec-001 ~]$ ls -ltr /data/test/x05la-test-bec/test/ +total 3 +drwxr-xr-x 7 gac-x05la unx-nogroup 4096 Nov 19 15:25 ophyd_devices +drwxr-xr-x 8 gac-x05la unx-nogroup 4096 Nov 19 15:25 bec_widgets +drwxr-xr-x 6 gac-x05la unx-nogroup 4096 Nov 19 15:26 bec_venv +-rw-r--r-- 1 gac-x05la unx-nogroup 451 Nov 19 15:29 bec_config.yaml +drwxr-xr-x 6 gac-x05la unx-nogroup 4096 Nov 27 13:35 tomcat_bec +drwxr-xr-x 15 gac-x05la unx-nogroup 4096 Nov 27 14:03 bec ``` A short summary of the folder structure: - bec_venv : The actual installation directory of the BEC framework @@ -61,8 +59,9 @@ A short summary of the folder structure: - ophyd_devices : Git repo as installation directory for shared ophyd devices - tomcat_bec : Git repo as installation directory for Tomcat specific **scans, devices and configs.** -In short: You should use the bec_venv and only edit the tomcat_bec folder. And this is easily done -in Visual Studio Code, a really handy IDE if you have a fast connection: +In short: You should activate the installation in the bec_venv directory and only edit the +tomcat_bec folder. And this is easily done in Visual Studio Code, a really handy IDE if you +have a fast connection: ``` code & ``` @@ -111,24 +110,26 @@ If the previous two configuration attempts were unsuccesfull the bec_device_serv without any devices. A single missing or mistyped IOC will cause a configuration failure, so once you fixed you configs you can reload your YAML config file: ``` -bec.config.update_session_with_file("/data/test/x05la-test-bec/bec_deployment/tomcat_bec/tomcat_bec/device_configs/microxas_test_bed.yaml") +bec.config.update_session_with_file("/data/test/x05la-test-bec/test/tomcat_bec/tomcat_bec/device_configs/microxas_test_bed.yaml") ``` If a single, unnecesary device doesn't come up , just comment it out. ## Early tests with GigaFrost and Aerotech -The main goal of the testbench is to test the various infrastructure component foreseen at the +The main goal of the testbench is to test the various infrastructure components foreseen at the Tomcat beamlines and ensure their collaboration. Namely the rotation stage with the Aerotech smart controller, the GigaFrost camera and the Standard-DAQ recording system. The individual repositories have more documentation on the components, but as a short summary, the Aerotech Automation1 IOC is a recently developed EPICS driver, the GigaFrost IOC is an ancient offshoot of Helge's camera driver -and the std-DAQ is a non-EPICS device that is controlled via a hybrid websocket and REST interface. +and the stdDAQ is a non-EPICS device that is controlled via a hybrid websocket and REST interface. The DAQ also provides preview streams with hardcoded throttling. -Note that the standard bluesky event model applies, i.e. configure sets up the device, stage and -trigger for stepping interface and kickoff and collect for flyers. This will be updated with the -recently updated event model. Redundant staging raises an exception. +Note that while in the bluesky event model a manual configuration step sets up the device for a +scan. Followed by commands stage and trigger for stepping interface and kickoff and collect for +flyers. While in the BEC event model, stage is called on all enabled deviced on the deviceserver. +Calling stage also configures the device from the scaninfo. Moreover all steges are called in +parallel, regardless of device order. Redundant staging raises an exception. ### Seeing is believing (GUI) @@ -141,116 +142,70 @@ caqtdm -macro "P=X02DA-ES1-SMP1" aeroauto1_ControllerOverview.ui ``` The std-DAQ doesn't have control panels, but the BEC can display the hard-coded preview streams. -The *daq_stream1* preview forwards displays 1 frames at a maximum of 5 Hz. +The *daq_stream0* preview forwards displays 1 frames at a maximum of 5 Hz. So we just need to add the correct widgets to the GUI: ``` gui.add_dock('tomolive') -gui.panels['tomolive'].add_widget('BECFigure').image('daq_stream1') -``` - -### Short run with the GigaFrost and std-DAQ - -This is a short, recorded test run with 2016x2016 frames at 100 Hz with the GigaFrost. The current -GigaFrost ophyd device includes the std-DAQ client, but they will probably be separated. -``` -# Configure -d = {'ntotal': 1000000, 'nimages': 555, 'exposure': 5, 'period': 10} -dev.gfclient.configure(d) -# Stage GF, DAQ and preview -dev.gfclient.stage() -dev.daq_stream0.stage() -# Trigger a few sequences -def.gfclient.trigger() -def.gfclient.trigger() -# Unstage -def.gfclient.unstage() -dev.daq_stream0.unstage() +gui.panels['tomolive'].add_widget('BECFigure').image('daq_stream0') ``` -## Reseting the Automation1 iSMC +## BEC scans at the testbench + +The concept of scans is slightly different in bluesky and BEC. Bluesky strictly separates +the device logic in ophyd from the scan logic in plans. Devices are passed in as arguments +allowing finetuning their roles. + +On the other hand, BEC has two scan interfaces and additional device specific scan logic is +placed on the ophyd device itself. The general idea is that the lower-level BEC scans should +be completely generic with absolutely minimal logic (although some examples counter this +argument). BEC devices live on the DeviceServer, and automatically participate in scans +whenever they are enabled. This puts the configuration role either on the ophyd device from +the scainfo or in the high level interface that anyways manages the enabling/disabling of devices. + +The current repository has several implemented scans to test compliance with standard BEC +interfaces and partly cover the old EPICS IOC functionality. + + - If a device is enabled for a scan it will be staged + - I.e. by the time stage finishes it must be configured + - This can be either manual or from the scan parameters + - Some scan parameters will overwrite the configuration (can be removed...) + - Certain scan kwargs will trigger the reconfiguration of a device + - The device will not try to make sure that the received configuration is correct + + + + parameters + +### anotherstepscan + +Simple software step scan in the low-level API that almost calls the standard BEC scan routine. Its +only difference is that it overrides the burst to use Gigafrost's HW burst mode. The ophyd devices +are capable to allocate the required number of points for DAQ and position readback. -There's some electrical disturbance at SLS that can bring the system to a problematic state. A workaround is to remotely reset the iSMC: ``` -dev.es1_ismc.reset() -``` - -FIXME: There is a known desync in PSO inputs upon iSMC restart that requires restarting the IOC. - - - - -## Scans at the testbench - -The current repository has several implemented scans, often offering different solutions to the -same problem using different APIs while providing similar functionality. The BEC itself has two -scan APIs for low- and highlevel scans, and the fastest scans can be directly implemented on the -Automation1 iSMC. The implemented BEC scans combine motor motion, PSO triggering, Gigafrost and -stdDAQ control and position capture in internal or external triggering mode. They were -intentionally designed to provide the same interface, althogh not every combination was tested. - -As I was unsure about the various triggering modes of the Gigafrost, so currently it's implemented -with only sofware trigger that is compatible with the standard bluesky step scanning interface. - - -### demostepscan - -Simple step scan in the scripting API that performs the device configuration and hands over to -a standard BEC scan routine. Note that there's absolutely no readback from the GigaFrost so we -don't know when it finished acquiring. -``` -def demostepscan(scan_start, scan_end, steps, exp_time=0.005, burst_at_each_point=1, settling_time=0, sync='event') -``` - -### gigastep - -Simple step scan in the low level API that performs the device configuration loops over each -position in BEC and reads back the position data. Note that there's absolutely no readback from the GigaFrost so we -don't know when it finished acquiring. -``` -scans.gigastep(scan_start, scan_end, steps, exp_time=0.005, settling_time=0.2, burst_at_each_point = 1, sync='event') +def demosanotherstepscantepscan(scan_start, scan_end, steps, exp_time=0.005, burst_at_each_point=1, settling_time=0, sync='event') ``` ### snapnstep -Scripted step scan that sets up all components, creates an AeroScript file from template and -executes it on the Automation1 iSMC controller. Upon succesfull completion it reads back the -positions from the data capture. - -NOTE: This scan just launches the GigaFrost, but hardware triggering is currently not implemented. +AeroScript controlled high-speed step-scan that sets up the devices and calls the corresponding +low-level scan API to substitute the jinja2 template file and launch the script. PSO and data +readback are configured and launched internally. It also waits for the script to finish. ``` -scans.snapnstep(scan_start, scan_end, steps, exp_time=0.005, settling_time=0.2, burst_at_each_point = 1, sync='event') +anothersnapnstepscan(33, 180, 180, exp_time=0.005, exp_frames=1800, repeats=10) ``` -### sequencescan - -Scripted scan that sets up all components, creates an AeroScript file from template and executes it -on the Automation1 iSMC controller. Upon succesfull completion it reads back the positions from the -data capture. Position readback works wth both internal and external triggers. - -NOTE: This scan just launches the GigaFrost, but hardware triggering is currently not implemented. +### anothersequencescan +AeroScript controlled fly scan that sets up the devices and calls the corresponding low-level scan +to substitute the jinja2 template file and launch the script. PSO and data readback are configured +and launched internally. It also waits for the script to finish. It might have problems with +configuring the readback of the number of repeats because that's done on the IOC, ``` -scans.sequencescan(scan_start, gate_high, gate_low, repeats=1, repmode="PosNeg", exp_time=0.005, exp_frames=180, roix=2016, roiy=2016, sync="pso") +anothersequencescan(33, 180, 180, exp_time=0.005, exp_frames=1800, repeats=10) ``` -### demosequencescan - -Basic sequence scan in the high level API that calls the corresponding low-level scan with some -extra checks. -``` -demosequencescan(scan_start, gate_high, gate_low, repeats=1, repmode="PosNeg", exp_time=0.005, exp_frames=180, roix=2016, roiy=2016, sync="pso") -``` - - -### becsequencescan - -Basic sequence scan script in BEC's high level interface. It a performs all trigger configurations -movements and readback from BEC. -``` -becsequencescan(scan_start, gate_high, gate_low, repeats=1, repmode="PosNeg", exp_time=0.005, exp_frames=180, roix=2016, roiy=2016, sync="pso") -``` - diff --git a/tomcat_bec/scans/tutorial_fly_scan.py b/tomcat_bec/scans/tutorial_fly_scan.py index 92a9b1b..5846aa3 100644 --- a/tomcat_bec/scans/tutorial_fly_scan.py +++ b/tomcat_bec/scans/tutorial_fly_scan.py @@ -27,11 +27,14 @@ class AcquireDark(Acquire): """ super().__init__(**kwargs) self.burst_at_each_point = num - self.shutter = "hx" # change to the correct shutter device + self.scan_motors = ["eyex"] # change to the correct shutter device + #self.shutter = "eyex" # change to the correct shutter device + self.dark_shutter_pos = 0 ### change with a variable def scan_core(self): # close the shutter - yield from self.stubs.set_and_wait(device=[self.shutter], positions=[0]) + yield from self._move_scan_motors_and_wait(self.dark_shutter_pos) + #yield from self.stubs.set_and_wait(device=[self.shutter], positions=[0]) yield from super().scan_core() diff --git a/tomcat_bec/scripts/anotherroundsans.py b/tomcat_bec/scripts/anotherroundsans.py index bf8c9d4..f90fdea 100644 --- a/tomcat_bec/scripts/anotherroundsans.py +++ b/tomcat_bec/scripts/anotherroundsans.py @@ -94,7 +94,7 @@ def anothersequencescan( Example: -------- - >>> demosequencescan(33, 180, 180, exp_time=0.005, exp_frames=1800, repeats=10) + >>> anothersequencescan(33, 180, 180, exp_time=0.005, exp_frames=1800, repeats=10) """ if not bl_check_beam(): raise RuntimeError("Beamline is not in ready state") @@ -146,7 +146,7 @@ def anothersnapnstepscan( Example: -------- - >>> demosequencescan(33, 180, 180, exp_time=0.005, exp_frames=1800, repeats=10) + >>> anothersnapnstepscan(33, 180, 180, exp_time=0.005, exp_frames=1800, repeats=10) """ if not bl_check_beam(): raise RuntimeError("Beamline is not in ready state") diff --git a/tomcat_bec/scripts/scans_fede.py b/tomcat_bec/scripts/scans_fede.py new file mode 100644 index 0000000..6c9f127 --- /dev/null +++ b/tomcat_bec/scripts/scans_fede.py @@ -0,0 +1,49 @@ +def fede_darks(num, exp_time=None, exp_period=None, roix=None, roiy=None): + """ Fede dark scan + + This is a small BEC user-space scan that sets up the gigafrost and calls + the low-level dark collection scan. + + Example: + -------- + tutorialdarks(num=100, exp_time=5) + """ + ###### TODO check how to pass only the required arguments + ###### TODO what we want is a function common to PCO.edge and GF + # Configure gigafrost + cfg = {} + if exp_time != None: + cfg.update({"exposure_time_ms": exp_time}) + if exp_period != None: + cfg.update({"exposure_period_ms": exp_period}) + if roix != None: + cfg.update({"image_width": roix}) + if roiy != None: + cfg.update({"image_height": roiy}) + + dev.gfcam.configure(d=cfg) + + dev.gfcam.cfgAcqMode.set(1).wait() + dev.gfcam.cfgEnableExt.set(0).wait() + dev.gfcam.cfgEnableSoft.set(0).wait() + dev.gfcam.cfgEnableAlways.set(1).wait() + + dev.gfcam.cfgTrigExt.set(0).wait() + dev.gfcam.cfgTrigSoft.set(0).wait() + dev.gfcam.cfgTrigTimer.set(0).wait() + dev.gfcam.cfgTrigAuto.set(1).wait() + + dev.gfcam.cfgExpExt.set(0).wait() + dev.gfcam.cfgExpSoft.set(0).wait() + dev.gfcam.cfgExpTimer.set(1).wait() + + dev.gfcam.cfgCntStartBit.set(0).wait() + + # Commit changes to GF + dev.gfcam.cmdSetParam.set(1).wait() + + + print("Handing over to 'scans.acquire_dark") + scans.acquire_dark(num=num) + +