Updated readme
This commit is contained in:
+74
-13
@@ -67,11 +67,9 @@ in Visual Studio Code, a really handy IDE if you have a fast connection:
|
||||
code &
|
||||
```
|
||||
|
||||
|
||||
|
||||
### The Tomcat BEC repository
|
||||
|
||||
The Tomcat BEC repository is a collection of Tomcat specific ophyd devices, scans, and
|
||||
The Tomcat BEC repository is a collection of Tomcat specific ophyd devices, scans, scripts and
|
||||
device configurations. It tries to enforce a standard structure across beamlines and it's
|
||||
**maintenance is the responsibility of the beamline.** I.e. it should be handed over from
|
||||
controls while still keeping the basic structure:
|
||||
@@ -95,6 +93,7 @@ From the list of folders the most important ones are:
|
||||
- device_configs : Ophyd device datbase as YAML file
|
||||
- devices : Ophyd device repository (i.e. Aerotech, Gigafrost)
|
||||
- scans : Tomcat specific base scans in the low-level API
|
||||
- scripts : Scripts and scans using the high level API
|
||||
|
||||
The official location of the beamline repository is:
|
||||
```
|
||||
@@ -124,8 +123,8 @@ Tomcat beamlines and ensure their collaboration. Namely the rotation stage with
|
||||
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 communicated via hybrid websocket and REST-API and also provides throttled preview
|
||||
streams.
|
||||
and the std-DAQ 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
|
||||
@@ -133,7 +132,7 @@ recently updated event model. Redundant staging raises an exception.
|
||||
|
||||
### Seeing is believing (GUI)
|
||||
|
||||
Since seeing is believing, it's often a good idea to bring up the panels and get some visual
|
||||
Since seeing is believing, it's often a good idea to bring up some panels and get visual
|
||||
feedback. You can start the standard CaQtDM panels for the Aerotech and GigaFrost from any
|
||||
beamline console running the contros stack by:
|
||||
```
|
||||
@@ -168,6 +167,7 @@ def.gfclient.unstage()
|
||||
dev.daq_stream0.unstage()
|
||||
```
|
||||
|
||||
|
||||
## Reseting the Automation1 iSMC
|
||||
|
||||
There's some electrical disturbance at SLS that can bring the system to a problematic state. A workaround is to remotely reset the iSMC:
|
||||
@@ -179,17 +179,78 @@ FIXME: There is a known desync in PSO inputs upon iSMC restart that requires res
|
||||
|
||||
|
||||
|
||||
### Simple scans
|
||||
|
||||
As I was unsure about the various triggering modes of the Gigafrost, I only prepared a simple
|
||||
step scanning implementation that is compatible with the standard bluesky step scanning interface
|
||||
using soft-triggers
|
||||
## 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.
|
||||
```
|
||||
scans.simplestep(range=(-20, 160), steps=18, exp_time=2, exp_burst=220)
|
||||
def demostepscan(scan_start, scan_end, steps, exp_time=0.005, burst_at_each_point=1, settling_time=0, sync='event')
|
||||
```
|
||||
|
||||
### Templated script scans
|
||||
### gigastep
|
||||
|
||||
A template has been prepared, but we should wait until I can test final cabling.
|
||||
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')
|
||||
```
|
||||
|
||||
### 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.
|
||||
```
|
||||
scans.snapnstep(scan_start, scan_end, steps, exp_time=0.005, settling_time=0.2, burst_at_each_point = 1, sync='event')
|
||||
```
|
||||
|
||||
|
||||
### 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.
|
||||
|
||||
```
|
||||
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")
|
||||
```
|
||||
|
||||
|
||||
### 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")
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ program
|
||||
var $iNumSteps as integer = {{ scan.numsteps }}
|
||||
var $fStepSize as real = {{ scan.stepsize }}
|
||||
var $fExposureTimeSec as real = {{ scan.exptime }}
|
||||
var $fSettlingTimeSec as real = {{ scan.settle }}
|
||||
var $fVelJog as real = {{ scan.travel or 200 }}
|
||||
var $fVelScan as real = {{ scan.velocity or 50 }}
|
||||
var $fAcceleration = {{ scan.acceleration or 500 }}
|
||||
@@ -78,6 +79,7 @@ program
|
||||
TaskSetError(TaskGetIndex(), "AxisFault on axis ROTY")
|
||||
end
|
||||
|
||||
Dwell($fSettlingTimeSec)
|
||||
PsoEventGenerateSingle($axis)
|
||||
Dwell($fExposureTimeSec)
|
||||
$fPosNext = $fPosNext + $fStepSize
|
||||
|
||||
@@ -247,6 +247,7 @@ class GigaStepScanBase(ScanBase):
|
||||
exp_time = 0.005,
|
||||
settling_time = 0.2,
|
||||
burst_at_each_point = 1,
|
||||
sync='event',
|
||||
**kwargs):
|
||||
super().__init__(
|
||||
exp_time=exp_time,
|
||||
@@ -270,8 +271,12 @@ class GigaStepScanBase(ScanBase):
|
||||
self.exp_time = settling_time + exp_time * 2 * burst_at_each_point
|
||||
|
||||
# Prepare configuration dicts
|
||||
# Aerotech DDC settings: Internal event trigger: PsoEvent = 1
|
||||
t_modes = {'pso': 0, 'event': 1, 'inp0': 2, 'inp1': 4}
|
||||
daq_trigger = t_modes[sync]
|
||||
|
||||
self.psocfg = {}
|
||||
self.daqcfg = {'ntotal': self.scan_ntotal, 'trigger': 1}
|
||||
self.daqcfg = {'ntotal': self.scan_ntotal, 'trigger': daq_trigger}
|
||||
self.camcfg = {
|
||||
"ntotal": self.scan_ntotal,
|
||||
"nimages": burst_at_each_point,
|
||||
@@ -342,7 +347,7 @@ class SnapAndStepScanBase(TemplatedScanBase):
|
||||
}
|
||||
|
||||
def __init__(self, scan_start, scan_end, steps,
|
||||
exp_time=0.005, burst_at_each_point=1,
|
||||
exp_time=0.005, settling_time=0, burst_at_each_point=1,
|
||||
roix=2016, roiy=2016, sync="event", **kwargs):
|
||||
# Auto-setup configuration parameters from input
|
||||
self.scan_start = scan_start
|
||||
@@ -350,6 +355,7 @@ class SnapAndStepScanBase(TemplatedScanBase):
|
||||
self.scan_steps = steps
|
||||
self.exp_time = exp_time
|
||||
self.exp_burst = burst_at_each_point
|
||||
self.settling_time = settling_time
|
||||
|
||||
# Synthetic values
|
||||
self.scan_stepsize = (scan_end-scan_start)/steps
|
||||
@@ -361,6 +367,7 @@ class SnapAndStepScanBase(TemplatedScanBase):
|
||||
'stepsize': self.scan_stepsize,
|
||||
'numsteps': self.scan_steps,
|
||||
'exptime': self.exp_time*self.exp_burst
|
||||
'settling': self.settling_time
|
||||
}
|
||||
|
||||
# Aerotech DDC settings: Internal event trigger: PsoEvent = 1
|
||||
|
||||
Reference in New Issue
Block a user