######################################################################## ### FILE: runcontrol.mod ### PURPOSE: Interface for defining/running protocols ### (procedures, stages, programs, legs) ### SCOPE: "FlowChip" branches ### ### Copyrights (C) 2010 Life Technologies. All rights reserved. ######################################################################## ######################################################################## ### MACRO: STARt, STOP ### PURPOSE: Start/stop instrument subsystems VARiable START "" DEFine STARt RUN ${START} DESCribe STARt Activate instrument subsystems VARiable STOP "" DEFine STOP RUN ${STOP} DESCribe STOP Deactivate instrument subsystems ######################################################################## ### PROCedure support ALIAS PROCedure MACRo+ -inline -asynchronous -replaceExisting DEFine -asynchronous RUNPROC $name$ $args* SET culprits $(:STATe:CULPrits? FlowChip${FC}:Ready) IF ${#culprits} ERRor -id=NotReady -procedure=$name$ \ "Not ready to run procedure '$name$' due to these conditions(s): ${culprits}" TRY :STATe= FlowChip${FC}:Running True TRACKer+ RUNTRACKER "$name$" $args* RUNTRACKER:TRACK Step RunProc '"$name$" -step=$index -state=Running' RUNTRACKER:TRACK Paused RunProc '"$name$" -step=$index -state=Paused' RUNTRACKER:TRACK Aborted RunProc '"$name$" -step=$index -state=Aborted' StartProc "$name$" PROCSTATE "$name$" Started $args* RUNTRACKER:RUN TRACKer- -ignoreMissing RUNTRACKER PROCSTATE "$name$" Completed TRACKer- -ignoreMissing RUNTRACKER IF ${#RunControl:-} PROCSTATE "$name$" ${RunControl} ELSE SET ERRID ${error} SET ERRARGS ${arguments} SET ERRMSG ${message} PROCSTATE "$name$" Failed ${text} USE Robot TRY :FLUidics:HOME PASS TRY :FLUidics:ARM:HomeSyringe PASS CLEARLOCKS ResumeImaging RAMP -asynchronous 25.0 CLEARLOCKS WARN "Failed to clean up after failure: ${text}" WARN "Original error: [${ERRID}] ${ERRARGS} ${ERRMSG}" TRY EndProc "$name$" WARN "Failed to stop after run: ${text}" CLEARLOCKS :STATe= FlowChip${FC}:Running False PUBlish RunProc '"$name$"' Ended IF ${#ERRID:-} "ERRor -id=${ERRID} ${ERRARGS} \${ERRMSG}" DEFINT STARTPROC $name$ VAR- -ignoreMissing RunControl VAR Procedure "$name$" START DEFINT ENDPROC $name$ STOP VAR- -ignoreMissing Procedure SET locks $(LOCK*) PUBLISH Info "Locks held after end of \"$name$\": ${locks:-(None)}" DEFINT PROCSTATE $name$ $state$ $args* VAR PROCSTATE '"$name$" $state$ $args*' PUBLish RunProc "${PROCSTATE}" ######################################################################## ### Client interface to get/set run state DEFine RUNPROC? TRY RETURN $(RUNTRACKER:TRACK?) RETURN "(None)" DEFine LASTPROC? TRY RETURN $(RUNRACKER:TRACK?) RETURN ${PROCSTATE:--} DEFine CLEARPROC VAR- -ignoreMissing PROCSTATE DEFine PAUSEPROC $name$= $atStep$= TRY RUNTRACKER:PAUSE $atStep$ ERRor -id=NotRunning "No procedure is currently running" DEFine RESUMEPROC $name$= $atStep$= TRY RUNTRACKER:RESUME $atStep$ ERRor -id=NotRunning "No procedure is currently running" DEFine ABORTPROC $name$= $atStep$= TRY VAR RunControl Aborted RUNTRACKER:ABORT $atStep$ ERRor -id=NotRunning "No procedure is currently running" DEFINE -asynchronous PAUSERUN ResumeImaging # ITERate -key=arm $(:FLUidics:ARM*) # :FLUidics:${arm}:HOME -prehome # :FLUidics:${arm}:PARK # DESCribe PAUSERUN Inform the Instrument Server that the fluidics run has paused. This allows the IS to tend to pending operations such as to resume imaging. ######################################################################## ### Misc. functions DEFine TIMER $name$ $timeout$ VAR Timer-$name$ $[ int($timeout$) ] SET delay $[ $timeout$ - int($timeout$) ] FLAG -asynchronous '$name$' SCHedule+ "FlowChip${FC}-Timer-$name$" -replaceExisting -counter=remain -interval=1 -step=-1 \ -start=${Timer-$name$} -count=${Timer-$name$} -delay=${delay} VARiable Timer-$name$ $[ $remain$ - 1 ] PUBLish Timer "$name$" -remaining=$remain$ WAIT $timeout$ SCHedule- -ignoreMissing "FlowChip${FC}-Timer-$name$" VARiable- -ignoreMissing Timer-$name$ PUBLish Timer "$name$" -remaining=0 ALIas- -ignoreMissing SYNChronize DEFine SYNChronize $name$ :IDLE:WORK -skipWait ${FlowChip${FC}-Timer-$name$:-0} FLAG- -ignoreMissing '$name$' DEFine COUNT? $delimiter$="," $match$ $list$="" SET count 0 ITERate -key=match -delimiter="$delimiter$" "$match$" ADDValue count $[ "$list$".lower().split("$delimiter$").count("${match}".lower()) ] RETurn ${count} ### Resource allocation commands ALIAS PauseIMAGing :PauseImaging ALIAS ResumeIMAGing :ResumeImaging ALIAS USE :ACQuisition+ -owner=FlowChip${FC} -reentrant ALIAS RELEASE :ACQuisition- -owner=FlowChip${FC} -ignoreMissing ALIAS CLEARLOCKS :ACQuisition~ -owner=FlowChip${FC} ALIAS LOCK* :ACQuisition* -owner=FlowChip${FC} ### Do not implicitly resume imaging at end of script, unless script fails (per Joon, Mar 21, 2011). #PREPend STOP "\n\tResumeImaging" :STATe:NEW FlowChip${FC}:Running :STATe:NEW FlowChip${FC}:Ready -requires=Instrument:Initialized -conflicts=FlowChip${FC}:Running