esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% MINIKAPPA.MAC
#%NAME% %B%minikappa.mac%B% - set of macros to handle the EMBL minikappa.
#
#%CATEGORY% MX
#%END%

#%UU% [omega kappa phi offset position]
#%MDESC% Set the minikappa %B%omega%B%, %B%kappa%B% and %B%phi%B% motor
#mnemonics and the kappa motor %B%offset%B% from the home switch [deg] and
#loading position when using the sample changer [deg].
def minikappasetup '{
global KAPPA_MNE KAPPA_MOT KAPPA_OFFSET
global KAPPA_OFFSET KAPPA_OK KAPPA_LOADPOS
global KAPPA_UDIFF KAPPA_DEV
global KAPPA_MOT_DOTC

local mne

  KAPPA_OK = 0
  if ($# == 0) {
    KAPPA_MNE["omega"] = getval ("Omega motor mnemonic:",  KAPPA_MNE["omega"])
    KAPPA_MOT["omega"] = motor_num(KAPPA_MNE["omega"])
    if (KAPPA_MOT["omega"] == -1) {
      eprintf ("Motor %s not configured, setup failed\n",KAPPA_MNE["omega"])
      KAPPA_OK = -1
    }

    KAPPA_MNE["kappa"] = getval ("Kappa motor mnemonic:",  KAPPA_MNE["kappa"])
    KAPPA_MNE["phi"] = getval ("Phi motor mnemonic:",  KAPPA_MNE["phi"])

    KAPPA_OFFSET = getval("Kappa motor offset from the home switch to the \"zero\" position [deg]:", KAPPA_OFFSET)
    KAPPA_LOADPOS["kappa"] = getval("Kappa loading position (used by the sample changer):", KAPPA_LOADPOS["kappa"])

    KAPPA_MNE["sampx"] = getval ("Sampx motor mnemonic:",  KAPPA_MNE["sampx"])
    KAPPA_MNE["sampy"] = getval ("Sampy motor mnemonic:",  KAPPA_MNE["sampy"])
    KAPPA_MNE["phiy"] = getval ("Phiy motor mnemonic:",  KAPPA_MNE["phiy"])
    if (!KAPPA_OK) {
      if (motor_par(KAPPA_MOT["omega"],"device_id") == "udiff_mot")
        KAPPA_UDIFF = 1
    }
    if (KAPPA_UDIFF == 1) {
      KAPPA_DEV["omega"] = motor_par(KAPPA_MOT["omega"],"address")
      KAPPA_DEV["kappa"] = getval("STAC server device name:", KAPPA_DEV["kappa"])
    } else {
      KAPPA_MNE["r_kappa"] = getval ("Real Kappa motor mnemonic:",  KAPPA_MNE["r_kappa"])
      KAPPA_MNE["r_phi"]=getval("Real Phi motor mnemonic:", KAPPA_MNE["r_phi"])
    }
  } else {
    KAPPA_MNE["omega"] = "$1"
    KAPPA_MNE["kappa"] = "$2"
    KAPPA_MNE["phi"] = "$3"
    KAPPA_OFFSET = $4
    KAPPA_LOADPOS["kappa"] = $5
    KAPPA_MNE["sampx"] = "$6"
    KAPPA_MNE["sampy"] = "$7"
    KAPPA_MNE["phiy"] = "$8"
    if ($# == 10) {
      KAPPA_MNE["r_kappa"] = "$9"
      KAPPA_MNE["r_phi"]="$10"
    }
  }

  if (!KAPPA_OFFSET)
    KAPPA_OFFSET = 4.5

  for (mne in KAPPA_MNE) {
    KAPPA_MOT[mne] =  motor_num(KAPPA_MNE[mne])
    if (KAPPA_MOT[mne] == -1) {
       eprintf ("Motor %s not configured, setup failed\n",KAPPA_MNE[mne])
       KAPPA_OK = -1
    }
  }
  if (KAPPA_OK != -1) {
    if (motor_par(KAPPA_MOT["omega"],"device_id") == "udiff_mot") {
      KAPPA_UDIFF = 1
      KAPPA_DEV["omega"] = motor_par(KAPPA_MOT["omega"],"address")
      KAPPA_DEV["kappa"] = "$9"
    } else {
      KAPPA_DEV["kappa"] = motor_par(KAPPA_MOT["r_kappa"], "misc_par_1")
    }
    if (!KAPPA_DEV["kappa"]) {
      KAPPA_DEV["kappa"] = "tango://localhost:5955/stac/stac_server/general#dbase=no"
      eprintf ("STAC device server to defined, setting to default: %s\n", \
	KAPPA_DEV["kappa"])
    }
  }

  # read the calibration settings
  readMiniKappaCalibration

  #define wait_ready() if needed
  if (whatis("wait_ready") == 0)
    eval("def wait_ready()\'{ }\'")
}'

#%UU%
#%MDESC% Define the minikappa as present.
def minikappa_on '{
  if (KAPPA_OK != -1) {
    KAPPA_OK = 1  
    SCKappaOn 
  }
}'

#%UU%
#%MDESC% Define the minikappa as absent.
def minikappa_off '{
  if (KAPPA_OK != -1) {
    KAPPA_OK = 0
    SCKappaOff
  }
}'

#%UU%
#%MDESC% Activate the translation correction when moving minikappa motors.
def minikappa_translation_correction_on '{
  KAPPA_MOT_DOTC=1
}'

#%UU%
#%MDESC% Deactivate the translation correction when moving minikappa motors.
def minikappa_translation_correction_off '{
  KAPPA_MOT_DOTC=0
}'

#%IU% ()
#%MDESC% Take out some of the minidiff equipment before initialising the
#kappa motor.
def kappa_prepare() '{
  fldetout
  cryout
  lightout
  backout
}'

#%IU% (msg)
#%MDESC%
def kappa_print(msg) '{
  printf ("%s\n", msg)
  egui_logmsg(msg)
}'

#%IU% (startPhi,endPhi,stepPhi,directory,prefix)
#%MDESC%
def sampleRotateSnapshots (startPhi,endPhi,stepPhi,directory,prefix) '{


  for (actPhi=startPhi;actPhi<=endPhi;actPhi+=stepPhi) {
    fname=sprintf("%s_%05.1f.jpg",prefix,actPhi)
    print fname
    mv phi actPhi
    kappa_takeimage(directory,fname)
  }

}'

def kappa_takeimage(directory,fname) '{
global KAPPA_IMAGEFNAMES KAPPA_IMAGEFCOUNT
local filename bkg_mtime k len i pos unix_cmd

  filename = sprintf("%s/%s", directory, fname)
  kappa_print( "creating dir...")
  unix_cmd=sprintf("mkdir %s",directory)
  print unix_cmd
  unix(unix_cmd)
  printf ("Taking image...\n")
  egui_logmsg("Taking image... please wait")
  len =10

  # take image
  if (MINIDIFF["tango_camera"]!="") {
    #old way
    #unix_cmd=sprintf("python -c %s", sprintf("\'import PyTango; import Image;img=PyTango.AttributeProxy(\"%s\"+\"/Image\"); w=PyTango.AttributeProxy(\"%s\"+\"/Width\");h=PyTango.AttributeProxy(\"%s\"+\"/Height\"); im=Image.frombuffer(\"RGB\", (w.read().value, h.read().value),img.read().value); im=im.transpose(Image.FLIP_TOP_BOTTOM); im.save(\"%s/%s\")\'",MINIDIFF["tango_camera"],MINIDIFF["tango_camera"], MINIDIFF["tango_camera"],directory, fname))

    unix_cmd1=sprintf("python -c \'import sys;sys.path.insert(0, \"/users/blissadm/python/bliss_modules/redhate4\");import PyTango; import Image; dev=PyTango.DeviceProxy(\"")
    unix_cmd2=sprintf("%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/%s\")\'", MINIDIFF["tango_camera"], directory, fname)
    unix_cmd=sprintf("%s%s", unix_cmd1, unix_cmd2)
  } else {
    unix_cmd=sprintf("python -c %s", sprintf("\'import TacoDevice; importImage;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/%s\")\'", MINIDIFF["camera"],directory, fname))
  }

  printf("%s\n", unix_cmd)
  unix(unix_cmd)

  egui_logmsg("Done !")

  KAPPA_IMAGEFNAMES[KAPPA_IMAGEFCOUNT]=fname
  KAPPA_IMAGEFCOUNT=KAPPA_IMAGEFCOUNT+1
}'

#%UU% (names,positions)
#%MDESC% Give a space separated list of motor %B%names%B% to move and space
#separated list of new motor %B%positions%B% to arrive to.
def syncMove(names,positions) '{
  if (KAPPA_UDIFF == 1) {
    return(_syncMove_udiff(names,positions))
  } else {
    return(_syncMove(names,positions))
  }
}'

#%IU% (names,positions)
#%MDESC% Give a space separated list of motor %B%names%B% to move and space
#separated list of new motor %B%positions%B% to arrive to. This function is used
#with minidiff configuration.
def _syncMove(names,positions) '{
local motlist[] newposlist[] oldposlist[] oldAList[] oldvelList[] oldvellimitList[]
local motorName dev

  split(names,motlist)
  split(positions,newposlist)

  #//get motor distances
  #//get (and store) original motor speeds
  timeMax=0
  getangles

  for (dev in motlist) {
    motorName=motlist[dev]

    pos=A[motor_num(motorName)]
    steps=motor_par(motor_num(motorName),"step_size")
    vel=motor_par(motor_num(motorName),"velocity")
    velLimit=motor_par(motor_num(motorName),"base_rate")

    newpos=newposlist[dev]
    Adiff=fabs(newpos-pos)*fabs(steps)
    oldvelList[motorName]=vel
    oldAList[motorName]=Adiff
    oldvellimitList[motorName]=velLimit

    if (Adiff/fabs(vel) > timeMax) {
      timeMax=Adiff/fabs(vel)
    }
  }

  cdef ("cleanup_once", "minikappa_cleanup();",motlist[0],0x20)
  #//get motor limits
  #//calculate and set speeds/target positions
  for (dev in motlist) {
    motorName=motlist[dev]
    velocity=oldvelList[motorName]
    Adiff=oldAList[motorName]
    velocityLimit=oldvellimitList[motorName]
    #//since velocity is treated as integer, we make it bigger then 1
    velocity_new=1
    if (Adiff/timeMax>velocity_new)
      velocity_new=Adiff/timeMax
    if (velocityLimit>velocity_new)
      velocity_new=velocityLimit
    if (velocity<velocity_new)
      velocity_new=velocity
    motor_par(motor_num(motorName),"velocity",velocity_new)
    A[motor_num(motorName)]=newposlist[dev]
    printf ("Motor %s: move to position %f\n", motorName, newposlist[dev])
    printf ("          with velocity %f\n", velocity_new)
  }

  #//move motors
  move_all;wait(0)

  #//set motor velocity to its original value
  for (dev in motlist){
    motorName=motlist[dev]
    velocity=oldvelList[motorName]
    motor_par(motor_num(motorName),"velocity",velocity)
  }

}'

#%IU% (names,positions)
#%MDESC% Give a space separated list of motor %B%names%B% to move and space
#separated list of new motor %B%positions%B% to arrive to. This function is used
#with microdiff configuration.
def _syncMove_udiff(names,positions) '{
local motlist[] newposlist[] mne cmd_par
local unix_cmd par_list

  split(names,motlist)
  split(positions,newposlist)

  cdef ("cleanup_once", "minikappa_cleanup();",motlist[0],0x20)

  for (mne in motlist) {
    cmd_par[1] = sprintf ("\"%sPosition\", %s",UDIFF_PARAMS[motor_num(motlist[mne])]["root_attr"], cmd_par[1])
    cmd_par[0] = sprintf ("%f, %s",newposlist[mne], cmd_par[0])
  }

  par_list = sprintf("import PyTango;dev=PyTango.DeviceProxy(\"%s\")", KAPPA_DEV["omega"])
  par_list = sprintf("%s; dev.command_inout(\"SyncMoveMotors\",[[%s],[%s]])",   par_list, cmd_par[0], cmd_par[1])

  unix_cmd = sprintf ("python -c \'%s\'", par_list)
  unix(unix_cmd)

  #tango_io(KAPPA_DEV["omega"], "SyncMoveMotors", cmd_par)
  #if (TANGO_ERR) {
  #  tty_cntl("md")
  #  printf ("motor %s:", motor_mne(motn))
  #  print_tango_err()
  #  tty_cntl("me")
  #  return(-1)
  #}
  if (wait_ready() < 0)
    return(-1)
  return(0)
}'

def readMiniKappaCalibration '{
  local calLines[]
  global MK_CALIB_RC_O[]
  global MK_CALIB_RC_K[]
  global MK_CALIB_RC_P[]
  global MK_CALIB_TC_KL[]
  global MK_CALIB_TC_PL[]
  global MK_CALIB_TC_KD[]
  global MK_CALIB_TC_PD[]
  global MK_CALIB_VALID

  #get the file
  unix("cat /users/blissadm/STAC/config/BCM.dat | head -8 | tail -7", caltext)
  #set values
  split(caltext,calLines,"\n")
  split(calLines[0],MK_CALIB_RC_O)
  split(calLines[1],MK_CALIB_RC_K)
  split(calLines[2],MK_CALIB_RC_P)
  split(calLines[3],MK_CALIB_TC_KL)
  split(calLines[4],MK_CALIB_TC_PL)
  split(calLines[5],MK_CALIB_TC_KD)
  split(calLines[6],MK_CALIB_TC_PD)
  if ( \
       MK_CALIB_RC_O[0]!="OmegaRot" || \
       MK_CALIB_RC_K[0]!="KappaRot" || \
       MK_CALIB_RC_P[0]!="PhiRot" || \
       MK_CALIB_TC_KL[0]!="KappaTrans" || \
       MK_CALIB_TC_PL[0]!="PhiTrans" || \
       MK_CALIB_TC_KD[0]!="KappaTransD" || \
       MK_CALIB_TC_PD[0]!="PhiTransD" ) {
     print "\n"
     print "===================================="
     print "COULD NOT GET MK CALIBRATION VALUES!" 
     print "===================================="
     MK_CALIB_VALID=0
  } else {
     print "\n"
     print "MK calibration values loaded"
     #p  MK_CALIB_RC_O
     #p  MK_CALIB_RC_K
     #p  MK_CALIB_RC_P
     #p  MK_CALIB_TC_KL
     #p  MK_CALIB_TC_PL
     #p  MK_CALIB_TC_KD
     #p  MK_CALIB_TC_PD      
     MK_CALIB_VALID=1
  }
}'

def moveMiniKappaCentered_mm(mne,pos) '{
  getangles
  if (mne == KAPPA_MNE["phi"]) {
    moveMiniKappaCentered(A[KAPPA_MOT["kappa"]],pos)
  } else if (mne == KAPPA_MNE["kappa"]) {
    moveMiniKappaCentered(pos,A[KAPPA_MOT["phi"]])
  }
}'

def moveKappaCentered(Kappa) '{
  moveMiniKappaCentered(Kappa,A[KAPPA_MOT["phi"]])
}'

def movePhiCentered(Phi) '{
  moveMiniKappaCentered(A[KAPPA_MOT["kappa"]],Phi)
}'

def moveMiniKappaCentered(Kappa,Phi) '{
local motor_pos_string mot_names mot_pos

  # get actual motor posiitions
  getangles
  
  # call translation correction calculation
  
  # by passing the calibration settings 
  #  sprintf("print dev.command_inout(\"TranslationCorrectionIntern\",[[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f],[\"Kappa\",\"Phi\",\"X\",\"Y\",\"Z\",\"Kappa2\",\"Phi2\",\"KPtx\",\"KPty\",\"KPtz\",\"PPtx\",\"PPty\",\"PPtz\",\"KDx\",\"KDy\",\"KDz\",\"PDx\",\"PDy\",\"PDz\"]]); \'", \
  #    A[KAPPA_MOT["kappa"]], \
  #    A[KAPPA_MOT["phi"]], \
  #    A[motor_num("sampx")], \
  #    A[motor_num("sampy")], \
  #    A[motor_num("phiy")], \
  #    Kappa, \
  #    Phi, \
  #    MK_CALIB_TC_KL[1],MK_CALIB_TC_KL[2],MK_CALIB_TC_KL[3], \
  #    MK_CALIB_TC_PL[1],MK_CALIB_TC_PL[2],MK_CALIB_TC_PL[3], \
  #    MK_CALIB_TC_KD[1],MK_CALIB_TC_KD[2],MK_CALIB_TC_KD[3], \
  #    MK_CALIB_TC_PD[1],MK_CALIB_TC_PD[2],MK_CALIB_TC_PD[3] ) )
  
  # by using the calibration settings of the server coming from its BCM.dat file
  motor_pos_string = sprintf("Kappa %f Phi %f X %f Y %f Z %f Kappa2 %f Phi2 %f", \
	A[KAPPA_MOT["kappa"]], \
	A[KAPPA_MOT["phi"]], \
	A[motor_num("sampx")], \
	A[motor_num("sampy")], \
	A[motor_num("phiy")], \
	Kappa, Phi)
  correctionResult = tango_io(KAPPA_DEV["kappa"], \
	"TranslationCorrectionString", motor_pos_string)

  if (TANGO_ERR) {
    tty_cntl("md")
    print_tango_err()
    tty_cntl("me")
    return(-1)
  }

  printf ("%s\n", correctionResult)
 
  if (KAPPA_UDIFF == 1) {
    mot_names = sprintf ("%s %s %s %s %s", KAPPA_MNE["kappa"], KAPPA_MNE["phi"], \
	KAPPA_MNE["sampx"], KAPPA_MNE["sampy"], KAPPA_MNE["phiy"])
  } else {
    mot_names = sprintf ("%s %s %s %s %s", KAPPA_MNE["r_kappa"], KAPPA_MNE["r_phi"], \
	KAPPA_MNE["sampx"], KAPPA_MNE["sampy"], KAPPA_MNE["phiy"])
  }
  mot_pos = sprintf("%f %f %s",Kappa,Phi,correctionResult)
  syncMove(mot_names, mot_pos)

}'

#%IU% ()
#%MDESC% Location vector: normalised motor positions to get a point centred.
#Normalisation is done to get location vectors in an isotropic (orthogonal
#and uniscale) right handed coordinate system. Note that the location vector
#of a point is orientation depended, this is why we need Translation
#correction when moving Kappa/Phi.
#Sample Position: inverse of the location vector at zero datum. Hence the
#Sample Position is an orientation independent identifier of a unique place
#of a sample.
def getCurrentSamplePosition() '{
local sx,sy,sz

  #get centered position
  getangles
  sx=A[motor_num("sampx")]
  sy=A[motor_num("sampy")]
  sz=A[motor_num("phiy")]
  return (getSamplePosition(sx,sy,sz))
  
}'  

#%IU% (sx,sy,sz)
#%MDESC% Without changing the orientation, it identifies the Sample Position
#(X,Y,Z) which would become centred at given motor settings (sx,sy,sz).
def getSamplePosition(sx,sy,sz) '{
local so,sk,sp,correctionResult,motor_pos_string,poslist[]
local X,Y,Z

  #get current orinetation
  getangles
  so=A[motor_num("phi")]
  sk=A[KAPPA_MOT["kappa"]]
  sp=A[KAPPA_MOT["phi"]]
  sx=A[motor_num("sampx")]
  sy=A[motor_num("sampy")]
  sz=A[motor_num("phiy")]
  #get the point at zero datum
  motor_pos_string = sprintf("Kappa %f Phi %f X %f Y %f Z %f Kappa2 %f Phi2 %f",sk,sp,sx,sy,sz,0,0)
  correctionResult = tango_io(motor_par(kap1, "misc_par_1"),"TranslationCorrectionString", motor_pos_string)
  if (TANGO_ERR) {
    tty_cntl("md")
    print_tango_err()
    tty_cntl("me")
    return(-1)
  }
  printf ("Zero datum translation: %s\n", correctionResult)
  split(correctionResult, poslist)
  #normalisation to get proper location vector
  X=-poslist["0"]
  Y=poslist["1"]
  Z=poslist["2"]
  #inverse to get Sample Position vector
  return (sprintf("%f %f %f",-X,-Y,-Z))
  
}'  

#%IU% (X,Y,Z)
#%MDESC% Without changing the orientation, it moves a specific Sample
#Position (X,Y,Z) to the centre.  
def moveToSamplePosition(X,Y,Z) '{
local sx,sy,sz,so,sk,sp,correctionResult,motor_pos_string,mot_names,mot_pos

  #inverse to get normalised location vector
  # and then convert to motor poistions at zero datum
  sx=X
  sy=-Y
  sz=-Z
  #get centered orinetation
  getangles
  so=A[motor_num("phi")]
  sk=A[KAPPA_MOT["kappa"]]
  sp=A[KAPPA_MOT["phi"]]
  #get the translation for the given datum
  motor_pos_string = sprintf("Kappa %f Phi %f X %f Y %f Z %f Kappa2 %f Phi2 %f",0,0,sx,sy,sz,sk,sp)
  correctionResult = tango_io(motor_par(kap1, "misc_par_1"),"TranslationCorrectionString", motor_pos_string)
  if (TANGO_ERR) {
    tty_cntl("md")
    print_tango_err()
    tty_cntl("me")
    return(-1)
  }
  printf ("Actual datum translation: %s\n", correctionResult)
  #move to given position
  if (KAPPA_UDIFF == 1) {
    mot_names = sprintf ("%s %s %s %s %s", KAPPA_MNE["kappa"], KAPPA_MNE["phi"], \
	KAPPA_MNE["sampx"], KAPPA_MNE["sampy"], KAPPA_MNE["phiy"])
  } else {
    mot_names = sprintf ("%s %s %s %s %s", KAPPA_MNE["r_kappa"], KAPPA_MNE["r_phi"], \
	KAPPA_MNE["sampx"], KAPPA_MNE["sampy"], KAPPA_MNE["phiy"])
  }
  mot_pos = sprintf("%f %f %s",sk,sp,correctionResult)
  syncMove(mot_names, mot_pos)
  
}'  

#%IU% (X,Y,Z)
#%MDESC%
def get2DSamplePosition(X,Y,Z) '{   
}'
  
#%IU%
#%MDESC%
def centerprepare '{

  minidiff_prepare_centring
  mv flight 0
  #mvr phiy 5
  #minidiff_take_backgrounds
  #mvr phiy -5
  mv zoom 0
}'


def motioncommand_eval(cmd,motorname,pos) '{
   eval(sprintf("%s %s %s; sleep(0.05)",cmd,motorname,pos))
}'

def mv_eval(motorname,pos) '{
   motioncommand_eval("mv",motorname,pos)
}'

def mvr_eval(motorname,pos) '{
   motioncommand_eval("mvr",motorname,pos)
}'

def _kappa_test(dir,motorname) '{

  if (motorname==KAPPA_MNE["kappa"]) {
    _kappa_init()

    kappa_takeimage(dir,sprintf("%s_home0.tif",motorname))
    _kappa_init()
    kappa_takeimage(dir,sprintf("%s_home1.tif",motorname))
    _kappa_init()
    kappa_takeimage(dir,sprintf("%s_home2.tif",motorname))
    _kappa_init()
    kappa_takeimage(dir,sprintf("%s_home3.tif",motorname))
  } else {	
    kappa_takeimage(dir,sprintf("%s_init0.tif",motorname))
    _kphi_init()
    kappa_takeimage(dir,sprintf("%s_init1.tif",motorname))
    _kphi_init()
    kappa_takeimage(dir,sprintf("%s_init2.tif",motorname))
    _kphi_init()
    kappa_takeimage(dir,sprintf("%s_init3.tif",motorname))

    mv_eval(motorname,360)
    kappa_takeimage(dir,sprintf("%s_turn0.tif",motorname))
    mv_eval(motorname, 720)
    kappa_takeimage(dir,sprintf("%s_turn1.tif",motorname))
    mv_eval(motorname, 360)
    kappa_takeimage(dir,sprintf("%s_backturn0.tif",motorname))
    mv_eval(motorname, 0)
    kappa_takeimage(dir,sprintf("%s_backturn1.tif",motorname))
  }

  mv_eval(motorname, 10); mv_eval( motorname, 0)
  kappa_takeimage(dir,sprintf("%s_back10.tif",motorname))
  mv_eval(motorname, 60); mv_eval( motorname, 0)
  kappa_takeimage(dir,sprintf("%s_back60.tif",motorname))
  mv_eval(motorname, 100); mv_eval( motorname, 0)
  kappa_takeimage(dir,sprintf("%s_back100.tif",motorname))
	
  mvr_eval(motorname ,10);mvr_eval( motorname, 10);mvr_eval( motorname, 10);mvr_eval( motorname, 10);mvr_eval( motorname, 10);mvr_eval( motorname, 10);mvr_eval( motorname, 10);mvr_eval( motorname, 10);mvr_eval( motorname, 10); mv_eval( motorname, 0)
  kappa_takeimage(dir,sprintf("%s_multifrontback.tif",motorname))
	
  mv_eval(motorname, 100);mvr_eval( motorname, -10);mvr_eval( motorname, -10);mvr_eval( motorname, -10);mvr_eval( motorname, -10);mvr_eval( motorname, -10);mvr_eval( motorname, -10);mvr_eval( motorname, -10);mvr_eval( motorname, -10); mv_eval( motorname, 0)
  kappa_takeimage(dir,sprintf("%s_frontmultiback.tif",motorname))
}'

def create_gimp_cmd(dir) '{
global KAPPA_IMAGEFNAMES KAPPA_IMAGEFCOUNT
local cmd unix_cmd listFiles g_cmdfile ct

  g_cmdfile=sprintf("%s/gimp.sh",dir)

  unix_cmd=sprintf("rm -f %s",g_cmdfile)
  unix(unix_cmd)
	
  listFiles=""
  for (ct=1; ct<KAPPA_IMAGEFCOUNT;ct++) {
    listFiles=sprintf("%s \"%s\" 0 0 \"%s\"",listFiles,KAPPA_IMAGEFNAMES[ct],KAPPA_IMAGEFNAMES[ct])
  }

  open(g_cmdfile)
  on(g_cmdfile)
  print ("{")
  print ("cat <<EOF")
  printf("(combine-images-into-layers \"kappa_test.xcf\" \"%s\" %d \'( %s ))\n",KAPPA_IMAGEFNAMES[0], KAPPA_IMAGEFCOUNT-1, listFiles)
  print ("EOF")
  print ("echo \"(gimp-quit 0)\"")
  print ("} | gimp -i -b - ")
  off(g_cmdfile)
  close(g_cmdfile)

  return cmd
}'

def kappa_test() '{
global KAPPA_IMAGEFNAMES KAPPA_IMAGEFCOUNT
local msg dir

  msg = sprintf("---- Kappa %s (kappa) testing started ----", KAPPA_MNE["kappa"])
  kappa_print (msg)

  minikappa_init

  dir=sprintf("/tmp/kappa_test_images_%s",date("%Y%m%d%H%M%S"))
  kappa_prepare()
  lightin

  KAPPA_IMAGEFCOUNT=0

  if (KAPPA_UDIFF == 1) {
    _kappa_test(dir,KAPPA_MNE["kappa"])
    _kappa_test(dir,KAPPA_MNE["phi"])
  } else {
    _kappa_test(dir,KAPPA_MNE["r_kappa"])
    _kappa_test(dir,KAPPA_MNE["r_phi"])
  }

  create_gimp_cmd(dir)
  unix_cmd=sprintf("cd %s;bash ./gimp.sh",dir)
  print unix_cmd
  unix(unix_cmd)
  unix_cmd=sprintf("gimp %s/kappa_test.xcf",dir)	
  print unix_cmd
  unix(unix_cmd)

  msg = sprintf("     Test Images collected in dir \"%s\". Please analyse them", dir)
  kappa_print (msg)
  msg = sprintf("     cp -r %s %s/MK3_A7BT1/", dir, getenv("HOME"))
  print (msg)

  msg = sprintf("---- Kappa %s (kappa) testing done ----", KAPPA_MNE["kappa"])
  kappa_print (msg)
}'


def kappa_reinstate() '{
  cryoin
}'


#%IU%
#%MDESC% Initialise the minikappa kappa motor.
def kappa_init '{
local msg

  if (KAPPA_UDIFF != 1) {
    if (KAPPA_OK == -1) {
      msg = sprintf ("Motors not set, please, run kapsetup first")
      eprintf ("%s\n", msg)
      egui_logmsg(msg)
      exit
    }
    kappa_prepare()
    _kappa_init()
  } else {
    _kappa_init_udiff()
  }
}'

#%IU% ()
#%MDESC% Search for the DPAP negative limit signal. Move the kappa motor to
#the reference position and set it as zero position. Set the speed. Calculate
#and set the motor limits.
def _kappa_init() '{
local ivel msg lowlim uplim

  msg = sprintf("---- Kappa %s (kappa) initialisation started ----", KAPPA_MNE["r_kappa"])
  printf ("%s\n", msg)
  egui_logmsg(msg)
  ivel = motor_par(KAPPA_MOT["r_kappa"],"config_velocity")
  motor_par(KAPPA_MOT["r_kappa"],"velocity",ivel)

  msg = sprintf ("Searching for reference signal, please wait")
  printf ("%s\n", msg)
  egui_logmsg(msg)
  getangles
  set_lim(KAPPA_MOT["r_kappa"],A[KAPPA_MOT["r_kappa"]]-600,A[KAPPA_MOT["r_kappa"]]+320)
  chg_dial(KAPPA_MOT["r_kappa"], "lim-")
  waitmove; get_angles
  A[KAPPA_MOT["r_kappa"]] += KAPPA_OFFSET
  move_em; waitmove; get_angles

  motor_par(KAPPA_MOT["r_kappa"],"velocity",500)
  chg_dial(KAPPA_MOT["r_kappa"], "lim-")
  waitmove; get_angles
  A[KAPPA_MOT["r_kappa"]] += KAPPA_OFFSET
  move_em; waitmove; get_angles

  msg = sprintf("Setting %s position to zero", KAPPA_MNE["r_kappa"])
  printf ("%s\n", msg)
  egui_logmsg(msg)
  chg_dial(KAPPA_MOT["r_kappa"],0)
  chg_offset(KAPPA_MOT["r_kappa"],0)

  msg = sprintf ("Setting %s limits and initial velocity", KAPPA_MNE["r_kappa"])
  printf ("%s\n", msg)
  egui_logmsg(msg)
  motor_par(KAPPA_MOT["r_kappa"],"velocity",ivel)
  lowlim = -KAPPA_OFFSET+0.2
  uplim = 270 - motor_par(KAPPA_MOT["r_kappa"], "backlash")/ motor_par(KAPPA_MOT["r_kappa"], "step_size")- KAPPA_OFFSET
  set_lim(KAPPA_MOT["r_kappa"], lowlim, uplim)

  A[KAPPA_MOT["r_kappa"]] = 0
  move_em; waitmove; get_angles

  msg = sprintf("---- Kappa %s (kappa) initialisation done ----",KAPPA_MNE["r_kappa"])
  printf ("%s\n", msg)
  egui_logmsg(msg)
}'
#%IU% ()
#%MDESC% Initialise the minikappa kappa motor using the MD2 device server
def _kappa_init_udiff() '{

  msclose
  printf("Initialising kappa. May take several minutes. Please wait\n")

  tango_io(MICRODIFF_DEVICE,"StartHomingKappa")

  if (TANGO_ERR) {
    print_tango_err()
    egui_fatal("MD2: error homing kappa.")
  } else {
    wait_ready()
  }

}'

#%IU%
#%MDESC% Initialise the minikappa phi motor.
def kphi_init '{
local msg

  if (KAPPA_OK == -1) {
    msg = sprintf ("Motors not set, please, run kapsetup first")
    eprintf ("%s\n", msg)
    egui_logmsg(msg)
    exit
  }
  if (KAPPA_UDIFF != 1) {
    _kphi_init()
  } else {
    _kphi_init_udiff()
  }
}'

#%IU% ()
#%MDESC% Set the minikappa phi motor speed to the configuration one. Move
#the motor 200 degdrees back and forth. Set the position to zero.
def _kphi_init() '{
local ivel msg

  if (KAPPA_MOT["r_phi"] == -1) {
    egui_logmsg("Nothing to do for microdiff")
    return(0)
  }
  msg = sprintf("---- Kappa %s (phi) initialisation started ----", KAPPA_MNE["r_phi"])
  printf ("%s\n", msg)
  egui_logmsg(msg)
  ivel = motor_par(KAPPA_MOT["r_phi"],"config_velocity")
  motor_par(KAPPA_MOT["r_phi"],"velocity",ivel)
  get_angles
  A[KAPPA_MOT["r_phi"]] += 200
  move_em; waitmove; get_angles
  A[KAPPA_MOT["r_phi"]] -= 200
  move_em; waitmove; get_angles
  chg_dial(KAPPA_MOT["r_phi"],0)
  chg_offset(KAPPA_MOT["r_phi"],0)
  msg = sprintf("---- Kappa %s (phi) initialisation done ----",KAPPA_MNE["r_phi"])
  printf ("%s\n", msg)
  egui_logmsg(msg)
}'

#%IU% ()
#%MDESC% Move the minikappa phi motor to zero.
def _kphi_init_udiff() '{
  A[KAPPA_MOT["phi"]] = 0
  move_em; waitmove; get_angles
   msg = sprintf("---- Kappa %s (phi) initialisation done ----",KAPPA_MNE["phi"])
  printf ("%s\n", msg)
  egui_logmsg(msg)   
}'

#%UU%
#%MDESC% Initialise the minikappa -  move the kappa, phi and omega motors to
#their init positions. Set these positions as zero. 
def minikappa_init '{
local msg
  msg = sprintf("-- Minikappa initialisation started --")
  printf ("%s\n", msg)
  egui_logmsg(msg)

  kappa_init
  kphi_init
  phi_init

  msg = sprintf("-- Minikappa initialisation done --")
  kappa_reinstate()
  printf ("%s\n", msg)
  egui_logmsg(msg)
}'

#%IU% ()
#%MDESC% Move the kappa motor to the loading position, when doing manual load.
#Take out the cryostat head.
def minikappa_manualload() '{
  cryout
  A[KAPPA_MOT["omega"]] = 220
  A[KAPPA_MOT["kappa"]] = 180
  move_em; waitmove; get_angles
}'

#%IU% ()
#%MDESC% Move the kappa motor home(zero) position. Put in the cryostat head.
def minikappa_home() '{
  A[KAPPA_MOT["kappa"]] = 0
  move_em; waitmove; get_angles
  cryoin
}'

#%IU% ()
#%MDESC% Move the kappa motor to the loading position, when using the sample
#changer.
def minikappa_autoload() '{
  A[KAPPA_MOT["kappa"]] = KAPPA_LOADPOS["kappa"]
  move_em; waitmove; get_angles
}'
#%IU% (pos)
#%MDESC% Set the kappa motor loading position %B%pos%B% in degrees.
def kappa_set_load_position(pos) '{
  KAPPA_LOADPOS["kappa"] = pos
}'

#%IU%()
#%MDESC% Return the kappa motor loading position in degrees
def kappa_get_load_position() '{
  return(KAPPA_LOADPOS["kappa"])
}'

def minikappa_cleanup() '{
  if (KAPPA_UDIFF == 1) {
    tango_io(KAPPA_DEV["omega"], "EmergencyStop")
  } else {
    for (mne in KAPPA_MOT)
      motor_par(KAPPA_MOT[mne], "velocity", \
	motor_par(KAPPA_MOT[mne], "config_velocity"))
  }
}'

#%MACROS%
#%IMACROS%
#%TOC%
#%AUTHOR% A.Beteva
#$Revision: 1.9 $$Date: 2012/07/18 09:26:29 $
#%END%
#%LOG%
#$Log: minikappa.mac,v $
#Revision 1.9  2012/07/18 09:26:29  beteva
#added _kphi_init_udiff()
#
#Revision 1.8  2012/07/09 14:35:40  beteva
#added Sandor's code from id23
#
#Revision 1.7  2011/10/26 15:39:13  beteva
#added moveMiniKappaCentered_mm, start STAC commands with PyTango
#(spec does not handle complex data types)
#
#Revision 1.6  2011/08/19 13:03:50  beteva
#added synchronous move - mini and microdiff
#
#Revision 1.5  2008/08/12 13:54:58  rey
#documentation changes
#
#Revision 1.4  2008/07/25 14:30:53  guijarro
#call SCKappaOn/Off at the same time as minikappa_on/off
#
#Revision 1.3  2008/04/09 13:51:54  spruce
#add sandors test macros to the package and the centring code
#
#Revision 1.2  2006/12/15 14:33:42  guijarro
#first attempt to put back things after kappa init
#
#Revision 1.1  2006/04/21 15:03:26  beteva
#Initial revision
####
####
####.gimp/scripts/combine-images-into-layers.scm
####