esrf

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

#%TITLE% C111_MHIP1CARD.MAC
#%NAME%
#  Macros to implement TDC on C111 card through device server
#
#%CATEGORY% other hardware
#%SEARCH% tdcsetup
#
#%DESCRIPTION%
#  These macros implement one C111(TDC) device which is exported by the
#  C111 Linux TACO device server. C111 TACO device server controls access
#  to one C111/P111 TDC card designed by Christian Herve. These macros work
#  with the version V1.4 of C111 device server [which in turn uses version
#  v.0.4.8 of the C111 device driver library].
#  These macro set does not cover all possible C111 configurations but is
#  written for the specific configuration which is using C111 in MHIP mode.
#  In this mode up to 4 detectors like for ex. APDs can be connected to
#  channels 0-3 (= inputs X1,X2,Y1,Y1) and common start is connected to
#  COM TDC input.%BR%
#  TDC card is always programmed in Normal mode (test mode has no sense 
#  for MHIP mode).
#
#%EXAMPLE%
#%DL%
#%DT%  tdcversion %DD%
#  (show the version of these macros)
#%DT%  tdcsetup <device> <RPC timeout> %DD%
#  (connect to TDC device and powers up ASIC if necessary)
#%DT%  tdcunsetup %DD%
#  (remove _tdccleanup from cleanup_always)

#%DT%  tdcstate %DD%
#  (state of TDC - idle/running)
#%DT%  tdcstatus <print> %DD%
#  (TDC status; if print flag is on, status is printed)
#%DT%  tdcshow %DD%
#  (shows most essential config/status fields)
#%DT%  tdcnewfile <data_dir> <file_prefix> <run_number>
#  (helps defining new file name for saving data outside scans)
#%DT%  tdcconfig %DD%
#  (reconfig TDC with the values from the db or interactively set)
#%DT%  tdctune %DD%
#  (tune the TDC hardware)
#%DT%  tdcstattimer <enable_disable> <duration> %DD%
#  (independently from tdcconfig can dis/enable statistics timer; if no
#   parameters passed, they are set interactively)
#%DT%  _tdcstatistics %DD%
#  (read statistics data during acq.)
#%DT%  tdcregs %DD%
#  (read value of some C111 registers.)

#%DT%  tdcsetacqbank <bank_id> %DD%
#  (independently from tdcconfig can select bank to be used for acquisition;
#   if no parameter passed the acq bank is set interactively)
#%DT%  tdcswapbanks %DD%
#  (swap the 2 memory banks)
#%DT%  tdcinitbank <start_value> <increment_flag> %DD%
#  (init bank that was selected for acq.; if no parameters passed the init
#   parameters: start_value + increment_flag are set interactively)
#%DT%  tdcinitbanks <start_value> <increment_flag> %DD%
#  (init both banks; if no parameters passed the init parameters:
#   start_value + increment_flag are set interactively)
#%DT%  tdcreadbank %DD%
#  (read one bank -> the one that is not selected for acquisition)
#%DT%  tdcreadbanks %DD%
#  (read both banks)
#%DT%  tdcsum1b %DD%
#  (get histogram sum in bank that is not selected for acq)
#%DT%  tdcsum2b %DD%
#  (get histogram sum in both banks)
#%DT%  tdcdata %DD%
#  (get sum of hits in all 4 histograms, max and digitized chan. at max)

#%DT%  tdcpower <up/down> %DD%
#  (power ASIC up or down)
#%DT%  tdcstart <n> %DD%
#  (trigger the acquisition on TDC for n seconds (n=0 or if no parameter
#   is passed then acq. is started for "infinite" time)
#%DT%  tdcstop %DD%
#  (stop the acquisition on TDC)
#%DT%  tdcpoll <refresh_period> <read_data_for_display> %DD%
#  (for finite-time acquisition it polls the state of TDC every 
#   refresh_period seconds to see when the acq. is over. It also
#   reads data for display if the seconds flag is on; if no parameters
#   are passed, then the poll period is 3 seconds and data are read for display)
#%DT%  tdcacq <n> <donotclearflag>%DD%
#  (make finite-time acquisition for n seconds; if second argument is passed,
#   then the memory is not cleared and data from the new acquisition are
#   cumulated with the data from the previous acq.)
#%DT%  tdcstatacq <n> %DD%
#  (make acq. in order to get statistics info; stat timer duration = n secs;
#   acq. stops quickly after stat.timer expiration)
#%DT%  tdcsave %DD%
#  (save data to 4 files (1 per TDC input channel) in MCA-like format
#   -> to be used outside counting and scans)
#%DT%  tdcsave_padi ot tdcsave_jadi %DD%
#  (save data to 1 file in format for padi/jadi visualization programs

#%DT%  tdcon %DD%
#  (switch on TDC acq. in ct and scan)
#%DT%  tdcoff %DD%
#  (switch off TDC acq. in ct and scan)

#%DT%  tdcroishow %DD%
#  (show the ROI(s) definitions)
#%DT%  tdcroi <mnemonic> <chan_min> <chan_max> %DD%
#  (add or modify an ROI)
#%DT%  tdcroimenu %DD%
#  (interactively add/remove/modify an ROI)
#%DT%  tdcroion %DD%
#  (activate use of ROI counters)
#%DT%  tdcroioff %DD%
#  (cancel use of ROI counters)

#%DT%  tdcsplotrange <xmin> <xmax> %DD%
#  (define the limit TDC digitized channels for plotting; if no parameters
#   passed, the TDC_PLOTMIN = 0 and TDC_PLOTMAX = TDC_NBCOLS-1)
#%DT%  tdcplot %DD%
#  (plots the data for all 4 channels on the same plot (superposed))
#%DT%  tdcplot0,1,2,3 %DD%
#  (plots the data for one of 4 channels)
#%DT%  tdctolin/log DD%
#  (changes Y-scale to linear/to logarithmic)



#============================================================
#
# Initialization/Setup related macros and functions 
#
#============================================================
#
#
#-------------------------- _tdcvarinit() ---------------------
#%IU%
#%MDESC%
#  Internal macro to declare global variables and initialise some.
#
def _tdcvarinit() '{

    global TDC_VERSION     # version of these macros

    global TDC_DEV         # name of C111 device (ex. ID10B/C111/01)
    global TDC_RPCTIMEOUT  # RPC timeout for esrf_io() calls

    # State, Status, Configuration related
    global TDC_STATE       # TDC state string (idle/running)
    global TDC_STATUS      # complete status array of TDC device
    global TDC_CONFIG      # configuration array of TDC device(subset of status)
    global TDC_STA_STR     # String array for status array fields (in total 34)
                           # of which first 14 (until and including acq_bank)
                           # are configuration array fields

    # Configuration/Status fields in detail:
    global TDC_DEBUGFL     # debug flag used in device server(1=debug on)
    global TDC_BOOT_CONFIG # FGPA boot config = mode select:0=GFD/1=MHIT/2=MHIP
                           # for MHIP should be 2
    global TDC_MODE_TYPE   # mode type (0=normal/1=test); for MHIP should be 0
    global TDC_TIMEOUT     # timeout in ns
    global TDC_SKIP        # skip flag - only for MHIT
                           # set to 0 (ignored) for MHIP
    global TDC_EXTINHFC    # ext. inhibit(0)/fast clear(1) flag - only for GFD
                           # always 0 (ignored) for MHIP
    global TDC_OFFSET_X    # X offset in ns - set to 0 for MHIP mode (ignored)
    global TDC_OFFSET_Y    # Y offset in ns - set to 0 for MHIP mode (ignored)
    global TDC_PILEUP_X    # X pileup = set to 0 for MHIP (ignored)
    global TDC_PILEUP_Y    # Y pileup = set to 0 for MHIP (ignored)
    global TDC_HALF_RES    # half resolution flag (0=full resol/1=half resol);
                           # set to 0 for MHIP (ignored)
    global TDC_FP_MONITOR  # front pannel signal for monitoring 0 = gate
    global TDC_MUX_SEL     # ASIC signal for monitoring (not important if gate)
    global TDC_STAT_TIMER  # statistics timer enable(1)/disable(0) flag
    global TDC_DURATION    # statistics timer duration in seconds
    global TDC_ACQ_BANK    # index of bank selected for acq (= bank on port M)
                           # normally would start with bank 0 
    # 2 more status fields in detail:
    global TDC_NBROWS      # nb of rows (Y) for data in memory = 1 for MHIP 
    global TDC_NBCOLS      # nb of columns (X) for data in memory: 16384

    # String array for Status array fields
    TDC_STA_STR[0] ="0/1 = server dbg flag off(0)/on(1)"
    TDC_STA_STR[1] ="Boot config (0=GFD/1=MHIT/2=MHIP) "
    TDC_STA_STR[2] ="Mode type (0=normal/1=test)       "
    TDC_STA_STR[3] ="Timeout value (ns)                "
    TDC_STA_STR[4] ="Skip (= no skip)     flag         "
    TDC_STA_STR[5] ="ExtInh(0)/FastClr(1) flag         "
    TDC_STA_STR[6] ="X offset value (ns)               "
    TDC_STA_STR[7] ="Y offset value (ns)               "
    TDC_STA_STR[8] ="X pileup disabled(0)/enabled(1)   "
    TDC_STA_STR[9] ="Y pileup disabled(0)/enabled(1)   "
    TDC_STA_STR[10] ="Half resolution(0=full/1=half)    "
    TDC_STA_STR[11] ="front pannel monitor              "
    TDC_STA_STR[12]="ASIC f.p. mon(0=MSB cntr/1=MASK4) "
    TDC_STA_STR[13]="Stat.timer disabled(0)/enabled(1) "
    TDC_STA_STR[14]="Stat.timer duration (s)           "
    TDC_STA_STR[15]="Bank selected for acquisition     "
    TDC_STA_STR[16]="Max Nb of Rows for data in memory "
    TDC_STA_STR[17]="Max Nb of Cols for data in memory "
    TDC_STA_STR[18]="CUB Low Voltage 1.8V (1=OK)       "
    TDC_STA_STR[19]="CUB Low Voltage 2.5V (1=OK)       "
    TDC_STA_STR[20]="CUB Low Voltage 3.3V (1=OK)       "
    TDC_STA_STR[21]="CUB Low Voltage  5V  (1=OK)       "
    TDC_STA_STR[22]="CUB Low Voltage +12V (1=OK)       "
    TDC_STA_STR[23]="CUB Low Voltage -12V (1=OK)       "
    TDC_STA_STR[24]="CUB All Low Voltages (1=OK)       "
    TDC_STA_STR[25]="33 Mhz PLL Lock (1=OK)            "
    TDC_STA_STR[26]="TDC Clock PLL Lock (1=OK)         "
    TDC_STA_STR[27]="CUB serial number                 "
    TDC_STA_STR[28]="TDC mode acknowledge              "
    TDC_STA_STR[29]="TDC ASIC power (1=UP)             "
    TDC_STA_STR[30]="TDC ASIC PLL Lock (1=OK)          "
    TDC_STA_STR[31]="TDC State (0=Idle/1=Running)      "
    TDC_STA_STR[32]="Nb of Interr. at stat timer expir."
    TDC_STA_STR[33]="Nb of Interr. at stat regs OVFlow "
    TDC_STA_STR[34]="Nb of Interr. at soft timer expir."
    TDC_STA_STR[35]="Driver signal number              "

    # Plotting Related
    global TDC_PLOTMIN     # minimal digitized channel index for spec std plot
    global TDC_PLOTMAX     # maximal digitized channel index for spec std plot 

    # Counting + Scanning Related
    global TDC_ON          # flag to indicate if TDC acquisition is done(1) or
                           # not(0) at each scan point

    # ROI Pseudo-counters Related
    global TDC_ROI[]       # assoc. array with 2 fields for each pseudo-cntr:
                           # TDC_ROI[countermnemonic]["min"]
                           # TDC_ROI[countermnemonic]["max"]
    global TDC_USINGROI    # flag telling if ROI pseudo-counters are used(1) 
                           # in counting/scanning or not(0)
    global TDC_SAVEONLYROI # flag if 1 will tell to save only ROI counters in
                           # standard SPEC file.

    # data saving related
    # - data acquired at each scan point are saved in file DATAFILE, when it
    #   is not /dev/null. The DATAFILE is defined by running macro newfile
    # - data acquired outside scan (with tdcacq macro for ex.) can be saved in
    #   a simple ASCII file which name is composed by concatenating
    #   TDC_DATA_DIR and TDC_FILE_PREFIX.
    #   These fields are defined by running macro tdcnewfile
    global TDC_DATA_DIR
    global TDC_FILE_OLD_PREFIX
    global TDC_FILE_PREFIX
    global TDC_RUN_NUMBER
    global TDC_SAVE         # flag to indicate if save(1) or not(0) the TDC
                            # data for the acquisitions OUTSIDE scan
    global TDC_SAVE_BOTH    # flag to indicate if for acquisition OUTSIDE scan
                            # save spectra only in 4 MCA-like files(0) or
                            # should save data in addition in PADI-like file(1)

    # be generous
    TDC_RPCTIMEOUT = 15

}'


#------------- _tdccleanup ------------------------------
#%IU%
#%MDESC%
#  Macro executed at cleanup(CTRL-C)
#
def _tdccleanup '{
    local tostop

    # If C111 is running stop it if user wants so
 
    TDC_STATE=esrf_io(TDC_DEV,"DevC111GetStateString")
    tostop = 0
    if (index(TDC_STATE,"RUNNING") != 0) {
      printf("The C111 TDC is running\n")
      tostop = yesno("Do you want to stop it",0)
    }
    if (tostop == 1) tdcstop

}'


#-------------------------- tdcversion -----------------------
#%UU%
#%MDESC%
#  Prints out the version of this software
#
def tdcversion '{
    TDC_VERSION = "MHIP 1 C111 CARD FS April 2005 "
    tty_cntl("md")
    print (sprintf("  TdcVersion %s\n",TDC_VERSION));
    tty_cntl("me")
}'


#-------------------------- tdcsetup -----------------------
#%UU%
#%MDESC%
#  This macro should normally be invoked at spec session start 
#  after C111 macro set was loaded.
#  Connects to TDC device and sets RPC timeout.
#
# Usage: tdcsetup <device> <RPC_timeout>
#
def tdcsetup '{
    local sowhat

    _tdcvarinit()

    tdcversion

    if ($# == 0) {
        printf("Current parameters for TDC setup\n\n")
        printf("Tdc device  = %s\n",TDC_DEV)
        printf("RPC timeout = %d seconds \n", TDC_RPCTIMEOUT)
        sowhat = yesno("\nDo you want to change setup values",0)
        if (sowhat) {
            printf("Enter new parameters:\n")
            TDC_DEV=getval(" TDC Device name ",TDC_DEV)
            TDC_RPCTIMEOUT=getval(" New RPC timeout value (sec)",TDC_RPCTIMEOUT)
        }
    } else if ($# == 1) {
        TDC_DEV = "$1"
        printf("RPC timeout = %d seconds \n", TDC_RPCTIMEOUT)
        sowhat = yesno("\nDo you want to change it",0)
        if (sowhat) {
            TDC_RPCTIMEOUT=getval(" New RPC timeout value (sec)",TDC_RPCTIMEOUT)
        }
    } else if ($# == 2) {
        TDC_DEV = "$1"
        TDC_RPCTIMEOUT = $2
    } else {
        printf("Usage: tdcsetup <C111 device> <RPC timeout>\n")
        exit
    } 
    if (TDC_RPCTIMEOUT < 3) TDC_RPCTIMEOUT = 3

    timeout=esrf_io(TDC_DEV,"timeout",TDC_RPCTIMEOUT)
    esrf_io(TDC_DEV,"tcp")

    #
    # read current status
    #
    tdcstatus 1                 # do not print the status fields 

    _tdccheckconfig

    # Power up ASIC AMS111 if not powered up
    # N.B. Could also drop this test here and put ASIC power ON at the 
    #      end of tdcconfig or until tdcstart.
    #
    if (TDC_STATUS[29] == 0) {
        if (esrf_io(TDC_DEV,"DevC111PowerUpDn",1) < 0) {
            printf("tdcsetup: Error powering up the C111 ASIC. Giving up\n")
            printf("tdcsetup: Fix dev. server resources and restart server\n")
            exit
        }
    }

    # show only most essential fields
    tdcshow

    cdef("cleanup_always","_tdccleanup; ","tdcset")

}'


#-------------------------- tdcunsetup -----------------------
#%UU%
#%MDESC%
#  Deletes tdc part in cleanup_always
#
def tdcunsetup '{

  cdef("","","tdcset","delete")

}'
#------------------------------------------------------------
# END of macros related to initialization/setup
#------------------------------------------------------------




#============================================================
#
# State/Status/Configuration/Statistics related macros
#
#============================================================
#
#
#------------------------- tdcstate ---------------------------------
#UU%
#%MDESC%
#  Get and show the state of TDC device
#  For brevity did not name this macro tdcgetstate but tdcstate
#
def tdcstate '{

    TDC_STATE=esrf_io(TDC_DEV,"DevC111GetStateString")
    printf("%s\n",TDC_STATE)

}'


#-------------------------- _tdcgetconfig ---------------------------
#%IU%
#%MDESC%
#  Get TDC configuration parameters (less than full status)
#
def _tdcgetconfig '{

    if (esrf_io(TDC_DEV,"DevC111GetConfig",TDC_CONFIG) < 0) {
        printf("tdcgetconfig: Error reading Tdc configuration. Giving up\n")
        exit
    }
    TDC_DEBUGFL     = TDC_CONFIG[0]
    TDC_BOOT_CONFIG = TDC_CONFIG[1]
    TDC_MODE_TYPE   = TDC_CONFIG[2]
    TDC_TIMEOUT     = TDC_CONFIG[3]
    TDC_SKIP        = TDC_CONFIG[4]
    TDC_EXTINHFC    = TDC_CONFIG[5]
    TDC_OFFSET_X    = TDC_CONFIG[6]
    TDC_OFFSET_Y    = TDC_CONFIG[7]
    TDC_PILEUP_X    = TDC_CONFIG[8]
    TDC_PILEUP_Y    = TDC_CONFIG[9]
    TDC_HALF_RES    = TDC_CONFIG[10]
    TDC_FP_MONITOR  = TDC_CONFIG[11]
    TDC_MUX_SEL     = TDC_CONFIG[12]
    TDC_STAT_TIMER  = TDC_CONFIG[13]
    TDC_DURATION    = TDC_CONFIG[14]
    TDC_ACQ_BANK    = TDC_CONFIG[15]

}'


#-------------------------- tdcstatus -----------------------
#%UU%
#%MDESC%
#  Gives full status information for C111.
#  For brevity did not name this macro tdcgetstatus but tdcstatus
#
def tdcstatus '{

    if (esrf_io(TDC_DEV,"DevC111GetStatus",TDC_STATUS) < 0) {
        printf("Error reading C111 status\n")
        exit
    }

    if ($# == 0) { # show status
        for (i = 0; i < 36; i++) {
            printf("%s = %d\n", TDC_STA_STR[i],TDC_STATUS[i])
        }
    }

    TDC_DEBUGFL     = TDC_STATUS[0]
    TDC_BOOT_CONFIG = TDC_STATUS[1]
    TDC_MODE_TYPE   = TDC_STATUS[2]
    TDC_TIMEOUT     = TDC_STATUS[3]
    TDC_SKIP        = TDC_STATUS[4]
    TDC_EXTINHFC    = TDC_STATUS[5]
    TDC_OFFSET_X    = TDC_STATUS[6]
    TDC_OFFSET_Y    = TDC_STATUS[7]
    TDC_PILEUP_X    = TDC_STATUS[8]
    TDC_PILEUP_Y    = TDC_STATUS[9]
    TDC_HALF_RES    = TDC_STATUS[10]
    TDC_FP_MONITOR  = TDC_STATUS[11]
    TDC_MUX_SEL     = TDC_STATUS[12]
    TDC_STAT_TIMER  = TDC_STATUS[13]
    TDC_DURATION    = TDC_STATUS[14]
    TDC_ACQ_BANK    = TDC_STATUS[15]
    TDC_NBROWS      = TDC_STATUS[16]
    TDC_NBCOLS      = TDC_STATUS[17]

    # TODO: could check here that acq. was requested in counting and 
    #       scanning, but makes sense to define these arrays independently
    #       of this since might want to do simply TDC acquisition outside
    #       scan. Moreover this macro is invoked already in tdcsetup,
    #       where we do not know whether TDC acq. will be selected in
    #       counting and scanning.

    # prepare limits and arrays for plotting
    if (whatis("TDC_PLOTMIN")&0x8000000) {
        # if TDC_PLOTMIN defined as global but not set/initialized
        TDC_PLOTMIN = 0
    }
    if (TDC_PLOTMIN >= TDC_NBCOLS-1) {
        # this is possible when passing from FULL to 1/2 resolution
        # and if user selected TDC_PLOTMIN to be > 2047 with the
        # tdcsplotrange macro !!
        TDC_PLOTMIN = 0
    }
    if (whatis("TDC_PLOTMAX")&0x8000000) {    
        # if TDC_PLOTMAX defined as global but not set/initialized
        TDC_PLOTMAX = TDC_NBCOLS-1
    } else {
        if (TDC_PLOTMAX >= TDC_NBCOLS-1) TDC_PLOTMAX = TDC_NBCOLS-1
    }
###    } else if (TDC_PLOTMAX > TDC_NBCOLS-1) {
###        TDC_PLOTMAX = TDC_NBCOLS-1
###    }
    shared ulong array tdc_data0[TDC_NBCOLS][1]
    shared ulong array tdc_data1[TDC_NBCOLS][1]
    shared ulong array tdc_data2[TDC_NBCOLS][1]
    shared ulong array tdc_data3[TDC_NBCOLS][1]
    shared ulong array tdc_xdata[TDC_NBCOLS][1]
    array_op("fill", tdc_xdata)
}' 


#-------------------------- tdcshow ---------------------------
#%UU%
#%MDESC%
#  Show main TDC config/status parameters
#
def tdcshow '{

    tty_cntl("md")
    printf("\n  Main TDC configuration parameters\n\n")
    printf("  Device name:\n")
    tty_cntl("me")
    printf("    - Tdc :  %s\n",TDC_DEV)

    # Boot Configuration (should be 1 = MHIT)
    tty_cntl("md")
    printf("\n  Boot Configuration (0=GFD/1=MHIT/2=MHIP): ")
    tty_cntl("me")
    printf(" %d\n",TDC_BOOT_CONFIG)

    # Operation Mode Type (should be 0 = Normal)
    tty_cntl("md")
    printf("\n  Operation Mode Type (0=Normal/1=Test): ")
    tty_cntl("me")
    printf(" %d\n",TDC_MODE_TYPE)

    tty_cntl("md")
    printf("\n  Timeout(ns):")
    tty_cntl("me")
    printf(" %d\n",TDC_TIMEOUT)


    if (TDC_BOOT_CONFIG == 0) {
        # Show offsets, pileups and half resolution only for GFD mode
        tty_cntl("md")
        printf("\n  ExtInh/FastClr:")
        tty_cntl("me")
        printf(" %d\n",TDC_EXTINHFC)
        tty_cntl("md")
        printf("\n  X offset(ns):")
        tty_cntl("me")
        printf(" %d\n",TDC_OFFSET_X)
        tty_cntl("md")
        printf("\n  Y offset(ns):")
        tty_cntl("me")
        printf(" %d\n",TDC_OFFSET_Y)
        tty_cntl("md")
        printf("\n  X pileup:")
        tty_cntl("me")
        printf(" %d\n",TDC_PILEUP_X)
        tty_cntl("md")
        printf("\n  Y pileup:")
        tty_cntl("me")
        printf(" %d\n",TDC_PILEUP_Y)
        tty_cntl("md")
        printf("\n  Half resolution(0 = full):")
        tty_cntl("me")
        printf(" %d\n",TDC_HALF_RES)
    } else if (TDC_BOOT_CONFIG == 1) {
        # Show skip flag only for MHIT mode
        tty_cntl("md")
        printf("\n  Skip flag (0 = no skip):")
        tty_cntl("me")
        printf(" %d\n",TDC_SKIP)
    } else {
        # Nothing extra to show for MHIP mode
    }

    tty_cntl("md")
    printf("\n  Signal for monitoring on front pannel:")
    tty_cntl("me")
    printf(" %d\n",TDC_FP_MONITOR)
    if (TDC_FP_MONITOR == 3) {
        tty_cntl("md")
        printf("\n  ASIC monitoring signal on front pannel:")
        tty_cntl("me")
        printf(" %d\n",TDC_MUX_SEL)
    }

    tty_cntl("md")
    printf("\n  Statistics timer enable:")
    tty_cntl("me")
    printf(" %d\n",TDC_STAT_TIMER)
    if (TDC_STAT_TIMER == 1) {
        tty_cntl("md")
        printf("\n  Statistics timer duration:")
        tty_cntl("me")
        printf(" %d\n",TDC_DURATION)
    }

    tty_cntl("md")
    printf("\n  Bank selected for acquisition:")
    tty_cntl("me")
    printf(" %d\n",TDC_ACQ_BANK)

    # up to here are fields that are obtained with _tdcgetconfig and
    # tdcstatus(=get status) but next 2 + many others are obtained
    # only with tdcstatus
    tty_cntl("md")
    printf("\n  Number of rows    for data in memory:")
    tty_cntl("me")
    printf(" %d\n",TDC_NBROWS)
    tty_cntl("md")
    printf("\n  Number of columns for data in memory:")
    tty_cntl("me")
    printf(" %d\n",TDC_NBCOLS)

    printf(" \n")

}'


#-------------------------- _tdccheckconfig -----------------------
#%UU%
#%MDESC%
#  Checks that the configuration corresponds to GFD 1D case
#
def _tdccheckconfig '{

    #
    # Check that Mode Select(FPGA boot config) is MHIP 
    # [this should be OK in device server resources!!]
    #
    if (TDC_BOOT_CONFIG != 2) {
        printf("_tdccheckconfig: The mode select is not MHIP. Giving up\n")
        printf("_tdccheckconfig: Fix dev. server resources + restart server\n")
        exit
    }
    #
    # Check that Mode Type is normal
    # [this should be OK in device server resources!!]
    #
    if (TDC_MODE_TYPE != 0) {
        printf("_tdccheckconfig: The mode type is not normal. Giving up\n")
        printf("_tdccheckconfig: Fix dev. server resources + restart server\n")
        exit
    }
    #
    # Dont have to check: TDC_EXTINHFC, TDC_OFFSET_X, TDC_OFFSET_Y,
    # TDC_PILEUP_X, TDC_PILEUP_Y, TDC_HALF_RES, since all these are
    # set to 0 and ignored in server. 

}'


#---------------------- tdcnewfile --------------------------
#%UU% [<data-directory> <file-prefix> <run-number>]
#%MDESC%
# Choose a new directory, file prefix and run/series number for data files
# when data are saved outside counting and scanning.
# If the run number is not passed as argument or if the file prefix is changed,
# the run number is reset to 0.
# This macro can be used at any moment to change data directory and/or
# file prefix as defined before in tdcsetup or tdcctscan.
#
# Usage: tdcnewfile <data-directory> <file-prefix> <run-number>
#
def tdcnewfile '{
    local filename

    if (TDC_DATA_DIR == "") TDC_DATA_DIR="/tmp"
    if (TDC_FILE_OLD_PREFIX == "") TDC_FILE_OLD_PREFIX="tst"

    if ($# == 0) {
        TDC_DATA_DIR   = getval("Directory for TDC data",TDC_DATA_DIR)
        TDC_FILE_PREFIX= getval("Prefix for data files",TDC_FILE_OLD_PREFIX)
        if (TDC_FILE_PREFIX != TDC_FILE_OLD_PREFIX) {
            TDC_RUN_NUMBER = 0
        } else {
            TDC_RUN_NUMBER = getval("Series/Run number", TDC_RUN_NUMBER)
        }
    } else if ($# == 1) {
        TDC_DATA_DIR   = "$1"
        TDC_FILE_PREFIX= getval("Prefix for data files",TDC_FILE_OLD_PREFIX)
        if (TDC_FILE_PREFIX != TDC_FILE_OLD_PREFIX) {
            TDC_RUN_NUMBER = 0
        } else {
            TDC_RUN_NUMBER = getval("Series/Run number", TDC_RUN_NUMBER)
        }
    } else if ($# == 2) {
        TDC_DATA_DIR    = "$1"
        TDC_FILE_PREFIX = "$2"
        if (TDC_FILE_PREFIX != TDC_FILE_OLD_PREFIX) {
            TDC_RUN_NUMBER = 0
        } else {
            TDC_RUN_NUMBER = getval("Series/Run number", TDC_RUN_NUMBER)
        }
    } else if ($# == 3) {
        TDC_DATA_DIR    = "$2"
        TDC_FILE_PREFIX = "$1"
        TDC_RUN_NUMBER  = $3
    } else if ($# > 3) {
        printf("Usage: tdcnewfile <data-directory> <file-prefix> <run-number>\n")
        exit
    }

    printf("TDC_DATA_DIR = %s\n", TDC_DATA_DIR)
    printf("TDC_FILE_OLD_PREFIX = %s\n", TDC_FILE_OLD_PREFIX)
    printf("TDC_FILE_PREFIX = %s\n", TDC_FILE_PREFIX)
    printf("TDC_RUN_NUMBER = %d\n", TDC_RUN_NUMBER)

    TDC_FILE_OLD_PREFIX = TDC_FILE_PREFIX
}'


#-------------- tdcconfig ------------------------
#%UU%
#%MDESC%
#  Configure C111 TDC either with:
#  - values from the database
#  - or with interactively entered parameters.
#  For brevity did not name this macro tdcsetconfig but tdcconfig
#
def tdcconfig '{
    local fromdb
    local tosave saveboth
 
    fromdb = yesno("Want to reconfigure TDC with values from DataBase ",0)
    if (fromdb) {
        _tdcreconfig
    } else {
        # reconfiguration with interactively entered parameters
        _tdcsetconfig
    }
    # show complete status
    tdcstatus

    # ask user if wants to do TDC acq. during counting and scanning
    # inside _tdcctscan ask if want to define ROIs.
    _tdcctscan

    # ask user if want to save data for acquisitions outside scan
    # (for ex. when doing tdcacq or manually running the sequence
    # tdcstart, tdcstop, tdcreadbanks, tdcsave)
    tosave = yesno("Want to save data in acq. outside ct+scan ",0)
    if (tosave) {
	TDC_SAVE = 1
        saveboth = yesno("Want to save both in MCA-like and PADI files ",0)
        if (saveboth) {
            TDC_SAVE_BOTH = 1
        } else {
            TDC_SAVE_BOTH = 0
        }
	#TDC_DATA_DIR = getval("Directory for data ",TDC_DATA_DIR)
	#TDC_FILE_PREFIX = getval("Prefix for data file ",TDC_FILE_PREFIX)
	#TDC_RUN_NUMBER = getval("RUN/Serial number ",TDC_RUN_NUMBER)
        tdcnewfile
    } else {
        TDC_SAVE = 0
        TDC_SAVE_BOTH = 0
    }  
    # Power up ASIC AMS111 if not powered up
    #       N.B. Could postpone this test until tdcstart.
    #
    if (TDC_STATUS[29] == 0) {
        if (esrf_io(TDC_DEV,"DevC111PowerUpDn",1) < 0) {
            printf("tdcconfig: Error powering up the C111 ASIC. Giving up\n")
            printf("tdcconfig: Fix dev. server resources and restart server\n")
            exit
        }
    }

}'


#-------------- _tdcreconfig ------------------------
#%IU%
#%MDESC%
#  ReConfigure C111 TDC with values FROM the DATABASE.
#
def _tdcreconfig '{

    if (esrf_io(TDC_DEV,"DevC111ReConfigFromDB",TDC_STATUS) < 0) {
        printf("tdcreconfig: Error reconfig Tdc. Giving up\n")
        exit
    }
    # check the configuration to be sure it correponds to 
    # MHIP Normal mode!!
    _tdccheckconfig 

}'


#-------------- _tdcsetconfig ------------------------
#%IU%
#%MDESC%
#  ReConfigure C111 with values entered interactively 
#
def _tdcsetconfig '{
    local stattimon

    # get current values before asking for new ones
    _tdcgetconfig
    # enter parameters interactively
    TDC_DEBUGFL=getval("Device server debug flag",TDC_DEBUGFL)
    TDC_BOOT_CONFIG = 2  # should be MHIP 
    TDC_MODE_TYPE = 0    # should be Normal mode
    TDC_TIMEOUT = getval("Timeout (in ns)",TDC_TIMEOUT)
    TDC_SKIP = 0         # set to 0 - ignored for MHIP
    TDC_EXTINHFC = 0     # set to 0 - ignored for MHIP
    TDC_PILEUP_X = 0     # set to 0 - ignored for MHIP
    TDC_PILEUP_Y = 0     # set to 0 - ignored for MHIP
    TDC_OFFSET_X = 0     # set to 0 - ignored for MHIP
    TDC_OFFSET_Y = 0     # set to 0 - ignored for MHIP
    TDC_HALF_RES = 0     # set to 0 - ignored for MHIP
    printf("Possible values for front pannel monitor:\n")
    printf("\t 0 = gate\n\t 1 = clear error\n\t 2 = ALU overflow\n\t 3 = AMS111(ASIC)monitor\n")
    TDC_FP_MONITOR = getval("Signal for front pannel monitor[0-3]",TDC_FP_MONITOR)
    if (TDC_FP_MONITOR == 3) {
        TDC_MUX_SEL = getval("ASIC monitor(0=MSB cntr/1=MASK4)",TDC_MUX_SEL)
    } else {
        TDC_MUX_SEL = 0
    }
    stattimon = yesno("Want to enable statistics timer ",0)
    if (stattimon) {
        TDC_STAT_TIMER = 1
        TDC_DURATION=getval("Stat.timer duration(sec) ",TDC_DURATION)
    } else {
        TDC_STAT_TIMER = 0
        TDC_DURATION=0
    }
    TDC_ACQ_BANK=getval("Select bank for acquisition ",TDC_ACQ_BANK)
    TDC_CONFIG[0]  = TDC_DEBUGFL
    TDC_CONFIG[1]  = TDC_BOOT_CONFIG
    TDC_CONFIG[2]  = TDC_MODE_TYPE
    TDC_CONFIG[3]  = TDC_TIMEOUT
    TDC_CONFIG[4]  = TDC_SKIP
    TDC_CONFIG[5]  = TDC_EXTINHFC
    TDC_CONFIG[6]  = TDC_OFFSET_X
    TDC_CONFIG[7]  = TDC_OFFSET_Y
    TDC_CONFIG[8]  = TDC_PILEUP_X
    TDC_CONFIG[9]  = TDC_PILEUP_Y
    TDC_CONFIG[10]  = TDC_HALF_RES
    TDC_CONFIG[11] = TDC_FP_MONITOR
    TDC_CONFIG[12] = TDC_MUX_SEL
    TDC_CONFIG[13] = TDC_STAT_TIMER
    TDC_CONFIG[14] = TDC_DURATION
    TDC_CONFIG[15] = TDC_ACQ_BANK

    if (esrf_io(TDC_DEV,"DevC111SetConfig",TDC_CONFIG, TDC_STATUS) < 0) {
        printf("tdcsetconfig: Error setting TDC config. Giving up\n")
        exit
    }

}'


#-------------- tdctune ------------------------
#%UU%
#%MDESC%
#  Tune + ReConfigure C111 TDC with few new values; i.e. does not
#  cover all parameters but only few which usually need tunning.
#  The following parameters can be changed:
#    - timeout   : timeout in ns
#    - skip      : Skip flag - set to 0 = ignored for MHIP
#    - extinhfc  : External inhibit(0) or Fast Clear Flag(1) 
#                  Ignored for MHIP = set to 0 (= Ext Inhibit)
#    - offset_x  : X offset in ns - set to 0 = ignored for MHIP
#    - offset_y  : Y offset in ns - set to 0 = ignored for MHIP
#    - half_res  : Half resolution flag - set to 0 = ignored for MHIP
#    - fp_monitor: external signal on front pannel for monitoring
#    - mux_sel   : subselection for ASCI monitor
#
def tdctune '{
    local timo fpmon mux

    global TDC_TUNE_ARGIN

    #
    # read current configuration/status
    #
    # _tdcgetconfig
    tdcstatus 1
    tdcshow

    timo  = TDC_TIMEOUT
    fpmon = TDC_FP_MONITOR
    mux   = TDC_MUX_SEL

    TDC_TIMEOUT=getval("Timeout (in ns)",timo)
    # set the following to 0 since MHIP case
    TDC_SKIP = 0
    TDC_EXTINHFC = 0
    TDC_OFFSET_X = 0
    TDC_OFFSET_Y = 0
    TDC_HALF_RES = 0 

    printf("Possible values for front pannel monitor:\n")
    printf("\t 0 = gate\n\t 1 = clear error\n\t 2 = ALU overflow\n\t 3 = AMS111(ASIC)monitor\n")
    TDC_FP_MONITOR = getval("Signal for front pannel monitor[0-3]",fpmon)
    if (TDC_FP_MONITOR == 3) {
        TDC_MUX_SEL = getval("ASIC monitor(0=MSB cntr/1=MASK4)",mux)
    } else {
        TDC_MUX_SEL = 0
    }

    # change config if new value(s) different from current ones
    if( (timo == TDC_TIMEOUT) && \
        (fpmon == TDC_FP_MONITOR) && \
        (mux == TDC_MUX_SEL) ) {
        unglobal TDC_TUNE_ARGIN
        exit
    }

    # check that the TDC is not running since cannot change its 
    # configuration while running!!
    TDC_STATE=esrf_io(TDC_DEV,"DevC111GetStateString")
    if (index(TDC_STATE,"RUNNING") != 0) {
        printf("The C111 TDC is running, will stop it for tunning\n")
        tdcstop
    }

    TDC_TUNE_ARGIN[0] = TDC_TIMEOUT
    TDC_TUNE_ARGIN[1] = TDC_SKIP
    TDC_TUNE_ARGIN[2] = TDC_EXTINHFC
    TDC_TUNE_ARGIN[3] = TDC_OFFSET_X
    TDC_TUNE_ARGIN[4] = TDC_OFFSET_Y
    TDC_TUNE_ARGIN[5] = TDC_HALF_RES
    TDC_TUNE_ARGIN[6] = TDC_FP_MONITOR
    TDC_TUNE_ARGIN[7] = TDC_MUX_SEL

    if (esrf_io(TDC_DEV,"DevC111Tune",TDC_TUNE_ARGIN,TDC_STATUS) < 0) {
      printf("tdctune: Error tunning Tdc. Giving up\n")
      unglobal TDC_TUNE_ARGIN
      exit
    }

    # show complete status
    tdcstatus

    unglobal TDC_TUNE_ARGIN

    # Power up ASIC AMS111 if not powered up
    #       N.B. Could postpone this test until tdcstart.
    #
    if (TDC_STATUS[29] == 0) {
        if (esrf_io(TDC_DEV,"DevC111PowerUpDn",1) < 0) {
            printf("tdctune: Error powering up the C111 ASIC. Giving up\n")
            printf("tdctune: Fix dev. server resources and restart server\n")
            exit
        }
    }
}'


#-------------- tdcstattimer ------------------------
#%UU%
#%MDESC%
#  Allows to disable or enable statistics timer with certain duration.
#  Statistcs timer disabling/enabling+defining its duration is done
#  among other things in the tdcconfig (= setting config), but this
#  macro can be convenient. It could also use DevC111SetConfig() D.S. command.
#
# Usage: tdcstattimer <enable_disable> <duration>
#
def tdcstattimer '{
    local stattimon
    global TDC_ST_IN

    if ($# == 2) {
        TDC_STAT_TIMER = $1
        TDC_DURATION = $2
    } else {
        stattimon = yesno("Want to enable statistics timer ",0)
        if (stattimon) {
            TDC_STAT_TIMER = 1
            TDC_DURATION=getval("Stat.timer duration(sec) ",TDC_DURATION)
        } else {
            TDC_STAT_TIMER = 0
            TDC_DURATION=0
        }
    }

    TDC_ST_IN[0] = TDC_STAT_TIMER
    TDC_ST_IN[1] = TDC_DURATION

    if (esrf_io(TDC_DEV,"DevC111EnDisStatTimer",TDC_ST_IN,TDC_STATUS) < 0){
        printf("tdcstattimer: Error dis/enable stat.timer. Giving up\n")
        unglobal TDC_ST_IN
        exit
    }

    # show complete status
    #tdcstatus 1

    unglobal TDC_ST_IN

}'


#-------------------------- _tdcstatistics -----------------------
#%IU%
#%MDESC%
#  Gives statistics information for C111
#
def _tdcstatistics '{

    global TDC_STT

    TDC_STT[0] = 0
    while (TDC_STT[0] < TDC_DURATION) {
        if (esrf_io(TDC_DEV,"DevC111GetStatistics",TDC_STT) < 0) {
            printf("tdcstatistics: Error reading C111 statistics\n")
            exit
        } else {
            if ($# == 0) {
                printf("Elapsed time (sec)        = %3.1f\n",TDC_STT[0])
                printf("Nb of hits on chan. 0(X1) = %d\n", TDC_STT[1])
                printf("Nb of hits on chan. 1(X2) = %d\n", TDC_STT[2])
                printf("Nb of hits on chan. 2(Y1) = %d\n", TDC_STT[3])
                printf("Nb of hits on chan. 3(Y2) = %d\n", TDC_STT[4])
    		# next one only meaningfull for MHIT mode
                #printf("Nb of lost hits           = %d\n", TDC_STT[5])
                printf("Nb of common starts       = %d\n", TDC_STT[6])
    		# next 2 are only meaningfull for GFD mode
                #printf("Nb of rejected events     = %d\n", TDC_STT[7])
                #printf("Nb of ALU overflows       = %d\n", TDC_STT[8])
            }
        }
        sleep(1)
    }
    # get statistics one more time
    if (esrf_io(TDC_DEV,"DevC111GetStatistics",TDC_STT) < 0) {
        printf("tdcstatistics: Error reading C111 statistics\n")
        exit
    }
    printf("Elapsed time (sec)        = %3.1f\n", TDC_STT[0])
    printf("Nb of hits on chan. 0(X1) = %d\n", TDC_STT[1])
    printf("Nb of hits on chan. 1(X2) = %d\n", TDC_STT[2])
    printf("Nb of hits on chan. 2(Y1) = %d\n", TDC_STT[3])
    printf("Nb of hits on chan. 3(Y2) = %d\n", TDC_STT[4])
    		# next one only meaningfull for MHIT mode
    #printf("Nb of lost hits           = %d\n", TDC_STT[5])
    printf("Nb of common starts       = %d\n", TDC_STT[6])
    # next 2 are only meaningfull for GFD mode
    #printf("Nb of rejected events     = %d\n", TDC_STT[7])
    #printf("Nb of ALU overflows       = %d\n", TDC_STT[8])

    unglobal TDC_STT
}'


#-------------------------- tdcregs -----------------------
#%IU%
#%MDESC%
#  Read value of some C111 registers
#  (usefull for debugging)
#
def tdcregs '{

    global TDC_REGS

    if (esrf_io(TDC_DEV,"DevC111GetSomeRegs",TDC_REGS) < 0) {
        printf("tdcregs: Error reading some C111 registers\n")
        exit
    }
    printf("CUB Status        reg. = 0x%08x\n", TDC_REGS[0])
    printf("CUB SDRAM clear   reg. = 0x%08x\n", TDC_REGS[1])
    printf("CUB SDRAM start   reg. = 0x%08x\n", TDC_REGS[2])
    printf("CUB SDRAM end     reg. = 0x%08x\n", TDC_REGS[3])
    printf("CUB SDRAM pattern reg. = 0x%08x\n", TDC_REGS[4])
    printf("Config1           reg. = 0x%08x\n", TDC_REGS[5])
    printf("Config2           reg. = 0x%08x\n", TDC_REGS[6])
    printf("Config3           reg. = 0x%08x\n", TDC_REGS[7])
    printf("Config4           reg. = 0x%08x\n", TDC_REGS[8])
    printf("Statistics timer  reg. = 0x%08x\n", TDC_REGS[9])

}'


#-------------- tdcreadreg ------------------------
#%UU%
#%MDESC%
#  Read a register (usefull for debugging)
#  Input:
#    - base adddress reg. index: 0 = AMCC, 1/2 = 1st/2dn group of TDC regs
#    - offs : offset to base
#
def tdcreadreg '{
    local value

    global TDC_RR_ARGIN

    if ($# == 2) {
        TDC_RR_ARGIN[0] = $1
        TDC_RR_ARGIN[1] = $2
    } else {
        TDC_RR_ARGIN[0] = getval("Base addr. reg. index",2)
        printf("Possible base address indeces are: \n")
        printf("0 = AMCC operation registers\n")
        printf("1 = C111 1st register group\n")
        printf("2 = C111 2nd register group\n")

        if (TDC_RR_ARGIN[0] == 0) {
            printf("Offsets of AMCC registers are:\n")

        } else if (TDC_RR_ARGIN[0] == 1) {
            printf("Offsets in 1st C111 reg. group are:\n")

        } else if (TDC_RR_ARGIN[0] == 2) {
            printf("Offsets in 2nd C111 reg. group are:\n")
        } else {
            printf("Bad base address reg. index!!!\n")
            unglobal TDC_RR_ARGIN
            exit
        }
        TDC_RR_ARGIN[1] = getval("Choose offset",0x08)
    }

    if (value = esrf_io(TDC_DEV,"DevC111ReadReg",TDC_RR_ARGIN) < 0) {
      printf("tdcreadreg: Error reading register\n")
      unglobal TDC_RR_ARGIN
      exit
    }
    unglobal TDC_RR_ARGIN

    printf("Register value = 0x%08x\n", value)

}'


#-------------- tdcwritereg ------------------------
#%UU%
#%MDESC%
#  Write a register (usefull for debugging)
#  Input:
#    - base adddress reg. index: 0 = AMCC, 1/2 = 1st/2dn group of TDC regs
#    - offs : offset to base
#    - value : register value 
#
def tdcwritereg '{
    local value

    global TDC_WR_ARGIN

    if ($# == 3) {
        TDC_WR_ARGIN[0] = $1
        TDC_WR_ARGIN[1] = $2
        TDC_WR_ARGIN[2] = $3
    } else {
        TDC_WR_ARGIN[0] = getval("Base addr. reg. index",2)
        printf("Possible base address indeces are: \n")
        printf("0 = AMCC operation registers\n")
        printf("1 = C111 1st register group\n")
        printf("2 = C111 2nd register group\n")

        if (TDC_WR_ARGIN[0] == 0) {
            printf("Offsets of AMCC registers are:\n")

        } else if (TDC_WR_ARGIN[0] == 1) {
            printf("Offsets in 1st C111 reg. group are:\n")

        } else if (TDC_WR_ARGIN[0] == 2) {
            printf("Offsets in 2nd C111 reg. group are:\n")
        } else {
            printf("Bad base address reg. index!!!\n")
            unglobal TDC_WR_ARGIN
            exit
        }
        TDC_WR_ARGIN[1] = getval("Choose offset",0x08)
        TDC_WR_ARGIN[2] = getval("Choose register value",0)
    }

    printf("Base reg. index = %d\n",TDC_WR_ARGIN[0])
    printf("Offset          = 0x%08x\n",TDC_WR_ARGIN[1])
    printf("Value           = 0x%08x\n",TDC_WR_ARGIN[2])

    if (esrf_io(TDC_DEV,"DevC111WriteReg",TDC_WR_ARGIN) < 0) {
        printf("tdcwritereg: Error writing register\n")
        unglobal TDC_WR_ARGIN
        exit
    } 

    unglobal TDC_WR_ARGIN

}'

# Here will not add macros tdcpupon/off like in GFD case, 
# since Pileup is ignored in MHIT mode
#------------------------------------------------------------
# END of macros related to state/status/configuration/statistics
#------------------------------------------------------------




#============================================================
#
# Memory banks related macros
#
#============================================================
#
#
#-------------------------- tdcsetacqbank -----------------------
#%UU%
#%MDESC%
#  Select bank to be used for acquisition. Acq. bank is already selected
#  with tdcconfig, but can be modified with this macro.
#
# Usage: tdcsetacqbank <bank_id>
#
def tdcsetacqbank '{
    local acqbank

    if ($# != 1 && $# != 0 ) {
        printf("Usage: tdcsetacqbank <bank_id>\n")
        exit
    }

    # next one is probably redundant
    tdcstatus 1
    if ($# == 0 ) {
        acq_bank=getval(" Enter bank to be used for acquisition ",TDC_ACQ_BANK)
    } else {
        acq_bank = $1
    }
    if ((acq_bank != 0) && (acq_bank != 1)) {
        printf("Bank index should be 0 or 1\n")
        exit
    }

    if (acq_bank != TDC_ACQ_BANK) {
        # change acq bank, otherwise do nothing
        if (esrf_io(TDC_DEV,"DevC111SetAcqBank",acq_bank) < 0) {
            printf("tdcsetacqbank: Error setting bank for acquisition\n")
            exit
        }
        TDC_ACQ_BANK = acq_bank
    }
}'


#-------------------------- tdcswapbanks -----------------------
#%UU%
#%MDESC%
#  Swap banks
#
def tdcswapbanks '{

    if (esrf_io(TDC_DEV,"DevC111SwapBanks") < 0) {
        printf("tdcswapbanks: Error swapping banks\n")
        exit
    }
    tdcstatus 1

}'


#-------------------------- tdcinitbank -----------------------
#%UU%
#%MDESC%
#  Init bank that is currently selected for acquisition (= bank
#  on port M). Even if user is not using all 4 channels the 
#  memory is cleared for all 4 channels.
#
# Usage: tdcinitbank <start_value> <increment_flag>
#
def tdcinitbank '{
    local startval ans increment
    global TDC_IBANK_ARGIN

    if ($# != 2 && $# !=0 ) {
        printf("Usage: tdcinitbank <start_value> <increment_flag> \n")
        exit
    }

    if ($# == 0) {
        startval = getval(" Memory start value ",0)
        ans      = yesno(" Want to increment from one loc.to next ",0)
        increment = 0
        if (ans) increment = 1
    }
    if ($# == 2) {
        startval  = $1
        increment = $2
    }

    TDC_IBANK_ARGIN[0] = startval
    TDC_IBANK_ARGIN[1] = increment

    if (esrf_io(TDC_DEV,"DevC111InitBank",TDC_IBANK_ARGIN) < 0) {
        printf("tdcinitbank: Error initialising bank selected for acq.\n")
        unglobal TDC_IBANK_ARGIN
        exit
    }
    unglobal TDC_IBANK_ARGIN

}'


#-------------------------- tdcinitbanks_long --------------------
#%UU%
#%MDESC%
#  Init BOTH banks (start with the one which is already on port M
#  = selected for acquisition, then swap them and clear the other)
#  Even if user is not using all 4 channels the memory is cleared
#  for all 4 channels.
#
# Usage: tdcinitbanks_long <start_value> <increment_flag>
#
def tdcinitbanks_long '{
    local startval ans increment
    global TDC_IBANK_ARGIN

    if ($# != 2 && $# !=0 ) {
        printf("Usage: tdcinitbanks_long <start_value> <increment_flag> \n")
        exit
    }

    if ($# == 0) {
        startval = getval(" Memory start value ",0)
        ans      = yesno(" Want to increment from one loc.to next ",0)
        increment = 0
        if (ans) increment = 1
    }
    if ($# == 2) {
        startval  = $1
        increment = $2
    }

    TDC_IBANK_ARGIN[0] = startval
    TDC_IBANK_ARGIN[1] = increment

    if (esrf_io(TDC_DEV,"DevC111InitBank",TDC_IBANK_ARGIN) < 0) {
        printf("tdcinitbanks: Error initialising bank %d\n", TDC_ACQ_BANK)
        unglobal TDC_IBANK_ARGIN
        exit
    }

    if (esrf_io(TDC_DEV,"DevC111SwapBanks") < 0) {
        printf("tdcinitbanks: Error swapping banks\n")
        unglobal TDC_IBANK_ARGIN
        exit
    }
    tdcstatus 1

    if (esrf_io(TDC_DEV,"DevC111InitBank",TDC_IBANK_ARGIN) < 0) {
        printf("tdcinitbanks: Error initialising bank %d\n", TDC_ACQ_BANK)
        unglobal TDC_IBANK_ARGIN
        exit
    }

    unglobal TDC_IBANK_ARGIN

}'


#-------------------------- tdcinitbanks -----------------------
#%UU%
#%MDESC%
#  Init BOTH banks. Similar to macro above, but this time more 
#  "compact" command ["DevC111InitBothBanks"] is used to make macro short.
#
# Usage: tdcinitbanks <start_value> <increment_flag>
#
def tdcinitbanks '{
    local startval ans increment
    global TDC_IBANK_ARGIN

    if ($# != 2 && $# !=0 ) {
        printf("Usage: tdcinitbanks <start_value> <increment_flag> \n")
        exit
    }

    if ($# == 0) {
        startval = getval(" Memory start value ",0)
        ans      = yesno(" Want to increment from one loc.to next ",0)
        increment = 0
        if (ans) increment = 1
    }
    if ($# == 2) {
        startval  = $1
        increment = $2
    }

    TDC_IBANK_ARGIN[0] = startval
    TDC_IBANK_ARGIN[1] = increment

    if (esrf_io(TDC_DEV,"DevC111InitBothBanks",TDC_IBANK_ARGIN) < 0) {
        printf("tdcinitbanks: Error initialising both banks \n")
        # to get TDC_ACQ_BANK
        tdcstatus 1
        unglobal TDC_IBANK_ARGIN
        exit
    }
    unglobal TDC_IBANK_ARGIN

    # to get TDC_ACQ_BANK
    tdcstatus 1

}'


#-------------------------- tdcinitwholebank -----------------------
#%UU%
#%MDESC%
#  Init bank that is currently selected for acquisition (= bank
#  on port M). Complete bank is initialized (= all 128MBytes)
#
# Usage: tdcinitwholebank <start_value> <increment_flag>
#
def tdcinitwholebank '{
    local startval ans increment
    global TDC_IBANK_ARGIN

    if ($# != 2 && $# !=0 ) {
        printf("Usage: tdcinitwholebank <start_value> <increment_flag> \n")
        exit
    }

    if ($# == 0) {
        startval = getval(" Memory start value ",0)
        ans      = yesno(" Want to increment from one loc.to next ",0)
        increment = 0
        if (ans) increment = 1
    }
    if ($# == 2) {
        startval  = $1
        increment = $2
    }

    TDC_IBANK_ARGIN[0] = startval
    TDC_IBANK_ARGIN[1] = increment

    if (esrf_io(TDC_DEV,"DevC111InitWholeBank",TDC_IBANK_ARGIN) < 0) {
        printf("tdcinitwholebank: Error initialising bank selected for acq.\n")
        unglobal TDC_IBANK_ARGIN
        exit
    }
    unglobal TDC_IBANK_ARGIN

}'


#-------------------------- tdcinitwholebanks -----------------------
#%UU%
#%MDESC%
#  Init BOTH banks. Similar to macro above, but this time more 
#  "compact" command ["DevC111InitWholeBanks"] is used to make macro short.
#
# Usage: tdcinitwholebanks <start_value> <increment_flag>
#
def tdcinitwholebanks '{
    local startval ans increment
    global TDC_IBANK_ARGIN

    if ($# != 2 && $# !=0 ) {
        printf("Usage: tdcinitwholebanks <start_value> <increment_flag> \n")
        exit
    }

    if ($# == 0) {
        startval = getval(" Memory start value ",0)
        ans      = yesno(" Want to increment from one loc.to next ",0)
        increment = 0
        if (ans) increment = 1
    }
    if ($# == 2) {
        startval  = $1
        increment = $2
    }

    TDC_IBANK_ARGIN[0] = startval
    TDC_IBANK_ARGIN[1] = increment

    if (esrf_io(TDC_DEV,"DevC111InitWholeBanks",TDC_IBANK_ARGIN) < 0) {
        printf("tdcinitwholebanks: Error initialising both banks \n")
        # to get TDC_ACQ_BANK
        tdcstatus 1
        unglobal TDC_IBANK_ARGIN
        exit
    }
    unglobal TDC_IBANK_ARGIN

    # to get TDC_ACQ_BANK
    tdcstatus 1

}'


#-------------------------- tdcreadbank -----------------------
#%UU%
#%MDESC%
#  Read data from ONE bank. The limits for reading out are 
#  0 and TDC_NBCOLS-1.
#  Read all 4 channels.
#
def tdcreadbank '{
    global TDC_RB_ARGIN

    #tdcstatus 1

    TDC_RB_ARGIN[1] = 0               # start coloumn
    TDC_RB_ARGIN[2] = TDC_NBCOLS-1    # end coloumn
    TDC_RB_ARGIN[3] = 0               # start row
    TDC_RB_ARGIN[4] = 0               # end row
    TDC_RB_ARGIN[5] = 0               # Binning OFF (since in 1D mode) 

    # make a reading into SHM array tdc_data0
    TDC_RB_ARGIN[0] = 0     # channel 0
    esrf_io(TDC_DEV,"tcp")
    if (esrf_io(TDC_DEV,"DevC111ReadBankData",TDC_RB_ARGIN, tdc_data0) < 0) {
        printf("Error reading spectrum %d\n", TDC_RB_ARGIN[0])
        unglobal TDC_RB_ARGIN
        exit
    }
    # make a reading into SHM array tdc_data1
    TDC_RB_ARGIN[0] = 1     # channel 1
    esrf_io(TDC_DEV,"tcp")
    if (esrf_io(TDC_DEV,"DevC111ReadBankData",TDC_RB_ARGIN, tdc_data1) < 0) {
        printf("Error reading spectrum %d\n", TDC_RB_ARGIN[0])
        unglobal TDC_RB_ARGIN
        exit
    }
    # make a reading into SHM array tdc_data2
    TDC_RB_ARGIN[0] = 2     # channel 2
    esrf_io(TDC_DEV,"tcp")
    if (esrf_io(TDC_DEV,"DevC111ReadBankData",TDC_RB_ARGIN, tdc_data2) < 0) {
        printf("Error reading spectrum %d\n", TDC_RB_ARGIN[0])
        unglobal TDC_RB_ARGIN
        exit
    }
    # make a reading into SHM array tdc_data3
    TDC_RB_ARGIN[0] = 3     # channel 3
    esrf_io(TDC_DEV,"tcp")
    if (esrf_io(TDC_DEV,"DevC111ReadBankData",TDC_RB_ARGIN, tdc_data3) < 0) {
        printf("Error reading spectrum %d\n", TDC_RB_ARGIN[0])
        unglobal TDC_RB_ARGIN
        exit
    }

    unglobal TDC_RB_ARGIN
    tdc_data0[0][0] = tdc_data0[0][0]
    tdc_data1[0][0] = tdc_data1[0][0]
    tdc_data2[0][0] = tdc_data2[0][0]
    tdc_data3[0][0] = tdc_data3[0][0]

}'


#-------------------------- tdcreadbanks -----------------------
#%UU%
#%MDESC%
#  Read data from BOTH banks. The limits for reading out are 
#  0 and TDC_NBCOLS-1.
#  Read all 4 channels.
#
def tdcreadbanks '{
    global TDC_RB_ARGIN

    #tdcstatus 1

    TDC_RB_ARGIN[1] = 0               # start coloumn
    TDC_RB_ARGIN[2] = TDC_NBCOLS-1    # end coloumn
    TDC_RB_ARGIN[3] = 0               # start row
    TDC_RB_ARGIN[4] = 0               # end row
    TDC_RB_ARGIN[5] = 0               # Binning OFF (since in 1D mode) 

    # make a reading into SHM array tdc_data0
    TDC_RB_ARGIN[0] = 0     # channel 0
    esrf_io(TDC_DEV,"tcp")
    if (esrf_io(TDC_DEV,"DevC111ReadBothBanks",TDC_RB_ARGIN, tdc_data0) < 0) {
        printf("Error reading spectrum %d\n", TDC_RB_ARGIN[0])
        unglobal TDC_RB_ARGIN
        exit
    }
    TDC_RB_ARGIN[0] = 1     # channel 1
    esrf_io(TDC_DEV,"tcp")
    if (esrf_io(TDC_DEV,"DevC111ReadBothBanks",TDC_RB_ARGIN, tdc_data1) < 0) {
        printf("Error reading spectrum %d\n", TDC_RB_ARGIN[0])
        unglobal TDC_RB_ARGIN
        exit
    }
    TDC_RB_ARGIN[0] = 2     # channel 2
    esrf_io(TDC_DEV,"tcp")
    if (esrf_io(TDC_DEV,"DevC111ReadBothBanks",TDC_RB_ARGIN, tdc_data2) < 0) {
        printf("Error reading spectrum %d\n", TDC_RB_ARGIN[0])
        unglobal TDC_RB_ARGIN
        exit
    }
    TDC_RB_ARGIN[0] = 3     # channel 3
    esrf_io(TDC_DEV,"tcp")
    if (esrf_io(TDC_DEV,"DevC111ReadBothBanks",TDC_RB_ARGIN, tdc_data3) < 0) {
        printf("Error reading spectrum %d\n", TDC_RB_ARGIN[0])
        unglobal TDC_RB_ARGIN
        exit
    }

    unglobal TDC_RB_ARGIN
    tdc_data0[0][0] = tdc_data0[0][0]
    tdc_data1[0][0] = tdc_data1[0][0]
    tdc_data2[0][0] = tdc_data2[0][0]
    tdc_data3[0][0] = tdc_data3[0][0]

}'


#-------------------------- tdcsum1b -----------------------
#%UU%
#%MDESC%
#  Get sum of hits in a histogram(s) from the bank that is not selected
#  for acquisition. Although this set of macros is for MHIP use here
#  general macro (good both for GFD and MHIT/P).
#
def tdcsum1b '{
    local hid sum

    #tdcstatus 1

    # if no arguments will get hist sum for
    # mode GFD 1D/2D: histogram = 0 
    # mode MHIP: all 4 histograms 

    hid = 0
    if (TDC_BOOT_CONFIG == 0) {
        # GFD mode
        esrf_io(TDC_DEV,"tcp")
        sumh = esrf_io(TDC_DEV,"DevC111GetHistSum1Bank",hid)
        if (sumh < 0) {
            printf("Error getting sum of histogram %d in bank %d\n", hid, 1-TDC_ACQ_BANK)
            exit
        } 
        printf("Sum of hits in histogram %d in bank %d is %f\n", hid, 1 - TDC_ACQ_BANK, sumh)
    } else {
        # MHIT or MHIP mode
        esrf_io(TDC_DEV,"tcp")
        for (hid = 0; hid < 4; hid++) { 
            sumh = esrf_io(TDC_DEV,"DevC111GetHistSum1Bank",hid)
            if (sumh < 0) {
                printf("Error getting sum of histogram %d in bank %d\n", hid, 1-TDC_ACQ_BANK)
                exit
            }
            printf("Sum of hits in histogram %d in bank %d is %f\n", hid, 1 - TDC_ACQ_BANK, sumh)
        }
    }
}'


#-------------------------- tdcsum2b -----------------------
#%UU%
#%MDESC%
#  Get sum of hits in a histogram(s) from both banks.
#  Although this set of macros is for MHIP use here
#  general macro (good both for GFD and MHIT/P).
#
def tdcsum2b '{
    local hid sum

    #tdcstatus 1

    # if no arguments will get hist sum for
    # mode GFD 1D/2D: histogram = 0 
    # mode MHIT/P: all 4 histograms 

    hid = 0
    if (TDC_BOOT_CONFIG == 0) {
        # GFD mode
        esrf_io(TDC_DEV,"tcp")
        sumh = esrf_io(TDC_DEV,"DevC111GetHistSum2Banks",hid)
        if (sumh < 0) {
            printf("Error getting sum of histogram %d\n", hid)
            exit
        }
        printf("Sum of hits in histogram %d is %f\n", hid, sumh)
    } else {
        # MHIT/P mode
        esrf_io(TDC_DEV,"tcp")
        for (hid = 0; hid < 4; hid++) { 
            sumh = esrf_io(TDC_DEV,"DevC111GetHistSum2Banks",hid)
            if (sumh < 0) {
                printf("Error getting sum of histogram %d \n", hid)
                exit
            }
            printf("Sum of hits in histogram %d is %f\n", hid, sumh)
        }
    }
}'



#-------------------------- tdcbanksum1b -----------------------
#%UU%
#%MDESC%
#  Get sum of hits in a complete bank for the bank that is
#  not selected for acquisition. 
#  Note that this command takes a lot of time.
#
def tdcbanksum1b '{
    local sum

    #tdcstatus 1
    esrf_io(TDC_DEV,"tcp")
    sum = esrf_io(TDC_DEV,"DevC111GetBankSum1Bank")
    if (sum < 0) {
        printf("Error getting sum of bank %d\n", 1-TDC_ACQ_BANK)
        exit
    } 
    printf("Sum of hits in bank %d is %f\n", 1 - TDC_ACQ_BANK, sum)
}'



#-------------------------- tdcbanksum2b -----------------------
#%UU%
#%MDESC%
#  Get sum of hits in a complete bank for both banks.
#  Note that this command takes a lot of time.
#
def tdcbanksum2b '{
    local sum

    #tdcstatus 1
    esrf_io(TDC_DEV,"tcp")
    sum = esrf_io(TDC_DEV,"DevC111GetBankSum2Banks")
    if (sum < 0) {
        printf("Error getting sum of both banks\n")
        exit
    } 
    printf("Sum of hits in both banks is %f\n", sum)
}'


#-------------------------- tdcdata_old -----------------------
#%UU%
#%MDESC%
#  Useful macro for X-check with tdcsum1b/2b. This macro is summing up
#  contents in tdc_datan(n=0->3) for MHIT and tdc_data for GFD.
#  Although this set of macros is for MHIT use here
#  general macro (good both for GFD and MHIT).
#
def tdcdata_old '{

    #tdcstatus 1
    if (TDC_BOOT_CONFIG == 0) {
        printf("Sum of hits in spectrum 0 = %d\n", array_op("sum",tdc_data))
    } else {
        printf("Sum of hits in spectrum 0 = %d\n", array_op("sum",tdc_data0))
        printf("Sum of hits in spectrum 1 = %d\n", array_op("sum",tdc_data1))
        printf("Sum of hits in spectrum 2 = %d\n", array_op("sum",tdc_data2))
        printf("Sum of hits in spectrum 3 = %d\n", array_op("sum",tdc_data3))
    }
}'


#-------------------------- tdcdata -----------------------
#%UU%
#%MDESC%
#  Useful macro for X-check with tdcsum1b/2b. This macro is summing up
#  contents in tdc_datan(n=0->3) for MHIT and tdc_data for GFD.
#  Although this set of macros is for MHIT use here
#  general macro (good both for GFD and MHIT).
#  Since ROI selected for display and readout can be smaller than
#  whole 2D image area (2K*2K pixels for half-resolution
#                       4K*4K pixels for full-resolution)
#  the sum obtained with this macro can be smaller than sum 
#  obtained with tdcsum1b/2b.
#
#  Added in this macro = getting max value and 
#                        col/row at max value.
#
def tdcdata '{ 
    
    #tdcstatus 1
    if (TDC_BOOT_CONFIG == 0) {
        if (TDC_PILEUP_Y == 0) {
            printf("Sum of hits in spectrum = %d\n", array_op("sum",tdc_data))
            printf("Maximum value is %d at col = %d\n", array_op("max",tdc_data), array_op("row_at_max",tdc_data))
        } else {
            printf("Sum of hits in histogram = %d\n", array_op("sum",tdc_data))
            printf("Maximum value is %d at col = %d, row = %d\n", array_op("max",tdc_data), array_op("row_at_max",tdc_data), array_op("col_at_max",tdc_data))
        }
    } else {
        printf("\n")
        printf("Sum of hits in spectrum 0 = %d\n", array_op("sum",tdc_data0))
        printf("Maximum value in spect. 0 is %d at col %d\n\n", array_op("max",tdc_data0),array_op("row_at_max",tdc_data0))
        printf("Sum of hits in spectrum 1 = %d\n", array_op("sum",tdc_data1))
        printf("Maximum value in spect. 1 is %d at col %d\n\n", array_op("max",tdc_data1),array_op("row_at_max",tdc_data1))
        printf("Sum of hits in spectrum 2 = %d\n", array_op("sum",tdc_data2))
        printf("Maximum value in spect. 2 is %d at col %d\n\n", array_op("max",tdc_data2),array_op("row_at_max",tdc_data2))
        printf("Sum of hits in spectrum 3 = %d\n", array_op("sum",tdc_data3))
        printf("Maximum value in spect. 3 is %d at col %d\n", array_op("max",tdc_data3),array_op("row_at_max",tdc_data3))
    }
}'

#------------------------------------------------------------
# END of macros related to the memory banks
#------------------------------------------------------------




#============================================================
#
# ASICPower/Starting/Stopping/Polling related macros
#
#============================================================
#
#
#-------------------------- tdcpower -----------------------
#%UU%
#%MDESC%
#  Powers ASIC C111 up or down
#
# Usage: tdcpower <up_dn>
#
def tdcpower '{

    if ($# != 1) {
        printf("Usage: tdcpower <0=down / 1=up>\n")
        exit
    }

    #
    # read current status
    #
    tdcstatus 1

    if (($1 == 0) && (TDC_STATUS[29] == 1)) {
        # power down the ASIC
        if (esrf_io(TDC_DEV,"DevC111PowerUpDn",0) < 0) {
          printf("tdcpower: Error powering down the C111 ASIC. Giving up\n")
          exit
        }
        exit
    }

    if (($1 == 1) && (TDC_STATUS[29] == 0)) {
        # power up the ASIC
        if (esrf_io(TDC_DEV,"DevC111PowerUpDn",1) < 0) {
            printf("tdcpower: Error powering up the C111 ASIC. Giving up\n")
            exit
        }
        exit
    }

}'


#-------------------------- tdcstart -----------------------
#%UU%
#%MDESC%
#  Starts the TDC if it is not running
#
def tdcstart '{
    local tdctime

    if ($#) {
        #
        # convert to miliseconds altohugh the 1/100 of a second is
        # used at the driver level
        #
        tdctime = $1 * 1000
    } else {
        tdctime = 0
    }
    if (whatis("tdc_data0") & 0x00010000)  tdc_data0 = 0
    if (whatis("tdc_data1") & 0x00010000)  tdc_data1 = 0
    if (whatis("tdc_data2") & 0x00010000)  tdc_data2 = 0
    if (whatis("tdc_data3") & 0x00010000)  tdc_data3 = 0

    # check ASIC power; if off put it on 
    #tdcstatus 1
    if (TDC_STATUS[29] == 0) {
        if (esrf_io(TDC_DEV,"DevC111PowerUpDn",1) < 0) {
            printf("tdcstart: Error power up C111 ASIC. Giving up\n")
            exit
        }
    }

    TDC_STATE=esrf_io(TDC_DEV,"DevC111GetStateString")
    # starts the C111 only if not yet running
    if (index(TDC_STATE,"RUNNING") == 0) {
        #printf("Will Start C111\n")
        if (esrf_io(TDC_DEV,"DevC111Start",tdctime) < 0) {
            print "tdcstart: Cannot start C111. Help!"
        }
    }

}'


#------------- tdcstop -----------------------------------
#%UU%
#%MDESC%
#  Stops the C111 if it is running.
#
def tdcstop '{

    TDC_STATE=esrf_io(TDC_DEV,"DevC111GetStateString")
    # stop the C111 only if not yet in IDLE state
    if (index(TDC_STATE,"IDLE") == 0) {
        #printf("Will Stop C111\n")
        if (esrf_io(TDC_DEV,"DevC111Stop") < 0) {
            print "tdcstop: Cannot stop C111. Help!"
        }
    }

}'


#------------- tdcpoll ------------------------------
#%UU%
#%MDESC%
#  Poll to see when acq. over (only for time limited acq.)
#
# Usage: tdcpoll <refresh_period> <read_data_for_display>
#
def tdcpoll '{
    local waitime readfordisp

    if (($# != 2) && ($# != 0)) {
        printf("Usage: tdcpoll <refresh_period> <read_data_for_display>\n")
        exit
    }

    if ($# == 0) {
        waitime     = 1
        readfordisp = 1
    }
    if ($# == 2) {
        waitime = $1
        readfordisp = $2
    }
    #if (waitime < 3) waitime = 3

    while(1) {
        TDC_STATE=esrf_io(TDC_DEV,"DevC111GetStateString")
        if (index(TDC_STATE,"RUNNING") == 0) {
            printf("tdcpoll: TDC has stopped\n")
            break;
        } else {
            printf("The TDC is running\n")
            if (readfordisp) {
                tdcreadbanks
		tdcplot
            }
        }
        sleep(waitime)
    }

}'


#------------- tdcacq_clear ------------------------------
#%UU%
#%MDESC%
#  Make a finite-time acquisition where memory in TDC is always cleared
#  so that data from the new acquisition do not cumulate with the data
#  from the previous acquisitons.
#  For short acq. times (< 5 seconds) only 1 bank is used;
#  For longer acq. times (>= 5 seconds) both memory banks are used.
#
# Usage: tdcacq_clear <acquisition_time>  
#
def tdcacq_clear '{

    # must give finite acq. time
    if (($# != 1) || ($1 == 0)) {
        printf("Usage: tdcacq_clear <acquisition_time>\n")
        exit
    }

    if ($1 != 0) COUNT_TIME = $1

    if ($1 < 5 ) {
        # For short acq. time it makes no sense to swap banks during
        # the acquisition -> all the data are acquired in one bank 
        # clear the bank that is selected for acquisition
        tdcinitbank 0 0
        tdcstart $1
        # poll with period of 0.1 second, but do not read the data
        # (since this would require bank swap)
        tdcpoll 0.1 0 
        # at the end of polling nevertheless invoke tdcstop to be sure
        # that the C111 is stopped.
        tdcstop
        # swap banks to read the one into which the acq. was done
        tdcswapbanks
        tdcreadbank
    } else {
        # clear both banks
        tdcinitbanks 0 0
        tdcstart $1
        # poll with period of 1 second, and each time read the data
        # for the display (plotting invoked inside tdcpoll macro)
        tdcpoll 1 1 
        # at the end of polling nevertheless invoke tdcstop to be sure
        # that the C111 is stopped.
        tdcstop
        # read banks one more time 
        tdcreadbanks
    }
    # display data
    tdcplot
    if (TDC_SAVE) {
        # save in 4 MCA-like files (one per TDC input channel)
	tdcsave
	if (TDC_SAVE_BOTH) {
            # decrement run number to have the same in MCA-like files 
            # and for PADI file
            TDC_RUN_NUMBER--
            # save in one file for PADI 
            tdcsave_padi
        }
    }
}'


#------------- tdcacq1b ------------------------------
#%UU%
#%MDESC%
#  Make a finite-time acquisition only in 1 bank
#  Memory is cleared before the acquisition.
#  This macro was written to compare the performance of
#  it with the tdcacq macro, where both banks are used.
#  Practically no difference was seen -> so it is more
#  practical to use tdcacq macro and use both banks, which
#  allow to read data during the acquisition for visualization.
#
# Usage: tdcacq1b <acquisition_time>
#
def tdcacq1b '{

    # must give finite acq. time
    if (($# != 1) || ($1 == 0)) {
        printf("Usage: tdcacq1b <acquisition_time>\n")
        exit
    }

    if ($1 != 0) COUNT_TIME = $1

    # all the data are acquired in one bank which is read out in the
    # end 
    #
    # clear the bank that is selected for acquisition
    tdcinitbank 0 0
    tdcstart $1
    # poll with period of 0.1 second, but do not read the data
    # since this would require bank swap (i.e. second arg. = 0)
    tdcpoll 0.1 0 
    # at the end of polling nevertheless invoke tdcstop to be sure
    # that the C111 is stopped.
    tdcstop
    # swap banks to read the one into which the acq. was done
    tdcswapbanks
    tdcreadbank

    # display data
    tdcplot
    if (TDC_SAVE) {
        # save in 4 MCA-like files (one per TDC input channel)
	tdcsave
	if (TDC_SAVE_BOTH) {
            # decrement run number to have the same in MCA-like files 
            # and for PADI file
            TDC_RUN_NUMBER--
            # save in one file for PADI 
            tdcsave_padi
        }
    }
}'


#------------- tdcacq ------------------------------
#%UU%
#%MDESC%
#  Make a finite-time acquisition. If pass only 1 parameter (= acq. time)
#  then the TDC memory is always cleared before the acquisition, while
#  if in addition the second parameter is passed the TDC memory is not
#  cleared.
#  Always (= independent of acq. time) both banks are used.
#  If automatic file-saving was selected in tdcconfig (TDC_SAVE)
#  the 4 spectra (1 for each TDC input channel) are saved in MCA-like
#  files with the names: TDC_FILE_PREFIX_N_TDC_RUN_NUMBER, where N 
#  is 0,1,2,3 for input channel 0,1,2,3 respectively.
#  If saving in both MCA-like and file for PADI/JADI was selected
#  in tdcconfig(TDC_SAVE_BOTH), then in addition to 4 MCA-like files
#  the file for PADI/JADI is written. Its name is:
#  TDC_FILE_PREFIX_TDC_RUN_NUMBER.
#
# Usage: tdcacq <acquisition_time> <donotclearflag>  
#
def tdcacq '{

    # must give finite acq. time
    if (($# < 1) || ($# > 2)) {
        printf("Usage: tdcacq <acquisition_time> <donotclear_flag>\n")
        exit
    }

    if ($1 == 0) COUNT_TIME = 10
    else         COUNT_TIME = $1

    if ($# < 2) {
        p "Will clear banks"
        # clear both banks
        tdcinitbanks 0 0
    }
    tdcstart COUNT_TIME 
    # poll with period of 1 second, and each time read the data
    # for the display (plotting invoked inside tdcpoll macro)
    tdcpoll 1 1 
    # at the end of polling nevertheless invoke tdcstop to be sure
    # that the C111 is stopped.
    tdcstop
    # read banks one more time 
    tdcreadbanks
    
    # display data
    tdcplot
    if (TDC_SAVE) {
        # save in 4 MCA-like files (one per TDC input channel)
	tdcsave
	if (TDC_SAVE_BOTH) {
            # decrement run number to have the same in MCA-like files 
            # and for PADI file
            TDC_RUN_NUMBER--
            # save in one file for PADI 
            tdcsave_padi
        }
    }
}'


#------------- tdcstatacq ------------------------------
#%UU%
#%MDESC%
#  Make a finite-time acquisition to look at statistics
#  Set statistics timer duration shorter than counting time.
#
# Usage: tdcstatacq <statistics_timer_duration>
#
def tdcstatacq '{
    local tostop

    # must give finite statistics timer duration
    if (($# != 1) || ($1 == 0)) {
        printf("Usage: tdcstatacq <statistics_timer_duration>\n")
        exit
    }

    TDC_STATE=esrf_io(TDC_DEV,"DevC111GetStateString")
    if (index(TDC_STATE,"RUNNING") != 0) {
        printf("The C111 TDC is running\n")
        tostop = yesno("Do you want to stop it",0)
        if (tostop) {
            tdcstop
        } else {
            printf("Sorry wont do statistics measurements\n")
            exit
        }
    }

    # Enable statistics timer with given duration
    tdcstattimer 1 $1
    
    # even not necessary, but usefull to read banks and plot in the end
    tdcinitbanks 0 0

    # invoke tdcstatus to get TDC_DURATION
    tdcstatus 1

    # acquire for "infinite" time (all data go in one bank)
    tdcstart 0 

    # polling is done inside _tdcstatistics until statistics timer expires

    # show statistics only in the end
    _tdcstatistics 1

    # show statistics during life-time of statistics timer + after its
    # expiration
    #_tdcstatistics

    # stop the acquisition now and disable statistics timer 
    tdcstop

    # even not necessary, but usefull to compare with total counts in plot 
    # of course in the plot will have a bit more hits since acq. is not
    # stopped exactly at statistics timer expiration.
    tdcreadbanks
    tdcplot
    
    # disable statistics timer
    tdcstattimer 0 $1

}'


#------------- tdcsave ------------------------------
#%UU%
#%MDESC%
#  Save data when acquire outside counting and scanning.
#
#  Each channel data are saved in its own file, which share in 
#  the name the same data directory, the same file prefix, and the
#  same "run" number. They differ in name in channel number (0->4).
#  So it should be possible to read such files with standard tools.
#
def tdcsave '{
    local ii

    for (ii=0; ii<4; ii++) {
        _tdcsavemultiprivate(ii)
    }
    TDC_RUN_NUMBER++
}'


#------------- _tdcsavemultiprivate(chn) ---------------------------
#%IU%
#%MDESC%
#  Writes a header and data into channel specific file.
#  Inside the same macros (_tdc_savemultichnheader and 
#  _tdc_savemultichndata) are used as in tdc_user_scan_loop 
#
def _tdcsavemultiprivate(chn) '{
    local filename ret

    #####filename = sprintf("%s/%s_%d_%03d.data",TDC_DATA_DIR,TDC_FILE_PREFIX,chn,TDC_RUN_NUMBER)
    filename = sprintf("%s/%s_%1d_%03d",TDC_DATA_DIR,TDC_FILE_PREFIX,chn,TDC_RUN_NUMBER)
    #printf("TDC_RUN_NUMBER = %d\n", TDC_RUN_NUMBER)
    #printf("filename = %s\n", filename)
    if (!filename) return (-1)

    ret= 0
    if (savefileheader(filename)<0) { ret= -1 }
    if (ret==0) {
        if (savestdheader(filename, 3, 0)<0) { ret=-1 }
    }

    if (ret==0) {
# modifed 19.05.2005
# changed the 3rd parameter to 1 so to get in the file also CTIME line
# when do tdcsave automatically in tdcacq macro or when execute tdcsave
# after counting.
# if (_tdc_savemultichnheader(filename, chn, 0)<0) {ret = -1}
        if (_tdc_savemultichnheader(filename, chn, 1)<0) {ret = -1}
    }

# added 17.05.2005
    if (ret==0) {
        if (savecntheader(filename)<0) { ret=-1 }
    }
    if (ret==0) {
        if (savecounters(filename)<0) { ret=-1 }
    }
#

    if (ret==0) {
        if (_tdc_savemultichndata(filename, chn)<0) {ret = -1}
    }
    if (ret) {
        printf("Failed to save spectrum for channel %d in %s\n",chn, filename)
    } else {
        printf("Saved spectrum for channel %d in file %s\n", chn, filename)
    }

    close(filename)
    return(0)
}'


#------------- tdcsave_padi (for PADI or JADI) ----------------------------
#%UU%
#%MDESC%
#  Save data in a simple ASCII file (when acquire outside scan)
#  Format in the file is such that the data can be then plotted
#  with padi(Python Display) or jadi (Java Display).
#  If the full filename is given as input parameter, then it
#  is used, otherwise the filename is composed from TDC_DATA_DIR,
#  TDC_FILE_PREFIX and TDC_RUN_NUMBER.
#
# Usage: tdcsave_padi <filename>
#
def tdcsave_padi '{
    local filename ii

    if ($# > 1) {
        printf("Usage: tdcsave_padi <filename>\n")
        exit
    }
    if ($# == 1) {
        filename = "$1"
    } else {
        filename = sprintf("%s/%s_%03d",TDC_DATA_DIR,TDC_FILE_PREFIX,TDC_RUN_NUMBER++)
    }
    if (open(filename)) {
        printf("tdcsave: Error opening file %s\n", filename)
        exit
    }
    on(filename)
    offt
    for (ii = 0; ii < TDC_NBCOLS; ii++) {
        #fprintf(filename,"%d\t%d\t%d\t%d\n", tdc_data0[ii][0], tdc_data1[ii][0], tdc_data2[ii][0], tdc_data3[ii][0])
        fprintf(filename,"%u\t%u\t%u\t%u\n", tdc_data0[ii][0], tdc_data1[ii][0], tdc_data2[ii][0], tdc_data3[ii][0])
    }
    off(filename)
    ont
    close(filename) 

    printf("Data saved in file %s\n", filename)
}'


def tdcsave_jadi 'tdcsave_padi'



#------------- tdcsave_padi1 (for PADI or JADI) ----------------------------
#%UU%
#%MDESC%
#  Save data of ONLY ONE channel in a simple ASCII file (when acquire
#  outside scan)
#  Format in the file is such that the data can be then plotted
#  with padi(Python Display) or jadi (Java Display).
#  If the full filename is given as input parameter, then it
#  is used, otherwise the filename is composed from TDC_DATA_DIR,
#  TDC_FILE_PREFIX and TDC_RUN_NUMBER.
#
# Usage: tdcsave_padi1 <filename>
#
def tdcsave_padi1 '{
    local filename ii

    if ($# > 2) {
        printf("Usage: tdcsave_padi <filename> <channel-index>\n")
        exit
    }
    if ($# == 2) {
        filename = "$1"
        channel = $2
    } 
    if ($# == 1) {
        filename = sprintf("%s/%s_%03d",TDC_DATA_DIR,TDC_FILE_PREFIX,TDC_RUN_NUMBER++)
        channel = $1
    }


    if (open(filename)) {
        printf("tdcsave: Error opening file %s\n", filename)
        exit
    }
    on(filename)
    offt
    if (channel == 0) {
        for (ii = 0; ii < TDC_NBCOLS; ii++) {
            fprintf(filename,"%u\n", tdc_data0[ii][0])
        } 
    } 
    if (channel == 1) {
        for (ii = 0; ii < TDC_NBCOLS; ii++) {
            fprintf(filename,"%u\n", tdc_data1[ii][0])
        } 
    }
    if (channel == 2) {
        for (ii = 0; ii < TDC_NBCOLS; ii++) {
            fprintf(filename,"%u\n", tdc_data2[ii][0])
        } 
    }
    if (channel == 3) {
        for (ii = 0; ii < TDC_NBCOLS; ii++) {
            fprintf(filename,"%u\n", tdc_data3[ii][0])
        } 
    }

    off(filename)
    ont
    close(filename) 

    printf("Data saved in file %s\n", filename)
}'



#------------- tdcsave_old (OLD,OLD) ----------------------------
#%UU%
#%MDESC%
#  Save data in a simple ASCII file (when acquire outside scan)
#  Format in the file is such that the data can be then plotted
#  with cplot.
#  If the full filename is given as input parameter, then it
#  is used, otherwise the filename is composed from TDC_DATA_DIR,
#  TDC_FILE_PREFIX and TDC_RUN_NUMBER.
#
#  NB: Note that the format limits the values to 16-bit dynamic range
#      (like used in MCA!!!), although arrays tdc_data0-3 are unsigned
#      long.
#
# Usage: tdcsave_old <filename>
#
def tdcsave_old '{
    local filename

    if ($# > 1) {
        printf("Usage: tdcsave_old <filename>\n")
        exit
    }
    if ($# == 1) {
        filename = "$1"
    } else {
        filename = sprintf("%s/%s_R%d.data",TDC_DATA_DIR,TDC_FILE_PREFIX, TDC_RUN_NUMBER++)
    }
    if (open(filename)) {
        printf("tdcsave: Error opening file %s\n", filename)
        exit
    }
    fprintf(filename,"@A ")
    #on(filename);offt;data_dump(tdc_data,"%16C");off(filename);ont
    on(filename)
    offt
    data_dump(tdc_data0,"%16C")
    data_dump(tdc_data1,"%16C")
    data_dump(tdc_data2,"%16C")
    data_dump(tdc_data3,"%16C")
    off(filename)
    ont
    close(filename) 
}'
#------------------------------------------------------------
# END of macros related to power/start/stop/poll/acquire/saving outside ct,scan
#------------------------------------------------------------




#============================================================
#
# Counting/Scanning related macros
#
#============================================================
#
#-------------------------- _tdcctscan -----------------------
#%UU%
#%MDESC%
#  Activate or not TDC acquisition during the counting and scanning.
#  When in scan and when DATAFILE is not /dev/null, the 1D TDC spectrum
#  is saved in a standard SPEC scan file as MCA spectrum. 
#
def _tdcctscan '{
local inctscan saveonlyroi roidef

    inctscan = yesno("Want to acquire during counting and scanning ",0)
    if (inctscan) {
        tdcoff
        TDC_SAVEONLYROI = yesno("Want to save only integral of ROI counts in scan file", 1)
        tdcon
        roidef = yesno("Want to (re)define ROIs pseudo-counter(s) ",0)
	if (roidef) tdcroimenu
    } else {
        TDC_SAVEONLYROI = 0
        tdcoff
    }

}'


#-------------------------- tdcon -----------------------
#%UU%
#%MDESC%
#  Switch on TDC acq. during ct + scan
#  By modifying user_prepcount + user_getcount rather than
#  measure0 and measure1 the code below is good both for
#  counting AND scanning. If would modify measure0/1 than
#  tdcon would swich on TDC acq. only during scan and not
#  during normal counting.
#
def tdcon '{
    cdef("user_prepcount","tdc_prepcount; ","tdc")
    ##cdef("user_pollcounts","tdc_pollcounts; ","tdc")
    cdef("user_getcounts","tdc_getcounts; ","tdc")
    if (TDC_SAVEONLYROI == 0) {
        cdef("user_scan_loop","tdc_user_scan_loop;","tdc")
    }
    cdef("user_Fheader","tdc_savehead;","tdc")
    if (!TDC_ON) TDC_ON = 1
    # activate ROI(s) pseudo-counter(s) that might be defined
    TDC_USINGROI = 1
    # ROIs can be also enabled separately with invoking tdcroion 
}'

 
#-------------------------- tdcoff -----------------------
#%UU%
#%MDESC%
#  Switch off TDC acq. during ct + scan
#
def tdcoff '{
    cdef("","","tdc","delete")
    if (TDC_ON) TDC_ON = 0
    tdcroioff
}'


#-------------------------- tdc_prepcount -----------------------
#%IU%
#%MDESC%
#  Done at each scan point before counting
#
def tdc_prepcount '{

    ## beamcheck
    ## while (!BCHK_BEAM) {
    ##     beampoll
    ##     beamcheck
    ## }
    if (TDC_USINGROI) {
        local roinb roi roinum
        roinb = list_n(TDC_ROI)
        for (roi=1; roi <= roinb; roi++) {
            roinum = cnt_num(list_item(TDC_ROI, roi))
            if (roinum != -1) S[roinum] = 0
        }
    }
    tdcinitbanks 0 0
    ##tdcinitbank 0 0
    # printf("**** In tdc_prepcount before tdc start \n")
    tdcstart 0
}'


#------------- tdc_pollcounts -----------------------------------
#
#%IU%
#%MDESC%
#  Done during counting when polling for end of counting
#  with polling interval COUNTERSPOLLTIME (0.01sec)
#  We DO NOT USE it!!!!!!!!
#
def tdc_pollcounts '{

    tdcreadbanks
    if (TDC_USINGROI) {
        local roinb roi roinum roimne roimin roimax
        roinb= list_n(TDC_ROI)
        for (roi=1; roi<=roinb; roi++) {
            roimne= list_item(TDC_ROI, roi)
            if ((roinum=cnt_num(roimne))!=-1) {
                roimin= TDC_ROI[roimne]["min"]
                roimax= TDC_ROI[roimne]["max"]
                S[roinum]= array_op("sum", tdc_data[roimin:roimax])
            }
        }
    }
}'


#------------- tdc_getcounts -----------------------------------
#%IU%
#%MDESC%
#  Done at each scan point, after counting and in scan also
#  during counting if selected by setscans. TDC is stopped
#  only when the counting is over (i.e. when chk_count = 0).
#
def tdc_getcounts '{
    if (chk_count==0) {
        tdcstop
    }
    tdcreadbanks
    ##tdcswapbanks
    ##tdcreadbank
    if (TDC_USINGROI) {
        local roinb roi roinum roimne roimin roimax
        roinb= list_n(TDC_ROI)
        for (roi=1; roi<=roinb; roi++) {
            roimne= list_item(TDC_ROI, roi)
            if ((roinum=cnt_num(roimne))!=-1) {
                tdcchan = list_getpar(TDC_ROI,roi,"chn")
                roimin= TDC_ROI[roimne]["min"]
                roimax= TDC_ROI[roimne]["max"]
                if (tdcchan == 0) {
                    S[roinum]= array_op("sum", tdc_data0[roimin:roimax])
		}
                if (tdcchan == 1) {
                    S[roinum]= array_op("sum", tdc_data1[roimin:roimax])
		}
                if (tdcchan == 2) {
                    S[roinum]= array_op("sum", tdc_data2[roimin:roimax])
		}
                if (tdcchan == 3) {
                    S[roinum]= array_op("sum", tdc_data3[roimin:roimax])
		}
            }
        }
    }
    #tdcplot
}'


#------------- tdc_user_scan_loop -----------------------------------
#%IU%
#%MDESC%
#  Adds TDC data to scan file
#  This macro adds TDC data to scan file for all 4 TDC input channels.
#  For simplicity assume that will always record all 4 channel data.
#  So this macro is somewhat similar to mcasavescandata.
#
#  TODO: refine so to choose which channel(s) to record.
#
#  REMARK: test on TDC_SAVEONLYROI is done in case macro tdc_user_scan_loop
#          is still hooked to user_scan_loop.
#
def tdc_user_scan_loop '{
    local ii
        for (ii=0; ii<4; ii++) {
            if (_tdc_savemultichndata(DATAFILE, ii)<0) {
                printf("Failed to wrote tdc chn %d data in %s\n", ii, filename)
            }
        }
}'


#------------- _tdc_savemultichndata -----------------------------------
#%IU% (file, chn)
#%MDESC% Save TDC spectrum data for TDC input channel <chn>
#%BR% Return 0 on sucess, -1 otherwise, to be consitent with
#     logic in saveload.mac.
#
#     Inside scan do nothing if only integral of ROI cnts required
#     Outside scan write complete spectrum. 
#
def _tdc_savemultichndata(file, chn) '{
    local darr

    if ( (TDC_SAVEONLYROI == 0) || (_n1 == NPTS) ) {
        if (open(file)) return (-1)
        darr= sprintf("tdc_data%1d", chn)
        fprintf(file,"@A ")
        on(file);offt
        data_dump(@darr[][0], "%16C")
        ont; off(file)
    } 
###    } else {
###        local nroi roinum
###       nroi=list_n(TDC_ROI)
###        for (roi=1; roi<=nroi; roi++) {
###            tdcchan= list_getpar(TDC_ROI, roi, "chn")
###            if (tdcchan == chn) {
###                roinum = cnt_num(list_item(TDC_ROI, roi))
###                #fprintf(file, "#@ROI %d %s %g \n", chn, list_item(TDC_ROI, roi),S[roinum])
###                fprintf(file, "%g ", S[roinum])
###            }
###       }
###        fprintf(file, " \n")
###    }

    return (0)
}'


#------------- tdc_user_scan_loop_old(OLD,OLD) --------------------------
#%IU%
#%MDESC%
#  Adds TDC data to scan file
#
def tdc_user_scan_loop_old '{
    savemcadata(DATAFILE,tdc_data0,TDC_NBCOLS,"%16C")
    savemcadata(DATAFILE,tdc_data1,TDC_NBCOLS,"%16C")
    savemcadata(DATAFILE,tdc_data2,TDC_NBCOLS,"%16C")
    savemcadata(DATAFILE,tdc_data3,TDC_NBCOLS,"%16C")
    #close(DATAFILE)
}'


#------------- tdc_savehead -----------------------------------
#%IU%
#%MDESC%
#  For all 4 TDC input channels this macro adds info on nb of 
#  channels read and elapsed time in scan header
#  Since in C111 server(driver) do not measure the acq. time take
#  the scan time per scan point.
#  For simplicity assume that will always record all 4 channel data.
#  So this macro is somewhat similar to mcasavescanheader.
#
#  TODO: refine so to choose which channel(s) to record.
#
def tdc_savehead '{
    local ii
    for (ii=0; ii<4; ii++) {
        if (_tdc_savemultichnheader(DATAFILE, ii, 1)<0) {
            printf("Failed to wrote tdc chn %d header in %s\n", ii,DATAFILE)
        }
    }
}'


#------------- _tdc_savemultichnheader -----------------------------------
#%IU%
#%MDESC%
#  Saves channel specfic header info 
#  TODO: see if it works like it is or need to change COUNT_TIME to _ctime
#
def _tdc_savemultichnheader(file,chn,withtime) '{
    local cmin cmax npts
    local nroi roi

    if (open(file)) return (-1)
    fprintf(file, "#@MCA %d %s\n", chn, "%16C")
    cmin= 0
    cmax= TDC_NBCOLS - 1
    npts= TDC_NBCOLS
    # since have no reduction (like MCA can have), its factor is fixed to 1
    fprintf(file, "#@CHANN %d %g %g %g 1\n", chn, npts, cmin, cmax)
    if (withtime) {
        fprintf(file, "#@CTIME %d %g %g %g\n", chn, COUNT_TIME, \
                  COUNT_TIME, COUNT_TIME)
    }
    # there is no calibration like in MCA case
    # can add roi counters (corresponding to this TDC input channel) info
    # TODO: should add this only if corresponndig ROIs active ?
    nroi=list_n(TDC_ROI)
    for (roi=1; roi<=nroi; roi++) {
        tdcchan= list_getpar(TDC_ROI, roi, "chn")
        if (tdcchan == chn) {
            fprintf(file, "#@ROI %d %s %g %g\n", chn, list_item(TDC_ROI, roi),\
                list_getpar(TDC_ROI, roi, "min"), \
                list_getpar(TDC_ROI, roi, "max"))
        }
    }
    return(0)
}'


#------------- tdc_savehead_old (OLD,OLD)-----------------------------------
#%IU%
#%MDESC%
#  Adds info on nb of channels read and elapsed time in scan header
#  Since in C111 server(driver) do not measure the acq. time take
#  the scan time per scan point.
#  For simplicity assume that will alwys record all 4 channel data.
#  So this macro is somewhat similar to mcaisavescanheader (which calls
#  in turn savemultimcaheader).
#  TODO: refine so to choose which channel(s) to record.
#
def tdc_savehead_old '{
    local npts cmin cmax meltime

    npts = TDC_NBCOLS
    cmin = 0
    # TODO: need to multiply nextby 4 since have 4 spectra???
    cmax = npts - 1
    meltime = _ctime
    savemcaheader(DATAFILE,"%16C",npts,cmin,cmax,0,0,meltime,meltime)
}'

#------------------------------------------------------------
# END of macros related to counting/scanning
#------------------------------------------------------------




#============================================================
#
# ROI related macros
#
# ==============================================================
#
#
#-------------------------- _tdcroiset -----------------------
#%IU% 
#%MDESC% 
#  Internal macro function to Setup(= Add or Modify) an ROI.
#  cmne = pseudo-counter mnemonic,
#  tdcchan = TDC input channel (0->3)
#  cmin/max = min/max digital channel
#
def _tdcroiset(cmne,tdcchan,cmin,cmax) '{
    local roimin roimax
    roimin= cmin>=0?cmin:0
    roimax= (cmax<=TDC_NBCOLS-1)?cmax:TDC_NBCOLS-1
    if (list_check(TDC_ROI, cmne)<=0) {
	list_add(TDC_ROI, cmne)
    }
    TDC_ROI[cmne]["min"]= roimin
    TDC_ROI[cmne]["max"]= roimax
    TDC_ROI[cmne]["chn"]= tdcchan 
}'


#-------------------------- _tdcroishow -----------------------
#%IU% ()
#%MDESC%
#  Internal macro function to show ROI(s) definitions.
#
def _tdcroishow() '{
    local nroi nb roimne inconfig

    if ((nroi=list_n(TDC_ROI))<0) list_init TDC_ROI

    clscreen()
    tty_move(0,1,"\[md\]<TDC ROI Definition>\[me\]")
    tty_move(0,3,sprintf("--> ROIs are now \[md\]%s\[me\]", TDC_USINGROI?"Active
":"Off"))
    tty_move(0,5,"Counter InChan From   To     Configured")
    tty_move(0,6,"------- ------ ------ ------ ----------")
    nb= 7
    for (roi=1; roi<=nroi; roi++) {
        tty_move(0,nb++, \
        sprintf("\[md\]%7s\[me\] %6d %6d %6d        %s", \
                list_item(TDC_ROI, roi), \
                list_getpar(TDC_ROI, roi, "chn"), \
                list_getpar(TDC_ROI, roi, "min"), \
                list_getpar(TDC_ROI, roi, "max"), \
                (cnt_num(TDC_ROI[roi-1])==-1)?" No":"Yes"))
    }
    nb++
    return (nb)
}'


#-------------------------- tdcroishow -----------------------
#%UU%
#%MDESC% 
#  Macro to Show the ROI definitions.
#
def tdcroishow '_tdcroishow()'


#-------------------------- tdcroi -----------------------
#%UU%
#%MDESC%
#  Macro to Add/Remove/Modify ROIs used to get integral count
#  for each of them. ROI index goes from 1 to 8.
#
def tdcroi '{
    if (list_n(TDC_ROI)<0) list_init TDC_ROI

    if ($#==0)	{
	tdcroimenu
    }
    else if ($#==4) {
	_tdcroiset("$1",$2,$3,$4)
    }
    else {
	print "USAGE: tdcroi <mnemonic> <input_chan> <chan_min> <chan_max>"
	print "    or tdcroi without arguments for interactive menu"
    }
}'


#-------------------------- tdcroimenu -----------------------
#%UU%
#%MDESC%
#  Macro to Interactively Add/Remove/Modify ROI(s) to get integral 
#  of counts for channels within ROI.
#
def tdcroimenu '{
    local key cmne tdcchan cmin cmax nb

    while (1) {
        nb= _tdcroishow()
	tty_move(0,nb++, \
		"\[md\]A\[se\]dd/\[md\]R\[se\]emove/\[md\]M\[se\]odify or \[md\]Q\[se\]uit ? ")
	while ((key=input(-1))=="") {}
	key=substr(key,1,1)
	printf("\n\n")
	if (key=="q"||key=="Q") break
	else if (key=="r"||key=="R") {
	    cmne= getval("Counter mnemonic",0)
	    if (cmne!="0") {
		list_remove(TDC_ROI, cmne)
	    }
	}
	else if (key=="a"||key=="A") {
	    cmne= getval("Counter mnemonic",0)
	    tdcchan = getval("Counter input channel",0)
	    if (cmne!="0") {
		cmin= getval("First channel ", 0)
		cmax= getval("Last channel  ", TDC_NBCOLS-1)
	    }
	    _tdcroiset(cmne, tdcchan, cmin, cmax)
	}
	else if (key=="m"||key=="M") {
	    cmne= getval("Counter mnemonic",0)
	    if (list_check(TDC_ROI, cmne)>0) {
		tdcchan= getval("TDC input channel ", TDC_ROI[cmne]["chn"])
		cmin= getval("First channel ", TDC_ROI[cmne]["min"])
		cmax= getval("Last channel  ", TDC_ROI[cmne]["max"])
		_tdcroiset(cmne, tdcchan, cmin, cmax)
	    }
	}
    }
}'


#-------------------------- tdcroioff -----------------------
#%UU%
#%MDESC% 
#  Macro to Cancel the use of ROI counters.
#
def tdcroioff '{
    local nb roi roinum

    nb= list_n(TDC_ROI)
    for (roi=1; roi<=nb; roi++) {
        roinum= cnt_num(list_item(TDC_ROI, roi))
        if (roinum!=-1) {
            S[roinum]= 0
        }
    }
    TDC_USINGROI = 0
}'


#-------------------------- tdcroion -----------------------
#%UU%
#%MDESC% 
#  Macro to Activate the use of ROI counters.
#
def tdcroion '{
    TDC_USINGROI = 1
}'
#------------------------------------------------------------
# END of ROI related macros 
#------------------------------------------------------------




# ==============================================================
#
# Plotting related macros
#
# ==============================================================
#
#
#-------------------------- _tdcsplotlin -----------------------
#%IU%
#%MDESC%
#  Internal macro to create plot and display 1D TDC spectrum using
#  standard SPEC plotting with linear Y scale.
#  - abscissa array = coloumns array = tdc_xdata
#  - ordinate array = TDC data for all 4 channels = tdc_data0-3
#  The range of TDC channels to be plotted is between minimum and 
#  maximum digitized TDC channel which are passed as parameters along
#  with macro name:
#  _tdcsplotlin <xmin> <xmax>
#
def _tdcsplotlin '{
    local pmin pmax
    local res01 res02
    local res11 res12
    local res21 res22
    local res31 res32
    local min max mi ma

    pmin= $1
    pmax= $2 - 1

    plot_cntl("filter2")

    if (PLOT_MODE&128) {
        plot_cntl(sprintf("colors=%s",splot_col))
        plot_cntl("open")
        plot_cntl("-ylog +lines -dots -ebars")
    }

    plot_cntl("erase")
    plot_move(0,1,"TDC ACQ SPECTRUM")
    plot_move(0,2,"Counts")
    plot_move(0,-1,"Channels")

    min[0] = array_op("min", tdc_data0[pmin:pmax])
    min[1] = array_op("min", tdc_data1[pmin:pmax])
    min[2] = array_op("min", tdc_data2[pmin:pmax])
    min[3] = array_op("min", tdc_data3[pmin:pmax])
    max[0] = array_op("max", tdc_data0[pmin:pmax])
    max[1] = array_op("max", tdc_data1[pmin:pmax])
    max[2] = array_op("max", tdc_data2[pmin:pmax])
    max[3] = array_op("max", tdc_data3[pmin:pmax])
    mi = 0
    ma = 0
    for (i = 0; i < 4; i++) {
        if (min[i] <= mi) mi = min[i]
        if (max[i] >= ma) ma = max[i]
    } 
    plot_range(pmin,pmax,mi,ma)

    plot_cntl("mca")
    array_plot(tdc_xdata[pmin:pmax], tdc_data0[pmin:pmax])
    array_plot(tdc_xdata[pmin:pmax], tdc_data1[pmin:pmax])
    array_plot(tdc_xdata[pmin:pmax], tdc_data2[pmin:pmax])
    array_plot(tdc_xdata[pmin:pmax], tdc_data3[pmin:pmax])

    res01 = sprintf("CH 0: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data0[pmin:pmax]), \
        array_op("max", tdc_data0[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data0[pmin:pmax]))
    res11 = sprintf("CH 1: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data1[pmin:pmax]), \
        array_op("max", tdc_data1[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data1[pmin:pmax]))
    res21 = sprintf("CH 2: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data2[pmin:pmax]), \
        array_op("max", tdc_data2[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data2[pmin:pmax]))
    res31 = sprintf("CH 3: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data3[pmin:pmax]), \
        array_op("max", tdc_data3[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data3[pmin:pmax]))

    plot_move(-50,0,res01)
    plot_move(-50,1,res11)
    plot_move(-50,2,res21)
    plot_move(-50,3,res31)

    plot_cntl("filter1")
}'


#-------------------------- _tdcsplotlin1 -----------------------
#%IU%
#%MDESC%
#  Internal macro to create plot and display 1D TDC spectrum using
#  standard SPEC plotting with linear Y scale.
#  - abscissa array = coloumns array = tdc_xdata
#  - ordinate array = TDC data for ONE channel (0->3) which is passed
#                     as first parameter.
#  The range of TDC channels to be plotted is between minimum and 
#  maximum digitized TDC channel which are passed as parameters along
#  with macro name:
#  _tdcsplotlin1 <inch> <xmin> <xmax>
#
def _tdcsplotlin1 '{
    local chn pmin pmax
    local ii
    local res1 res2
    local min max

    chn = $1 
    pmin= $2
    pmax= $3 - 1

    plot_cntl("filter2")

    if (PLOT_MODE&128) {
        plot_cntl(sprintf("colors=%s",splot_col))
        plot_cntl("open")
        plot_cntl("-ylog +lines -dots -ebars")
    }

    plot_cntl("erase")
    plot_move(0,1,"TDC ACQ SPECTRUM")
    plot_move(0,2,"Counts")
    plot_move(0,-1,"Channels")

    for (ii = 0; ii < 4; ii++) {
        if (ii == chn) {
            if (chn == 0) {
                min = array_op("min", tdc_data0[pmin:pmax])
                max = array_op("max", tdc_data0[pmin:pmax])
            } else if (chn == 1) {
                min = array_op("min", tdc_data1[pmin:pmax])
                max = array_op("max", tdc_data1[pmin:pmax])
            } else if (chn == 2) {
                min = array_op("min", tdc_data2[pmin:pmax])
                max = array_op("max", tdc_data2[pmin:pmax])
            } else {
                min = array_op("min", tdc_data3[pmin:pmax])
                max = array_op("max", tdc_data3[pmin:pmax])
            }
        }
    }

    plot_range(pmin,pmax,min,max)

    plot_cntl("mca")
    if (chn == 0) {
        array_plot(tdc_xdata[pmin:pmax], tdc_data0[pmin:pmax])
    } else if (chn == 1) {
        array_plot(tdc_xdata[pmin:pmax], tdc_data1[pmin:pmax])
    } else if (chn == 2) {
        array_plot(tdc_xdata[pmin:pmax], tdc_data2[pmin:pmax])
    } else {
        array_plot(tdc_xdata[pmin:pmax], tdc_data3[pmin:pmax])
    }

    if (chn == 0) {
      res = sprintf("CH 0: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data0[pmin:pmax]), \
        array_op("max", tdc_data0[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data0[pmin:pmax]))
    } else if (chn == 1) {
      res = sprintf("CH 1: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data1[pmin:pmax]), \
        array_op("max", tdc_data1[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data1[pmin:pmax]))
    } else if (chn == 2) {
      res = sprintf("CH 2: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data2[pmin:pmax]), \
        array_op("max", tdc_data2[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data2[pmin:pmax]))
    } else {
      res = sprintf("CH 3: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data3[pmin:pmax]), \
        array_op("max", tdc_data3[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data3[pmin:pmax]))
    }

    plot_move(-50,0,res)

    plot_cntl("filter1")
}'


#-------------------------- _tdcsplotlog -----------------------
#%IU%
#%MDESC%
#  Internal macro to create plot and display 1D TDC spectrum using
#  standard SPEC plotting with logarithmic Y scale.
#  - abscissa array = coloumns array = tdc_xdata
#  - ordinate array = TDC data for all 4 channels = tdc_data0-3
#  The range of TDC channels to be plotted is between minimum and 
#  maximum digitized TDC channel which are passed as parameters along
#  with macro name:
#  _tdcsplotlog <xmin> <xmax>
#
def _tdcsplotlog '{
    local pmin pmax
    local res01 res02
    local res11 res12
    local res21 res22
    local res31 res32
    local min max mi ma

    pmin= $1
    pmax= $2 - 1

    plot_cntl("filter2")

    if (PLOT_MODE&128) {
        plot_cntl(sprintf("colors=%s",splot_col))
        plot_cntl("open")
        plot_cntl("-ylog +lines -dots -ebars")
    }

    plot_cntl("erase")
    plot_move(0,1,"TDC ACQ SPECTRUM")
    plot_move(0,2,"Counts")
    plot_move(0,-1,"Channels")

    min[0] = array_op("min", tdc_data0[pmin:pmax])
    min[1] = array_op("min", tdc_data1[pmin:pmax])
    min[2] = array_op("min", tdc_data2[pmin:pmax])
    min[3] = array_op("min", tdc_data3[pmin:pmax])
    max[0] = array_op("max", tdc_data0[pmin:pmax])
    max[1] = array_op("max", tdc_data1[pmin:pmax])
    max[2] = array_op("max", tdc_data2[pmin:pmax])
    max[3] = array_op("max", tdc_data3[pmin:pmax])
    mi = 0
    ma = 0
    for (i = 0; i < 4; i++) {
        if (min[i] <= mi) mi = min[i]
        if (max[i] >= ma) ma = max[i]
    } 
    plot_range(pmin,pmax,mi,ma)

    plot_cntl("mca")
    plot_cntl("+ylog")
    array_plot(tdc_xdata[pmin:pmax], tdc_data0[pmin:pmax])
    array_plot(tdc_xdata[pmin:pmax], tdc_data1[pmin:pmax])
    array_plot(tdc_xdata[pmin:pmax], tdc_data2[pmin:pmax])
    array_plot(tdc_xdata[pmin:pmax], tdc_data3[pmin:pmax])

    res01 = sprintf("CH 0: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data0[pmin:pmax]), \
        array_op("max", tdc_data0[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data0[pmin:pmax]))
    res11 = sprintf("CH 1: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data1[pmin:pmax]), \
        array_op("max", tdc_data1[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data1[pmin:pmax]))
    res21 = sprintf("CH 2: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data2[pmin:pmax]), \
        array_op("max", tdc_data2[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data2[pmin:pmax]))
    res31 = sprintf("CH 3: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data3[pmin:pmax]), \
        array_op("max", tdc_data3[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data3[pmin:pmax]))

    plot_move(-50,0,res01)
    plot_move(-50,1,res11)
    plot_move(-50,2,res21)
    plot_move(-50,3,res31)

    plot_cntl("filter1")
}'


#-------------------------- _tdcsplotlog1 -----------------------
#%IU%
#%MDESC%
#  Internal macro to create plot and display 1D TDC spectrum using
#  standard SPEC plotting with logarithmic Y scale.
#  - abscissa array = coloumns array = tdc_xdata
#  - ordinate array = TDC data for ONE channel (0->3) which is passed
#                     as first parameter.
#  The range of TDC channels to be plotted is between minimum and 
#  maximum digitized TDC channel which are passed as parameters along
#  with macro name:
#  _tdcsplotlin1 <inch> <xmin> <xmax>
#
def _tdcsplotlog1 '{
    local chn pmin pmax
    local ii
    local res1 res2
    local min max

    chn = $1 
    pmin= $2
    pmax= $3 - 1

    plot_cntl("filter2")

    if (PLOT_MODE&128) {
        plot_cntl(sprintf("colors=%s",splot_col))
        plot_cntl("open")
        plot_cntl("-ylog +lines -dots -ebars")
    }

    plot_cntl("erase")
    plot_move(0,1,"TDC ACQ SPECTRUM")
    plot_move(0,2,"Counts")
    plot_move(0,-1,"Channels")

    for (ii = 0; ii < 4; ii++) {
        if (ii == chn) {
            if (chn == 0) {
                min = array_op("min", tdc_data0[pmin:pmax])
                max = array_op("max", tdc_data0[pmin:pmax])
            } else if (chn == 1) {
                min = array_op("min", tdc_data1[pmin:pmax])
                max = array_op("max", tdc_data1[pmin:pmax])
            } else if (chn == 2) {
                min = array_op("min", tdc_data2[pmin:pmax])
                max = array_op("max", tdc_data2[pmin:pmax])
            } else {
                min = array_op("min", tdc_data3[pmin:pmax])
                max = array_op("max", tdc_data3[pmin:pmax])
            }
        }
    }

    plot_range(pmin,pmax,min,max)

    plot_cntl("mca")
    plot_cntl("+ylog")
    if (chn == 0) {
        array_plot(tdc_xdata[pmin:pmax], tdc_data0[pmin:pmax])
    } else if (chn == 1) {
        array_plot(tdc_xdata[pmin:pmax], tdc_data1[pmin:pmax])
    } else if (chn == 2) {
        array_plot(tdc_xdata[pmin:pmax], tdc_data2[pmin:pmax])
    } else {
        array_plot(tdc_xdata[pmin:pmax], tdc_data3[pmin:pmax])
    }

    if (chn == 0) {
      res = sprintf("CH 0: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data0[pmin:pmax]), \
        array_op("max", tdc_data0[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data0[pmin:pmax]))
    } else if (chn == 1) {
      res = sprintf("CH 1: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data1[pmin:pmax]), \
        array_op("max", tdc_data1[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data1[pmin:pmax]))
    } else if (chn == 2) {
      res = sprintf("CH 2: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data2[pmin:pmax]), \
        array_op("max", tdc_data2[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data2[pmin:pmax]))
    } else {
      res = sprintf("CH 3: Peak at %.5g is %.5g.  COM at %.5g.   ", \
        array_op("row_at_max", tdc_data3[pmin:pmax]), \
        array_op("max", tdc_data3[pmin:pmax]), \
        array_op("com", tdc_xdata[pmin:pmax], tdc_data3[pmin:pmax]))
    }

    plot_move(-50,0,res)

    plot_cntl("filter1")
}'


#-------------------------- tdcplot -----------------------
#%UU%
#%MDESC%
#  Macro that wraps _tdcsplotlin and which is to be used without parameters
#  i.e. it creates a plot covering channels between TDC_PLOTMIN and 
#  TDC_PLOTMAX. It is defined to make a plot with linear Y-scale.
#  (need this definition before doing tdctolog where the macro is
#   redefined).
#
def tdcplot '{
   _tdcsplotlin TDC_PLOTMIN TDC_PLOTMAX
}'


#-------------------------- tdcplot0,1,2,3 -----------------------
#%UU%
#%MDESC%
#  Macro that wraps _tdcsplotlin1 for each one of 4 TDC input channels.
#  It creates a plot for selected TDC input channel covering
#  digitized channels between TDC_PLOTMIN and TDC_PLOTMAX.
#  It is defined to make a plot with linear Y-scale.
#  (need this definition before doing tdctolog where the macros are 
#   redefined).
#
def tdcplot0 '{_tdcsplotlin1 0 TDC_PLOTMIN TDC_PLOTMAX }'
def tdcplot1 '{_tdcsplotlin1 1 TDC_PLOTMIN TDC_PLOTMAX }'
def tdcplot2 '{_tdcsplotlin1 2 TDC_PLOTMIN TDC_PLOTMAX }'
def tdcplot3 '{_tdcsplotlin1 3 TDC_PLOTMIN TDC_PLOTMAX }'


#-------------------------- tdctolin -----------------------
#%UU%
#%MDESC%
#  Macro to redefine tdcplot (all 4 channels) and tdcplot1 (1 ch.)
#  to plot in linear Y-scale.
#
def tdctolin '{
   rdef tdcplot \'_tdcsplotlin TDC_PLOTMIN TDC_PLOTMAX\'
   rdef tdcplot0 \'_tdcsplotlin1 0 TDC_PLOTMIN TDC_PLOTMAX\'
   rdef tdcplot1 \'_tdcsplotlin1 1 TDC_PLOTMIN TDC_PLOTMAX\'
   rdef tdcplot2 \'_tdcsplotlin1 2 TDC_PLOTMIN TDC_PLOTMAX\'
   rdef tdcplot3 \'_tdcsplotlin1 3 TDC_PLOTMIN TDC_PLOTMAX\'
}'


#-------------------------- tdctolog -----------------------
#%UU%
#%MDESC%
#  Macro to redefine tdcplot (all 4 channels) and tdcplot1 (1 ch.)
#  to plot in logarithmic Y-scale.
#
def tdctolog '{
   rdef tdcplot \'_tdcsplotlog TDC_PLOTMIN TDC_PLOTMAX\'
   rdef tdcplot0 \'_tdcsplotlog1 0 TDC_PLOTMIN TDC_PLOTMAX\'
   rdef tdcplot1 \'_tdcsplotlog1 1 TDC_PLOTMIN TDC_PLOTMAX\'
   rdef tdcplot2 \'_tdcsplotlog1 2 TDC_PLOTMIN TDC_PLOTMAX\'
   rdef tdcplot3 \'_tdcsplotlog1 3 TDC_PLOTMIN TDC_PLOTMAX\'
}'


#-------------------------- tdcsplotrange -----------------------
#%UU%
#%MDESC%
#  Macro that allows to change limit channels for plotting if new 
#  limits are passed as input parameters. 
#  tdcsplotrange <xmin> <xmax>
#  If no parameters passed then TDC_PLOTMIN = 0           and 
#                               TDC_PLOTMAX = TDC_NBCOLS-1
#
def tdcsplotrange '{
    if ($#==2) {
        TDC_PLOTMIN= int($1)
        TDC_PLOTMAX= int($2)
        if (TDC_PLOTMIN<0||TDC_PLOTMIN>=TDC_NBCOLS-1) TDC_PLOTMIN= 0
        if (TDC_PLOTMAX<0||TDC_PLOTMAX>=TDC_NBCOLS-1) TDC_PLOTMAX= TDC_NBCOLS-1
    } else {
        TDC_PLOTMIN= 0
        TDC_PLOTMAX= TDC_NBCOLS-1
    }
    printf("TDC Plot Range is : %d - %d\n", TDC_PLOTMIN, TDC_PLOTMAX)
}'
#------------------------------------------------------------
# END of Plotting related macros 
#------------------------------------------------------------
#

#
# Some auxiliary macros
#

def tdcgetbank '{
    tdcstatus 1
    printf(" %d\n",TDC_ACQ_BANK)
}'

# to investigate problem with bank contents
def tdcinvest '{
    local acqtime pollper
    if ($# == 1) acqtime = $1
    else         acqtime = 1
    pollper = acqtime/5

    for (;;) {
        tdcgetbank
        tdcinitbanks 0 0
        tdcgetbank
        tdcstart acqtime
        tdcpoll pollper 0
        tdcreadbanks
        tdcdata
    }
}'


#%MACROS%
#%DEPENDENCIES%
#%PRE%
#  - The file %B%saveload.mac%B% has to be read in/loaded before
#    these macros are used
#%PRE%