#%TITLE% MINIDIFF.MAC
#%NAME% %B%minidiff.mac%B% - Macros to controll the mini diffractometer
#%DESCRIPTION%
# Set of macros to control different eqipment of the MD2M diffractometer.
#%CATEGORY% MX
#%END%
global MINIDIFF[]
global MINIDIFF_CENTERING_POS[]
global MINIDIFF_HO_NAME
global MINIDIFF_SETUP
global AUTO_CENTRING_FLAG
global ENABLE_AUTO_LOOP_CENTRING
global ENABLE_AUTO_CRYSTAL_CENTRING
global ENABLE_PLAYBACK_CENTRING
def minidiff_setup '{
unglobal MINIDIFF
global MINIDIFF[]
unglobal MINIDIFF_CENTERING_POS
global MINIDIFF_CENTERING_POS[]
local _OBJ_MINIDIFF[] tmp[]
global MINIDIFF_PCONST
global MINIDIFF_TCONST
if ($# < 2) {
print "Usage : minidiff_setup <minidiff Hardware Object> <phi pos. at ref>\nexample: minidiff_setup /minidiff 235"
exit
}
MINIDIFF_HO_NAME = "$1"
MINIDIFF_SETUP = 0
MINIDIFF_TCONST=40
MINIDIFF_PCONST=0.005
xml_readRoles(MINIDIFF_HO_NAME)
tmp = asso_keys(XML_tmp)
for (role in tmp) {
MINIDIFF[role]["ho"]=XML_tmp[role]["hwrid"]
}
camera_ho = XML_tmp["camera"]["hwrid"]
if ((xml_read(camera_ho, "/device/taconame") > -1)||(xml_read(camera_ho, "/device/tangoname") > -1)) {
MINIDIFF["camera"]=XML_tmp[0]["__value__"]
if (xml_read(camera_ho, "/device/tangoname")>-1) {
# add tango device, if any (for take_backgrounds)
MINIDIFF["tango_camera"]=XML_tmp[0]["__value__"]
} else {
MINIDIFF["tango_camera"]=""
}
} else {
print "Could not find Falcon Device Server for Minidiff"
exit
}
_OBJ_MINIDIFF = xml_readMotorsByRoles(MINIDIFF_HO_NAME)
if (("focus" in _OBJ_MINIDIFF) && ("phi" in _OBJ_MINIDIFF) \
&& ("phiy" in _OBJ_MINIDIFF) && ("phiz" in _OBJ_MINIDIFF) \
&& ("sampx" in _OBJ_MINIDIFF) && ("sampy" in _OBJ_MINIDIFF) \
&& ("bstopz" in _OBJ_MINIDIFF) && ("zoom" in _OBJ_MINIDIFF) \
&& ("light" in _OBJ_MINIDIFF)) {
ass_copy(_OBJ_MINIDIFF, MINIDIFF)
MINIDIFF["phi"]["reference"] = $2
if (getMinidiffCenteringPositions() < 0) {
print "Minidiff: could not get centring positions => will not move to centring position."
} else {
print "Minidiff successfully configured."
}
MINIDIFF_SETUP=1
} else {
print "Could not retrieve motors from Minidiff Hardware Object : " "$1"
exit
}
if (whatis("backgrounds_local_prepare") == 0)
eval("def backgrounds_local_prepare()\'{ }\'")
if (whatis("backgrounds_local_finish") == 0)
eval("def backgrounds_local_finish()\'{ }\'")
}'
cdef("collection_local_prepare", "minidiff_prepare\n", "minidiff")
def _remove_safety_bath '{
local t0
wwrite safetyin 0
t0 = time()
while (wago_readch("safetyback") == 0) {
if ((time() - t0) > 3) {
print "Cannot move virus bath out !"
exit
}
}
}'
def lightin '{
local waittime
if (wago_readch("cndout") == 1) {
# should wait
waittime=2
} else {
waittime=0
}
wago_writech("lightin",1)
sleep(waittime)
}'
def lightout '{
local t0
wago_writech("lightin",0)
t0 = time()
while (wago_readch("cndout") == 0) {
if ((time() - t0) > 3) {
print "Cannot move light out !"
exit
}
}
}'
def _backlightstate() '{
local st
st = wago_readch("cndout")
if (st == 0) {
return("IN")
} else if (st == 1) {
return("OUT")
} else {
return "unknown"
}
}'
def _flightstate() '{
local st
st = wago_readch("light2off")
if (st == 0) {
return("ON")
} else if (st == 1) {
return("OFF")
} else {
return "unknown"
}
}'
def fldetin '{ wago_writech("fldin",1) }'
def fldetout '{ wago_writech("fldin",0) }'
def cryoin '{ wago_writech("SCcryoctrl",0); wago_writech("cryoin",1) }'
def cryout '{ wago_writech("cryoin",0) }'
def lighton '{ wwrite light1off 0 }'
def lightoff '{ wwrite light1off 1 }'
def light2on '{ wwrite light2off 0 }'
def light2off '{ wwrite light2off 1 }'
def light2_is_on() '{ return 1-wago_readch("light2off") }'
def flighton() '{
light2on
if (FLIGHT_ON == 0)
FLIGHT_ON = WAGODAC_VAL["flight"]
A[flight] = FLIGHT_ON
move_all; waitmove; getangles
}'
def flightoff() '{
global FLIGHT_ON
getangles
FLIGHT_ON = A[flight]
light2off
mv flight 0
}'
def annealon '{ wago_writech("anneal",1); while (wago_readch("annealin")==0) { sleep(0.01) } }'
def annealoff '{ wago_writech("anneal",0); while (wago_readch("annealin")==1) { sleep(0.01) }; cryoin }'
def anneal '{
local anneal_time, hutch_status[]
local backwasout
local backst scintst flightst
if ($# != 1) {
print "Usage: anneal time(s)"
exit
}
anneal_time = $1
backst = _backlightstate()
flightst = _flightstate()
backwasout = is_backstop_out()
lightout
backout
fldetout
cryout
flighton()
sleep(0.1)
cdef("cleanup_once","annealoff\n","__anneal__")
annealon
sleep(anneal_time)
annealoff
sleep(0.1)
cryoin
# one improvement would be to check the hutch status and only
# put the backstop in if the search has been done.
if (backwasout == 0)
backin
if (backst == "IN")
lightin
if (flightst == "OFF")
flightoff()
}'
def minidiff_prepare '{
local i0gain
lightout
fldetout
msclose
# Find gain on i0. apply it to i1
# need so that diagnostics with musst read proper values
#wcadj i0
#i0gain = wcreadgain(i0)
#wcgain i1 i0gain
}'
def phi_init '{
local mot_par[] PHI_MOTNUM PHI_AT_REF PHIDEV
PHI_MOTNUM=motor_num(MINIDIFF["phi"])
PHI_AT_REF=MINIDIFF["phi"]["reference"]
PHIDEV=motor_par(PHI_MOTNUM, "device_id")
SCMinidiffGetControl
printf("PHI INIT:\n - Setting phi velocity and acceleration\n")
mot_par[0] = motor_par(PHI_MOTNUM,"config_velocity")
mot_par[1] = motor_par(PHI_MOTNUM,"config_acceleration")
chg_dial(PHI_MOTNUM,0)
chg_offset(PHI_MOTNUM,0)
esrf_io(PHIDEV, "AxisWrCmdSync",sprintf("SP %d",mot_par[0]))
esrf_io(PHIDEV, "AxisWrCmdSync",sprintf("AC %d",mot_par[0]/mot_par[1]*1000))
printf(" - Resetting GALIL controller\n")
esrf_io(PHIDEV, "AxisWrCmdSync", "OE0")
esrf_io(PHIDEV, "AxisWrCmdSync", "SHA")
sleep(3)
printf(" - Now searching for HOME signal\n ")
esrf_io(PHIDEV, "AxisWrCmdSync", "FIA")
esrf_io(PHIDEV, "AxisWrCmdSync", "BGA")
while(esrf_io(PHIDEV, "AxisWrCmdSync", "TSA") & 0x80) {
printf(".");sleep(0.5)
}
printf ("\n")
if (esrf_io(PHIDEV, "AxisWrCmdSync", "TI") == 15) {
printf(" - Setting positions to zero ")
get_angles
A[PHI_MOTNUM] = PHI_AT_REF
move_em; move_poll; get_angles
chg_dial(PHI_MOTNUM,0)
chg_offset(PHI_MOTNUM,0)
tty_cntl("md")
printf("Ok: done\n")
tty_cntl("me")
} else {
tty_cntl("md")
printf("Error!\n")
tty_cntl("me")
}
esrf_io(PHIDEV, "AxisWrCmdSync", "OE1")
}'
def zoom_init '{
printf("ZOOM INIT:\n - Adjusting zoom motor\n")
set_lm zoom 300 -300
printf(" - Searching for reference signal\n")
chg_dial( zoom, "lim-" )
set_dial zoom 102
set zoom 102
printf(" - Moving zoom to 50%\n")
mv zoom 50
set_lm zoom 0 100
tty_cntl("md")
printf("Ok: done\n")
tty_cntl("me")
mv zoom 0
}'
def autofocus '{
local negativeStep, n_contrast
local positiveStep, p_contrast
local old_contrast, phix_pos
negativeStep = -0.1
positiveStep = 0.1
while ((negativeStep <= -0.015) || (positiveStep >= 0.005)) {
mvr phix positiveStep
p_contrast = esrf_io(MINIDIFF["camera"], "DevCcdGetTGradient", 15000)
phix_pos = negativeStep - positiveStep
mvr phix phix_pos
n_contrast = esrf_io(MINIDIFF["camera"], "DevCcdGetTGradient", 15000)
if ((p_contrast > old_contrast) && (p_contrast > n_contrast)) {
phix_pos = positiveStep - negativeStep
mvr phix phix_pos
positiveStep = positiveStep * 0.75
negativeStep = negativeStep * 0.33
old_contrast = p_contrast
} else if ((n_contrast > old_contrast) && (n_contrast > p_contrast)) {
positiveStep = positiveStep * 0.33
negativeStep = negativeStep * 0.75
old_contrast = n_contrast
} else {
mvr phix -negativeStep
positiveStep = positiveStep * 0.5
negativeStep = negativeStep * 0.5
}
}
}'
def minidiff_init '{
# does minidiff reset : move motors to switches,
# and set default position from Minidiff XML file
local query queryResult[] motrole motmne motnum position
local i k m tmp tmp0[] REFERENCE_POS[] scdisabled
scdisabled = wago_readch("SCdisable")
if (scdisabled == 0) {
SCInUse 0
}
printf("MINIDIFF INIT:\n")
query = sprintf("xml_read(\"%s\", \"/equipment/resetPosition/*\")", MINIDIFF_HO_NAME)
queryResult = prop_get(HWR_dev, query)
if (!("__error__" in queryResult)) {
tmp0 = asso_keys(queryResult)
for (k in tmp0) {
i = split(queryResult[k]["__path__"], tmp, "/")
motrole = substr(tmp[i-1], 0, length(tmp[i-1])-3)
position = queryResult[k]["__value__"]
REFERENCE_POS[motrole]=position
}
} else {
printf("Error: could not retrieve reset pos. from Mindiff Hardware Object\n")
exit
}
get_angles
for (motrole in REFERENCE_POS) {
if (($# == 0)||(motrole=="$1")) {
motmne = MINIDIFF[motrole]
motnum = motor_num(motmne)
cntrl = motor_par(motnum,"controller")
if (motnum >= 0) {
tstart = time()
tcurr = time()
read_motors(0)
pstart = A[motnum]
motsign = motor_par(motnum, "step_size") > 0 ? 1: -1
if ((pstart-(motsign*0.1))<get_lim(motnum, -1)) {
dest=get_lim(motnum, -1)
} else {
dest=pstart-(motsign*0.1)
}
printf(" - mvr %s %f\n", motmne, dest-pstart)
A[motnum]=dest
move_em; move_poll
printf(" - searching lim- for motor %s ", motmne)
chg_dial(motnum, "lim-")
sleep(0.5)
while(wait(0x21)){
if (cntrl == "MAXE_E") {
read_motors(0)
if (fabs(A[motnum] - pstart) < MINIDIFF_PCONST) {
print "motor is at " A[motnum] " and was at " pstart
eprintf ("Motor %s is not moving, exiting...\n", motmne)
stop(1)
exit
} else {
pstart=A[motnum]
}
} else {
if ((time() - tstart) > MINIDIFF_TCONST) {
eprintf("Timeout while searching limit switch for motor %s,", motmne)
eprintf (" exiting...\n")
stop(1)
exit
}
}
printf("\b%s", substr("-\\|/", (m=++m%4)+1, 1))
sleep(0.5)
}
printf("\b\n")
printf(" - setting reference pos. to %g\n", REFERENCE_POS[motrole])
chg_dial(motnum,REFERENCE_POS[motrole])
chg_offset(motnum, REFERENCE_POS[motrole])
motsign = motor_par(motnum, "step_size") > 0 ? 1: -1
printf(" - moving back motor from limit\n")
get_angles
A[motnum] = A[motnum] + (motsign*2)
move_em; move_poll
} else {
printf("Invalid motor %s, exiting", motmne)
exit
}
}}
if ($# == 0) {
if (KAPPA_IN_USE)
minikappa_init
else
phi_init
}
#SCInUse 1-scdisabled
SCInUse 1
}'
def getMinidiffCenteringPositions() '{
local k, i, motrole, query, queryResult[], position, delta, tmp0[], tmp[]
unglobal MINIDIFF_CENTERING_POS
global MINIDIFF_CENTERING_POS[]
query = sprintf("xml_read(\"%s\", \"/equipment/autoCentering/referencePosition/*\")", MINIDIFF_HO_NAME)
queryResult = prop_get(HWR_dev, query)
if (!("__error__" in queryResult)) {
tmp0 = asso_keys(queryResult)
for (k in tmp0) {
i = split(queryResult[k]["__path__"], tmp, "/")
motrole = substr(tmp[i-1], 0, length(tmp[i-1])-3)
position = queryResult[k]["__value__"]
delta = queryResult[k]["delta"]
MINIDIFF_CENTERING_POS[motrole]["delta"]=delta
MINIDIFF_CENTERING_POS[motrole]=position
}
return (1)
} else {
print queryResult["__error__"]
return(-1)
}
}'
def minidiff_prepare_centring '{
local tmp[] tmp2[] motrole motmne motnum delta position
print "moving minidiff to centring position..."
tmp = asso_keys(MINIDIFF_CENTERING_POS)
getangles
for (motrole in tmp) {
motmne = MINIDIFF[motrole]
printf(" - moving %s to %f\n", motmne, MINIDIFF_CENTERING_POS[motrole])
motnum = motor_num(motmne)
A[motnum]=MINIDIFF_CENTERING_POS[motrole]
}
if (($# > 0)&&(length("$1")>0)) {
print "moving minidiff to crystal last centered pos."
tmp2 = _minidiff_split("$1")
for (motrole in tmp2) {
motmne = MINIDIFF[motrole]
printf(" - moving %s to %f\n", motmne, tmp2[motrole])
motnum = motor_num(motmne)
A[motnum]=tmp2[motrole]
}
}
move_em
while (wago_readch("SCparked")==0) {
sleep(1)
}
lightin
move_poll
ZOOM_LIGHT["old_zoom_pos"]=-1
AUTO_CENTRING_FLAG=AUTO_CENTRING_FLAG+1
}'
def minidiff_prepare_autocentring '{
mv flight 0
AUTO_CENTRING_FLAG=-1
minidiff_prepare_centring
}'
def _minidiff_split(s) '{
local tmp[] tmp2[] tmp3[]
split(s, tmp, ";")
for (i in tmp) {
split(tmp[i], tmp2, " ")
tmp3[tmp2[0]]=tmp2[1]
}
return tmp3
}'
def minidiff_take_periodic_backgrounds '{
local directory filename bkg_mtime
# find where backgrounds are stored
if (xml_read(MINIDIFF_HO_NAME, "/equipment/autoCentering/imagesFolder") >= 0) {
directory = XML_tmp[0]["__value__"]
filename = sprintf("%s/background1.tif", directory)
# now check background 1 file last modification time
bkg_mtime = file_info(filename, "mtime")
if ((time() - bkg_mtime) > (1*3600)) {
minidiff_take_backgrounds
}
else {
print "Backgrounds are recent. Nothing to do."
}
}
}'
def _minidiff_take_zoom_backgrounds '{
# move to zoom levels, and take images
getangles
ZOOM_LIGHT["old_zoom_pos"]=-1
zoom_mot = motor_num(ZOOM_LIGHT["zoom_motor"])
if (zoom_mot < 0) {
print "ABORTING: could not retrieve zoom motor !"
egui_logmsg("ABORTING: could not retrieve zoom motor (check zoomlight macro setup)")
} else {
len=0
for (k in ZOOM_LIGHT[zoom_mot]) {
len+=1
}
for (i=0; i<len;i+=1) {
pos = i*20
egui_logmsg(sprintf(" - moving to zoom level %d (%d)", i+1, pos))
A[zoom_mot]=pos
move_em; move_poll
# take image
egui_logmsg(sprintf(" - taking background image %d : %s/background%d_%d.tif", i+1, directory, MINIDIFF["aperture_index"], i+1))
if (MINIDIFF["tango_camera"]!="") {
local idx
idx = MINIDIFF["aperture_index"]
unix_cmd=sprintf("python -c %s", sprintf("\'import PyTango; import Image; dev=PyTango.DeviceProxy(\"%s\"); w=dev.read_attribute(\"Width\").value; h=dev.read_attribute(\"Height\").value;img=dev.read_attribute(\"Image\").value\ntry: im=Image.frombuffer(\"RGB\", (w,h), img)\nexcept: im=Image.frombuffer(\"RGB\", (w,h), dev.read_attribute(\"RgbImage\").value)\nim=im.transpose(Image.FLIP_TOP_BOTTOM)\nim.save(\"%s/background%d_%d.tif\")\'", MINIDIFF["tango_camera"],directory,idx,i+1))
} else {
local idx
idx = MINIDIFF["aperture_index"]
unix_cmd=sprintf("python -c %s", sprintf("\'import TacoDevice; import Image; dev=TacoDevice.TacoDevice(\"%s\"); dev.tcp(); data=dev.DevCcdRead(1); img=Image.frombuffer(\"RGB\", (dev.DevCcdXSize(), dev.DevCcdYSize()), data); pixmap=img.tostring(\"raw\", \"BGR\"); img=Image.frombuffer(\"RGB\", img.size, pixmap);img.save(\"%s/background%d_%d.tif\")\'", MINIDIFF["camera"], directory, idx, i+1))
}
#print unix_cmd
unix(unix_cmd)
}
egui_logmsg("Done !")
}
}'
if (whatis("multiaperture_diameter")==0) {
eval("def multiaperture_diameter() '\{\}'")
}
def minidiff_take_backgrounds '{
local directory filename bkg_mtime k len i pos
# find where backgrounds are stored
if (xml_read(MINIDIFF_HO_NAME, "/equipment/autoCentering/imagesFolder") >= 0) {
directory = XML_tmp[0]["__value__"]
print "taking backgrounds for Automatic Centring... please wait"
egui_logmsg("Taking backgrounds for Automatic Centring... please wait")
lightin
backout
backgrounds_local_prepare()
if (AP_XML == 0) {
MINIDIFF["aperture_index"] = 0
_minidiff_take_zoom_backgrounds
} else {
for (diameter in AP_IDX) {
multiaperture_diameter(diameter)
MINIDIFF["aperture_index"] = AP_IDX[diameter]
_minidiff_take_zoom_backgrounds
}
}
backgrounds_local_finish()
} else {
printf("Could not retrieve autocentring information from minidiff XML file\n")
}
}'
#%MACROS%
#%IMACROS%
#%TOC%
#%AUTHOR% BLISS%BR%
#$Revision: 1.53 $$Date: 2012/09/06 16:17:16 $
#%END%
#%LOG%
#$Log: minidiff.mac,v $
#Revision 1.53 2012/09/06 16:17:16 guijarro
#workaround spec interpreter bug with continue keyword
#
#Revision 1.52 2011/05/30 17:32:16 guijarro
#define multiaperture_diameter function if necessary (spec is weird!)
#
#Revision 1.51 2011/05/30 11:40:54 guijarro
#added [] when missing on local associative array declaration
#
#Revision 1.50 2011/04/19 14:26:35 guijarro
#take backgrounds for each aperture
#
#Revision 1.49 2011/02/18 12:29:00 beteva
#added backgrounds_local actions. Changed the safety to virus bath.
#
#Revision 1.48 2010/11/16 12:53:48 guijarro
#do not move light in in minidiff_prepare_centring if SC arm is not parked
#
#Revision 1.47 2010/11/16 11:02:49 guijarro
#call minikappa_init instead of phi_init if kappa i sused
#
#Revision 1.46 2010/11/16 10:26:20 guijarro
#perform a small movement of all the motors involved in the minidiff_init macro at the start of the macro
#
#Revision 1.45 2010/11/02 15:55:11 beteva
#changed the IN/OUT state of the front light, added change of the
#flight motor when flighton/off
#
#Revision 1.44 2010/10/28 11:45:09 beteva
#restore the lights (back and front) and the backstop at the end
#of the anneal procedure
#
|