Added templated scan and required status updates
This commit is contained in:
parent
1f3ef42a9d
commit
16f033a833
@ -119,6 +119,7 @@ class aa1Tasks(Device):
|
||||
it and run it directly on a certain thread. But there's no way to
|
||||
retrieve the source code.
|
||||
"""
|
||||
SUB_PROGRESS = "progress"
|
||||
_failure = Component(EpicsSignalRO, "FAILURE", kind=Kind.hinted)
|
||||
errStatus = Component(EpicsSignalRO, "ERRW", auto_monitor=True, kind=Kind.hinted)
|
||||
warnStatus = Component(EpicsSignalRO, "WARNW", auto_monitor=True, kind=Kind.hinted)
|
||||
@ -139,6 +140,22 @@ class aa1Tasks(Device):
|
||||
self._textToExecute = None
|
||||
self._isConfigured = False
|
||||
self._isStepConfig = False
|
||||
self.subscribe(self._progress_update, "progress", run=False)
|
||||
|
||||
def _progress_update(self, value, **kwargs) -> None:
|
||||
"""Progress update on the scan"""
|
||||
value = self.progress()
|
||||
self._run_subs( sub_type=self.SUB_PROGRESS, value=value, max_value=1, done=1, )
|
||||
|
||||
def _progress(self) -> None:
|
||||
"""Progress update on the scan"""
|
||||
if self._currentTaskMonitor is None:
|
||||
return 1
|
||||
else:
|
||||
if self._currentTaskMonitor.status.value in ["Running", 4]:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
def readFile(self, filename: str) -> str:
|
||||
""" Read a file from the controller """
|
||||
@ -198,7 +215,8 @@ class aa1Tasks(Device):
|
||||
old = self.read_configuration()
|
||||
self.taskIndex.set(taskIndex).wait()
|
||||
self._textToExecute = None
|
||||
#self._currentTaskMonitor = aa1TaskState()
|
||||
self._currentTaskMonitor = aa1TaskState(prefix=self.prefix+f"T{taskIndex}:", name="taskmon")
|
||||
self._currentTaskMonitor.wait_for_connection()
|
||||
|
||||
# Choose the right execution mode
|
||||
if (filename is None) and (text not in [None, ""]):
|
||||
@ -270,9 +288,20 @@ class aa1Tasks(Device):
|
||||
|
||||
def complete(self) -> DeviceStatus:
|
||||
""" Execute the script on the configured task"""
|
||||
print("Called aa1Task.complete()")
|
||||
#return self._currentTaskMonitor.complete()
|
||||
status = DeviceStatus(self)
|
||||
status.set_finished()
|
||||
#status = DeviceStatus(self)
|
||||
#status.set_finished()
|
||||
#return status
|
||||
timestamp_ = 0
|
||||
def notRunning(*args, old_value, value, timestamp, **kwargs):
|
||||
nonlocal timestamp_
|
||||
result = False if (timestamp_== 0) else (value not in ["Running", 4])
|
||||
timestamp_ = timestamp
|
||||
print(result)
|
||||
return result
|
||||
# Subscribe and wait for update
|
||||
status = SubscriptionStatus(self._currentTaskMonitor.status, notRunning, settle_time=0.5)
|
||||
return status
|
||||
|
||||
def describe_collect(self) -> OrderedDict:
|
||||
@ -300,12 +329,14 @@ class aa1TaskState(Device):
|
||||
|
||||
def complete(self) -> StatusBase:
|
||||
""" Bluesky flyer interface"""
|
||||
print("Called aa1TaskState.complete()")
|
||||
# Define wait until the busy flag goes down (excluding initial update)
|
||||
timestamp_ = 0
|
||||
def notRunning(*args, old_value, value, timestamp, **kwargs):
|
||||
nonlocal timestamp_
|
||||
result = False if (timestamp_== 0) else (value not in ["Running", 4])
|
||||
timestamp_ = timestamp
|
||||
print(result)
|
||||
return result
|
||||
|
||||
# Subscribe and wait for update
|
||||
|
@ -0,0 +1,87 @@
|
||||
// Snap-and-step
|
||||
// Test program for high speed step scanning with individual triggers on PSO output.
|
||||
// The file expects external parameter validation.
|
||||
|
||||
|
||||
|
||||
program
|
||||
// External parameters
|
||||
var $fStartPosition as real = {{ scan.startpos }}
|
||||
var $iNumSteps as integer = {{ scan.numsteps }}
|
||||
var $fStepSize as real = {{ scan.stepsize }}
|
||||
var $fExposureTimeSec as real = {{ scan.exptime }}
|
||||
var $fVelJog as real = {{ scan.travel or 200 }}
|
||||
var $fVelScan as real = {{ scan.velocity or 50 }}
|
||||
var $fAcceleration = {{ scan.acceleration or 500 }}
|
||||
|
||||
// Internal
|
||||
var $axis as axis = ROTY
|
||||
var $ii as integer
|
||||
|
||||
// Set acceleration
|
||||
SetupAxisRampType($axis, RampType.Linear)
|
||||
SetupAxisRampValue($axis,0,$fAcceleration)
|
||||
|
||||
// Move to start position before the scan
|
||||
var $fPosNext as real = $fStartPosition
|
||||
MoveAbsolute($axis, $fPosNext, $fVelJog)
|
||||
WaitForInPosition($axis)
|
||||
|
||||
// Configure PSO (to manual event generation)
|
||||
PsoDistanceEventsOff($axis)
|
||||
PsoWindowConfigureEvents($axis, PsoWindowEventMode.None)
|
||||
PsoWaveformConfigurePulseFixedTotalTime($axis, 50)
|
||||
PsoWaveformConfigurePulseFixedOnTime($axis, 20)
|
||||
PsoWaveformConfigurePulseFixedCount($axis, 1)
|
||||
PsoWaveformApplyPulseConfiguration($axis)
|
||||
PsoWaveformConfigureMode($axis, PsoWaveformMode.Pulse)
|
||||
PsoOutputConfigureSource($axis, PsoOutputSource.Waveform)
|
||||
PsoWaveformOn($axis)
|
||||
|
||||
// Configure Drive Data Collection
|
||||
var $iDdcArrayAddr as integer = 8388608
|
||||
var $iDdcArraySize as integer = iMaximum(5000, $iNumSteps)
|
||||
var $iDdcSafeSpace as integer = 4096
|
||||
|
||||
DriveDataCaptureConfigureInput($axis, 0, DriveDataCaptureInput.PrimaryFeedback);
|
||||
DriveDataCaptureConfigureInput($axis, 1, DriveDataCaptureInput.AnalogInput0 );
|
||||
|
||||
DriveDataCaptureConfigureTrigger($axis, 0, DriveDataCaptureTrigger.PsoOutput );
|
||||
DriveDataCaptureConfigureTrigger($axis, 1, DriveDataCaptureTrigger.PsoOutput );
|
||||
|
||||
DriveDataCaptureConfigureArray($axis, 0, $iDdcArrayAddr, $iDdcArraySize);
|
||||
DriveDataCaptureConfigureArray($axis, 1, $iDdcArrayAddr + $iDdcSafeSpace + 8 * $iDdcArraySize, $iDdcArraySize);
|
||||
|
||||
// Directly before scan
|
||||
PsoDistanceCounterOn($axis)
|
||||
DriveDataCaptureOn($axis, 0)
|
||||
DriveDataCaptureOn($axis, 1)
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Start the actual scanning
|
||||
///////////////////////////////////////////////////////////
|
||||
for $ii = 0 to ($iNumSteps-1)
|
||||
MoveAbsolute($axis, $fPosNext, $fVelScan)
|
||||
WaitForInPosition($axis)
|
||||
PsoEventGenerateSingle($axis)
|
||||
Dwell($fExposureTimeSec)
|
||||
$fPosNext = $fPosNext + $fStepSize
|
||||
end
|
||||
|
||||
// Directly after scan
|
||||
PsoWaveformOff($axis)
|
||||
DriveDataCaptureOff($axis, 0)
|
||||
DriveDataCaptureOff($axis, 1)
|
||||
end
|
||||
|
||||
// Demonstrates using a switch/case conditional.
|
||||
function iMaximum($A as integer, $B as integer) as integer
|
||||
var $retVal
|
||||
if ($A > $B)
|
||||
$retVal = $A
|
||||
else
|
||||
$retVal = $B
|
||||
end
|
||||
return $retVal
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user