Reverted to working trigger mode

This commit is contained in:
gac-x05la
2024-10-21 15:57:26 +02:00
parent d681a82878
commit 4f3e31205f
3 changed files with 140 additions and 71 deletions

View File

@@ -268,50 +268,41 @@ class GigaFrostCamera(PSIDetectorBase):
EpicsSignal, "SOFT_TRIG.PROC", put_complete=True, kind=Kind.omitted)
cmdSoftExposure = Component(EpicsSignal, "SOFT_EXP", put_complete=True)
# Trigger configuration PVs
cfgCntStartBit = Component(
EpicsSignal,
"CNT_STARTBIT_RBV",
write_pv="CNT_STARTBIT",
###############################################################################################
# Enable schemes
# NOTE: 0 physical, 1 virtual (i.e. always running, but logs enable signal)
cfgEnableScheme = Component(
EpicsSignal,
"MODE_ENBL_EXP_RBV",
write_pv="MODE_ENBL_EXP",
put_complete=True,
kind=Kind.config,
)
cfgCntEndBit = Component(
EpicsSignal,
"CNT_ENDBIT_RBV",
write_pv="CNT_ENDBIT",
put_complete=True,
kind=Kind.config
)
# Enable modes
cfgTrigEnableExt = Component(
# Enable signals (combined by OR gate)
cfgEnableExt = Component(
EpicsSignal,
"MODE_ENBL_EXT_RBV",
write_pv="MODE_ENBL_EXT",
put_complete=True,
kind=Kind.config,
)
cfgTrigEnableSoft = Component(
cfgEnableSoft = Component(
EpicsSignal,
"MODE_ENBL_SOFT_RBV",
write_pv="MODE_ENBL_SOFT",
put_complete=True,
kind=Kind.config,
)
cfgTrigEnableAuto = Component(
cfgEnableAlways = Component(
EpicsSignal,
"MODE_ENBL_AUTO_RBV",
write_pv="MODE_ENBL_AUTO",
put_complete=True,
kind=Kind.config,
)
cfgTrigVirtEnable = Component(
EpicsSignal,
"MODE_ENBL_EXP_RBV",
write_pv="MODE_ENBL_EXP",
put_complete=True,
kind=Kind.config,
)
###############################################################################################
# Trigger modes
cfgTrigExt = Component(
EpicsSignal,
@@ -341,22 +332,25 @@ class GigaFrostCamera(PSIDetectorBase):
put_complete=True,
kind=Kind.config,
)
###############################################################################################
# Exposure modes
cfgTrigExpExt = Component(
# NOTE: I.e.exposure time control, usually TIMER
cfgExpExt = Component(
EpicsSignal,
"MODE_EXP_EXT_RBV",
write_pv="MODE_EXP_EXT",
put_complete=True,
kind=Kind.config,
)
cfgTrigExpSoft = Component(
cfgExpSoft = Component(
EpicsSignal,
"MODE_EXP_SOFT_RBV",
write_pv="MODE_EXP_SOFT",
put_complete=True,
kind=Kind.config,
)
cfgTrigExpTimer = Component(
cfgExpTimer = Component(
EpicsSignal,
"MODE_EXP_TIMER_RBV",
write_pv="MODE_EXP_TIMER",
@@ -364,6 +358,24 @@ class GigaFrostCamera(PSIDetectorBase):
kind=Kind.config,
)
###############################################################################################
# Trigger configuration PVs
# NOTE: Theese PVs set the behavior on posedge and negedge of the trigger signal
cfgCntStartBit = Component(
EpicsSignal,
"CNT_STARTBIT_RBV",
write_pv="CNT_STARTBIT",
put_complete=True,
kind=Kind.config,
)
cfgCntEndBit = Component(
EpicsSignal,
"CNT_ENDBIT_RBV",
write_pv="CNT_ENDBIT",
put_complete=True,
kind=Kind.config
)
# Line swap selection
cfgLineSwapSW = Component(EpicsSignal, "LS_SW", put_complete=True, kind=Kind.config)
cfgLineSwapNW = Component(EpicsSignal, "LS_NW", put_complete=True, kind=Kind.config)
@@ -453,6 +465,9 @@ class GigaFrostCamera(PSIDetectorBase):
scanid : int, optional
Scan identification number to be associated with the scan data
(default = 0)
trigger_mode : str, optional
Trigger mode of the gifafrost
(default = unchanged)
correction_mode : int, optional
The correction to be applied to the imaging data. The following
modes are available (default = 5):
@@ -481,6 +496,7 @@ class GigaFrostCamera(PSIDetectorBase):
pixel_width = d.get('roix', pixel_width)
pixel_height = d.get('roiy', pixel_height)
scanid = d.get('scanid', 0)
trigger_mode = d.get('trigger_mode', None)
correction_mode = d.get('correction_mode', 5)
# change settings
@@ -492,9 +508,55 @@ class GigaFrostCamera(PSIDetectorBase):
self.cfgCntNum.set(nimages).wait()
self.cfgCorrMode.set(correction_mode).wait()
# if trigger_mode is not None:
# self.set_trigger_mode(str(trigger_mode))
# Commit parameter
self.cmdSetParam.set(1).wait()
def set_trigger_mode(self, trigger_mode):
if trigger_mode=="soft":
# Switch to physical enable signal
self.cfgEnableScheme.set(0).wait()
# Set enable signal to always
self.cfgEnableExt.set(0).wait()
self.cfgEnableSoft.set(1).wait()
self.cfgEnableAlways.set(1).wait()
# Set trigger mode to software
self.cfgTrigExt.set(0).wait()
self.cfgTrigSoft.set(1).wait()
self.cfgTrigTimer.set(1).wait()
self.cfgTrigAuto.set(0).wait()
# Set exposure mode to timer
self.cfgExpExt.set(0).wait()
self.cfgExpSoft.set(0).wait()
self.cfgExpTimer.set(1).wait()
# Set trigger edge to fixed frames on posedge
self.cfgCntStartBit.set(1).wait()
self.cfgCntEndBit.set(0).wait()
elif trigger_mode in ["ext", "external"]:
# Switch to physical enable signal
self.cfgEnableScheme.set(0).wait()
# Set enable signal to always
self.cfgEnableExt.set(0).wait()
self.cfgEnableSoft.set(0).wait()
self.cfgEnableAlways.set(1).wait()
# Set trigger mode to external
self.cfgTrigExt.set(1).wait()
self.cfgTrigSoft.set(0).wait()
self.cfgTrigTimer.set(0).wait()
self.cfgTrigAuto.set(0).wait()
# Set exposure mode to timer
self.cfgExpExt.set(0).wait()
self.cfgExpSoft.set(0).wait()
self.cfgExpTimer.set(1).wait()
# Set trigger edge to fixed frames on posedge
self.cfgCntStartBit.set(1).wait()
self.cfgCntEndBit.set(0).wait()
else:
raise RuntimeError(f"Unsupported trigger mode: {trigger_mode}")
def stage(self):
""" Standard stage command"""
if not self._initialized:
@@ -514,9 +576,9 @@ class GigaFrostCamera(PSIDetectorBase):
The camera's active exposure mode.
If more than one mode is active at the same time, it returns None.
"""
mode_soft = self.cfgTrigExpSoft.get()
mode_timer = self.cfgTrigExpTimer.get()
mode_external = self.cfgTrigExpExt.get()
mode_soft = self.cfgExpSoft.get()
mode_timer = self.cfgExpTimer.get()
mode_external = self.cfgExpExt.get()
if mode_soft and not mode_timer and not mode_external:
return "soft"
if not mode_soft and mode_timer and not mode_external:
@@ -536,17 +598,17 @@ class GigaFrostCamera(PSIDetectorBase):
The exposure mode to be set.
"""
if exp_mode == "external":
self.cfgTrigExpExt.set(1).wait()
self.cfgTrigExpSoft.set(0).wait()
self.cfgTrigExpTimer.set(0).wait()
self.cfgExpExt.set(1).wait()
self.cfgExpSoft.set(0).wait()
self.cfgExpTimer.set(0).wait()
elif exp_mode == "timer":
self.cfgTrigExpExt.set(0).wait()
self.cfgTrigExpSoft.set(0).wait()
self.cfgTrigExpTimer.set(1).wait()
self.cfgExpExt.set(0).wait()
self.cfgExpSoft.set(0).wait()
self.cfgExpTimer.set(1).wait()
elif exp_mode == "soft":
self.cfgTrigExpExt.set(0).wait()
self.cfgTrigExpSoft.set(1).wait()
self.cfgTrigExpTimer.set(0).wait()
self.cfgExpExt.set(0).wait()
self.cfgExpSoft.set(1).wait()
self.cfgExpTimer.set(0).wait()
else:
raise ValueError(
f"Invalid exposure mode! Valid modes are:\n{const.gf_valid_exposure_modes}"
@@ -679,22 +741,26 @@ class GigaFrostCamera(PSIDetectorBase):
enable_mode: {'soft', 'external', 'soft+ext', 'always'}
The camera's active enable mode.
"""
mode_soft = self.cfgTrigEnableSoft.get()
mode_external = self.cfgTrigEnableExt.get()
mode_auto = self.cfgTrigEnableAuto.get()
if mode_soft and not mode_auto:
return "soft+ext" if mode_external else "soft"
if mode_auto and not mode_soft and not mode_external:
mode_soft = self.cfgEnableSoft.get()
mode_external = self.cfgEnableExt.get()
mode_always = self.cfgEnableAlways.get()
if mode_always:
return "always"
if mode_external and not mode_soft and not mode_auto:
elif mode_soft and mode_external:
return "soft+ext"
elif mode_soft and not mode_external:
return "soft"
elif mode_external and not mode_soft:
return "external"
return None
else:
return None
@enable_mode.setter
def enable_mode(self, mode):
"""Apply the enable mode for the GigaFRoST camera.
NOTE: Always does not seem to work and Enablesoft works like a trigger
Parameters
----------
mode : {'soft', 'external', 'soft+ext', 'always'}
@@ -706,21 +772,21 @@ class GigaFrostCamera(PSIDetectorBase):
)
if mode == "soft":
self.cfgTrigEnableExt.set(0).wait()
self.cfgTrigEnableSoft.set(1).wait()
self.cfgTrigEnableAuto.set(0).wait()
self.cfgEnableExt.set(0).wait()
self.cfgEnableSoft.set(1).wait()
self.cfgEnableAlways.set(0).wait()
elif mode == "external":
self.cfgTrigEnableExt.set(1).wait()
self.cfgTrigEnableSoft.set(0).wait()
self.cfgTrigEnableAuto.set(0).wait()
self.cfgEnableExt.set(1).wait()
self.cfgEnableSoft.set(0).wait()
self.cfgEnableAlways.set(0).wait()
elif mode == "soft+ext":
self.cfgTrigEnableExt.set(1).wait()
self.cfgTrigEnableSoft.set(1).wait()
self.cfgTrigEnableAuto.set(0).wait()
self.cfgEnableExt.set(1).wait()
self.cfgEnableSoft.set(1).wait()
self.cfgEnableAlways.set(0).wait()
elif mode == "always":
self.cfgTrigEnableExt.set(0).wait()
self.cfgTrigEnableSoft.set(0).wait()
self.cfgTrigEnableAuto.set(1).wait()
self.cfgEnableExt.set(0).wait()
self.cfgEnableSoft.set(0).wait()
self.cfgEnableAlways.set(1).wait()
# Commit parameters
self.cmdSetParam.set(1).wait()

View File

@@ -289,7 +289,8 @@ class GigaStepScanBase(ScanBase):
"ntotal": self.scan_ntotal,
"nimages": burst_at_each_point,
"exposure": 1000*exp_time,
"period": 2000*exp_time,
"period": 2000*exp_time,
"trigger_mode": "soft",
"pixel_width": self.scan_roix,
"pixel_height": self.scan_roiy
}
@@ -393,7 +394,8 @@ class SnapAndStepScanBase(TemplatedScanBase):
"ntotal": self.scan_ntotal,
"nimages": burst_at_each_point,
"exposure": 1000 * exp_time,
"period": 2000*exp_time,
"period": 2000*exp_time,
"trigger_mode": "eternal",
"pixel_width": roix,
"pixel_height": roiy
}

View File

@@ -9,7 +9,7 @@ def bl_check_beam():
def demostepscan(scan_start, scan_end, steps, exp_time=0.005, burst_at_each_point=1, settling_time=0, roix=2016, roiy=2016, sync='event'):
def demostepscan(scan_start, scan_end, steps, exp_time=0.005, exp_burst=1, settling_time=0, roix=2016, roiy=2016, sync='event'):
""" Demo step scan with GigaFrost
This is a small BEC user-space demo step scan at the microXAS testbench
@@ -18,33 +18,34 @@ def demostepscan(scan_start, scan_end, steps, exp_time=0.005, burst_at_each_poin
Example:
--------
demostepscan(scan_start=-32, scan_end=148, steps=180, exp_time=0.005, burst_at_each_point=5)
demostepscan(scan_start=-32, scan_end=148, steps=180, exp_time=0.005, exp_burst=5)
"""
if not bl_check_beam():
raise RuntimeError("Beamline is not in ready state")
scan_ntotal = burst_at_each_point * (steps + 1)
scan_ntotal = exp_burst * (steps + 1)
# Move to start position
t_modes = {'pso': 0, 'event': 1, 'inp0': 2, 'inp1': 4}
cfg = {'ntotal': scan_ntotal, 'trigger': t_modes[sync]}
cfg = {'ntotal': scan_ntotal*10, 'trigger': t_modes[sync]}
dev.es1_ddaq.configure(d=cfg)
# Configure gigafrost
cfg = {
"ntotal": scan_ntotal, "nimages": burst_at_each_point,
"ntotal": scan_ntotal, "nimages": exp_burst,
"exposure": 1000*exp_time, "period": 2000*exp_time,
"pixel_width": roix, "pixel_height": roiy
"pixel_width": roix, "pixel_height": roiy, "trigger_mode": "soft"
}
dev.gfclient.configure(d=cfg)
# Configure PSO trigger (trigger is normally disabled in fly mode)
dev.es1_psod.configure(d={})
dev.es1_psod.software_trigger = True
# dev.es1_psod.configure(d={})
# dev.es1_psod.software_trigger = True
# Explicitly arm trigger (and detector in future)
dev.es1_psod.prepare()
# dev.es1_psod.prepare()
# dev.es1_roty.move(scan_start).wait()
print("Handing over to 'scans.line_scan'")
wait_time = 0.1 + 2*exp_time * burst_at_each_point
wait_time = 2*exp_time * exp_burst
scans.line_scan(
dev.es1_roty, scan_start, scan_end,
steps=steps, exp_time=wait_time, relative=False, settling_time=settling_time)