esrf

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

#%TITLE% GROUPS.MAC
#%NAME%
# Macros for handling motors in groups
#
#%CATEGORY% Tools
#
#%DESCRIPTION%
# This package defines some macros for handling motors in groups.
# Macros for defining the groups, adding and deleting motors from
# a group, and to display the motors and motor positions for a group
# are available.
#
#%LOG%
#$Log: groups.mac,v $
#Revision 1.3  2008/04/25 08:13:08  rey
#documentation changes
#
#Revision 1.2  2002/04/08 18:01:25  beteva
#Added group_index, show_grp and show_grpf macros (A.Beteva)
#
#%END%

#%UU% <function> <group> <motor> <motor> ...
#%MDESC%
# The user interface. Group can be called with the following arguments and functions:
#%DL%
#
#%DT% group %DD%
# display short explanatory text
#
#%DT% group reset %DD%
# deletes all groups except "others" and adds all motors into "others"
#
#%DT% group update [-q]%DD%
# to be called after config. Removed "dead" motors and adds new motors
# to group "others"
#
#%DT% group add [-q] <group> <motor> <motor> ... %DD%
# add motors to a group and delete them from their previous group.
# if <group> does not exist, it will be created. If any empty groups
# result from the operation, they will be deleted.
#
#%DT% group delete [-q] <group> <motor> <motor> ... %DD%
# same as group add others <motor> ... except that
# if no motor is specified, the complete group will be moved to others
# Note that group delete others <motor> has no effect!
#
#%DT% group list [-a] <group> %DD%
# display list of motors in group.
# if no group is specified, all groups are listed
#
#%DT% group where [-a] <group> %DD%
# display positions of all motors in group.
# if no group is specified, the motors of all groups are listed
#
#%DT% group hide [-q] <group> <group> ... %DD%
# hide groups so that they are not listed by group where and group list
# commands
#
#%DT% group unhide [-q] <group> <group> ... %DD%
# remove hidden status of groups.
#%XDL%
def group '{
   local action

   action = "$1"

   if(action == "reset") { 
      group_reset $*
   } else if(action == "update") { 
      group_update $* 
   } else if(action == "add") { 
      group_add $* 
   } else if(action == "delete") { 
      if($# == 1 || ($# == 2 && "$2" == "-q")) {
         printf("group delete: you must specify a group!\n")
      } else if($# == 2 || ($# == 3 && "$2" == "-q")) {
         group_delete $*
      } else {
         group_add others $*
      }
   } else if(action == "list") {
      group_list $*
   } else if(action == "where") { 
      group_where $*
   } else if(action == "hide" || action == "unhide") {
      group_hide $*
   } else {
      p "group - macros for listing motors in groups";
      p "usage:";
      p "   group                             : display this message";
      p "   group reset [-q]                  : reset";
      p "   group update [-q]                 : update motor list after config";
      p "   group add [-q] <group> <motor>    : add <motor> to <group>";
      p "   group delete [-q] <group> <motor> : delete <motor> from <group>";
      p "   group list [-a] <group>           : list motors in <group>";
      p "   group where [-a] <group>          : display motor positions for <group>";
      p "   group hide|unhide [-q] <group>    : hide group from normal display";
      p "common flags:"
      p "   [-a] : list/display all groups, hidden and unhidden"
      p "   [-q] : quiet mode"
   }
}'
#%UU%
#%MDESC%
# Abbreviation for group where
def wg '{ group where $* }'
#%IU% <substring> <string>
#%MDESC%
# delete <substring> from <string>
def del_item(mne, list) '{
   local n s nl

   nl = ""
   split(list, s)
   for(n in s) {
      if(s[n] != mne) {
         nl = sprintf("%s %s", nl, s[n]);  
      }
   }
   return(nl);
}'
#%IU% <mne>
#%MDESC% 
# is this mnemonic a current group?
def isgroup(mne) '{
   global GROUP_PARS

   return(index(GROUP_PARS["GROUPS"], mne));
}'
#%IU%
#%MDESC%
# delete all empty groups
def group_purge(quiet) '{
   global GROUP_PARS
   local g groups[]

   split(GROUP_PARS["GROUPS"], groups)
   for(g in groups) {
      if(GROUP_PARS[groups[g]] == "") {
         GROUP_PARS["GROUPS"] = del_item(groups[g], GROUP_PARS["GROUPS"])
         if(!quiet)
            printf("deleted empty group \"%s\".\n", groups[g]);
      }
   }
}
'
#%IU%
def group_reset '{
   unglobal GROUP_PARS

   global GROUP_PARS
   local i

   quiet = ("$2" == "-q")
   GROUP_PARS["GROUPS"] = "others"
   GROUP_PARS["HIDDEN"] = ""
   GROUP_PARS["others"] = ""
   for(i=0; i < MOTORS; i++) {
      GROUP_PARS["others"] = sprintf("%s %s", GROUP_PARS["others"], motor_mne(i));
   }
}'
#%IU%
def group_hide '{
   global GROUP_PARS
   local a na args[] quiet

   if($# < 2) {
	printf("group_hide: not enough arguments, no action.\n");
   }
   na = split("$*", args)

   for(a = 1; a < na; a++) {
      if(args[a] == "-q")
         quiet = 1
      else {
         GROUP_PARS["HIDDEN"] = del_item(args[a], GROUP_PARS["HIDDEN"]);
         if(!isgroup(args[a])) {
            if(!quiet)
               printf("group_hide: \"%s\" is not a current group.\n", args[a]);
         } else if(args[0] == "hide") {
            GROUP_PARS["HIDDEN"] = sprintf("%s %s", GROUP_PARS["HIDDEN"], args[a]);
         }
      }
   }
}'
#%IU%
def group_update '{
   global GROUP_PARS
   local i g groups[] m mot[] found[] new_motors quiet

   quiet = ("$2" == "-q")

   # a priori, we have not found any motor
   for(i = 0; i < MOTORS; i++) {
      found[i] = 0;
   }

   # go through all groups
   split(GROUP_PARS["GROUPS"], groups)   
   for(g in groups) {
      new_motors = ""
      # look at all motors in this group
      split(GROUP_PARS[groups[g]], mot)
      for(m in mot) {
         if(motor_num(mot[m]) != -1) {
            # re-add motor to the current list
            new_motors = sprintf("%s %s", new_motors, mot[m])
            # this motor was found
            found[motor_num(mot[m])] = -1
         }
      }
      GROUP_PARS[groups[g]] = new_motors
   }

   # check if all motors are covered
   for(i=0; i < MOTORS; i++) {
      if(!found[i]) {
         GROUP_PARS["others"] = sprintf("%s %s", GROUP_PARS["others"], motor_mne(i))
      }
   }
   group_purge(quiet)
}'
#%IU%
def group_add '
{
   global GROUP_PARS
   local i0 i npars pars[] g groups[]

   if($# > 2) {
      npars = split("$*", pars)
      i0 = 1;
      if(pars[i0] == "-q") {
         quiet = 1
         i0++ 
      } else {
         quiet = 0
      }
      if(!isgroup(pars[i0])) {
         if(!quiet)
            printf("group_add: new group \"%s\".\n", pars[i0]);
         # this is a new group
         GROUP_PARS["GROUPS"] = sprintf("%s %s", pars[i0], GROUP_PARS["GROUPS"])
         GROUP_PARS[pars[i0]] = ""
      }	
      # go through the list of motors
      for(i=i0+1; i < npars; ++i) {
         if(motor_num(pars[i]) == -1) {
            if(!quiet)
               printf("group_add: \"%s\" is not a current motor.\n", pars[i]);
         } else {
            # remove motor from other groups
            split(GROUP_PARS["GROUPS"], groups)
            for(g in groups) {
               GROUP_PARS[groups[g]] = del_item(pars[i], GROUP_PARS[groups[g]]);
            }
            GROUP_PARS[pars[i0]] = sprintf("%s %s", GROUP_PARS[pars[i0]], pars[i]);
            if(!quiet)
               printf("added motor \"%s\" to group \"%s\".\n", pars[i], pars[i0]);
         }
      }
   } else if (!quiet) {
      p "group_add: not enough parameters, no action."
   }
   group_purge(quiet)
}'
#%IU%
def group_delete '
{
   global GROUP_PARS
   local arg quiet

   if("$2" == "-q") {
      quiet = 1
      arg = $3 
   } else {
      quiet = 0
      arg = $2
   }

   if(isgroup(arg)) {
      group_add add others GROUP_PARS[arg]
   } else if (!quiet) {
      printf("group_delete: \"%s\" is not a current group.\n", arg);
   }
}'
#%IU%
def group_list '
{
   global GROUP_PARS
   local np i pars[] mode

   np = split("$*", pars)
   i =  1;

   mode = 0
   if((np > 1) && (pars[i] == "-a")) {
      i++
      mode |= 0x1
   }

   # if no arg given, list everything
   if(!(i < np)) {
	np = split(GROUP_PARS["GROUPS"], pars)
        i = 0;
   }

   for(; i < np; ++i) {
      if(!isgroup(pars[i])) {
         printf("group_list: \"%s\" is not a current group.\n", pars[i]);
      } else {
         if((mode & 0x1) || !index(GROUP_PARS["HIDDEN"], pars[i])) {
            printf("group \"%s\": %s\n", pars[i], GROUP_PARS[pars[i]]);
         }
      }
   }
}'
#%IU%
def group_where '
{
   global GROUP_PARS
   local np i pars[] s[] m nm mots[] mA[] mode

   np = split("$*", pars)
   i =  1;

   mode = 0
   if((np > 1) && (pars[i] == "-a")) {
      i++
      mode |= 0x1
   }

   # if no arg given, list everything
   if(!(i < np)) {
	np = split(GROUP_PARS["GROUPS"], pars)
        i = 0;
   }

   for(; i < np; ++i) {
      if(!isgroup(pars[i])) {
         printf("group_where: \"%s\" is not a current group.\n", pars[i]); 
      } else {
         if((mode & 0x1) || !index(GROUP_PARS["HIDDEN"], pars[i])) {
            printf("\n ---------- group \"%s\": ---------\n", pars[i]);

            nm = split(GROUP_PARS[pars[i]], mots)
            for(m in mots) {
               mA[m] = motor_num(mots[m]);
            }

            s[0] = "name"
	    s[1] = "mne"
	    s[2] = "user"
	    s[3] = "dial"
            group_show_motor_info(s, 4, nm, mA)
         }
      }
   }
}'
#%IU%
#%MDESC%
# Internal macro used to display motor information at 8 motors per line.
# Listing of motors named "unused" or that are disabled is suppressed.
# First argument is array of info-types as "name", "mne", "user",
# "dial", "lim+", "lim-", "ulim+" and "ulim-".  Second argument
# is number of elements in array.  Third argument is number of motors.
# If first argument is a single string as above, that is okay.
def group_show_motor_info(f, ns, n, mA) '{
    local i, j, k, m, s[], t
    for (i=0; i<n && i<MOTORS; i++) {
	for (k=0;k<ns;k++)
	    s[k]=""
	for (j=0; i<n && i<MOTORS; i++) {
	    if (!is_using_motor(mA[i]))
		continue;
	    for (k=0;k<ns;k++) {
	        get_angles
		m = mA[i]
		t = (whatis("f")&0x01000000)? f[k]:f
		if (t =="name")
		    s[k] = s[k] sprintf("%9.9s", motor_name(m))
		else if (t == "mne")
		    s[k] = s[k] sprintf("%9.9s", motor_mne(m))
		else if (t == "user")
		    s[k] = s[k] sprintf("%9.4f", A[m])
		else if (t == "dial")
		    s[k] = s[k] sprintf("%9.4f", dial(m, A[m]))
		else if (t == "lim+")
		    s[k] = s[k] sprintf("%9.4f", get_lim(m, +1))
		else if (t == "ulim+")
		    s[k] = s[k] sprintf("%9.4f", user(m, get_lim(m, +1)))
		else if (t == "lim-")
		    s[k] = s[k] sprintf("%9.4f", get_lim(m, -1))
		else if (t == "ulim-")
		    s[k] = s[k] sprintf("%9.4f", user(m, get_lim(m, -1)))
	    }
	    if (j%8 == 7)
		break
	    for (k=0;k<ns;k++)
		s[k] = s[k] " "
	    j++
	}
	for (k=0;k<ns;k++)
	    p s[k]
    }
}'

#%IU%
#%MDESC% Sethe groups indexes in arrays.
def group_index '{
   global GROUP_IND GROUP_MOT GROUP_NB
   local i j
    local groups[] mots[]

  GROUP_NB = split(GROUP_PARS["GROUPS"], groups)
  for (i=0; i<GROUP_NB; i++) {
     GROUP_IND[i] = groups[i]
     GROUP_MOT[i][0] = split(GROUP_PARS[groups[i]], mots)
     for (j=0; j<GROUP_MOT[i][0]; j++)
       GROUP_MOT[i][j+1] = motor_num(mots[j])
   }
}'

#%IU% [group_name or all]
#%MDESC% Show a group_name or all groups as 8 motors/line.
def show_grp '{
local i ret

  if ("$1" == "all") {
    for (i=0; i<GROUP_NB; i++)
       show_grpf(i)
    } else {
     for (i=0; i<GROUP_NB; i++) {
       if (GROUP_IND[i] == "$1") {
         show_grpf(i)
         ret = 0
         break
       } else
         ret = 1
      }
    if (ret == 1) {
       printf ("\n\t\tgroup %s is not configured\n\n", "$1")
       group_list
     }
   }
}'

#%IU% (ind)
#%MDESC% Show a group (defined by its index) as 8 motors/line.
def show_grpf(ind) '{
local i nam mnem us di k

  k=0
  printf ("\t---- group: %s ----\n",GROUP_IND[ind])
  get_angles
  for (i=1; i<=GROUP_MOT[ind][0]; i++) {
     if (!is_using_motor(GROUP_MOT[ind][i]))
        continue
       if (i>8)
         k=1
       nam[k] = sprintf("%s %9.9s", nam[k], motor_name(GROUP_MOT[ind][i]))
       mnem[k] = sprintf("%s %9.9s", mnem[k], motor_mne(GROUP_MOT[ind][i]))
       us[k] = sprintf("%s %9.4f", us[k], A[GROUP_MOT[ind][i]])
       di[k]= sprintf("%s %9.4f", di[k], dial(GROUP_MOT[ind][i], A[GROUP_MOT[ind][i]]))
    }
  for (i=0; i<=k; i++)
    printf ("%s\n%s\n%s\n%s\n",nam[i], mnem[i], us[i], di[i])
}'

#%MACROS%
#%IMACROS%
#%AUTHOR% GROUP.MAC - C.D., AB%BR%
#$Revision: 1.3 $, $Date: 2008/04/25 08:13:08 $
#%TOC%