Reverted to working trigger mode
This commit is contained in:
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user