esrf

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

#%TITLE% HEAT.MAC
#%NAME%
#  %B%heat.mac%B% - macros to compensate the crystal temperature due to the
#decrease of the machine current.
#%DESCRIPTION%
# The macro reads the machine current and changes the horizontal gap of
# the primary slits so the heat on the crystal is constant
#%SETUP%
#%B%motors%B%%B%used%B% - pf (front blade), pb (back blade) of the primary
#                         slits%BR%
#%B%pseudo%B%%B%motor%B% - phg (horizontal gap)%BR%
#%B%machine%B%%B%current%B% - read from the "machine" - sys/machstat
#%END%

#%UU% [sleep_time motor_to_move [thc_device thc_channel]]
#%MDESC% setup the compensation loop: set %B%sleep_time%B% betweeen the
#compensation and the %B%motor_to_move%B% to compensate the temperature
#of the monochromator crystal due to the decrease of the machine current.
#If desired, set the reading the monochromator crystal temperature - read the
#%B%thc_channel%B% of the %B%thc_device%B%. Finaly read the initial horizontal
#gap and machine current.
def heat_setup '{
global MACH_CURRENT HEAT_POWER SLEEP_TIME
global THC_TEMP THC_DEVICE THC_CHANNEL
global GAP_MOT GAP_MNE GAP_MAX


  SLEEP_TIME = 300
  GAP_MOT = -1

  if ($#) {
    SLEEP_TIME = $1
    GAP_MNE = "$2"
    if ($# > 2) {
      THC_DEVICE = "$3"
      THC_CHANNEL = $4
    }
  } else {
    SLEEP_TIME = getval("Time to wait between compensation [s]:",SLEEP_TIME)
    if ((SLEEP_TIME < 10) || (SLEEP_TIME > 600)) {
      printf ("Sleep time of %d s incorrect.\n", SLEEP_TIME)
      SLEEP_TIME = 300
      SLEEP_TIME = getval("Please, choose value between 10 and 600 s:", \
	SLEEP_TIME)
    }
    GAP_MNE = getval("Gap motor mnemonic (e.g. phg):", GAP_MNE)
    if (yesno("Read the monochromator crystal temperature?", 0)) {
      THC_DEVICE = \
	getval("ADC device name (e.g. d23/wcthc/oh):",THC_DEVICE)
      THC_CHANNEL = \
	getval("ADC channel number (0-31):", THC_CHANNEL)
    } else
      THC_DEVICE = ""
  }

  if ((SLEEP_TIME < 10) || (SLEEP_TIME > 600)) {
    tty_cntl("md")
    printf ("Sleep time of %d s incorrect, setting it to 300 s\n", SLEEP_TIME)
    tty_cntl("me")
  }

  GAP_MOT = motor_num(GAP_MNE)
  if (GAP_MOT == -1) {
    tty_cntl("md")
    eprintf ("Motor %s not configured, setup not done!\n", GAP_MNE)
    tty_cntl("me")
    return
  }
  _heat_first_read()
}'

#%UU% 
#%MDESC% Start the compensation procedure.%BR%
#Attention!! - this is an infinite loop. Use ^C to stop it
def heat_loop '{
local mc[] delta_heat mv_gap

  if (SLEEP_TIME == 0) {
    printf ("The compensation parameters are not set\n")
    printf ("Please, execute heat_setup first\n")
    exit
  }
  if (GAP_MOT == -1) {
    eprintf ("Motor not configured, cannot start compensation, exiting ..\n")
    exit
  }
  while (1) {
    if (THC_DEVICE) {
      if (esrf_io(THC_DEVICE, "DevReadSigValues", THC_TEMP) != -1) {
        get_angles
        if (THC_TEMP[THC_CHANNEL] > 100) {
          A[GAP_MOT] = 0; move_em; move_poll; get_angles
	  printf ("Temperature exceeding 100 deg C. Compensation stopped.\n")
	  printf ("Primary slits horizontal gap set to zero\n")
      	  exit
	}
      }
    }
    _read_mach_current(mc)
    if (mc[2] < 1) {
      printf ("Injection! Primary slits horizontal gap unchanged (%6.4f mm)\n", A[GAP_MOT])
    } else {
      printf ("Current %5.2f mA, slits gap %6.3f mm", mc[0], A[GAP_MOT])
      if (THC_DEVICE)
        printf (", temp %6.3f degC\n", THC_TEMP[THC_CHANNEL])
      else
        printf ("\n")
      delta_heat = HEAT_POWER - (mc[0] * A[GAP_MOT])
      printf ("delta_heat %6.4f HEAT_POWER %6.4f\n", delta_heat,HEAT_POWER)
      if (fabs(delta_heat) > 1) {
	mv_gap = HEAT_POWER / mc[0] - A[GAP_MOT]
 	if ((mv_gap + A[GAP_MOT]) > GAP_MAX)
	  mv_gap = GAP_MAX - A[GAP_MOT]
	printf ("Changing the gap by %6.4f mm\n", mv_gap)
        A[GAP_MOT] += mv_gap; move_em; move_poll; get_angles
      }
    }
    sleep(SLEEP_TIME)
  }
}'

#%IU% 
#%MDESC% reads the machine current ("sys/mach/current") and the gap (phg)
#at the begining of the compensation loop
def _heat_first_read() '{
local mc[]

  if (GAP_MOT == -1) {
    eprintf ("Motor not configured, cannot initialise compensation!\n")
    return(-1)
  }
  _read_mach_current(mc)
  if (mc[2] < 1) {
    tty_cntl("md")
    printf ("Injection, machine current value unreliable!\n")
    tty_cntl("me")
  }
  MACH_CURRENT = mc[0]
  get_angles
  HEAT_POWER = MACH_CURRENT * A[GAP_MOT]
  get_angles
  printf ("Current %5.2f mA, primary slits horizontal gap: %6.4f mm\n",\
	MACH_CURRENT, A[GAP_MOT])
  if (THC_DEVICE) {
    esrf_io(THC_DEVICE, "DevReadSigValues", THC_TEMP)
    printf ("Mono crystal temperature: %5.2f deg C\n", THC_TEMP[THC_CHANNEL])
  }
  GAP_MAX = A[GAP_MOT]*1.3
}'

#%MACROS%
#%IMACROS%
#%TOC%
#%DEPENDENCIES% ring_current.mac%BR%
#%AUTHOR% A.Beteva/BLISS %BR%
#$Revision: 1.5 $, $Date: 2012/03/21 16:30:23 $
#%END%
#%LOG%
#$Log: heat.mac,v $
#Revision 1.5  2012/03/21 16:30:23  beteva
#Changes the machine current reading to cope with the new front end software.
#More tests for the motor name.
#Make the temperature reading optional.
#
#Revision 1.4  2004/01/28 13:54:26  beteva
#replaced test for negative current with test for injection mode.
#
#Revision 1.3  2003/04/22 16:43:44  beteva
#fixed bug in _heat_first_read.
#
#Revision 1.2  2002/10/23 17:04:24  beteva
#removed the datacollector part.
#
#Revision 1.1  2002/10/23 17:03:33  beteva
#Initial revision
#