esrf

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

#%TITLE% dld.mpc
#%NAME% 
#  Delay Line Detector / OBSOLETE
#
#%CATEGORY% Detection, Obsolete
#
#%WARNING%
# 
#  This macros are now OBSOLETE
#
#%DESCRIPTION%
#
#  This macro implements access to F.Sever's device servers controlling
#  the delay line detector complex.
#
#%BR%%BR%
#  
#  The aim of this implementation is to provide easy access to the detector
#  from SPEC, a full access to the functionalities of the Dld is available
#  with F.Sever's SPEC-independent client. %BR%
#
#  The frame information has to be prepared in a file. Each line of this
#  file will represent a framepair. Each framepair is made up of seven
#  values.
#  %UL% 
#  %LI%   Number of frames.
#  %LI%   Dead time (in seconds) 
#  %LI%   Dead output (line output active while in dead)
#  %LI%   Dead pause (yes or no, value 1 or 0)
#  %LI%   Live time 
#  %LI%   Live output 
#  %LI%   Live pause 
# %XUL%
#%EXAMPLE%
#%DL%
#%DT%  dldsetup id13/dld/1 id13/xfr/1 red data/dld /users/a/opid13/data/dld id13/dc/egy id13/dc/sampledistance id13/dc/detposition  %DD%
#  (Setup the dld macros with device server names and other parameters)
#%DT%  dldconfig %DD%
#  (will prompt for all necessary information for a new acquisition cycle)
#%DT%  dldstart %DD%
#  (triggers the acquisition)
#%DT%  dldhmread  %DD%
#  (reads data into file)
#%XDL%
#%END%
##
#2 HISTORY
#  08-Dec-1995	header and data version 2.0 
#               hm data file has no header any more  (0 bytes instead of 512)
#  14-Dec-1995  dldsum changed for transmission
#
#  19-Jan-1996  version 2.100. 
#               header and data version 2.1
#               Added two lines in header for scaler data to
#               provide this block with an identifier and its length
#               Due to this change, requested by A. Hammersley, the scaler
#               data block is not longer forward compatible
#               Older version of gas2saxs do not work any more. 
#               The headers are only forward compatible if changes are added to
#               the END (!!) of the blocks.
#  20-Jan-1996  version 2.200.00
#               DLD_DETECTORPOSITION written to header file
#  23-Jan-1996  version 2.200.01
#               DLD_DETECTORINFO
##
#  DldVersion
##
def dldversion '
  DLD_VERSION = "2.200.01 PB/VR 23-Jan-1996"
  print (sprintf("DldVersion %s\n",DLD_VERSION));
'


##
#  DldSetup
##
#%UU%   [dld_dev xfr_dev host remdir headdir energy_dc sample-distance_dc detector-position_dc] :
#%MDESC%
#        The following parameters have to be given with this command
#        or it will ask for them interactively:
#        - dld_dev:          device server name for main dld control
#        - xfr_dev:          device server name for data transfer
#        - host:             where to store remote data
#        - remdir:           name of directory where to store data in
#                            remote host
#        - headdir:          name of local directory where temporarily
#                            store header data
#        - energy_dc:        name for energy device in data collector
#                            it must follow device nomenclature. i.e
#                            domain/family/member and be the same as
#                            that in monochromator spec application
#        - sample_distance_dc name for sample distance in data collector
#        - detector_position_dc name for detector position in data collector
def dldsetup '
global DLD_DEV TFG_DEV MCS_DEV VHIST_DEV DLD_SUMCG DLD_SUMCG_IN
global DLD_GRP1 DLD_GRP2 DLD_GRP3 DLD_GRP4
global DLD_FRAME_LEN DLD_FRAME_INFO DLD_FRAME_FILE
global DLD_STA_STR DLD_PARDA
global DLD_READ_FILE DLD_READ_PART DLD_READ_STATUS
global DLD_SEPARATOR DLD_RUN_NUMBER DLD_STATUS
global DLD_DATA_HOST DLD_DATA_DIR DLD_HDDATA_DIR DLD_FILE_PREFIX DLD_TIMEOUT
global DLD_XFRTIMEOUT
global DLD_SCALER DLD_PART_FIELD DLD_RESOL
global DLD_STNUMBER DLD_DATA_LENGTH DLD_NO_FRAMES DLD_NO_CYCLES
global DLD_SCALER_ARGIN
global DLD15_DATA DLD_15_ITERATION 
global DLD15_SCALER_READ DLD_HMSCALER_DEPTH DLD_SCALER_DEPTH DLD_SCALER_NAME
global DLD_SCALER_ZERO DLD_SCALER_CALIB
global DLD_ACQ_STATE DLD_TRANSFER_STATE
global DLD_CYCLE DLD_FRAME
global DLD_OLDFRAME DLD_OLDCYCLE DLD_OLDITER 
global DLD_DCUP
global DLD_VERSION

global DLD_CENTER_1 DLD_CENTER_2 DLD_PIXSIZE_1 DLD_PIXSIZE_2
global DLD_WAVELENGTH DLD_SAMPLEDISTANCE DLD_TITLE DLD_SUBTITLE
global DLD_DEFAULT_TITLE
global DLD_DETECTORINFO DLD_MACHINEINFO DLD_OPTICSINFO
global DLD_DETECTORPOSITION
global DLD_STATIONINFO DLD_PROPOSALINFO
global DLD_SCALER_I0 DLD_SCALER_I1 DLD_SCALER_ANODE DLD_SCALER_TIME
global DLD_SCALER_I0S DLD_SCALER_I1S DLD_SCALER_ANODES DLD_SCALER_TIMES
global DLD_HMSTARTTIME
global DLD_EPS DLD_HC
global DLD_DC_EGY DLD_DC_SAMPLEDISTANCE DLD_DC_DETECTORPOSITION
global DLD_ACQ_TIME DLD_ACQ_STARTTIME DLD_XFILE

global DLD_DEVICES XFR_DEV DLD_MEMSTRUCT
global ESRF_ERR

local sowhat

dldversion

if ($# != 8 && $# !=0 )
{
   print "Usage: dldsetup [dld_dev xfr_dev host remdir headdir energy_dc sample-distance_dc detector-position_dc]"
   exit
}

#
# Initialize strings.
#
DLD_STA_STR[0]="Number of TFG cycles              "
DLD_STA_STR[1]="Number of TFG frames              "
DLD_STA_STR[2]="Data length (in bits)             "
DLD_STA_STR[3]="Detector type (1/2D)              "
DLD_STA_STR[4]="Resolution in X                   "
DLD_STA_STR[5]="Resolution in Y                   "
DLD_STA_STR[6]="VHIST_HM Bus (0=VME 1=VSB)        "
DLD_STA_STR[7]="Total Memory size (Mb)            "
DLD_STA_STR[8]="Number of partitions              "
DLD_STA_STR[9]="Memory size as in VHIST CSR(MB)   "
DLD_STA_STR[10]="Total Size of partition (Bytes)   "
DLD_STA_STR[11]="Used size of partition (Bytes)    "
DLD_STA_STR[12]="Current partition number          "
DLD_STA_STR[13]="Current partition VME base addr   "
DLD_STA_STR[14]="Current partition VSB base addr   "
DLD_STA_STR[15]="Current partition status          "
DLD_STA_STR[16]="Current cycle number              "
DLD_STA_STR[17]="Current frame number              "

DLD_SEPARATOR=0xffffffff

DLD_TIMEOUT    = 90
DLD_XFRTIMEOUT = 450

DLD_TRANSFER_STATE = "Init"
DLD_ACQ_STATE      = "Init"

DLD_EPS = 1e-30;
DLD_HC  = 1239.85;

#
# Assign device names.
#
if ($# == 0 )
{
  printf("Current parameters for dld setup\n\n")
  printf("Dld device                      :     %s\n",DLD_DEV)
  printf("Xfr device                      :     %s\n",XFR_DEV)
  printf("Host for remote data            :     %s\n",DLD_DATA_HOST)
  printf("Directory for remote data       :     %s\n",DLD_DATA_DIR)
  printf("Directory for local data(header):     %s\n",DLD_HDDATA_DIR)
  printf("\nData collector devices:\n")
  printf("\tEnergy            :     %s\n",DLD_DC_EGY)
  printf("\tSample Distance   :     %s\n",DLD_DC_SAMPLEDISTANCE)
  printf("\tDetector Position :     %s\n",DLD_DC_DETECTORPOSITION)

  sowhat = yesno("\nDo you want to change setup values",0)
  if (sowhat == 0) exit
  printf("Enter parameters for Dld device server:\n")
  DLD_DEV=getval("  Device name ",DLD_DEV)
  XFR_DEV=getval("  Xfr Device  ",XFR_DEV)

  printf("\n")
  DLD_DATA_HOST  =getval("Host for storing remote data         ",DLD_DATA_HOST)
  DLD_DATA_DIR   =getval("Directory for storing remote data    ",DLD_DATA_DIR)
  DLD_HDDATA_DIR =getval("Directory for headers and scaler data",DLD_HDDATA_DIR)

}

if ($# == 8)
{
   DLD_DEV="$1";  XFR_DEV="$2"
   DLD_DATA_HOST="$3"; DLD_DATA_DIR="$4"; DLD_HDDATA_DIR="$5"; 
   DLD_DC_EGY="$6", DLD_DC_SAMPLEDISTANCE="$7";
   DLD_DC_DETECTORPOSITION="$8";
}

  #
  # First import and timeouts
  #
  dldconnect

  #
  # Set defaults for DEPTH
  #
  if (DLD_HMSCALER_DEPTH == 0 ) DLD_HMSCALER_DEPTH = 24
  if (DLD_SCALER_DEPTH == 0 ) DLD_SCALER_DEPTH = DLD_HMSCALER_DEPTH 

  if (DLD_DCUP == 0) dlddcup
#
# Define group for:
#              dldgetframe   93 
#              read scaler   94
#              dldscaler     95
#
#              group   111 (DLD_GRP4 is used later on for scaler reading)
# 
DLD_GRP1=93; DLD_GRP2=94; DLD_GRP3=95
data_grp(DLD_GRP1,200,7); data_grp(DLD_GRP2,2048,2); data_grp(DLD_GRP3,2048,1)

cdef("user_cleanup2","dld_cleanup; ","dld")

'

#%IU%
#%MDESC%
#   Import devices and set timeouts
def dldconnect '

  timeout=esrf_io(DLD_DEV,"timeout",DLD_TIMEOUT)
  timeout=esrf_io(XFR_DEV,"timeout",DLD_XFRTIMEOUT)

  dld_stat = esrf_io(DLD_DEV,"DevDldGetDeviceNames",DLD_DEVICES)
  if (dld_stat == -1) {
      printf("Dld: error getting device names for Dld \n")
      exit
  } else {
      TFG_DEV=DLD_DEVICES[0]
      MCS_DEV=DLD_DEVICES[1]
      VHIST_DEV=DLD_DEVICES[2]
  }

  if (TFG_DEV != "notpresent") {
         timeout=esrf_io(TFG_DEV,"timeout",DLD_TIMEOUT)
  } else {
         printf("Tfg Device is not present\n")
  }
  if (MCS_DEV != "notpresent") {
         timeout=esrf_io(MCS_DEV,"timeout",DLD_TIMEOUT)
  } else {
         printf("Mcs Device is not present\n")
  }
  if (VHIST_DEV != "notpresent") {
         timeout=esrf_io(VHIST_DEV,"timeout",DLD_TIMEOUT)
  } else {
         printf("Vhist Device is not present\n")
  }
'

##
# DldCleanup
##
#%IU%
#%MDESC%
#  Macro executed at cleanup
#
def dld_cleanup '
    local dldstopall
    #
    # First check if an acquistion is running
    #
    #
    # If so stop it
    #
    # (if GUI is running do not ask question. Otherwise ask confirmation)
    # 
    # uhmm! what to do if transferring?... (no stop is possible)
    #
    DLD_STNUMBER=esrf_io(DLD_DEV,"DevDldGetStateNumber")
    dldstopall = 0
    if (DLD_STNUMBER == 137625602) {
       printf("There is a DLD acquistion running\n")
       if (GUI_RUN) {
          dldstopall=1
       } else {
          dldstopall = yesno("Do you want to stop the current acquisition",0)
       }
       if (dldstopall == 0) exit
    }
    if (dldstopall == 1 ) {
          dldidle
    }
'


##
# DldDcup
##
#%IU%
#%MDESC%
#
# Creates devices for Data Collector
#
def dlddcup '
     esrf_dc(DLD_DC_EGY,"create","DevRead","D_DOUBLE_TYPE");
     esrf_dc(DLD_DC_SAMPLEDISTANCE,"create","DevRead","D_DOUBLE_TYPE");
     esrf_dc(DLD_DC_DETECTORPOSITION,"create","DevRead","D_DOUBLE_TYPE");

     DLD_DCUP = 1
'

##
# Dldacq
##
#%UU% acqtime
#%MDESC%
#  Do an acquisition on Dld for acqtime seconds on live
#  Single frame, single cycle
#
def dldacq '

    if ($# != 1) {
       p "Usage: dldacq acqtime(in seconds)"
       exit
    }
    #
    #  First config
    #
    DLD_NO_CYCLES = 1
    DLD_15_ITERATION=1

    dldsettime  $1
    dldnocycles
    dldconfigstart
    dldconfigall "nofile"
    dldconfigshow
    dldconfigend
    DLD_ACQ_STATE = "Idle"
    Xdldgui

    #
    # Set iteration to 1
    #

    #
    # Then start
    #
    dldstart 0 0
'

##
# DldSetTime
##
#%UU%
#%MDESC%
#    Set time for dldacq
#
def dldsettime '

   local dldacqtime

   global DLD_FRAME_ARGIN

   dldacqtime = $1

   DLD_FRAME_ARGIN[0]=1
   DLD_FRAME_ARGIN[1]=0.006
   DLD_FRAME_ARGIN[2]=1
   DLD_FRAME_ARGIN[3]=0
   DLD_FRAME_ARGIN[4]=dldacqtime
   DLD_FRAME_ARGIN[5]=1
   DLD_FRAME_ARGIN[6]=0

'

##
# Dldconfig
##
#%UU%

#%MDESC%
#        Ask for values to prepare a new configuration for an acquistion.
#        and make them effective.
#        The values asked are:
#          Resolution in X (possible values: 1,256,512,1024,2048,4096)
#          Resolution in Y (possible values: 1,256,512,1024,2048,4096)
#          Data Length (bits: 16,32)
#          Frame information file name
#          Number of cycles
#          Prefix for output filenames
# 
def dldconfig '

    global DLD_SCAN_YESNO DLD_SCAN_ON
    global DLD_OLD_RUN_NUMBER DLD_FILE_ROOT DLD_BEAMCHECK
    #
    # Ask for values.
    #
    if (DLD_15_ITERATION == 0) DLD_15_ITERATION=1
    if (DLD_RESOL[0] == 0) DLD_RESOL[0]=512
    if (DLD_RESOL[1] == 0) DLD_RESOL[1]=512
    if (DLD_DATA_LENGTH == 0) DLD_DATA_LENGTH=32
    if (DLD_DATA_LENGTH == 0) DLD_DATA_LENGTH=32
    if (DLD_FRAME_FILE == 0) DLD_FRAME_FILE="fs1"
    if (DLD_FRAME_FILE == 0) DLD_FRAME_FILE="fs1"
    if (DLD_FILE_ROOT  == 0) DLD_FILE_ROOT="test"

    if (($# == 8) || ($# ==9))
    {
        DLD_RESOL[0]=$1
        DLD_RESOL[1]=$2
        DLD_DATA_LENGTH =$3
        DLD_FRAME_FILE="$4"
        DLD_NO_CYCLES=$5
        DLD_FILE_PREFIX="$6"
        DLD_SCAN_YESNO=$7
        DLD_15_ITERATION=$8
        DLD_BEAMCHECK=$9
    } else {

    DLD_RESOL[0]=getval("Resolution in X",DLD_RESOL[0])
    DLD_RESOL[1]=getval("Resolution in Y",DLD_RESOL[1])
    DLD_DATA_LENGTH =getval("Data Length",DLD_DATA_LENGTH )
    DLD_FRAME_FILE=getval("Frame information file name",DLD_FRAME_FILE)
    DLD_NO_CYCLES=getval("No_cycles",1)
    DLD_FILE_PREFIX=getval("Prefix for output file names",DLD_FILE_ROOT)
    DLD_SCAN_YESNO=yesno("Do a Dld acquisition and transfer after each scan point ",DLD_SCAN_ON)
    DLD_15_ITERATION=getval("How many iterations on scalers do you want ",1)
    DLD_BEAMCHECK=yesno("Do you want to activate the beamcheck", DLD_BEAMCHECK)
    }
    if (DLD_BEAMCHECK) {
       beamchecksetup
       beamcheckon
    } else {
       beamcheckoff
    }
    DLD_FILE_ROOT=DLD_FILE_PREFIX
    if (DLD_SCAN_YESNO == 1)
    {
        if (!DLD_SCAN_ON)
        {
               DLD_SCAN_ON = 1
               DLD_OLD_RUN_NUMBER = DLD_RUN_NUMBER
               dldscanon
        }
    } else {
        if (DLD_SCAN_ON)
        {
               DLD_SCAN_ON = 0
               DLD_RUN_NUMBER = DLD_OLD_RUN_NUMBER
               dldscanoff
        }
    }
    #
    # Then configure
    #
    dldconfigstart
    dldnocycles
    dldconfigall
    dldconfigshow
    dldconfigend
    DLD_ACQ_STATE = "Idle"
    Xdldgui

'

##
# DldIdle
##
#%IU%
def dldidle '
    dldstop
    if (MCS_DEV != "notpresent") 
       esrf_io(MCS_DEV,"DevMcsStop")
'

##
# DldRunCheck
##
#%IU%
def dldruncheck '

    DLD_STNUMBER=esrf_io(DLD_DEV,"DevDldGetStateNumber")
    if (DLD_STNUMBER == 137625602) {
       printf("There is a DLD acquistion running\n")
       dldstopall = yesno("Do you want to stop the current acquisition",0)
       if (dldstopall == 0) exit
    }

    dldidle
'

##
#  DldStart
##
#%UU% [0/1 [part-no [title-string [rel. position]]]]  
#%MDESC%
#        Triggers an acquisition.
#        When a parameter ( 0 or 1 ) is given the acquisition is started
#        in internal mode (0) or in external mode (1). When no parameter
#        is given the default is internal mode, without needing of external
#        trigger.
#        The second parameter, if present, is the number of the partition to
#        be used. If not present the macro will ask for used partition and
#        will prompt the user for the next partition to be used.
# Special macro for dealing with 24bit scalers... Saturated after 15seconds
# with 1 MHz input rate. 
# The macro uses all data in dldconfig but takes as parameter the number
# of iterations for the acquisition to be performed. Each iteration will save
# the scaler values in SPEC memory 
# The title-string is stored by dldhmread in the header file. If not specified
# the default given in dldinfo is used.
# The relative position is the offset (in mm) of the sample relative to the
# detector position. It is used to calculate the sampledistance from the 
# detector position (sample distance = detector position + relative position). 
# The sample distance is stored by dldhmread in the header file. If not 
# specified, the sample position is used that is stored in the data base. 
# The following additional parameters are read (mainly from the database):
# machine info, station info, optics info (currently not), 
# detector position, sample distance, start time
# Dldconfig has to be issued first.
#
def dldstart '
global _dld15error _dld15frames _dld15read
global mode
local DLD_STSTRING

if ($# > 4 )
{
  printf("Usage: dldstart [0/1 [part-no [title [rel. position]]]] (0=intern, 1=extern)\n")
  exit
} 

if ($# == 1)
   mode = $1
else mode = 0

# Beamcheck
beampoll

dldruncheck 

if ($# < 2) {
    dldchangepart
} else {
    dldchangepart "$2"
}

_dld15error=0

printf("\n")
#
#  read title  (DLD_TITLE)
#
   DLD_TITLE = DLD_DEFAULT_TITLE;
   if ($# >= 3) {
     DLD_TITLE = "$3";
   } else {
     if ($# < 2) {
        DLD_TITLE = getval(" Please enter a title",DLD_TITLE);
     }
   }
   printf("  Title           = %s\n", DLD_TITLE);

#
# Clear scaler group. Create it.
#
DLD_GRP4=111
data_grp(DLD_GRP4,0,0)
data_grp(DLD_GRP4,1024,32)

#
# Find number of frames.
#
dld_sta_len=esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
if(dld_sta_len == -1)
{
    printf("Dld15: Error reading Dld status. Giving up\n")
    exit
} else {
    _dld15frames=DLD_STATUS[1]    # Number of frames
}

#
# Get machine and optics information 
#
   miread;
   DLD_MACHINEINFO    = sprintf(\
      "  Ie=%5.2fmA,gap46=%5.2fmm,taper46=%5.2fmm,gap26=%5.2fmm,taper26=%5.2fmm",\
      MI_CUR,MI_GAP1,MI_TAPER1,MI_GAP2,MI_TAPER2);
   printf("%s\n", DLD_MACHINEINFO);

   DLD_STATIONINFO    = sprintf("%s",MI_BL);
   printf("  Station         = %s\n", DLD_STATIONINFO);

   DLD_OPTICSINFO     = "optics"

#
#  read current wavelength (DLD_WAVELENGTH in meters from the data collector)   
#
   DLD_WAVELENGTH     = DLD_HC/esrf_dc(DLD_DC_EGY,"DevRead")*1e-9;
     printf("  Wavelength      = %9.4g nm\n", DLD_WAVELENGTH*1e9);

#
#  read current sample distance  (DLD_SAMPLEDISTANCE in meters from dettube)
#
   DLD_DETECTORPOSITION   = esrf_dc(DLD_DC_DETECTORPOSITION,"DevRead")*0.001;
   if ($# < 4) {
     DLD_SAMPLEDISTANCE   = esrf_dc(DLD_DC_SAMPLEDISTANCE,"DevRead")*0.001;
   } else {
     DLD_SAMPLEDISTANCE   = DLD_DETECTORPOSITION+0.001*$4; 
   }
   printf("  Sample distance = %9.4g mm\n", DLD_SAMPLEDISTANCE*1000);

#
# Set start time (approximate: the real time should be returned from OS9 crate)
#
   DLD_HMSTARTTIME = sprintf("%s",date());
   printf("  Start time      = %s\n", DLD_HMSTARTTIME);

   printf("\n")
#
#  Iteration.
#
DLD_OLDFRAME = -2
DLD_OLDCYCLE = -2
DLD_OLDITER  = -2
DLD_SCALER_DEPTH = 0
DLD_ACQ_STARTTIME = time()
DLD_ACQ_TIME      = DLD_ACQ_STARTTIME

for (k=0;k<DLD_15_ITERATION;k++) {
   DLD_SCALER_DEPTH = (log(k+1)/log(2)) + DLD_HMSCALER_DEPTH
   if (k>0) mode = 0
   #
   #           dldstart
   #
   if (mode==0)      ###  Internal (default ) ###
   {
      if ((dld_stat = esrf_io(DLD_DEV,"DevDldIntStart")) == -1)
      {
                   printf("Could not start Dld in internal mode\n")
                   exit
               }
          } else {
               print "Dld: Bad start mode"
          }

   #
   #           dldpoll
   #
   if (mode == 1) {
       printf("Dld: waiting for external signal to start ")
       DLD_EXTERNAL_RUNNING = 0
   }
   _dld15read=1
   while(_dld15read)
   {
       DLD_STNUMBER=esrf_io(DLD_DEV,"DevDldGetStateNumber")
       DLD_ACQ_STATE = "Running"
       DLD_ACQ_TIME = time() - DLD_ACQ_STARTTIME
       Xdldgui
       sleep(0.2)
       DLD_STSTRING=esrf_io(DLD_DEV,"DevDldGetStateString")
       if (index(DLD_STSTRING,"RUNN") != 0) {
           if (TFG_DEV != "notpresent") {
              DLD_CYCLE = esrf_io(TFG_DEV,"DevTfgReadCycle")
              DLD_FRAME = esrf_io(TFG_DEV,"DevTfgReadFrame")
           } else {
              DLD_CYCLE = 1
              DLD_FRAME = 1
           }
       }
       if (DLD_OLDITER != k+1 || DLD_OLDCYCLE != DLD_CYCLE || DLD_FRAME != DLD_OLDFRAME) {
           printf("Iteration %d, Cycle %d, Frame %d    \r",k+1,DLD_CYCLE,DLD_FRAME)
           DLD_OLDITER  = k+1
           DLD_OLDCYCLE = DLD_CYCLE
           DLD_OLDFRAME = DLD_FRAME
       }
       if (mode == 1 && !DLD_EXTERNAL_RUNNING) {
          if (DLD_STNUMBER == 137625602) {
                printf("\nDld: External start received\n")
                DLD_EXTERNAL_RUNNING = 1
          } else {
               printf(".")
               continue
          }
       }
       if (DLD_STNUMBER != 137625602) _dld15read=0
   }
   DLD_ACQ_STATE = "Iteration"
   DLD_ACQ_TIME  = time() - DLD_ACQ_STARTTIME
   Xdldgui
 
   if (MCS_DEV != "notpresent")
      dldscatomem
}
DLD_ACQ_STATE = "Idle"
Xdldgui

'

##
# DldScaToMem
##
#%IU%
def dldscatomem '
   local i

   for (i=0;i<_dld15frames;i++)
   {
       global DLD_SCALER_ARGIN
       local _l

       DLD_SCALER_ARGIN[0]=i+1
       DLD_SCALER_ARGIN[1]=1
       DLD_SCALER_ARGIN[2]=32
       DLD_ARG_LEN=esrf_io(MCS_DEV,"DevMcsRdMem",DLD_SCALER_ARGIN,DLD15_SCALER_READ)

       if(DLD_ARG_LEN==-1)
            printf("Error reading scaler %d\n",i+1)

       for(_l=0;_l<32;_l++) {
          data_put(DLD_GRP4,i,_l,data_get(DLD_GRP4,i,_l)+DLD15_SCALER_READ[_l])
       }
       #
       # Scaler clear.
       #
       if (mode == 1) {
           dld_stat=esrf_io(MCS_DEV,"DevMcsStop")
           if (dld_stat==-1)
               printf("Couldn\'t stop scalers in external mode\n")
       }

   }
   dld_stat=esrf_io(MCS_DEV,"DevMcsReset")
   if (dld_stat==-1)
        printf("Couldn\'t clear scalers \n")

   if (mode == 1) {
        dld_stat=esrf_io(MCS_DEV,"DevMcsStart")
        if (dld_stat==-1)
            printf("Couldn\'t stop scalers in external mode\n")
   }

'

##
#  dldsum 
##
#%UU% [frame-no [part-no]] 
#%MDESC%
#        Displays the detector counts, anode counts, the number of incident
#        and transmitted photons and the counting time. 
#        The number of detector counts are calculated only for 32 bits/pixel.
#        From these numbers the rejection and the effective count 
#        rate are calculated.
#        If an other than the current partition number is used only the 
#        detector counts are displayed.
#        dldscalerassign must be used first. 

def dldsum ' {
   local frameno partno param_no
   local no_frames active_part data_length frame_size
   local detector_counts_I
   local detector_counts
   local anode_I  
   local anode_calib1 anode_calib2
   local anode_counts anode_count1 anode_counts2
   local anode_value anode_value1 anode_value2
   local time_I
   local time_counts time_count1 time_counts2
   local time_value time_value1 time_value2
   local mon_I
   local mon_calib1 mon_calib2
   local mon_counts mon_count1 mon_counts2
   local mon_value mon_value1 mon_value2
   local mon_zero1 mon_zero2
   local trm_I
   local trm_calib1 trm_calib2
   local trm_counts trm_count1 trm_counts2
   local trm_value trm_value1 trm_value2
   local trm_zero1 trm_zero2
   local rejection acceptance transmission
   local max_counts max_value
   local eff_count_rate

   if ($# > 2 )
   {
     print "Usage: dldsum [frame-no [part-no]]"
     exit
   }

   if (MCS_DEV == "notpresent") {
          printf("Scaler not present. Giving up with dldsum\n")
          exit
   }
   # 
   # Get DLD status
   #
   dld_sta_len=esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
   if(dld_sta_len == -1)
   { printf("ERROR : Cannot read Dld status\n")
       exit
   } 
   no_frames    = DLD_STATUS[1] 
   active_part  = DLD_STATUS[12]
   data_length  = DLD_STATUS[2]/8 
   frame_size   = DLD_STATUS[4]*DLD_STATUS[5]*DLD_STATUS[2]/8
 
   #
   # Read frame number 
   #
   if ($# > 0) {
     if ($1<0) frameno = (no_frames+($1)); else frameno = $1;
     } else frameno = no_frames;

   if ((frameno>no_frames)||(frameno<1)) {
     printf("ERROR : Frame number %d does not exist\n",frameno);exit;
     }
    
   #
   # Get number of active partition.
   #
   if ($# > 1) partno = $2 
     else partno = active_part 

   if (partno<0) {
     printf("ERROR : Wrong partition number %d\n",partno);exit;
     }

   #
   # Get the integrated number of detector counts in the frame 
   #
   #
   #  [2] Flag 0 = nocalc; 1 = calc center of gravity
   detector_counts_I = 0

   DLD_SUMCG_IN[0] = partno 
   DLD_SUMCG_IN[1] = frameno-1
   DLD_SUMCG_IN[2] = 0 

   param_no = esrf_io(DLD_DEV,"DevDldGetSumAndCg",DLD_SUMCG_IN,DLD_SUMCG);
   if (param_no == 3 ) {
      detector_counts = DLD_SUMCG[0]
      detector_counts_I = 1
   } else { 
      printf("Error reading total counts\n")
      exit
   }

   # 
   # Get the number of anode counts (first scaler)
   #
   anode_counts_I = 0
   if ((1<=DLD_SCALER_ANODE) && (DLD_SCALER_ANODE<=32)) {
     anode_counts1 = data_get(DLD_GRP4,frameno-1,DLD_SCALER_ANODE-1);
     anode_counts_I = 1;
     anode_calib1 = DLD_SCALER_CALIB[DLD_SCALER_ANODE-1];
     anode_value1 = anode_counts1 * anode_calib1;
     } else {
     anode_calib1 = 1; anode_counts1 = 0; anode_value1 = 0;
     }

   #
   # Get the number of anode counts (alternative scaler)
   #
   if ((1<=DLD_SCALER_ANODES) && (DLD_SCALER_ANODES<=32)) {
     anode_counts2 = data_get(DLD_GRP4,frameno-1,DLD_SCALER_ANODES-1);
     anode_counts_I = 1;
     anode_calib2 = DLD_SCALER_CALIB[DLD_SCALER_ANODES-1];
     anode_value2 = anode_counts2 * anode_calib2;
     } else {
     anode_counts2 = 0; anode_calib2 = 1; anode_value2 = 0;
     }

   # 
   # Use alternative scaler if first scaler has an overflow
   #
   max_count = exp(log(2)*DLD_SCALER_DEPTH);
   max_value = max_count*anode_calib1;

   if (anode_value2 < max_value*0.99 ) {
     # no overflow of first scaler
     anode_scaler = DLD_SCALER_ANODE;
     anode_counts = anode_counts1; 
     anode_value = anode_value1;
     } else {  
     # overflow of first scaler, use second scaler
     anode_scaler = DLD_SCALER_ANODES;
     if (anode_calib2<=0) {
       printf("ERROR : Check calibration factor of scaler %d (%s) = %g\n", \
               anode_scaler, DLD_SCALER_NAME[anode_scaler-1], anode_calib2); 
       exit;
       }
     anode_counts = anode_counts2*(anode_calib1/anode_calib2);
     anode_value = anode_value2;
     }

   #
   # Get the time (first scaler)
   #
   time_I = 0;
   if ((1<=DLD_SCALER_TIME) && (DLD_SCALER_TIME<=32)) {
     time_counts1 = data_get(DLD_GRP4,frameno-1,DLD_SCALER_TIME-1);
     time_I = 1;
     time_calib1 = DLD_SCALER_CALIB[DLD_SCALER_TIME-1];
     time_value1 = time_counts1 * time_calib1;
     } else {
     time_counts1 = 0; time_calib1 = 1; time_value1 = 0;
     }

   #
   # Get the time (alternative scaler)
   #
   if ((1<=DLD_SCALER_TIMES) && (DLD_SCALER_TIMES<=32)) {
     time_counts2 = data_get(DLD_GRP4,frameno-1,DLD_SCALER_TIMES-1);
     time_I = 1;
     time_calib2 = DLD_SCALER_CALIB[DLD_SCALER_TIMES-1];
     time_value2 = time_counts2 * time_calib2;

     } else { 
     time_counts2 = 0; time_calib2 = 1; time_value2 = 0; 
     }

   #
   # Use alternative scaler if first time scaler has an overflow
   #
   max_count = exp(log(2)*DLD_SCALER_DEPTH);
   max_value  = max_count*time_calib1;

   if (time_value2 < max_value*0.99 ) {
     # no overflow of first scaler
     time_scaler = DLD_SCALER_TIME;
     time_counts = time_counts1;
     time_value  = time_value1;
     } else {
     # overflow of first scaler, use second scaler
     time_scaler = DLD_SCALER_TIMES;
     if (time_calib2<=0) {
       printf("ERROR : Check calibration factor of scaler %d (%s) = %g\n", \
               time_scaler, DLD_SCALER_NAME[time_scaler-1], time_calib2);
       exit;
       }
     time_counts = time_counts2*(anode_calib1/time_calib2);
     time_value  = time_value2;
     }

   #
   # Get the monitor (first scaler)
   #
   mon_I = 0;
   if ((1<=DLD_SCALER_I0) && (DLD_SCALER_I0<=32)) {
     mon_counts1 = data_get(DLD_GRP4,frameno-1,DLD_SCALER_I0-1);
     mon_I = 1;
     mon_calib1 = DLD_SCALER_CALIB[DLD_SCALER_I0-1];
     mon_zero1  = DLD_SCALER_ZERO[DLD_SCALER_I0-1];
     mon_value1 = (mon_counts1 - mon_zero1*time_value) * mon_calib1;
     } else {
     mon_counts1 = 0; mon_calib1 = 1; mon_zero1 = 0; mon_value1 = 0;
     }

   #
   # Get the monitor (alternative scaler)
   #
   if ((1<=DLD_SCALER_I0S) && (DLD_SCALER_I0S<=32)) {
     mon_counts2 = data_get(DLD_GRP4,frameno-1,DLD_SCALER_I0S-1);
     mon_I = 1
     mon_calib2 = DLD_SCALER_CALIB[DLD_SCALER_I0S-1];
     mon_zero2  = DLD_SCALER_ZERO[DLD_SCALER_I0S-1];
     mon_value2 = (mon_counts2 - mon_zero2*time_value) * mon_calib2;
     } else {
     mon_counts2 = 0; mon_calib2 = 1; mon_zero2 = 0; mon_value2 = 0;
     }

   #
   # Use alternative scaler if first monitor scaler has an overflow
   #
   max_count = exp(log(2)*DLD_SCALER_DEPTH);
   max_value  = max_count*mon_calib1;

   if ((mon_counts2*mon_calib2) < max_value*0.99 ) {
     # no overflow of first scaler
     mon_scaler = DLD_SCALER_I0;
     mon_counts = mon_counts1;
     mon_value  = mon_value1;
     } else {
     # overflow of first scaler, use second scaler
     mon_scaler = DLD_SCALER_I0S;
     if (mon_calib2<=0) {
       printf("ERROR : Check calibration factor of scaler %d (%s) = %g\n", \
               mon_scaler, DLD_SCALER_NAME[mon_scaler-1], mon_calib2);
       exit;
       }
     mon_counts = mon_counts2*(anode_calib1/mon_calib2);
     mon_value  = mon_value2;
     }


   #
   # Get the transmission monitor (first scaler)
   #
   trm_I = 0;
   if ((1<=DLD_SCALER_I1) && (DLD_SCALER_I1<=32)) {
     trm_counts1 = data_get(DLD_GRP4,frameno-1,DLD_SCALER_I1-1);
     trm_I = 1;
     trm_calib1 = DLD_SCALER_CALIB[DLD_SCALER_I1-1];
     trm_zero1  = DLD_SCALER_ZERO[DLD_SCALER_I1-1];
     trm_value1 = (trm_counts1 - trm_zero1*time_value) * trm_calib1;
     } else {
     trm_counts1 = 0; trm_calib1 = 1; trm_zero1 = 0; trm_value1 = 0;
     }

   #
   # Get the transmission monitor (alternative scaler)
   #
   if ((1<=DLD_SCALER_I1S) && (DLD_SCALER_I1S<=32)) {
     trm_counts2 = data_get(DLD_GRP4,frameno-1,DLD_SCALER_I1S-1);
     trm_I = 1;
     trm_calib2 = DLD_SCALER_CALIB[DLD_SCALER_I1S-1];
     trm_zero2  = DLD_SCALER_ZERO[DLD_SCALER_I1S-1];
     trm_value2 = (trm_counts2 - trm_zero2*time_value) * trm_calib2;
     } else {
     trm_counts2 = 0; trm_calib2 = 1; trm_zero2 = 0; trm_value2 = 0;
     }

   #
   # Use alternative scaler if first transmission monitor scaler has an overflow
   #
   max_count = exp(log(2)*DLD_SCALER_DEPTH);
   max_value  = max_count*trm_calib1;

   if ((trm_counts2*trm_calib2) < max_value*0.99 ) {
     # no overflow of first scaler
     trm_scaler = DLD_SCALER_I1;
     trm_counts = trm_counts1;
     trm_value  = trm_value1;
     } else {
     # overflow of first scaler, use second scaler
     trm_scaler = DLD_SCALER_I1S;
     if (trm_calib2<=0) {
       printf("ERROR : Check calibration factor of scaler %d (%s) = %g\n", \
               trm_scaler, DLD_SCALER_NAME[trm_scaler-1], trm_calib2);
       exit;
       }
     trm_counts = trm_counts2*(anode_calib1/trm_calib2);
     trm_value  = trm_value2;
     }

   #
   # calculate transmission
   # 

   transmission = -1;
   if (mon_I && (fabs(mon_value)>0)) 
     transmission = 1;
   if (mon_I && trm_I && (fabs(mon_value)>0)) 
     transmission = trm_value/mon_value;

   # 
   # calculate acceptance 
   #
   if (fabs(anode_value>DLD_EPS)) acceptance = detector_counts/anode_value;
     else acceptance = -1;

   #
   # calculate effective count rate 
   #
   if (fabs(time_value)>DLD_EPS) 
     eff_count_rate = detector_counts/time_value; else eff_count_rate = -1;

   #
   # write on screen
   #
   if (GUI_RUN ) {
         local line1 line2 line3 line4 line5 line6 line7

         line1 = sprintf(" Number of detector counts (frame %3u, partition %3u)       = %9.3g ",\
                frameno,partno,detector_counts)
         if (partno != active_part) {
            line2 = sprintf(" No scaler available for partition %d ",partno)
            line3 = sprintf(" ")
            line4 = sprintf(" ")
            line5 = sprintf(" ")
            line6 = sprintf(" ")
            line7 = sprintf(" ")
         } else {
            line2 = sprintf(" Number of anode counts (%9s)                         = %9.3g ",\
                     DLD_SCALER_NAME[anode_scaler-1],anode_value)
            line3 = sprintf(" Counting time (%9s)                                  = %9.3g s",\
                    DLD_SCALER_NAME[time_scaler-1],time_value)
            line4 = sprintf(" Total number of incident photons (%9s)               = %9.3g ph",\
                    DLD_SCALER_NAME[mon_scaler-1], mon_value)
            line5 = sprintf(" Total number of transmitted photons (%9s)            = %9.3g ph",\
                    DLD_SCALER_NAME[mon_scaler-1], trm_value)
            line6 = sprintf(" Transmission %9s                                     = %9.3g /s",\
                    " ",transmission)
            if (acceptance>=0)
                line7 = sprintf(" Rejection     = %9.3g %%, Effective count rate    = %9.3g /s",\
                   (1.0-acceptance)*100, eff_count_rate);
            else 
                line7 = sprintf(" --- NO COUNTS ---")
         }
         bpipe updateval
            fprintf("pipe","Xsumline1  \"%s\" ",line1)
            fprintf("pipe","Xsumline2  \"%s\" ",line2)
            fprintf("pipe","Xsumline3  \"%s\" ",line3)
            fprintf("pipe","Xsumline4  \"%s\" ",line4)
            fprintf("pipe","Xsumline5  \"%s\" ",line5)
            fprintf("pipe","Xsumline6  \"%s\" ",line6)
            fprintf("pipe","Xsumline7  \"%s\" ",line7)
         epipe
   } 
         printf("\n Number of detector counts (frame %3u, partition %3u) = %9.3g \n",\
                frameno,partno,detector_counts);

         # Scaler data not valid, if partno!=active_part
         if (partno != active_part) { 
             printf(" No scaler values available for partition %d\n",partno);
             exit
         }
        printf(" Number of anode counts (%9s)                   = %9.3g \n",\
            DLD_SCALER_NAME[anode_scaler-1],anode_value);
        printf(" Counting time (%9s)                            = %9.3g s\n",\
            DLD_SCALER_NAME[time_scaler-1],time_value);
        printf(" Total number of incident photons (%9s)         = %9.3g ph\n",\
            DLD_SCALER_NAME[mon_scaler-1], mon_value);
        printf(" Total number of transmitted photons (%9s)      = %9.3g ph\n",\
            DLD_SCALER_NAME[trm_scaler-1], trm_value)
        printf(" Transmission %9s                               = %9.3g\n",\
            " ",transmission)
        if (acceptance>=0)
            printf(" Rejection     = %9.3g %%, Effective count rate    = %9.3g \
/s\n\n",\
              (1.0-acceptance)*100, eff_count_rate);
          else printf(" --- NO COUNTS ---\n\n")
 }
'

##
#  DldConfigStart
##
#%UU% 

#%MDESC%
#        Change the internal state of the Dld server to "Init"
def dldconfigstart '
   DLD_STATE=esrf_io(DLD_DEV,"DevDldGetStateString")
   if (index(DLD_STATE,"IDLE") != 0) {
         dld_stat = esrf_io(DLD_DEV,"DevDldBackToInit")
         if (dld_stat == -1) printf("dldconfigstart failed\n")
   }
'

##
#  DldConfigEnd
##
#%UU% 

#%MDESC%
#        Change the internal state of the Dld server to "Idle"
def dldconfigend '
   DLD_STATE=esrf_io(DLD_DEV,"DevDldGetStateString")
   if (index(DLD_STATE,"INIT") != 0) {
        dld_stat = esrf_io(DLD_DEV,"DevDldConfigFinished")
        if (dld_stat == -1) printf("dldconfigend failed\n")
   }
'


##
#  DldConfigAll
##
#%UU% 
#%MDESC%

#        Reads frame information from DLD_FRAME_FILE and makes it effective.
#        Then uses DLD_DATA_LENGT and DLD_RESOL values and give them
#        to device server
#        Gives frame info to Tfg
#
def dldconfigall '

global DLD_FRAME_ARGIN
global DLD_RESLEN_ARGIN

#
# read the frame info from file 
# if first argument is "nofile" we skip file reading. Data for argin
# has to be prepared before calling the macro (i.e dldscalerzero)
#
if ("$1" != "nofile") {
    no_groups=data_read(DLD_FRAME_FILE,DLD_GRP1,0,0)

    if (no_groups == -1) {
        print "Dld: error in opening frame information file"
        exit
    }

    #
    # Now prepare argin.
    # 
    for(i=0;i<no_groups;i++)
    {
          DLD_FRAME_ARGIN[i*7]=data_get(DLD_GRP1,i,0)
          DLD_FRAME_ARGIN[i*7 + 1]=data_get(DLD_GRP1,i,1)
          DLD_FRAME_ARGIN[i*7 + 2]=data_get(DLD_GRP1,i,2)
          DLD_FRAME_ARGIN[i*7 + 3]=data_get(DLD_GRP1,i,3)
          DLD_FRAME_ARGIN[i*7 + 4]=data_get(DLD_GRP1,i,4)
          DLD_FRAME_ARGIN[i*7 + 5]=data_get(DLD_GRP1,i,5)
          DLD_FRAME_ARGIN[i*7 + 6]=data_get(DLD_GRP1,i,6)
    }
}

DLD_ARG_LEN=esrf_io(DLD_DEV,"DevDldGetNbOfFrames",DLD_FRAME_ARGIN)
if(DLD_ARG_LEN==-1)
     printf("Error setting frame memory\n")


DLD_RESLEN_ARGIN[0] = DLD_DATA_LENGTH
DLD_RESLEN_ARGIN[1] = DLD_RESOL[0]
DLD_RESLEN_ARGIN[2] = DLD_RESOL[1]

dld_stat = esrf_io(DLD_DEV,"DevDldSetDLenAndRes",DLD_RESLEN_ARGIN ) 

if (dld_stat == -1 )
   printf("Error setting data-length/resol for dld device\n")

if (TFG_DEV != "notpresent") {
DLD_ARG_LEN=esrf_io(TFG_DEV,"DevTfgSetFrameMemory",DLD_FRAME_ARGIN,DLD_FRAME_INFO)
if(DLD_ARG_LEN==-1)
     printf("Error setting frame memory\n")
}

unglobal DLD_RESLEN_ARGIN
unglobal DLD_FRAME_ARGIN

'

##
# DldConfigShow
##
#%IU%
#%MDESC%
#  Shows values from last dldconfigall
#

def dldconfigshow '
if(DLD_ARG_LEN==-1)
     printf("Last config was not succesful. No data\n")
else {
   for (i=0;i<DLD_ARG_LEN;i+=2)
   {
      printf("Frame %d, dead time: %f\n",(i+2)/2,DLD_FRAME_INFO[i])
      printf("          live time: %f\n",DLD_FRAME_INFO[i+1])
   }
}

'

##
#  DldNoCycles 
##
#%UU%  number
#%MDESC%
#        Sets the value for the number of cycles.
def dldnocycles '

if (TFG_DEV != "notpresent" ) {
   nb_cycles = DLD_NO_CYCLES

   dld_stat = esrf_io(TFG_DEV,"DevTfgSetCyclesInRun",nb_cycles) 

   if (dld_stat == -1 )
      printf("Error setting number of cycles for dld device\n")
}

'

##
#  DldChangePart
##
#%UU% [partition-number] 

#%MDESC%
#        Gives information about the partition status and then prompts
#        the user for a new partition to use. If the partition chosen
#        already has data gives the user the option of clear it or reuse 
#        it keeping the old values.
#        When the macros is invoked with no parameter it will prompt the
#        user for a partition number.
#        When one parameter is given, this correspond to the partition number
#        to be used and by default the partition is cleared if it already
#        had data
def dldchangepart '
global DLD_ARGIN partition_no
if ($# > 1)
{ 
  printf("Usage: dldchangepart [part-number]\n")
  exit
}

if ($# == 1)
{
  DLD_ARGIN[0] = $1
  DLD_ARGIN[1] = 1     # Always clear in this case.
} else {
  #
  # Check status of dld device. (Get number of partitions, and current partition)
  #
  esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
  nb_par=DLD_STATUS[8]
  cur_par=DLD_STATUS[12]
  printf("Total nb of partitions = %d and current partition is %d\n",nb_par, cur_par)
  
  #
  # Which of them have data?
  #
  noparda=esrf_io(DLD_DEV,"DevDldGetPartWithData",DLD_PARDA)
  flag_selec_data=0
  if(noparda==0)
  {
     printf("There is no partition with data\n")
     partition_no=getval("Which partition do you want to use next",cur_par)
  }
  else
  {
     for(j=0;j<noparda;j++) {
        if(DLD_PARDA[j] >= 0)
            printf("\tpartition %d has data\n",DLD_PARDA[j])
     }
     partition_no=getval("Which partition do you want to use next",cur_par)
     for(j=0;j<noparda;j++) {
        if (partition_no == DLD_PARDA[j])
               flag_selec_data=1
     }
  }
 
  #
  # Give the option to clear the partition or not.
  #
  if (flag_selec_data == 1)
  {
       printf("The partition %d has data\n",partition_no)
       clear_par=yesno(" Do you want to clear it?",1)
       DLD_ARGIN[0]= partition_no
       DLD_ARGIN[1]=clear_par
  } else {
       DLD_ARGIN[0] = partition_no
       DLD_ARGIN[1] = 1
  }

}

# 
# Finally select it!
#
dld_stat=esrf_io(DLD_DEV,"DevDldSelNextPart",DLD_ARGIN)
if (dld_stat==-1)
    printf("Couldn\'t change to partition %d\n",DLD_ARGIN[0])
else
   printf("Active partition is now %d\n",DLD_ARGIN[0])


#
# Clear scalers
#
if (MCS_DEV != "notpresent") {
   dld_stat=esrf_io(MCS_DEV,"DevMcsReset")
   if (dld_stat==-1)
       printf("Couldn\'t clear scalers \n")
}
'

##
#  DldState
##
def dldstate '
DLD_STATE=esrf_io(DLD_DEV,"DevDldGetStateString")
DLD_ACQ_STATE = substr(DLD_STATE,17,5)
Xdldgui
printf("%s\n",DLD_STATE)
'
##
#  get_detector_info 
##
#%MDESC%
#        Get the global variable DLD_DETECTORINFO

def get_detector_info ' {
 local SN IF
 global DLD_DETECTORINFO

 SN = 0
 IF[0] = 0
 IF[1] = 0

 DLD_DETECTORINFO = "two dimensional delay line detector"
 if (esrf_io("id2/ntdc/01","DevNTdcShowInterpFactor",IF)==2) {
   SN = esrf_io("id2/ntdc/01","DevNTdcShowSN")

   DLD_DETECTORINFO = sprintf("%s (IF = %d, SN = %d)",\
                               DLD_DETECTORINFO,IF[0],SN)
   }

 }
 '

##
#  dldinfo 
##
#%MDESC%
#        Prompts for experiment specific parameters which are stored in the
#        header file. 
def dldinfo '

   if ( $# == 0 ) {
   get_detector_info
   DLD_PROPOSALINFO   = getval("Proposal number ",DLD_PROPOSALINFO)
   DLD_DEFAULT_TITLE  = getval("Title",DLD_DEFAULT_TITLE)
   DLD_SUBTITLE       = getval("Subtitle",DLD_SUBTITLE)
   DLD_CENTER_1       = getval("Center_1 [pixel units]",DLD_CENTER_1)
   DLD_CENTER_2       = getval("Center_2 [pixel units]",DLD_CENTER_2)
   DLD_PIXSIZE_1      = 0.001*getval("Pixel Size 1 [mm]",1000*DLD_PIXSIZE_1)
   DLD_PIXSIZE_2      = 0.001*getval("Pixel Size 2 [mm]",1000*DLD_PIXSIZE_2)

   dldscalerassign
   }

   printf("Detector info           = %s\n",\
          DLD_DETECTORINFO);
   printf("Proposal number         = %s\n",\
          DLD_PROPOSALINFO);
   printf("Title                   = %s\n",\
          DLD_DEFAULT_TITLE);
   printf("Subtitle                = %s\n",\
          DLD_SUBTITLE);
   printf("Center 1                = %f pixel units\n",\
          DLD_CENTER_1);
   printf("Center 2                = %f pixel units\n",\
          DLD_CENTER_2);
   printf("Pixel Size 1            = %f mm\n",\
          DLD_PIXSIZE_1*1000);
   printf("Pixel Size 2            = %f mm\n",\
          DLD_PIXSIZE_2*1000);
   printf("\n");

   dldmono
'

##
# dldmono
##
##
def dldmono '
   global DLD_EGYVAL DLD_DISTVAL

   if (USER == "opid02" ) {
   }

   if (USER == "opid13" ) {
      DLD_EGYVAL = esrf_dc(DLD_DC_EGY,"DevRead")/1000
      DLD_DISTVAL = esrf_dc(DLD_DC_SAMPLEDISTANCE,"DevRead")
      if ($# == 2 ) {
         DLD_EGYVAL  = $1
         DLD_DISTVAL = $2
      } else {
         printf("Introduce values for,\n")
         DLD_EGYVAL = getval("\tEnergy(keV):",DLD_EGYVAL)
         DLD_DISTVAL = getval("\tSample distance(mm):",DLD_DISTVAL)
      }

      esrf_dc(DLD_DC_EGY,"put",DLD_EGYVAL*1000)
      esrf_dc(DLD_DC_SAMPLEDISTANCE,"put",DLD_DISTVAL)
      esrf_dc(DLD_DC_DETECTORPOSITION,"put",DLD_DISTVAL)
   }
'

##
#  DldPoll
##
def dldpoll '
DLD_OLDFRAME = -2
DLD_OLDCYCLE = -2
DLD_OLDITER  = -2
while(1)
{
    DLD_ACQ_STATE = "Running"
    DLD_STNUMBER=esrf_io(DLD_DEV,"DevDldGetStateNumber")
    DLD_STSTRING=esrf_io(DLD_DEV,"DevDldGetStateString")
    if (index(DLD_STSTRING,"RUNN") != 0) {
        if (TFG_DEV != "notpresent") {
           DLD_CYCLE = esrf_io(TFG_DEV,"DevTfgReadCycle")
           DLD_FRAME = esrf_io(TFG_DEV,"DevTfgReadFrame")
        } else {
           DLD_CYCLE = 1
           DLD_FRAME = 1
        }
    }
    if (DLD_OLDITER != DLD_15_ITERATION || DLD_OLDCYCLE != DLD_CYCLE || DLD_FRAME != DLD_OLDFRAME) {
        printf("Iteration %d, Cycle %d, Frame %d     \r",DLD_15_ITERATION,DLD_CYCLE,DLD_FRAME)
        DLD_OLDITER = DLD_15_ITERATION
        DLD_OLDCYCLE = DLD_CYCLE
        DLD_OLDFRAME = DLD_FRAME
    }
    Xdldgui
    sleep(1)
    if (DLD_STNUMBER != 137625602) {
      printf("\n")
      DLD_ACQ_STATE = "Idle"
      Xdldgui
      break
    }
}
'

##
#  DldStatus
##
#%UU% 

#%MDESC%
#        Gives full status information.
def dldstatus '

dld_sta_len=esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
if(dld_sta_len == -1)
{
    printf("Error reading Dld status\n")
    exit
} else {
  for (i=0;i<dld_sta_len;i++)
  {
     # Print Adresses and part status in Hexa
     if (i==13 || i==14 || i==15) {
         printf("%s : %x\n",DLD_STA_STR[i],DLD_STATUS[i])
     } else {
         printf("%s : %d\n",DLD_STA_STR[i],DLD_STATUS[i])
     }
  }
}
'

##
# DldGetPartStatus
##
def dldpartstatus '
    
    local _number _part part_status

    _number = esrf_io(DLD_DEV,"DevDldGetMemStructures",DLD_MEMSTRUCT)
    printf("Part   Define  Selec  Nonemp  Acquir  Transf  Displ  Ima  Pix  Col  Row\n")

    for (_part=0;_part<DLD_MEMSTRUCT[0];_part++) {
       part_status=esrf_io(DLD_DEV,"DevDldGetPartStatus",_part)
       printf("%3d ",_part)
       printf("%8s",(part_status&0x0001)?"YES":"NO ")
       printf("%8s",(part_status&0x0002)?"YES":"NO ")
       printf("%8s",(part_status&0x0004)?"YES":"NO ")
       printf("%8s",(part_status&0x0008)?"YES":"NO ")
       printf("%8s",(part_status&0x0010)?"YES":"NO ")
       printf("%8s",(part_status&0x0020)?"YES":"NO ")
       printf("%5d",DLD_MEMSTRUCT[_part*4+1])
       printf("%5d",DLD_MEMSTRUCT[_part*4+2])
       printf("%5d",DLD_MEMSTRUCT[_part*4+3])
       printf("%5d",DLD_MEMSTRUCT[_part*4+4])
       printf("\n")
    }
'

##
#  DldStop
##
#%UU% 
#%MDESC%
#        Stops the acquisition that is currently running.
def dldstop '
DLD_STATE=esrf_io(DLD_DEV,"DevDldGetStateString")
if (index(DLD_STATE,"IDLE") == 0) {
    printf("Stopping.\n")
    if ((dld_stat = esrf_io(DLD_DEV,"DevDldStop")) == -1)
    {
        printf("Could not stop Dld\n")
        DLD_ACQ_STATE = "Error"
        exit
    } else {
        DLD_ACQ_STATE = "Idle"
    }
}

Xdldgui
if (MCS_DEV != "notpresent")
     dldscatomem
'

##
#  DldPause
##
#%UU%  [0/1]
#%MDESC%
#        Suspends the execution of an acquisition until a new dldstart command
#        is issued. Like 'dldstart' this macro accepts a mode parameter 
#        0=internal, 1=external.
def dldpause '
if ($# > 1 )
{
    printf("Usage: dldpause [0/1] (0=internal, 1=internal)\n")
    exit
}  

if ($# == 1)
   mode = $1
else mode = 0

if (mode==0)      ###  Internal (default ) ###
{
   if ((dld_stat = esrf_io(DLD_DEV,"DevDldIntPause")) == -1)
   {
       printf("Could not pause Dld in internal mode\n")
       exit
   }
   print "Dld paused in internal mode"
} else if (mode==1)
       {
            if ((dld_stat = esrf_io(DLD_DEV,"DevDldExtPause")) == -1)
            {
                printf("Could not pause Dld in external mode\n")
                exit
            }
            print "Dld paused in internal mode"
       } else {
            print "Dld: Bad pause mode"
       }
'

##
# Dld read memory
##
#%UU%  [part-no]
#        Dumps the 32 scalers and a partition into a file. If the partition
#        number is not given the current partition is dumped. The name of
#        the file is formed with the prefix given in the configuration plus
#        a three number suffix starting with 001. This number is automatically
#        incremented. The full name of the file is echoed to the user.
#        The user should avoid starting a new acquisition on a partition that
#        is being dumped. This risks to make losing the data.
#        To know the status of the reading process use the macro dldreadpoll.
def dldhmread ' 
{
local full_unix_name full_os9_name filename
local first_scalerno last_scalerno first_frameno last_frameno scaler_size
local header_length xfr_state
local unix_cmd

if ($# > 1 )
{
      print "Usage: dldhmread [part-no]"
      exit
}

if ($# !=1 ) {

    #
    # If no partition number is given read from current partition.
    #
    esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
    DLD_READ_PART=DLD_STATUS[12]
} else {
    DLD_READ_PART=$1
}

    DLD_READ_FILE=sprintf("%s/%s%.3d",DLD_HDDATA_DIR,DLD_FILE_PREFIX,++DLD_RUN_NUMBER)
  
    DLD_XFILE = sprintf("%s%.3d",DLD_FILE_PREFIX,DLD_RUN_NUMBER)
    printf("Transferring Dld data\n")
    printf("\tHeader file:  %s\n",DLD_READ_FILE)

    if (unix(sprintf("test -f %s\n",DLD_READ_FILE)) == 0) {
       printf("File %s exists\n",DLD_READ_FILE)
       print "Choose another name"
       exit
    } else {
       unix(sprintf("touch %s\n",DLD_READ_FILE))
    }

    DLD_TRANSFER_STATE="Header"
    Xdldgui
#
# -- TOP HEADER
#
    on(DLD_READ_FILE);offt
    print 4                    # length of header
    print DLD_RUN_NUMBER       # run number
    print "2.2"                # header and data version 2.2 
    print DLD_SEPARATOR
    ont;close(DLD_READ_FILE)

#
# -- SCALER HEADER
#
   dld_sta_len=esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
   if(dld_sta_len == -1) {
       printf("Error reading Dld status\n")
       on(DLD_READ_FILE);offt
       print "Status error for HM Memory: Not read"
       ont;close(DLD_READ_FILE)
       exit
   }
   first_scalerno = 1
   last_scalerno  = 32
   first_frameno  = 1
   last_frameno   = DLD_STATUS[1]
   scaler_size=(last_scalerno-first_scalerno+1)*(last_frameno-first_frameno+1)*4
   header_length  = 10

   on(DLD_READ_FILE);offt
   print 10             #  Length of header
   print 2              #  Scaler memory ID
   print first_scalerno #  first scaler number (1 <= x <= 32)
   print last_scalerno  #  last scaler number (1 <= x <= 32)
   print first_frameno  #  first frame number
   print last_frameno   #  last frame number
   print 0              #
   print 0              #
   print scaler_size    #  Length of scaler memory in bytes
   print DLD_SEPARATOR
   ont;close(DLD_READ_FILE)

#
# -- SCALER DATA
#
   header_length  = (last_frameno - first_frameno + 1) * (last_scalerno - \
                     first_scalerno + 1) + 3 

   on(DLD_READ_FILE);offt
   if (MCS_DEV != "notpresent") {
      print header_length  #  Length of header
      print 5              #  Scaler data ID
      for (i=first_scalerno-1;i<last_scalerno;i++)
      {
          for (j=first_frameno-1;j<last_frameno;j++) {
               print data_get(DLD_GRP4,j,i)
          }
   
      }
   } else {
      print 4              #  Length of header
      print 5              #  Scaler data ID
      print "MCS scaler notpresent"
   }
   print DLD_SEPARATOR
   ont;close(DLD_READ_FILE)

#
# -- IMAGE HEADER
#
   on(DLD_READ_FILE);offt
   print 12               # Length of header
   print 3                # HM Id
   print DLD_STATUS[2]    # Data length
   print DLD_STATUS[4]    # Dim_1 Resolution in x
   print DLD_STATUS[5]    # Dim_2 Resolution in y
   print DLD_STATUS[1]    # Total number of frames
   print 0
   print 0
   print DLD_STATUS[11]   # Length of HM in bytes (=effective partition size)
   print 0                # Offset_1  (must be 0 or positive)
   print 0                # Offset_2  (must be 0 or positive)
   print DLD_SEPARATOR
   ont;close(DLD_READ_FILE)

#
# --- TIMING HEADER
#
   first_frameno = 1;
   last_frameno = DLD_STATUS[1];
   header_length = 4+last_frameno-first_frameno+1;

   on(DLD_READ_FILE);offt
   print header_length    # Length of header
   print "TIMING"         # Timing ID
   print DLD_HMSTARTTIME  # Start time of acquisition
   DLD_HMDELTATIME = 0;   # Start time of life frame since DLD_HMSTARTTIME
   for (i=1,k=0;i<first_frameno;i=i++) {
      DLD_HMDELTATIME = DLD_HMDELTATIME+DLD_FRAME_INFO[k++]+DLD_FRAME_INFO[k++];
   }
   for (i=first_frameno;i<=last_frameno;i++) {
      DLD_HMDELTATIME = DLD_HMDELTATIME + DLD_FRAME_INFO[k++]
      print DLD_HMDELTATIME;
      DLD_HMDELTATIME = DLD_HMDELTATIME + DLD_FRAME_INFO[k++]
   }
   print DLD_SEPARATOR
   ont;close(DLD_READ_FILE)

#
# --- SCALER CALIBRATION HEADER
#
   header_length = 10+3*(last_scalerno-first_scalerno+1)+4

   on(DLD_READ_FILE);offt
   print header_length
   print "SCALERCALIB"        #
   print DLD_SCALER_DEPTH     # valid bit of scaler data
   print DLD_SCALER_I0        # scaler number for incident number of photons
   print DLD_SCALER_I1        # scaler number for transmitted number of photons
   print DLD_SCALER_ANODE     # scaler number for anode counts
   print DLD_SCALER_TIME      # scaler number for exposure time
   print first_scalerno
   print last_scalerno
   for (i=first_scalerno-1;i<last_scalerno;i++) {
      print DLD_SCALER_NAME[i];
      print DLD_SCALER_ZERO[i];
      print DLD_SCALER_CALIB[i];
   }
   print DLD_SCALER_I0S       # 2nd scaler number for incident number of photons
   print DLD_SCALER_I1S       # 2nd scaler number for transmitted number of photons
   print DLD_SCALER_ANODES    # 2nd scaler number for anode counts
   print DLD_SCALER_TIMES     # 2nd scaler number for exposure time
   print DLD_SEPARATOR
   ont;close(DLD_READ_FILE)

#
# --- EXPERIMENT HEADER
#
   on(DLD_READ_FILE);offt
   print 12                   # header length
   print "EXPERIMENT"         # experiment header ID
   print DLD_CENTER_1         # beam center in direction 1 (pixel units)
   print DLD_CENTER_2         # beam center in direction 2 (pixel units)
   print DLD_PIXSIZE_1        # pixel size in direction 1 (meters)
   print DLD_PIXSIZE_2        # pixel size in direction 2 (meters)
   print DLD_WAVELENGTH       # wavelength (meters)
   print DLD_SAMPLEDISTANCE   # distance between sample and detector (meters)
   print DLD_TITLE            # user supplied title
   print DLD_SUBTITLE         # user supplied name of the sample etc.
   print DLD_DETECTORPOSITION # position of the detector (meters)
   print DLD_SEPARATOR

#
# --- INFO HEADER
#
   print 8                    # header length
   print "INFO"               # info header ID
   print DLD_DETECTORINFO     # detector info 
   print DLD_MACHINEINFO      # machine info
   print DLD_OPTICSINFO       # optics info
   print DLD_STATIONINFO      # name of the station
   print DLD_PROPOSALINFO     # proposal number and info
   print DLD_SEPARATOR
   ont;close(DLD_READ_FILE)

#
# Transfer header file into remote host.
#
   OWD=CWD
   on("/dev/null");offt
   chdir(DLD_HDDATA_DIR)
   ont;close("/dev/null")

   unix_cmd = sprintf("/users/a/das/bin/s700/xfrfile %s%.3d %s %s",DLD_FILE_PREFIX,DLD_RUN_NUMBER,DLD_DATA_HOST,DLD_DATA_DIR)
   unix(unix_cmd)

   sleep(1)

   on("/dev/null");offt
   chdir(OWD)
   ont;close("/dev/null")
#
#     Data
#
#
    DLD_TRANSFER_STATE="Memory"
    Xdldgui
    # Open Connection to host 

    xfr_state = esrf_io(XFR_DEV,"DevXfrOpen",DLD_DATA_HOST)
    if (xfr_state == -1) {
       dldxfrerror ESRF_ERR
    }

    # Open file

    full_os9_name=sprintf("%s%.3dhm",DLD_FILE_PREFIX,DLD_RUN_NUMBER)
    printf("\n\tMemory data to file %s\n",full_os9_name)

    global DLD_XFR_ARGIN
    DLD_XFR_ARGIN[0] = USER
    # printf("TESTING TESTING... User is OPID00\n")
    # DLD_XFR_ARGIN[0] = "opid00"
    DLD_XFR_ARGIN[1] = DLD_DATA_DIR
    DLD_XFR_ARGIN[2] = full_os9_name
    DLD_XFR_ARGIN[3] = "w"

    xfr_state = esrf_io(XFR_DEV,"DevXfrOpenFile",DLD_XFR_ARGIN)
    if (xfr_state == -1) {
       dldxfrerror ESRF_ERR
    }

    unglobal DLD_XFR_ARGIN

    xfr_state = esrf_io(XFR_DEV,"DevXfrWritePartition",DLD_READ_PART)
    if (xfr_state == -1) {
       #  dldxfrerror ESRF_ERR
       p "Ignore last error. I am fine"
    }

    DLD_READ_STATUS=1
    while(DLD_READ_STATUS)
    {
      sleep(0.5)
      dldreadpoll
    }

    #
    # Close connection to file and host
    #
    xfr_state = esrf_io(XFR_DEV,"DevXfrCloseFile")
    if (xfr_state == -1) {
       dldxfrerror ESRF_ERR
    }

    xfr_state = esrf_io(XFR_DEV,"DevXfrClose")
    if (xfr_state == -1) {
       dldxfrerror ESRF_ERR
    }


}

'

def dldxfrstate '
local dld_stat
dld_stat = esrf_io(XFR_DEV,"DevXfrState")

printf("Xfr is (%d) ",dld_stat)
if (dld_stat == -1) {
   printf("Command error\n")
}
if (dld_stat == 1) {
   printf("Init \n")
}
if (dld_stat == 2) {
   printf("Opened \n")
}
if (dld_stat == 3) {
   printf("Ready\n")
}
if (dld_stat == 4) {
   printf("Transferring\n")
}
if (dld_stat == 5) {
   printf("Write error\n")
}
'

###
# dldreadpoll
###
#%IU% 
#%MDESC%
#        Informs about the status of the reading process.
def dldreadpoll '
local dld_stat
dld_stat = esrf_io(XFR_DEV,"DevXfrState")

if (dld_stat == -1 || dld_stat == 0 || dld_stat > 5)
{
    DLD_TRANSFER_STATE = "Unknown"
    printf("Dld: Cannot get Xfr state\n")
    DLD_READ_STATUS=0
}

if (dld_stat == 1) 
{
   DLD_TRANSFER_STATE = "Init"
   print "Xfr: connection to remote host is closed"
   DLD_READ_STATUS=0
}

if (dld_stat == 2) 
{
   DLD_TRANSFER_STATE = "Open"
   print "Xfr: no file opened on remote host"
   DLD_READ_STATUS=0
}

if (dld_stat == 3) 
{
   DLD_TRANSFER_STATE = "Ready"
   DLD_READ_STATUS=0
}

if (dld_stat == 4) 
{
   DLD_TRANSFER_STATE = "Reading"
}

if (dld_stat == 5) 
{
   DLD_TRANSFER_STATE = "Error"
   print "Xfr: write error"
   DLD_READ_STATUS=0
}

Xdldgui

'

##
# dldxfrerror
###
#%IU%
#%MDESC%
#   Checks error coming from Xfr device when transferring data.
#
def dldxfrerror '

   local _error xfr_state

   _error = $1

   #
   # If error from lower level call DevXfrStrError
   if (_error & 0xff000000) {
       xfr_state = esrf_io(XFR_DEV,"DevXfrStrError",_error)
       if (xfr_state != -1 ) {
           printf("Xfr: %s\n",xfr_state)
       } else {
           printf("Xfr: cannot find the error (%d). \n",_error)  
       }
   } 
  
   dldxfrstop
'

##
# DldXfrStop
##
#%UU%
#%MDESC%
#   Allows to return Xfr to a well known state. Current transfer
#   is stoped. And connections to file and remote hosts are closed.
def dldxfrstop '
    local dld_stat

    #
    # First close transfer if any
    dld_stat = esrf_io(XFR_DEV,"DevXfrAbort")
    if (dld_stat == -1) {
        printf("Cannot Abort XFR. Help!\n")
    } 
     
    dld_stat = esrf_io(XFR_DEV,"DevXfrState")
    if (dld_stat != 1 ) {
        printf("Error resetting XFR (%d)\n",dld_stat)
    }
    exit
'

##
# dldreadsc
###
#%UU%  [scaler-no]
#%MDESC%

#        Reads into SPEC memory the contents of a selected scaler. If the
#        scaler number is not given the user is prompted for one.
def dldreadsc '

if ($# > 1)
{
      print "Usage: dldreadsc [scaler-no]"
      exit
}
     
if ($# == 1 )
{
    DLD_SCALER = $1
}

if ($# == 0 )
{
    DLD_SCALER = getval("Scaler number",DLD_SCALER)
}

for(i=0;i<1024;i++) {
    data_put(DLD_GRP2,i,0,i)
    data_put(DLD_GRP2,i,1,data_get(DLD_GRP4,i,DLD_SCALER))
}

if (DLD_ARG_LEN==-1)
     printf("Error reading scaler\n")
else {

#
# Plot and save.
#
     dldplot
}

'

#%UU% 
#%MDESC%
#        Shows in a plot the values read by the previous 'dldreadsc'. 
#
# Usage : dldplot firstfr lastfr ymin ymax
#         dldplot firstfr lastfr 
#         dldplot 
def dldplot '
{
local _xmin _xmax _ymin _ymax
local pelem nopar grp nn n1 offset _imin _imax
pelem = 0
grp = DLD_GRP2
nopar = $#
if (!nopar) {
  _xmin=0
  _xmax=1024
  }
else {
  _xmin=$1
  _xmax=$2 +1
  }

_imax[0] = data_anal(grp,0,0,0,0,"max")
_imin[0] = data_anal(grp,0,0,0,0,"min")

if (_xmin<_imin[0]) _xmin = _imin[0]
if (_xmax>_imax[0]) _xmax = _imax[0]

if ((_xmin>_imax[0]) || (_xmax<_imin[0])) {
  printf ("No valid plot range ch %d - %d \n",_xmin,_xmax)
  exit
  }

offset=data_get(grp,0,0)
n1 = int((_xmin-offset))
nn = int((_xmax-_xmin))
_ymin=data_anal(grp,n1,nn,1,1,"min")
_ymax=data_anal(grp,n1,nn,1,1,"max")

_res1 = sprintf("Peak at %.5g is %.5g.  COM at %.5g.   ",\
        data_anal(grp,n1,nn,pelem,1,"x_at_max"),\
        data_anal(grp,n1,nn,0,1,"max"),\
        data_anal(grp,n1,nn,pelem,1,"com"))
_res2 = sprintf("FWHM is %.5g at %.5g.   ",\
        data_anal(grp,n1,nn,pelem,1,"fwhm"),\
        data_anal(grp,n1,nn,pelem,1,"cfwhm"))

if (nopar ==4) {
  dld_plot1 grp pelem 1 _xmin _xmax $3 $4
  }
if ((nopar ==2) || (nopar==0)) {
  dld_plot1 grp pelem 1 _xmin _xmax _ymin _ymax
  }
}
'

##
# DldScaler
##
#%UU% [scaler-no]
#%MDESC%
def dldscaler '
   if ($# > 1)
   {
         print "Usage: dldscaler [scaler-no]"
         exit
   }
     
   if ($# == 1 )
   {
       DLD_SCALER = $1
   }

   if ($# == 0 )
   {
       DLD_SCALER = getval("Scaler number",DLD_SCALER)
   }


   #
   # First get number of frames of last acquisition.
   #
   dld_sta_len=esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
   if(dld_sta_len == -1)
   {
        printf("Error reading Dld number of frames\n")
        exit
   } else {
        DLD_NO_FRAMES = DLD_STATUS[1]
   }

   #
   # Then read that scaler
   #
   printf("DldScaler data for scaler %d ( %d frames)\n",DLD_SCALER,DLD_NO_FRAMES)
   printf("---------------------------- \n")
   printf("Frame    Value    \n\n")
   for(i = 0; i < DLD_NO_FRAMES;i++) {
        printf("%4d   %d\n",i+1,data_get(DLD_GRP4,i,DLD_SCALER-1)) 
   }
'

##
# DldScalerSetup
##
#%UU%
#%MDESC%
# Macro that allows the user to give information about each individual
# scaler.
def dldscalersetup '
{
    local scaler_no

    if ($# > 4 || $# < 0) {
      printf("Usage: dldscalersetup [number [zero [calib [name ]]]]\n") 
      exit
    } 

    if ($# > 0 ) scaler_no = $1 - 1;
      else scaler_no = \
           getval("\tScaler number",scaler_no + 1) - 1;
    if ($# > 1) DLD_SCALER_ZERO[scaler_no]  =  $2;
      else DLD_SCALER_ZERO[scaler_no] = \
           getval("\tzero (ct/s)",DLD_SCALER_ZERO[scaler_no]);
    if ($# > 2) DLD_SCALER_CALIB[scaler_no]  = $3;
      else DLD_SCALER_CALIB[scaler_no] = \
           getval("\tcalibration (unit/ct)",DLD_SCALER_CALIB[scaler_no]);
    if ($# > 3) DLD_SCALER_NAME[scaler_no]  = "$4";
      else DLD_SCALER_NAME[scaler_no] = \
           getval("\tname ",DLD_SCALER_NAME[scaler_no]);

}
'

##
# dldsave
##
#
#%UU% [filename]
#%MDESC%
#  Save scaler setup values.
#  Takes filename as input. But only considered the string until the
#  first dot. Completes the name with suffix dld.
#
def dldsave '
{
   local dldarr

   if ($# == 0 ) {
     fileroot = getval("Save current scaler setup under which name","")
   }  else {
     fileroot = "$1"
   }
   split(fileroot,dldarr,".")
   fileroot = dldarr[0]
    
   filename = sprintf("%s/local/spec/userconf/%s.dld",BLISSADM,fileroot)

   on(filename);offt
   for (i=0;i<32;i++) {
     if (DLD_SCALER_NAME[i] != "") {
         printf("DLD_SCALER_NAME[%d]=\"%s\"\n",i,DLD_SCALER_NAME[i])
     }
     printf("DLD_SCALER_ZERO[%d]=%g\n",i,DLD_SCALER_ZERO[i])
     printf("DLD_SCALER_CALIB[%d]=%g\n",i,DLD_SCALER_CALIB[i])
   }
   ont;close(filename)

   printf("\nOk. Current scaler setup saved with name \"%s\"\n",fileroot)
   printf("Use dldrestore \"%s\" to restore\n",fileroot)
}
'

##
# dldrestore
##
#
#%UU% [filename]
#%MDESC%
#  Restore scaler setup values from a previous dldsave.
#  Takes filename as input. But only considered the string until the
#  first dot. Completes the name with suffix dld.
def dldrestore '
{
   local dldarr fileroot

   if ($# == 0 ) {
      unix(sprintf("cd %s/local/spec/userconf;ls *.dld",BLISSADM))
      fileroot = getval("\nSelect file to restore","")
   }  else {
      fileroot = "$1"
   }

   split(fileroot,dldarr,".")
   fileroot = dldarr[0]
    
   filename = sprintf("%s/local/spec/userconf/%s.dld",BLISSADM,fileroot)

   qdofile(filename)

   printf("\nOk. Done\n")
}
'

###
# dldwatchscalers
###
#%UU% [frame-no]
#%MDESC%
# Macro to show scaler values. 
#
def ws 'dldwatchscalers'

def dldwatchscalers '
{   local counting_time
    local frameno 

    if (MCS_DEV == "notpresent") {
          printf("No scaler configured in this crate\n")
          exit
    }
    printf("Watch Dld scaler values: Usage ws [frame]\n")
    printf("----------------------------------------------\n")

   #
   # First get number of frames of last acquisition.
   #
   dld_sta_len=esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
   if(dld_sta_len == -1)
   {
        printf("Error reading Dld number of frames\n")
        exit
   } else {
        DLD_NO_FRAMES = DLD_STATUS[1]
   }
   if ($# == 1) {
       if ($1<0) frameno = (DLD_NO_FRAMES+($1))
       else frameno = $1; 
   } else {
      frameno = DLD_NO_FRAMES;
   }

   printf("frame %d: scaler depth %d (number,name,counts,value)\n",\
                        frameno,DLD_SCALER_DEPTH)

   if ((frameno>DLD_NO_FRAMES)||(frameno<1)) exit

   if ((DLD_SCALER_TIME>0) && (DLD_SCALER_TIME<=32)) { 
       counting_time=(data_get(DLD_GRP4,frameno-1,DLD_SCALER_TIME-1) * \
                             DLD_SCALER_CALIB[DLD_SCALER_TIME-1])
   } else { 
       counting_time = 1.0 
   }
      
   for (i = 0,k = 32; i < k;i+=8) {
       for (j=0;j<8;j++) {
          printf("scaler %2d ",i+j+1)
       }
       printf("\n")
       for (j=0;j<8;j++) {
          printf("%9s ",DLD_SCALER_NAME[i+j])
       }
       printf("\n")
       for (j=0;j<8;j++) {
          printf("%9.3g ",data_get(DLD_GRP4,frameno-1,i+j))
       }
       printf("\n")
       for (j=0;j<8;j++) {
          printf("%9.3g ",( data_get(DLD_GRP4,frameno-1,i+j) - \
                  DLD_SCALER_ZERO[i+j]*counting_time )*DLD_SCALER_CALIB[i+j] )
       }
       printf("\n")
       if (i<k-8) printf("\n");
    }
}
'

###
# dldwatchscalersetup 
###
#%UU%  
#%MDESC%
#
#        Displays the zero values and calibration values of all scalers.
#        This information is introduced with dldscalersetup

def wss 'dldwatchscalersetup'
def dldwatchscalersetup '
{   
    printf("Watch dld scaler setup\n")
    printf("----------------------\n")
    printf("HS32 scaler depth %d (number,name,zero,calib)\n",\
                     DLD_HMSCALER_DEPTH)

    for (i = 0,k = 32; i < k;i+=8) {
       for (j=0;j<8;j++) {
          printf("scaler %2d ",i+j+1)
       }
       printf("\n")
       for (j=0;j<8;j++) {
          printf("%9s ",DLD_SCALER_NAME[i+j])
       }
       printf("\n")
       for (j=0;j<8;j++) {
          printf("%9.3g ",DLD_SCALER_ZERO[i+j])
       }
       printf("\n")
       for (j=0;j<8;j++) {
          printf("%9.3g ",DLD_SCALER_CALIB[i+j])
       }
       printf("\n")
       if (i<k-8) printf("\n");
    }
}
'

###
# dldscalerassign
###
#%UU% i0-scaler i1-scaler time-scaler anode-scaler + 4 alt. scalers + HS32depth 
#%MDESC%
#       Assignment of a scaler and an alternative scaler as monitor for 
#       incident photons (i0), transmitted photons (i1), 
#       time (time) and anode counts (anode).
#       An alternative scaler is used, if its value shows, that the basic
#       scaler has an overflow.  

def dldscalerassign '
   if ($# != 0 && $# != 9) {
      printf(\
       "Usage: dldscalerassign i0-scaler i1-scaler time-scaler anode-scaler\n");
      printf(\
       "                       alt.-i0   alt.-i1   alt.-time   alt.-anode\n");
      printf(\
       "                       HS32-depth\n");
      exit
   }
   
   if ($# == 0 ) {
    if ((DLD_SCALER_I0<1) || (DLD_SCALER_I0>32)) DLD_SCALER_I0=4
    DLD_SCALER_I0      = getval(sprintf("Scaler for incident photons (%s)", \
          DLD_SCALER_NAME[DLD_SCALER_I0-1]), DLD_SCALER_I0)
    if ((DLD_SCALER_I1<1) || (DLD_SCALER_I1>32)) DLD_SCALER_I1=6
    DLD_SCALER_I1      = getval(sprintf("Scaler for transmitted photons (%s)", \
          DLD_SCALER_NAME[DLD_SCALER_I1-1]), DLD_SCALER_I1)
    if ((DLD_SCALER_TIME<1) || (DLD_SCALER_TIME>32)) DLD_SCALER_TIME=6
    DLD_SCALER_TIME   = getval(sprintf("Scaler for exposure time (%s)", \
          DLD_SCALER_NAME[DLD_SCALER_TIME-1]), DLD_SCALER_TIME)
    if ((DLD_SCALER_ANODE<1) || (DLD_SCALER_ANODE>32)) DLD_SCALER_ANODE=6
    DLD_SCALER_ANODE   = getval(sprintf("Scaler for anode counts (%s)", \
          DLD_SCALER_NAME[DLD_SCALER_ANODE-1]), DLD_SCALER_ANODE)

    if ((DLD_SCALER_I0S<1) || (DLD_SCALER_I0S>32)) DLD_SCALER_I0S=0
    DLD_SCALER_I0S      = getval(\
          sprintf("Second scaler for incident photons (%s)", \
          DLD_SCALER_NAME[DLD_SCALER_I0S-1]), DLD_SCALER_I0S)
    if ((DLD_SCALER_I1S<1) || (DLD_SCALER_I1S>32)) DLD_SCALER_I1S=0
    DLD_SCALER_I1S     = getval(\
          sprintf("Second scaler for transmitted photons (%s)", \
          DLD_SCALER_NAME[DLD_SCALER_I1S-1]), DLD_SCALER_I1S)
    DLD_SCALER_TIMES  = getval(\
          sprintf("Second scaler for exposure time (%s)", \
          DLD_SCALER_NAME[DLD_SCALER_TIMES-1]), DLD_SCALER_TIMES)
    if ((DLD_SCALER_ANODES<1) || (DLD_SCALER_ANODES>32)) DLD_SCALER_ANODES=0
    DLD_SCALER_ANODES  = getval(\
          sprintf("Second scaler for anode counts (%s)", \
          DLD_SCALER_NAME[DLD_SCALER_ANODES-1]), DLD_SCALER_ANODES)
    if (DLD_SCALER_DEPTH == 0 ) DLD_SCALER_DEPTH = 24
    DLD_HMSCALER_DEPTH=getval("Depth of HS32 scaler",DLD_HMSCALER_DEPTH)

   } else {
        DLD_SCALER_I0      = $1
        DLD_SCALER_I1      = $2
        DLD_SCALER_TIME    = $3
        DLD_SCALER_ANODE   = $4
        DLD_SCALER_I0S     = $5
        DLD_SCALER_I1S     = $6
        DLD_SCALER_TIMES   = $7
        DLD_SCALER_ANODES  = $8
        DLD_HMSCALER_DEPTH = $9

   }

   printf("\n");
   printf("Scaler for incident photons (%9s)          = %d\n", \
          DLD_SCALER_NAME[DLD_SCALER_I0-1], DLD_SCALER_I0)
   printf("Scaler for transmitted photons (%9s)       = %d\n", \
          DLD_SCALER_NAME[DLD_SCALER_I1-1], DLD_SCALER_I1)
   printf("Scaler for exposure time (%9s)             = %d\n", \
          DLD_SCALER_NAME[DLD_SCALER_TIME-1], DLD_SCALER_TIME)
   printf("Scaler for anode counts (%9s)              = %d\n", \
          DLD_SCALER_NAME[DLD_SCALER_ANODE-1], DLD_SCALER_ANODE)

   printf("Second scaler for incident photons (%9s)   = %d\n", \
          DLD_SCALER_NAME[DLD_SCALER_I0S-1], DLD_SCALER_I0S)
   printf("Second scaler for transmitted photons (%9s)= %d\n", \
          DLD_SCALER_NAME[DLD_SCALER_I1S-1], DLD_SCALER_I1S)
   printf("Second scaler for exposure time (%9s)      = %d\n", \
          DLD_SCALER_NAME[DLD_SCALER_TIMES-1], DLD_SCALER_TIMES)
   printf("Second scaler for anode counts (%9s)       = %d\n", \
          DLD_SCALER_NAME[DLD_SCALER_ANODES-1], DLD_SCALER_ANODES)

   printf("Depth of HS32 scaler %9s                   = %d\n\n",\
          " ",DLD_HMSCALER_DEPTH)

'
###
# dlddump 
###
#%UU% [startno [endno]]
#%MDESC%
#        Dump scaler setup on the screen
# 

def dlddump '
{ 
  local dld_startno dld_endno i

  if (($# < 0 ) || ($#>2)) {
    printf("dlddump [startno [endno]]\n")
    exit
  }
  dld_startno = 1
  dld_endno = 32 

  if ($# > 0) {
      dld_startno = $1
      dld_endno = $1
  }
  if ($# > 1) dld_endno = $2

  if (dld_startno<1) dld_startno=1
  if (dld_endno>32) dld_endno=32

  print("# " date());
  for (i = dld_startno-1 ;i< dld_endno;i++ ) {
    printf("dldscalersetup %d %g %g \"%s\";\n",\
           i+1,DLD_SCALER_ZERO[i],DLD_SCALER_CALIB[i],DLD_SCALER_NAME[i]);
  }

  printf("dldscalerassign %d %d %d %d %d %d %d %d %d;\n",\
          DLD_SCALER_I0, DLD_SCALER_I1, DLD_SCALER_TIME, DLD_SCALER_ANODE,\
          DLD_SCALER_I0S, DLD_SCALER_I1S, DLD_SCALER_TIMES, DLD_SCALER_ANODES,\
          DLD_HMSCALER_DEPTH); 

} 
'

###
# dldscalerzero
###
#%UU% count-time [iterations [startno [endno]]] 
#%MDESC%
#       Measurement of the zero values for scaler startno to endno, 
#       default is 1 to 16.

def dldscalerzero '
{  
   local frameno i

   local dld_total_time
   local dld_startno
   local dld_endno

   if (MCS_DEV == "notpresent") {
         printf("No scaler configured in this crate\n")
         exit
   }

   if (($# < 1 ) || ($#>4)) {
      printf("dldscalerzero count-time [iterations [startno [endno]]]\n")
      exit
   }

   if ($# != 3) {
   _bidon = input("Type return when your frontend beamshutter is closed; ")
   }

   #
   # First get number of frames of last acquisition.
   #
   dld_sta_len=esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
   if(dld_sta_len == -1)
   {
        printf("Error reading Dld number of frames\n")
        exit
   } else {
        DLD_NO_FRAMES = DLD_STATUS[1]
   }
   frameno = DLD_NO_FRAMES;

   dld_startno = 1
   dld_endno = 16

   if ($# > 1) DLD_15_ITERATION = $2
   if ($# > 2) {dld_startno = $3; dld_endno = $3;}
   if ($# > 3) dld_endno = $4 

   if (dld_startno<1) dld_startno=1
   if (dld_endno>32) dld_endno=32

   global DLD_FRAME_ARGIN
   #
   # Now prepare argin.
   #
   DLD_FRAME_ARGIN[0]=1 
   DLD_FRAME_ARGIN[1]=0.01
   DLD_FRAME_ARGIN[2]=0 
   DLD_FRAME_ARGIN[3]=0
   DLD_FRAME_ARGIN[4]=$1
   DLD_FRAME_ARGIN[5]=0
   DLD_FRAME_ARGIN[6]=0

   dldconfigstart
   dldconfigall "nofile"

   #
   # Show info from config
   #
   for (i=0;i<DLD_ARG_LEN;i+=2)
   {
      printf("          live time: %f\n",DLD_FRAME_INFO[i+1])
   }

   printf("          iterations: %d\n",DLD_15_ITERATION)
   dld_total_time = DLD_FRAME_INFO[1] * DLD_15_ITERATION
   printf("          total counting time: %f\n",dld_total_time)
   printf("          selected scaler range: %d .. %d\n",dld_startno, dld_endno)

   dldconfigend
   #
   # Starts the acquisition for live_time * iterations seconds.
   #
   dldstart 0 0

   #
   # Then set the variable DLD_SCALER_ZERO equal to COUNT/TOTAL_TIME
   # 
   for (i = dld_startno-1 ;i< dld_endno;i++ ) {
       DLD_SCALER_ZERO[i] = data_get(DLD_GRP4,0,i)/dld_total_time
   }

   printf("Ok. Done\n")
   printf("Do not forget to do a dldconfig before your next acquisition\n")

}
'

##
# DldScalerCalib
##
#%UU%
#%MDESC%
def dldscalercalib '
{ 
  local frameno
  local counting_time;
  local reference_value;
  local scaler_count;
  local eps;

  frameno = DLD_NO_FRAMES;
  eps=1e-32;

  if (MCS_DEV == "notpresent") {
     printf("No scalers configured in this crate\n")
     exit
  }
  if (($# < 2 ) || ($#>3)) {
     printf("dldscalercalib referenceno startno [endno] \n")
     exit
  }
  printf("Calibrating scalers to a reference scaler\n"); 
  if ((DLD_SCALER_TIME<1) || (DLD_SCALER_TIME)>32) {
     printf("The scaler for the exposure time is not defined.\n");
     printf("It is not possible to calibrate scalers.\n");
     exit
  }

  #
  # First get number of frames of last acquisition.
  #
  dld_sta_len=esrf_io(DLD_DEV,"DevDldGetStatus",DLD_STATUS)
  if(dld_sta_len == -1)
  {
        printf("Error reading Dld number of frames\n")
        exit
  } else {
        DLD_NO_FRAMES = DLD_STATUS[1]
  }
  frameno = DLD_NO_FRAMES

  counting_time=(data_get(DLD_GRP4,frameno-1,DLD_SCALER_TIME-1) * \
                          DLD_SCALER_CALIB[DLD_SCALER_TIME-1])

  dld_referenceno = $1
  dld_startno = $2
  dld_endno = dld_startno
  if ($# > 2) dld_endno = $3

  if ((dld_referenceno<1) || (dld_referenceno)>32) {
     printf("Number of reference scaler out of range: %d\n",dld_referenceno)
     exit
  }
  if (dld_startno<1) dld_startno=1
  if (dld_endno>32) dld_endno=32
  if (dld_startno>dld_endno) {
     printf("No change\n");
     exit;
  }

  reference_value = (data_get(DLD_GRP4,frameno-1,dld_referenceno-1) - \
     DLD_SCALER_ZERO[dld_referenceno-1]*counting_time ) * \
     DLD_SCALER_CALIB[dld_referenceno-1];

  printf("          reference scaler:      %d (%s)\n",dld_referenceno,\
                    DLD_SCALER_NAME[dld_referenceno-1])
  printf("          selected scaler range: %d .. %d\n",dld_startno, dld_endno)
  printf("          counting time:         %g seconds\n",counting_time);
  printf("          reference value:       %g\n",reference_value);


  for (i=dld_startno-1;i<dld_endno;i++) {
    scaler_count = (data_get(DLD_GRP4,frameno-1,i) - \
        DLD_SCALER_ZERO[i]*counting_time ) 
    if (fabs(scaler_count)>eps) { 
        DLD_SCALER_CALIB[i] = reference_value/scaler_count;   
    } else { 
        printf("Scaler %d not calibrated\n",i+1)
    } 
  }
}
'

##
# DldScanOn
##
#%IU% 
#%MDESC%
def dldscanon '
{
rdef scan_head \'
  _head
  dld_head
  \'

rdef scan_loop \'
  _loop
  dld_loop
  \'
}
'

##
# DldScanOff
##
#%IU% 
#%MDESC%
def dldscanoff '
{
rdef scan_head \'
  _head
  \'
rdef scan_loop \'
  _loop
  \'
}
'

##
# Dld_Head
##
#%IU% 
#%MDESC%
#        Loop point in  dldscan
def dld_head '
{
    DLD_RUN_NUMBER = 0
    if (DATAFILE != "") {
        ond;offt
        printf("#U %s%.3d ; dld file prefix \n",DLD_FILE_ROOT,SCAN_N)
        offd;ont
    }
}
'

##
# Dld_Loop
##
#%IU% 
#%MDESC%
#       Loop point in  dldscan
def dld_loop '
{
    DLD_FILE_PREFIX = sprintf("%s%.3d-",DLD_FILE_ROOT,SCAN_N)
    p DLD_FILE_PREFIX
    dldstart 0 0
    
    # Beamcheck
    beamcheck; while (!BCHK_BEAM) {
       beampoll
       dldstart 0 0
       beamcheck
    }
    
    dldhmread 0
    DLD_FILE_PREFIX= DLD_FILE_ROOT

}
'

##
# DldScalerSave
##
#%UU% 
#%MDESC%
#        Save the data from 'dldreadsc' into a file. Can be restored with 
#        'dldload'
def dldscalersave '
{
   global DLD_FILENAME DLD_EXT DLD_COMMENT
   local filen g
   g = DLD_GRP2
   if ($# > 0) {
       DLD_FILENAME="$1"
   } else {
       DLD_FILENAME=getval("Filename to write spectrum",DLD_FILENAME)
   }

   if ($# > 1) {
      DLD_EXT=$2
   } else {
      DLD_EXT=getval("Filename run number",DLD_EXT+1)
   }

   if ($# > 2) {
      DLD_COMMENT="$3"
   } else {
      DLD_COMMENT=getval("Comment",DLD_COMMENT)
   }

   filen = sprintf("%s_%03d.dld",DLD_FILENAME,DLD_EXT)
   if (unix(sprintf("test -r %s",filen)) == 0) {
      if (yesno(sprintf("File %s already exists! Delete it",filen),1)) {
         unix(sprintf("rm -f %s",filen))
      } else {
         printf ("Nothing saved - try again\n")
         exit
      }
   }

   on(filen); offt
   fch = data_anal(g,0,0,0,0,"min") 
   lch = data_anal(g,0,0,0,0,"max")
   PS_NOPTS= lch -fch +1
   printf("#C %20s %20s %30s\n","User","Version","Date")
   printf("#H %20s %20s %30s\n",USER,SPEC,date())
   printf("#C User Comment:\n")
   printf("#U %-75s\n",DLD_COMMENT)
   printf("#C DLD Scaler: %d\n",DLD_SCALER)
   printf("#C %15s %15s %15s\n","First Frame","Last Frame","No of Pts")
   printf("#S %15d %15d %15d\n",fch,lch,PS_NOPTS)
   data_dump(g,0,0,1,"%8")
   close(filen); ont

   printf("%d datapoints written to %s\n",PS_NOPTS,filen)
}
'

##
# DldPlot1
##
#%IU%
#%MDESC%
def dld_plot1 '

   if (PLOT_MODE&128) {
       plot_cntl(sprintf("colors=%s",splot_col))
       plot_cntl("open")
   }
   plot_cntl("erase")
   plot_range($4,$5,$6,$7)

   plot_move(0,1,sprintf("DLD Scaler %d ",DLD_SCALER)) 
   plot_move(0,2,"Counts")
   plot_move(0,-1,sprintf("%.8s", "Frame")) 
   {
      _pl_arg $*
      data_plot(pl_g,0,0,pl_x,pl_y)
      plot_move(-50,0,_res1)
      plot_move(-50,1,_res2)
   }

'

##
# DldLoad
##
#%UU% 
#%MDESC%
#        Restores scaler data previously saved with dldsave.
def dldload '
global PS_NOPTS DLD_FILENAME DLD_EXT
{
   local filen g fch lch lea leb lec lwa lwb

   g = DLD_GRP2
   if ($# > 0) {
      DLD_FILENAME="$1"
   } else {
      DLD_FILENAME=getval("Filename to read spectrum",DLD_FILENAME)
   }

   if ($# > 1) {
      DLD_EXT=$2
   } else {
      DLD_EXT=getval("Filename run number",DLD_EXT)
   }

   filen = sprintf("%s_%03d.dld",DLD_FILENAME,DLD_EXT)
   getline(filen,"open")
   for ((line=getline(filen)), ii=0; line != -1; line=getline(filen)) { 
     split(line,ftemp)
     if (ftemp[0]=="") continue
     if (substr(ftemp[0],1,1) == "#") {
         local ident

         ident = substr(ftemp[0],1,2)
         if (ident == "#S") {
              fch = ftemp[1]; lch = ftemp[2]; PS_NOPTS = ftemp[3]
         } else if (ident == "#F") {
                   lea = ftemp[1] ; leb = ftemp[2] ; lec = ftemp[3] ;
                } else if (ident == "#W") {
                            lwa = ftemp[1] ; lwb = ftemp[2]
                       } else continue
     }  else {
        for (jj=0;jj<8;jj++) {
             data_put(g,ii+jj,1,ftemp[jj])
        }
        ii+=8
     }
   }
   PS_NOPTS=ii
   getline(filen,"close")
   data_uop(g,0,g,0,"fill")
   data_uop(g,0,g,0,"add",fch)
   ps_chtoE DLD_GRP2 0 DLD_GRP2 2  
   si_roi_Ech 0
   printf("%d datapoints read from file %s\n",PS_NOPTS,filen)
}
'

##
# DldPrint
##
#%UU%  [xmin xmax [ymin ymax]]
#%MDESC%
#        Sends to the plot the values from 'dldreadsc'.
#        It allows to select a region of the data by specifying min and max
#        values for both axes.
def dldprint '
   #
   # Usage.
   #
   if ($# != 2 && $# != 0 && $# !=4) {
       print "Usage: dldprint "
       print "       dldprint "
       print "       dldprint xmin xmax"
       print "       dldprint xmin xmax ymin ymax"
       exit
   }
   
   #
   # Gets data
   # 
   # Send everything to file cplot.tmp. Another name should be chosen.
   #
   close("/tmp/cplot.tmp")
   unix("rm -f /tmp/cplot.tmp")
   on("/tmp/cplot.tmp"); offt

   #
   # Reset. Erase. Select filter.
   printf("re\n")
   printf("zi %s\n", "psfilter @lp @-dp4bid13")
   printf("zew\n")

   xla  = "Frame"
   yla  = "Counts"
      
   #
   # Give data to cplot.
   #
   printf("gd 1\n")
   if ($# == 0)       # All points
      data_dump(DLD_GRP2,0,0,0,1)
   if ($# == 2 || $# == 4 )
       data_dump(DLD_GRP2,$1,$2-$1+1,0,1)
   printf("^D\n")
   #
   # Set title and labels.
   #
   if ($# == 4)
        printf("ra y %d %d\n",$3,$4);
   printf("tx\n")
   printf("DLD Scaler %d\n",DLD_SCALER)
   if (xla != "0")
       printf("%s",xla)
   printf("\n\n")
   if (yla != "0")
       printf("%s",yla)
   printf("\n\n")
   printf("\n\n")

   #
   # Font, character size, plotting symbol.
   #
   printf("ft 2\n")
   printf("cs s 2\n");
   printf("sy L\n")
   #
   # Date
   #
   printf("zdw\n")
   #
   # Plot all. aXES,pOINTS,lABELS,tITLE.
   #
   printf("zapltw\n")
   #
   # Plot the points again. With different symbol.
   #
   # And close filter.
   #
   printf("sy 0\n")
   printf("zpx\n")

   #
   # If X11. Wait.
   #
   printf("w\n")
   #
   # End. Execute the file.
   #
   printf("ex\n")
   ont;close("/tmp/cplot.tmp")
   unix(sprintf("(cplot -s /tmp/cplot.tmp; rm /tmp/cplot.tmp) 2>&1"))
'

#%MACROS%
#%IMACROS%
#%ATTENTION%
#%PRE%
#   Changes in this macro are foreseen:
#   - To use the scalers as pseudo-counters inside spec.
#   - Two modes of operation, two version of device servers may coexist
#     for a while
#%PRE%
#%DEPENDENCIES%
#   The macro plot2.mac has to be read before this one.
#   The macro Xdld.mac has to be read with this one.
#%AUTHOR% Vicente Rey
#%TOC%