#%TITLE% SC.mac
#%NAME%
# Macros for Sample changer operation
#
#%CATEGORY% MX, Other hardware
#
#%LOG%
#
#$Log: SC.mac,v $
#Revision 2.30 2013/10/31 12:20:01 guijarro
#more permissive with missing motors regarding setup
#
#Revision 2.29 2012/07/09 14:27:12 beteva
#avoid delete of the minidiff motors when Minikappa Off
#
#Revision 2.28 2011/11/02 10:58:37 guijarro
#fixed SCKappaOn
#added yagin'
#added code to disable safety bath
#
#Revision 2.27 2010/07/07 08:47:22 guijarro
#do not include r_kappa motor in SC sequence
#
#Revision 2.26 2010/06/10 16:16:57 guijarro
#added more time for safety bath to be in
#
#Revision 2.25 2010/01/28 14:00:36 guijarro
#changed minidiff_take_backgrounds to minidiff_take_periodic_backgrounds
#
#Revision 2.24 2008/07/17 14:58:34 rey
#documentation changes
#
#Revision 2.23 2008/05/23 07:24:50 spruce
#wait for 0.5 seconds before checking if the safety bath is in after putting it in
#
#Revision 2.22 2008/04/03 14:36:27 gabadinh
#-added new global variable PY_SC_LOADED_SAMPLE (a python dictionary encoded as a string) to share the current loaded sample information across BlissFramework applications
#
#Revision 2.21 2008/03/18 14:16:01 guijarro
#takes minikappa into account in setup
#
#Revision 2.20 2008/03/11 15:19:00 guijarro
#*** empty log message ***
#
#Revision 2.19 2008/03/11 13:24:17 guijarro
#Lock and Unlock macros disable/enable beamstop as well
#
#Revision 2.18 2007/09/03 15:23:50 guijarro
#move_em replaced by move_poll,
#user_postmove replaced by user_finished1
#
#Revision 2.17 2007/08/21 09:42:40 guijarro
#use _backout instead of bstopz reference position in xml file
#
#Revision 2.16 2007/05/31 08:26:57 gabadinh
#new spec functions to act as wrappers of the SCMoveToLoadingPosition and SCMoveToUnloadingPosition macros
#
#Revision 2.15 2007/05/29 16:23:52 gabadinh
#new global variable SC_MD_FLAGS, storing the current operational state:
#bit 1: sample changer is in use
#bit 2: minidiff can move
#bit 3: sample changer is in loading position
#
#Revision 2.14 2007/05/15 13:53:01 guijarro
#added SCKappaOn and SCKappaOff for minikappa ;
#needs modifications to the minidiff.xml file!!!
#
#Revision 2.13 2006/09/28 11:49:08 guijarro
#added sleep in SCMinidiffGetControl,
#to let time for Wago to really do the job
#before looking at the status again
#
#Revision 2.12 2006/09/12 13:00:54 guijarro
#calls exit if SCMoveToLoadingPosition fails and also gives back control to minidiff
#
#Revision 2.11 2006/09/06 08:01:09 guijarro
#adapted to call minidiff_take_backgrounds
#
#Revision 2.10 2006/05/17 07:27:14 guijarro
#*** empty log message ***
#
#Revision 2.8 2006/04/21 14:18:16 beteva
#added the kappa motor handling
#
#%END%
cdef("prompt_mac", "SC_prompt_check;\n", "samplechanger")
cdef("user_checkall", "SC_minidiff_check();\n", "samplechanger")
cdef("_SC_minidiff_check", "_SC_minidiff_check0();\n", "_SC_minidiff")
cdef("user_finished1", "SC_safetybath_get\n", "_SC_minidiff")
cdef("user_checkall", "SC_safetybath_check\n", "_SC_minidiff")
cdef("cleanup_always", "SC_safetybath_get\n","_SC_minidiff")
global MINIDIFF_SETUP
global MINIDIFF_BSTOPZ_POS
global KAPPA_IN_USE
global SC_MD_FLAGS
global PY_SC_LOADED_SAMPLE
def SC_safetybath_get '{
global MINIDIFF_BSTOPZ_POS
local bstopzmot
bstopzmot = motor_num(MINIDIFF["bstopz"])
if (bstopzmot < 0) {
print "invalid motor bstopz in Minidiff Hardware Object"
exit
}
get_angles
MINIDIFF_BSTOPZ_POS = A[bstopzmot]
}'
def SC_safetybath_check '{
local bstopzmot t0
bstopzmot = motor_num(MINIDIFF["bstopz"])
if (whatis("MINIDIFF_BSTOPZ_POS")&0x0800) {
SC_safetybath_get
}
if (A[bstopzmot] != MINIDIFF_BSTOPZ_POS) {
_remove_safety_bath
}
}'
def SCMinidiffSetup '{
global SC_MD_FLAGS
global PY_SC_LOADED_SAMPLE
global SC_NO_SAFETY_BATH
PY_SC_LOADED_SAMPLE=""
SC_MD_FLAGS=0
if (MINIDIFF_SETUP) {
if (KAPPA_IN_USE) {
SCKappaOn
} else {
SCGetLoadingPosition()
}
SCMinidiffOn
SCInUse 1
if ($1 == 1) {
# desactivate safety bath
rdef SC_safetybath_check ""
rdef SC_safetybath_get ""
rdef _remove_safety_bath ""
SC_NO_SAFETY_BATH=1
cdef("user_finished1", "", "_SC_minidiff", "delete")
cdef("user_checkall", "", "_SC_minidiff", "delete")
cdef("cleanup_always", "","_SC_minidiff", "delete")
}
print "Sample Changer properly configured for SPEC"
} else {
SCInUse 0
print "Minidiff setup incomplete: cannot continue with Sample Changer. Please run minidiff_setup."
exit
}
}'
def SCKappaOn '{
global KAPPA_IN_USE
KAPPA_IN_USE = 1
for (mne in KAPPA_MNE) {
if ((mne != "omega")&&(mne!="kappa")&&(mne!="phi")) {
motmne = KAPPA_MNE[mne]
MINIDIFF[motmne]=motmne
MINIDIFF[motmne]["ho"]=sprintf("/%s/%s", SPEC, motmne)
}
}
SCGetLoadingPosition()
}'
def SCKappaOff '{
local _OBJ_MINIDIFF[]
global KAPPA_IN_USE
KAPPA_IN_USE = 0
_OBJ_MINIDIFF = xml_readMotorsByRoles(MINIDIFF_HO_NAME)
for (mne in KAPPA_MNE) {
if (mne in _OBJ_MINIDIFF) {
} else {
if (mne != "omega") {
motmne = KAPPA_MNE[mne]
delete MINIDIFF[motmne]
delete MINIDIFF[motmne]["ho"]
}
}
}
SCGetLoadingPosition()
}'
def SCSetLoadingPosition '{
local holderLength, motmne, motnum
if ($# >= 1) {
holderLength = $1
} else {
motmne = MINIDIFF["phiy"]
motnum = motor_num(motmne)
holderLength = A[motnum]
}
print "setting loading position with holder length = " holderLength
_SCSetLoadingPosition(holderLength)
if (yesno("Are you sure you want to save the new reference position ?", 1) == 1) {
if (_SCWriteMinidiffReferencePosition() == 0) {
print "Reference position saved."
unix("mkdir -p ~/SClog")
on("~/SClog/SC_positions.log");offt
print date()
SCShowStatus
print
ont; close("~/SClog/SC_positions.log")
} else {
print "Warning: could not save reference position !"
}
} else {
print "Warning: reference position is left unsaved."
}
}'
def _SCSetLoadingPosition(holderLength) '{
local role, motor, motmne, tmp[]
unglobal MINIDIFF_LOAD_POSITION
global MINIDIFF_LOAD_POSITION[]
tmp = asso_keys(MINIDIFF)
for (role in tmp) {
if ((role != "zoom")&&(role != "light")&&(role != "camera")) {
motmne = MINIDIFF[role]
motnum = motor_num(motmne)
MINIDIFF_LOAD_POSITION[motmne] = A[motnum]
}
}
# set holder length
motmne = MINIDIFF["phiy"]
MINIDIFF_LOAD_POSITION[motmne] = holderLength
print MINIDIFF_LOAD_POSITION
}'
def _SCWriteMinidiffReferencePosition() '{
local tmp0[], role, motmne, query, queryResult[], path, update, updatesList, updateResult
tmp0 = asso_keys(MINIDIFF)
updatesList = "("
for (role in tmp0) {
if ((role != "zoom")&&(role != "light")&&(role != "camera"))
{
motmne = MINIDIFF[role]
if (KAPPA_IN_USE) {
query = sprintf("xml_read(\"%s\", \"/equipment/referencePositionWithKappa/%s[1]\")", MINIDIFF_HO_NAME, role)
} else {
query = sprintf("xml_read(\"%s\", \"/equipment/referencePosition/%s[1]\")", MINIDIFF_HO_NAME, role)
}
queryResult = prop_get(HWR_dev, query)
if (!("__error__" in queryResult)) {
path = queryResult[0]["__path__"]
update = sprintf("(\"%s\", %s)", path, MINIDIFF_LOAD_POSITION[motmne])
if (updatesList == "(") {
updatesList = sprintf("(%s", update)
} else {
updatesList = sprintf("%s,%s", updatesList, update)
}
} else {
print queryResult["__error__"]
return(-1)
}
}
}
updatesList = sprintf("%s)", updatesList)
query = sprintf("xml_multiwrite(\"%s\", \'%s\')", MINIDIFF_HO_NAME, updatesList)
updateResult = remote_eval(HWR_dev, query)
if ("__error__" in updateResult) {
print updateResult["__error__"]
return(-1)
} else {
return(0)
}
}'
def SCGetLoadingPosition() '{
local role, motmne, query, queryResult[], position, tmp0[], tmp[], tmp2[]
tmp0 = asso_keys(MINIDIFF)
for (role in tmp0) {
if ((role != "zoom")&&(role != "light")&&(role != "camera")&&(role != "bstopz")) {
motmne = MINIDIFF[role]
if (KAPPA_IN_USE) {
query = sprintf("xml_read(\"%s\", \"/equipment/referencePositionWithKappa/%s[1]\")", MINIDIFF_HO_NAME, role)
} else {
query = sprintf("xml_read(\"%s\", \"/equipment/referencePosition/%s[1]\")", MINIDIFF_HO_NAME, role)
}
queryResult = prop_get(HWR_dev, query)
if (!("__error__" in queryResult)) {
position = queryResult[0]["__value__"]
tmp[motmne] = position
if (KAPPA_IN_USE) {
query = sprintf("xml_read(\"%s\", \"/equipment/referencePositionWithKappa/%s[1]/@delta\")", MINIDIFF_HO_NAME, role)
} else {
query = sprintf("xml_read(\"%s\", \"/equipment/referencePosition/%s[1]/@delta\")", MINIDIFF_HO_NAME, role)
}
queryResult = prop_get(HWR_dev, query)
if (!("__error__" in queryResult)) {
delta = queryResult[0]["__value__"]
tmp2[motmne] = delta
} else {
tmp2[motmne] = 0.0001
}
}
}
}
unglobal MINIDIFF_LOAD_POSITION
unglobal MINIDIFF_DELTAS
global MINIDIFF_LOAD_POSITION[]
global MINIDIFF_DELTAS[]
ass_copy(tmp, MINIDIFF_LOAD_POSITION)
ass_copy(tmp2, MINIDIFF_DELTAS)
return(1)
}'
def SCMinidiffOn '{
cdef("_SC_minidiff_check", "_SC_minidiff_check0()\n","_SC_minidiff")
}'
def SCMinidiffOff '{
local _yn
tty_cntl("md")
print
print "***** THIS ACTION HAS SECURITY IMPLICATIONS *****"
print "** Checking on Sample Changer / Minidiff will be disabled **"
tty_cntl("me")
if (yesno("Do you really want to do it ?",0) == 1) {
cdef("", "","_SC_minidiff","delete")
}
}'
def inPosition(motmne) '{
# *******************************************************
# * Compare given motor position with loading position, *
# * taking the tolerance into account ; return 0 if the *
# * motor is not in the position, 1 otherwise *
# *******************************************************
local delta, motnum, position
motnum = motor_num(motmne)
position = MINIDIFF_LOAD_POSITION[motmne]
delta = MINIDIFF_DELTAS[motmne]
if (delta <= 0) {
return(0)
} else {
if (motnum < 0) {
return(0)
}
#return 1 if motor position is between position-delta and position+delta
return(fabs(A[motnum] - position) <= delta)
}
}'
def SC_minidiff_check() '{
_SC_minidiff_check
}'
def _SC_minidiff_check0() '{
# *****************************************************
# * This macro is called before each motor movement ; *
# * if the minidiff should not move from the loading *
# * position, it prevents Spec from moving the motor *
# *****************************************************
if (SCMinidiffCanMove() == 0) {
# prevent Spec from moving the Minidiff motors
SCLockMinidiff
}
}'
def SCMoveToLoadingPos() '{
SCMoveToLoadingPosition
helical_resetpos()
return SCCanOperate()
}'
def SCMoveToLoadingPosition '{
if (PIPELINE) { minidiff_take_periodic_backgrounds }
_SCMoveToLoadingPosition $*
}'
def _SCMoveToLoadingPosition '{
global MINIDIFF_LOAD_POSITION[]
local motmne, motnum
wago_writech("swpermit", 0)
wago_writech("SCcryoctrl", 0)
if (SCMinidiffCanMove()==1) SCUnlockMinidiff
if (MINIDIFF_SETUP == 0) { print "no minidiff defined"; exit }
# the loading position is always re-read from the file ;
# maybe we can do differently (no re-reading it if MINIDIFF_LOAD_POSITION
# is already filled ?)
if ( ( ret = SCGetLoadingPosition()) != 1) {
# an error occured
if (asso_len(MINIDIFF_LOAD_POSITION) > 0) {
print "Cannot get object minidiff. Check hardware repository"
} else {
print "No loading position defined ! Aborting."
}
exit
}
if ($# >= 1) {
# set a different holder length
motmne = MINIDIFF["phiy"]
MINIDIFF_LOAD_POSITION[motmne] = $1
}
get_angles
_backout()
for (motmne in MINIDIFF_LOAD_POSITION) {
motnum = motor_num(motmne)
A[motnum] = MINIDIFF_LOAD_POSITION[motmne]
}
print "Moving minidiff to loading position"
move_em
print "Moving fluorescence detector out"
wago_writech("fldin", 0)
if (WAGOKEYS["laserin"] > 0) {
print "Removing laser"
wago_writech("laserin", 0)
}
if (WAGOKEYS["scntin"] > 0) {
print "Removing scintillator"
wago_writech("scntin", 0)
}
if (WAGOKEYS["yag_in"] > 0) {
print "Removing scintillator"
yagout
}
move_poll
print "Moving light out"
lightout
if (SCMotorsInLoadingPosition() == 1) {
if (!SC_NO_SAFETY_BATH) {
print "Putting safety screen in"
wago_writech("safetyin", 1)
sleep(1)
}
if (SCPneumaticsInLoadingPosition(1) == 1) {
print " -- done."
# give software permit for loading to SC ;
# as a consequence, it will "lock" (software lock)
# the minidiff motors (see _SC_minidiff_check macro)
wago_writech("swpermit", 1)
wago_writech("SCcryoctrl", 1)
if (SCMinidiffCanMove() == 0) SCLockMinidiff
} else {
tty_cntl("md")
print "Cannot get minidiff to loading position"
SCShowStatus
tty_cntl("me")
SCMinidiffGetControl
exit
}
} else {
tty_cntl("md")
print "Cannot get minidiff to loading position"
SCShowStatus
tty_cntl("me")
SCMinidiffGetControl
exit
}
}'
def SCMoveToUnloadingPos() '{
SCMoveToUnloadingPosition
helical_resetpos()
return SCCanOperate()
}'
def SCMoveToUnloadingPosition '{
_SCMoveToLoadingPosition $*
}'
def SCMinidiffGetControl '{
if (! SC_NO_SAFETY_BATH) { wago_writech("safetyin", 0) }
wago_writech("swpermit", 0)
wago_writech("SCcryoctrl", 0)
sleep(0.5)
if (SCMinidiffCanMove() == 1) {
SCUnlockMinidiff
} else {
printf("cannot get control to minidiff: is SC arm parked ?\n")
exit
}
}'
def SCLockMinidiff '{
local motnum
for (motmne in MINIDIFF_LOAD_POSITION) {
motnum = motor_num(motmne)
motor_par(motnum, "disable", 1)
}
motnum = motor_num(BEAMSTOP["z"]["motor"])
motor_par(motnum, "disable", 1)
}'
def SCUnlockMinidiff '{
local motnum
for (motmne in MINIDIFF_LOAD_POSITION) {
motnum = motor_num(motmne)
motor_par(motnum, "disable", 0)
}
motnum = motor_num(BEAMSTOP["z"]["motor"])
motor_par(motnum, "disable", 0)
}'
def SCInUse '{
global SC_MD_FLAGS
if ( $1 == 1 ) {
wago_writech("SCdisable", 0)
SC_MD_FLAGS=SC_MD_FLAGS | 1
SCMinidiffCanMove()
} else {
wago_writech("SCdisable", 1)
SC_MD_FLAGS=SC_MD_FLAGS & ~1
SCMinidiffGetControl
}
SCIsInUse(1)
}'
def SCIsInUse(verbose) '{
nowis = wago_readch("SCdisable")
if (verbose==1) {
if( nowis == 0 ) { using = "" } else { using = "not" }
print "Sample Changer is " using " being used. "
} else {
return( nowis? 0:1)
}
}'
def SCShowStatus '{
local motmne, motnum, status
get_angles
print "Current Minidiff signals/positions"
print " -- motors :"
for (motmne in MINIDIFF_LOAD_POSITION) {
motnum = motor_num(motmne)
if (inPosition(motmne)) status="ok"; else status=sprintf("invalid (should be %.5g)", MINIDIFF_LOAD_POSITION[motmne])
printf("%15s %.5g\t%10s\n", motmne, A[motnum], status)
}
print " -- wagos (check correct interlock state with \'intlck show\') :"
wread SCdisable lightin cryoin mdpermit swpermit SCcryoctrl fldin safetyok
if (WAGOKEYS["laserin"] > 0) wread laserin
if (WAGOKEYS["scntin"] > 0) wread scntin
}'
def SC_prompt_check '{
# ***************************************************************
# * Check minidiff and sample changer and display status *
# ***************************************************************
local msg
if (SCIsInUse(0) == 1) {
if (SCCanOperate() == 1) {
msg = "SAMPLE CHANGER CAN LOAD/UNLOAD SAMPLE"
} else {
msg = "SAMPLE CHANGER LOCKED"
}
} else {
msg = "SAMPLE CHANGER NOT IN USE"
}
if (SCMinidiffCanMove() == 1) {
msg = sprintf("%s / %s", msg, "MINIDIFF CAN MOVE")
} else {
msg = sprintf("%s / %s", msg, "MINIDIFF LOCKED")
}
tty_cntl("md");printf("%s", msg);tty_cntl("me")
}'
def SCMinidiffCanMove() '{
# **************************************************************
# Minidiff can move only if sample changer arm is parked, *
# and if the software permit to allow sample loading/unloading *
# is not set *
# **************************************************************
local SCparked, swpermit
global SC_MD_FLAGS
SCparked = wago_readch("SCparked")
swpermit = wago_readch("swpermit")
if (wago_readch("SCdisable") == 1) {
SC_MD_FLAGS = SC_MD_FLAGS & ~4
SC_MD_FLAGS = SC_MD_FLAGS | 2
return(1)
}
if ( (SCparked == 1) && (swpermit == 0) ) {
#print "Minidiff could move"
SC_MD_FLAGS = SC_MD_FLAGS & ~4
SC_MD_FLAGS = SC_MD_FLAGS | 2
return(1)
} else {
#print "Minidiff should not move"
SC_MD_FLAGS = SC_MD_FLAGS & ~2
return(0)
}
}'
def SCPneumaticsInLoadingPosition(waitend) '{
local inload timeout inittime
inload = 0
timeout = 6
inittime = time()
while (inload == 0) {
inload = wago_readch("mdpermit")
if (waitend == 0) {
break
}
if ((time()-inittime) > timeout) {
break
}
}
return(inload)
}'
def SCMinidiffInLoadingPosition(waitend) '{
# ********************************************************
# * Minidiff is in loading position if all the motors *
# * are in the right positions and if the pneumatic *
# * devices are out (except safety screen) *
# ********************************************************
if (SCMotorsInLoadingPosition() > 0) {
return SCPneumaticsInLoadingPosition(waitend)
} else {
return 0
}
}'
def SCMotorsInLoadingPosition() '{
global MINIDIFF_LOAD_POSITION[]
local motmne, motnum
if (asso_len(MINIDIFF_LOAD_POSITION) == 0) {
# no positions defined ?!
return(0)
}
get_angles
for (motmne in MINIDIFF_LOAD_POSITION) {
if (inPosition(motmne) == 0) {
return(0)
}
}
return(1)
}'
def SCCanOperate() '{
# ******************************************************
# * SC can load/unload a sample if minidiff is in load *
# * position and if it has the software authorization *
# ******************************************************
global SC_MD_FLAGS
local res
res = wago_readch("swpermit") && SCMinidiffInLoadingPosition()
if (res) {
SC_MD_FLAGS = SC_MD_FLAGS & ~2
SC_MD_FLAGS = SC_MD_FLAGS | 4
} else{
SC_MD_FLAGS = SC_MD_FLAGS & ~4
}
return( res )
}'
#%MACROS%
#%IMACROS%
#%TOC%
#%AUTHOR%
#$Revision: 2.30 $$Date: 2013/10/31 12:20:01 $
|