Scan Macros can be interrupted by Ctrl-Cs. Sardana behaves differently depending on the number of Ctrl-Cs pressed. Single and double Ctrl-Cs do not require any fix-up procedure. However, triple Ctrl-Cs need a special treatment. But they are needed, if the sample time is too long to wait for the completion of even a single cycle.
Note: SardanaRestartBoth3.py -x resolves all issues related to Ctrl-Cs. But this requires human intervention and it takes time. The purpose of this section is to explain how the brute force method can be avoided. Below you find a pre_scan_hook which can automatically be executed and which brings Sardana back to an operational state after multiple Ctrl-Cs have been pressed.
p09/door/haso107d10.01 [8]: ascan exp_dmy01 3 4 10 10 Operation will be saved in /home/kracht/Misc/IVP/temp/pppurgetest_[ScanId].fio (fio from FIO_FileRecorder) Scan #319 started at Tue May 14 17:48:08 2024. It will take at least 0:01:50.000263 findCountersAndMCAs: elm 'tango://haso107d10:10000/expchan/dgg2_eh_01/1' NOT displayed ^C Ctrl-C received: Stopping... Stopping Motion(['exp_dmy01']) reserved by ascan Motion(['exp_dmy01']) stopped Stopping mg_tk reserved by ascan mg_tk stopped Operation saved in /home/kracht/Misc/IVP/temp/pppurgetest_00319.fio (fio) Scan #319 ended at Tue May 14 17:48:20 2024, taking 0:00:12.190734. Dead time 3.5% (setup time 14.5%, motion dead time 0.2%) general_features.gh_post_scan: eiger2_1m not in the MG, DONE Executing ascan.on_stop method... Stopping done! p09/door/haso107d10.01 [9]:
p09/door/haso107d10.01 [9]: ascan exp_dmy01 3 4 10 10 Operation will be saved in /home/kracht/Misc/IVP/temp/pppurgetest_[ScanId].fio (fio from FIO_FileRecorder) Scan #320 started at Tue May 14 17:54:21 2024. It will take at least 0:01:50.000200 fioRecorder: FioAdditions AND MetadataScript are used findCountersAndMCAs: elm 'tango://haso107d10:10000/expchan/dgg2_eh_01/1' NOT displayed #Pt No exp_dmy01 eh_t01 eh_c01 eh_c02 eh_mca01 dt 0 3 10 73.1124 131.103 (2048,) 1.9647 ^C Ctrl-C received: Stopping... Stopping Motion(['exp_dmy01']) reserved by ascan Motion(['exp_dmy01']) stopped Stopping mg_tk reserved by ascan ^C2nd Ctrl-C received: Aborting... Stopping mg_tk was interrupted Aborting mg_tk reserved by ascan Operation saved in /home/kracht/Misc/IVP/temp/pppurgetest_00320.fio (fio) Scan #320 ended at Tue May 14 17:54:35 2024, taking 0:00:13.857848. Dead time 14.8% (setup time 13.0%, motion dead time 0.3%) mg_tk aborted Executing ascan.on_abort method... Aborting done!
p09/door/haso107d10.01 [7]: ascan exp_dmy01 3 4 10 111 general_features.pre_scan hook general_features.pre_scan_hook: ECStatus is OK Operation will be saved in /home/kracht/Misc/IVP/temp/tst_[ScanId].fio (fio from FIO_FileRecorder) Scan #1002 started at Tue May 21 14:49:05 2024. It will take at least 0:20:21.000263 ^C Ctrl-C received: Stopping... Stopping Motion(['exp_dmy01']) reserved by ascan Motion(['exp_dmy01']) stopped Stopping mg_tk reserved by ascan ^C2nd Ctrl-C received: Aborting... Stopping mg_tk was interrupted Aborting mg_tk reserved by ascan Operation saved in /home/kracht/Misc/IVP/temp/tst_01002.fio (fio) Scan #1002 ended at Tue May 21 14:49:15 2024, taking 0:00:09.281169. Dead time 82.4% (setup time 17.6%, motion dead time 0.2%) ^C3rd Ctrl-C received: Releasing... Aborting mg_tk was interrupted. Releasing it. Executing ascan.on_abort method... Releasing done!
This time the MG remains in a MOVING state, see below.
p09/door/haso107d10.01 [4]: HasyUtils.checkECStatus( verbose=True) Checking Pool p09/pool/haso107d10 p09/pool/haso107d10, state ON Checking Motorlist Checking ExpChannelList Checking IORegisterList Checking MeasurementGroupList checking mg_ivp checking mg_pysp checking mg_sr checking mg_tk Checking Macroserver p09/macroserver/haso107d10.01, state ON Checking Doors p09/door/haso107d10.01, state ON p09/door/haso107d10.02, state ON p09/door/haso107d10.03, state ON Checking ActiveMntGrp mg_tk Checking MeasurementGroup, mgName: mg_tk mg_tk, state MOVING eh_t01, state MOVING, haso107d10:10000/p09/dgg2/eh.01 eh_c01, state MOVING, haso107d10:10000/p09/counter/eh.01 eh_c02, state MOVING, haso107d10:10000/p09/counter/eh.02 eh_mca01, state MOVING, haso107d10:10000/p09/mca/eh.01 Result [4]: False
In this condition, if the users enters a new scan command the door will go to RUNNING and this can only be resolved by RestartBoth.
Here is an example for a hook that senses the status of the MG and restarts the Pool. This way the issue is resolved.
class gh_pre_scan(Macro): ... def run( self): self.output( "general_features.pre_scan hook") buffer = [] # # checkMotor=False save a few seconds # if not HasyUtils.checkECStatus( errorMsgs = buffer, checkMotor=False): self.output( "general_features.pre_scan_hook: %s" % repr( buffer)) self.output( "general_features.pre_scan_hook: restartingPool") HasyUtils.restartPool( macro = self) if not HasyUtils.checkECStatus( errorMsgs = buffer): self.output( "general_features.pre_scan_hook: %s" % repr( buffer)) self.output( "general_features.pre_scan_hook: restartingPool failed, restartBoth needed") else: self.output( "general_features.pre_scan_hook: restartingPool DONE") else: self.output( "general_features.pre_scan_hook: ECStatus is OK")