esrf

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

#%TITLE% XDS_cub.mac
#%NAME% XDS board control
#%DESCRIPTION% Control of XDS boards for acquisition.
#%BR%In the spec setup, the user should define:
#%UL%
#%LI%- XDS_setup <device0> <virtex0> <spartan0> <device1> <virtex1> ...
#%BR% which defines the devices, virtex files and spartan list file.
#%LI%- The definition of ROIs that the user wants by
#board/mezzanin/channel.
#%XUL%
#%BR%*****************************************
#%BR%The XDS boards may have 1 or 2 mezzanines. 
#%BR%board numbers: [0..n]
#%BR%mezzanin: [1,2]
#%BR%channels: [1,2,3,4]
#%BR%*****************************************
#%BR%We apply the following conventions for all the boards:
#%BR%- if 2 mezzanins, always mezzanin 1 will be the master
#and mezzanin 2 will be the slave
#%BR%- timer bit is disabled (stop acquisition done by a software stop
#and the data are normalized with the real acquisition time).
#%BR%- modes for acquisition: there are 3 modes:
#%BR%-- softare mode: each board is started independently
#%BR%-- hardware mode: a board is defined by the user as master trig board
#and is supposed to be daisy chained to all the other to transmit the start
#of acquisition. master trig board is started by soft.
#%BR%-- hardware external mode: same as previous but the master trig board is 
#started by a hardware external signal.
#%BR%Modifications since the previous version:
#%BR%- XDS_get_hwctrl_new: now takes one file per board/mezz
#XDS_get_hwctrl remains the same
#%BR%- XDS_xxx instead of xds_xxx on useful commands
#%BR%- XDS_savegain/XDS_getgain: storage to file in spec format
#%BR%- XDS_ARR["FIR"] and XDS_ARR["hwctrl"]
#%BR%- XDS_load_virtex_spartan (instead of XDS_load_virtex_spartan)
#%BR%- XDS_savespec: remove .txt extension on data files (for matlab)
#%BR%- XDS_readroimatlab <file>
#%BR%- XDS_write_hwctrl <file>
#%BR%- XDS_debug
#%END%

long array XDS_acqen[2]
long array XDS_timer[2]
long array XDS_trig_hs[2]
long array XDS_trig_master[2]
long array XDS_tim_reg[2]
long array XDS_acq_tim_reg[2]
long array XDS_chan_en[2][4]
long array XDS_dac_en[2][4]
global XDSON
global XDSSCAN
global XDSHISTO
global XDS_size
global XDSROIS_LO
global XDSROIS_HI
global XDSROIS_nb
global XDSROISMNE_nb
global XDS_ARR XDS_NBDEV XDS_ROI
global XDS_statname
global XDS_stat
global ROI_FAST

#===============================================================
# XDS_setup
#===============================================================
#%UU% <device> <virtex> <spartanlist>
#%MDESC%list of XDS devices with virtex and spartan. The path to these files is
#/users/blissadm/local/spec/userconf/CUB/XDS/BIT. 
def XDS_setup'{
   
   local ii myarr nn jj 
   XDS_size = 0x2000

#  some definitions ...
   XDS_statname[0] = "pup8"
   XDS_statname[1] = "evt8"
   XDS_statname[2] = "pup6"
   XDS_statname[3] = "evt6"
   XDS_statname[4] = "pup4"
   XDS_statname[5] = "evt4"
 
   if($#){
      nn = split("$*",myarr)
      XDS_NBDEV = int(nn/3)
      if ( (XDS_NBDEV*3) != nn) {
         p "usage: XDS_setup <device0> <virtex0> <spartan0> <device1> ..."
         exit
      }
      jj = 0
      for (ii=0; ii<XDS_NBDEV; ii++) {
          XDS_ARR[ii]["dev"] = myarr[jj]
          jj++
          XDS_ARR[ii]["virtex"] = sprintf("/users/blissadm/local/spec/userconf/CUB/XDS/BIT/%s",myarr[jj])
          jj++
          XDS_ARR[ii]["spartan"] = sprintf("/users/blissadm/local/spec/userconf/CUB/XDS/BIT/%s",myarr[jj])
          jj++
      }
   }
   else {
      p "usage: XDS_setup <device0> <virtex0> <spartan0> <device1> ..."
      exit
   } 
	 

}'

#===============================================================
# XDS_load_virtex_spartan
#===============================================================
#%UU%[0,1,2]
#%MDESC%load list of XDS devices with virtex and spartan. The path to these files is
#/users/blissadm/local/spec/userconf/CUB/XDS/BIT. 
#%BR% 0 (or no parameter): load virtex then spartan
#%BR% 1: load virtex only
#%BR% 2: load spartan only
def XDS_load_virtex_spartan'{
   local ii mypar
	 
	 mypar = $1
	 if ( (mypar == 0) || (mypar == 1) ){
      for (ii=0; ii<XDS_NBDEV; ii++) {
         _XDS_LoadVirtex  ii XDS_ARR[ii]["virtex"]
      }
	 }
	 if ( (mypar == 0) || (mypar == 2) ) {
      for (ii=0; ii<XDS_NBDEV; ii++) {
         _XDS_LoadSpartanList  ii XDS_ARR[ii]["spartan"]
      }
	 
   
      XDSsetdim
      _XDS_preparearray 
	   
	 } 
   
}'

#===============================================================
# _XDS_LoadVirtex
#===============================================================
#%IU% <board> <bit file>
#%MDESC% loads virtex. A timeout of 40 sec is set for the load
#on the device
def _XDS_LoadVirtex '{
   local bitFile myboard
   
   if ($# != 2) { 
   
      p "usage: _XDS_LoadVirtex <board> <bit file>"
          exit
   }
   bitFile = $2
   myboard = XDS_ARR[$1]["dev"]

   printf("--- _XDS_LoadVirtex: [%s]\n", bitFile);
   esrf_io(myboard,"timeout",40)
   esrf_io(myboard,"DevLoadVirtex",bitFile)
   esrf_io(myboard,"timeout",0)

}'

#===============================================================
# _XDS_LoadSpartanList
#===============================================================
#%IU% <board> <bit file>
#%MDESC% loads spartan. A timeout of 40 sec is set for the load
#on the device 
def _XDS_LoadSpartanList '{
   local bitFileList myboard
   
   if ($# != 2) { 
      p "usage: _XDS_LoadSpartanList <board> <bit file>"
      exit
   }
   bitFileList = $2
   myboard = XDS_ARR[$1]["dev"]

   printf("--- _XDS_LoadSpartanList: [%s]\n", bitFileList);
   esrf_io(myboard,"timeout",40)
   esrf_io(myboard,"DevLoadSpartanList",bitFileList)
   esrf_io(myboard,"timeout",0)

}'

#===============================================================
# XDS_roisetup
#===============================================================
#%UU%<roi_mne> <roi_mne> ...
#%MDESC%declares how many ROIs to implement and the associated mnemonics
def XDS_roisetup'{

#   XDSROISetnb  $#
   split("$*",myarr)
	 XDSROISMNE_nb = $#
	 for (ii=0; ii<XDSROISMNE_nb; ii++) {
	    XDS_ROI["mne"][ii] = myarr[ii]
	 }
}'

#===============================================================
# XDSROISall
#===============================================================
#%UU% <roi1lo> <roi1hi> <roi2lo> <roi2hi> ...
#%MDESC% defines the rois for everybody.
def XDSROISall'{
    local mynb myarr ii jj kk  ll

   mynb = split("$*",myarr)
   mynb = mynb/2

   if (mynb > XDSROISMNE_nb) {
      p "too many rois(" mynb ") for the defined mnemonics(" XDSROISMNE_nb ")"
      exit
   }

   jj = 0
   for (ii=0; ii<mynb; ii++) {
      XDS_ROI["LO"][ii] = myarr[jj]
      XDS_ROI["HI"][ii] = myarr[jj+1]
      jj = jj+2
   }

   XDSROISinit mynb 

   for (ll=0; ll< XDSROIS_nb; ll++){
      for (ii=0; ii< XDS_NBDEV; ii++) {
         for (jj=1; jj<3; jj++) {
            for (kk=1; kk<5; kk++) {
#              if (XDSDEB >0) { p ii " " jj " " kk " " ll " "} 
               XDSROISadd ii jj kk ll XDS_ROI["LO"][ll] XDS_ROI["HI"][ll]
            }
         }
      }
   }
}'

#===============================================================
# XDSROISdisplay
#===============================================================
#%UU% <roi1lo> <roi1hi> <roi2lo> <roi2hi> ...
#%MDESC% defines the rois for everybody.
def XDSROISdisplay'{
    local iidis, jjdis, kkdis, lldis, disindex


	  for (iidis=0;iidis<XDS_NBDEV;iidis++) {
			for (jjdis=0; jjdis<2; jjdis++) {
				for (kkdis=0; kkdis<4; kkdis++) {
					disindex = (iidis*100) +(jjdis+1)*10 + (kkdis+1)
					for (lldis=0; lldis < XDSROIS_nb; lldis++) {
            printf("B#%1d-M#%1d-Ch#%1d : ROI#%2d : %4d - %4d\n", iidis, jjdis, kkdis, lldis, XDSROIS_LO[disindex][lldis],  XDSROIS_HI[disindex][lldis])
          }
        }
      }
   }
}'

#===============================================================
# XDSROISinit
#===============================================================
#%UU%<how_many_ROIs>
#%MDESC%declares how many ROIs to implement
def XDSROISinit'{

   unglobal XDSROIS_LO
   unglobal XDSROIS_HI
   global XDSROIS_LO
   global XDSROIS_HI
   long array total_roi[$1]
   long array tablu_roi[101*XDS_NBDEV][$1]   
   XDSROIS_nb =  $1
   ulong array tablu_roibm[XDS_NBDEV*2+1][$1]
        
}'

#===============================================================
# XDSROISadd
#===============================================================
#%UU%<board[0..]> <mezz[1,2]> <ch[1,2,3,4]> <roinb[0..]> <roilo> <roihi>
#%MDESC%defines a roi for a board/mezz/channel.
def XDSROISadd'{
   local mynb roiarr myb mymez mych ind roind
   
   mynb = split("$*",roiarr)
   
   if (mynb !=6) {
      p "usage: XDSROISadd <board[0..]> <mezz[1,2]> <ch[1,2,3,4]> <roinb[0..]> <roilo> <roihi>"
      exit
   }
	 
   myb = $1
   mymez = $2
   mych = $3
	 if (XDSDEB >0) {p myb " " mymez " " mych}
   if ( (myb <0) || (myb >= XDS_NBDEV) || ((mymez !=1) && (mymez !=2)) || \
        (mych <1 || (mych >4)) ){
      p "bad board mez or channel <board[0..]> <mezz[1,2]> <ch[1,2,3,4]> <roi1lo>..."
      exit
   }
	 
   roind = myb*100 + mymez*10 + mych
   ind = $4
   XDSROIS_LO[roind][ind] = $5
   XDSROIS_HI[roind][ind] = $6
}'

#===============================================================
# _XDS_checkifset
#===============================================================
#%IU%
#%MDESC% checks if XDS_ARR global associative array has
#been already set
def _XDS_checkifset'{
  if((whatis("XDS_ARR") & 0x08000000)) {
     p "ERROR: XDS_setup must be called first"
     exit
  }
}'

#===============================================================
# _XDS_preparearray
#===============================================================
#%IU%
#%MDESC%prepare the XDS_ARR array with some information.
#%BR%Should be called inside XDS_setup. 
#%BR%- reads if mezzanine 2 is present
#%BR%If following not already set decide that:
#%BR%- all boards are in use (can be changed with XDS_enable, XDS_disable)
#%BR%- work in software mode (can be changed with XDS_setmodehard, setmodehardext,
#setmodesoft)
#%BR%- enable all 4 channels on each mezzanine
#%BR%for all, mezzanine 1 is master and mezzanine 2 is slave (cannot be changed)
def _XDS_preparearray'{
   local ii mystr mm mystr
	 
#  define bmc (b*100+m*10+c) arrays
   long array XDSch_gain[101*XDS_NBDEV]
   long array XDSch_offset[101*XDS_NBDEV]
   long array XDSch_ramplo[101*XDS_NBDEV]
   long array XDSch_ramphi[101*XDS_NBDEV]
   long array XDSch_VRD[101*XDS_NBDEV]
   long array XDSch_VRE[101*XDS_NBDEV]
   long array XDSch_trig[101*XDS_NBDEV]

#  get information on mezzanine 2    
   for (ii=0; ii<XDS_NBDEV; ii++) {
      if (_XDSh_ismez2(ii)) {
         XDS_ARR[ii]["mezz2"] = 1
      }
      else {
         XDS_ARR[ii]["mezz2"] = 0
      }
   }

#  to start with some default values if not already set
#  both mezzanines are set, even if mezzanine 2 not present
#  XDS_ARR[ii]["mezz2"] will say if we use info of mezzanine 2. 

#  decide master trig board is the first
   if ( whatis("XDS_ARR[\"master_trig\"]") == 0) {   
      XDS_ARR["master_trig"] = 0
   }
#  decide mode software
   if (whatis("XDS_ARR[\"mode\"]") == 0) {   
      XDS_ARR["mode"] = 0
   }

   for (ii=0; ii<XDS_NBDEV; ii++) {
#     decide that everybody is valid
      mystr = sprintf("XDS_ARR[%d][\"used\"]",ii)
      if (whatis(mystr) == 0) {
        XDS_ARR[ii]["used"] = 1 
      }
#     decide that work in software mode
      mystr = sprintf("XDS_ARR[%d][\"hwbit_mezz1\"]",ii)
      if (whatis(mystr) == 0) {
        XDS_ARR[ii]["hwbit_mezz1"] = 0 
      }
      mystr = sprintf("XDS_ARR[%d][\"hwbit_mezz2\"]",ii)
      if (whatis(mystr) == 0) {
        XDS_ARR[ii]["hwbit_mezz2"] = 0 
      }
#     decide that timer is disable
      mystr = sprintf("XDS_ARR[%d][\"timerbit_mezz1\"]",ii)
      if (whatis(mystr) == 0) {
        XDS_ARR[ii]["timerbit_mezz1"] = 0 
      }
      mystr = sprintf("XDS_ARR[%d][\"timerbit_mezz2\"]",ii)
      if (whatis(mystr) == 0) {
        XDS_ARR[ii]["timerbit_mezz2"] = 0 
      }
#     decide that mezzanine 1 is master and 2 is slave  
      mystr = sprintf("XDS_ARR[%d][\"masterbit_mezz1\"]",ii)   
      if (whatis(mystr) == 0) {
        XDS_ARR[ii]["masterbit_mezz1"] = 1 
      }
      mystr = sprintf("XDS_ARR[%d][\"masterbit_mezz2\"]",ii)
      if (whatis(mystr) == 0) {
        XDS_ARR[ii]["masterbit_mezz2"] = 0 
      }
#     enable all 4 channels on both mezzanines
#     and define default roi for everyone
#     and set channel hardware controls to default
#     work on mezzanin 1
      mystr = sprintf("XDS_ARR[%d][\"ch11\"]",ii)
      if (whatis(mystr) == 0) {
         XDS_ARR[ii]["ch11"] = 1
				XDSROIS_LO[ii*100 + 10 + 1][1] = 1
				XDSROIS_HI[ii*100 + 10 + 1][1] = 2
         XDSch_gain[ii*100 + 10 + 1] = 0x800
         XDSch_offset[ii*100 + 10 + 1] = 0x800
         XDSch_ramplo[ii*100 + 10 + 1] = 0x400
         XDSch_ramphi[ii*100 + 10 + 1] = 0xC00
         XDSch_VRD[ii*100 + 10 + 1] = 0x00b000d0
         XDSch_VRE[ii*100 + 10 + 1] = 0x2c3200f0
         XDSch_trig[ii*100 + 10 + 1] = 0x50
      }
      mystr = sprintf("XDS_ARR[%d][\"ch12\"]",ii)
      if (whatis(mystr) == 0) {
         XDS_ARR[ii]["ch12"] = 1
				XDSROIS_LO[ii*100 + 10 + 2][1] = 1
				XDSROIS_HI[ii*100 + 10 + 2][1] = 2
         XDSch_gain[ii*100 + 10 + 2] = 0x800
         XDSch_offset[ii*100 + 10 + 2] = 0x800
         XDSch_ramplo[ii*100 + 10 + 2] = 0x400
         XDSch_ramphi[ii*100 + 10 + 2] = 0xC00
         XDSch_VRD[ii*100 + 10 + 2] = 0x00b000d0
         XDSch_VRE[ii*100 + 10 + 2] = 0x2c3200f0
         XDSch_trig[ii*100 + 10 + 2] = 0x50
      }
      mystr = sprintf("XDS_ARR[%d][\"ch13\"]",ii)
      if (whatis(mystr) == 0) {
         XDS_ARR[ii]["ch13"] = 1
				XDSROIS_LO[ii*100 + 10 + 3][1] = 1
				XDSROIS_HI[ii*100 + 10 + 3][1] = 2
         XDSch_gain[ii*100 + 10 + 3] = 0x800
         XDSch_offset[ii*100 + 10 + 3] = 0x800
         XDSch_ramplo[ii*100 + 10 + 3] = 0x400
         XDSch_ramphi[ii*100 + 10 + 3] = 0xC00
         XDSch_VRD[ii*100 + 10 + 3] = 0x00b000d0
         XDSch_VRE[ii*100 + 10 + 3] = 0x2c3200f0
         XDSch_trig[ii*100 + 10 + 3] = 0x50
      }
      mystr = sprintf("XDS_ARR[%d][\"ch14\"]",ii)
      if (whatis(mystr) == 0) {
         XDS_ARR[ii]["ch14"] = 1
				XDSROIS_LO[ii*100 + 10 + 4][1] = 1
				XDSROIS_HI[ii*100 + 10 + 4][1] = 2
         XDSch_gain[ii*100 + 10 + 4] = 0x800
         XDSch_offset[ii*100 + 10 + 4] = 0x800
         XDSch_ramplo[ii*100 + 10 + 4] = 0x400
         XDSch_ramphi[ii*100 + 10 + 4] = 0xC00
         XDSch_VRD[ii*100 + 10 + 4] = 0x00b000d0
         XDSch_VRE[ii*100 + 10 + 4] = 0x2c3200f0
         XDSch_trig[ii*100 + 10 + 4] = 0x50
      }
#     work on mezzanin 2
      mystr = sprintf("XDS_ARR[%d][\"ch21\"]",ii)
      if (whatis(mystr) == 0) {
         XDS_ARR[ii]["ch21"] = 1
				XDSROIS_LO[ii*100 + 2*10 + 1][1] = 1
				XDSROIS_HI[ii*100 + 2*10 + 1][1] = 2
         XDSch_gain[ii*100 + 2*10 + 1] = 0x800
         XDSch_offset[ii*100 + 2*10 + 1] = 0x800
         XDSch_ramplo[ii*100 + 2*10 + 1] = 0x400
         XDSch_ramphi[ii*100 + 2*10 + 1] = 0xC00
         XDSch_VRD[ii*100 + 2*10 + 1] = 0x00b000d0
         XDSch_VRE[ii*100 + 2*10 + 1] = 0x2c3200f0
         XDSch_trig[ii*100 + 2*10 + 1] = 0x50
      }
      mystr = sprintf("XDS_ARR[%d][\"ch22\"]",ii)
      if (whatis(mystr) == 0) {
         XDS_ARR[ii]["ch22"] = 1
				XDSROIS_LO[ii*100 + 2*10 + 2][1] = 1
				XDSROIS_HI[ii*100 + 2*10 + 2][1] = 2
         XDSch_gain[ii*100 + 2*10 + 2] = 0x800
         XDSch_offset[ii*100 + 2*10 + 2] = 0x800
         XDSch_ramplo[ii*100 + 2*10 + 2] = 0x400
         XDSch_ramphi[ii*100 + 2*10 + 2] = 0xC00
         XDSch_VRD[ii*100 + 2*10 + 2] = 0x00b000d0
         XDSch_VRE[ii*100 + 2*10 + 2] = 0x2c3200f0
         XDSch_trig[ii*100 + 2*10 + 2] = 0x50
      }
      mystr = sprintf("XDS_ARR[%d][\"ch23\"]",ii)
      if (whatis(mystr) == 0) {
         XDS_ARR[ii]["ch23"] = 1
 				XDSROIS_LO[ii*100 + 2*10 + 3][1] = 1
				XDSROIS_HI[ii*100 + 2*10 + 3][1] = 2
         XDSch_gain[ii*100 + 2*10 + 3] = 0x800
         XDSch_offset[ii*100 + 2*10 + 3] = 0x800
         XDSch_ramplo[ii*100 + 2*10 + 3] = 0x400
         XDSch_ramphi[ii*100 + 2*10 + 3] = 0xC00
         XDSch_VRD[ii*100 + 2*10 + 3] = 0x00b000d0
         XDSch_VRE[ii*100 + 2*10 + 3] = 0x2c3200f0
         XDSch_trig[ii*100 + 2*10 + 3] = 0x50
     }
      mystr = sprintf("XDS_ARR[%d][\"ch24\"]",ii)
      if (whatis(mystr) == 0) {
         XDS_ARR[ii]["ch24"] = 1
				XDSROIS_LO[ii*100 + 2*10 + 4][1] = 1
				XDSROIS_HI[ii*100 + 2*10 + 4][1] = 2
         XDSch_gain[ii*100 + 2*10 + 4] = 0x800
         XDSch_offset[ii*100 + 2*10 + 4] = 0x800
         XDSch_ramplo[ii*100 + 2*10 + 4] = 0x400
         XDSch_ramphi[ii*100 + 2*10 + 4] = 0xC00
         XDSch_VRD[ii*100 + 2*10 + 4] = 0x00b000d0
         XDSch_VRE[ii*100 + 2*10 + 4] = 0x2c3200f0
         XDSch_trig[ii*100 + 2*10 + 4] = 0x50
      }
   }
}'

#===============================================================
# XDS_showconf
#===============================================================
#%UU%
#%MDESC% Shows the XDS_ARR definitions
def XDS_showconf'{
   local ii inf jj 

   p "---------------------------------------- "   
   p "Your present XDS configuration is:"
   p " "
   p "   * XDS boards (not use: 0, in use: 1) are:"
   for (ii=0; ii<XDS_NBDEV; ii++) {
      inf = XDS_ARR[ii]["used"] 
      if (inf == 1) {
         inf = XDS_ARR[ii]["mezz2"] 
         p " "
         p "     board " ii ": used with " inf+1 " mezzanines" 
         for (jj=0; jj<4; jj++) {
            inf = XDS_ARR[ii][sprintf("ch%d",jj+11)] 
            p "       mezz1: channel" jj+1 ": " inf
         }
         if (XDS_ARR[ii]["mezz2"] ==1 ) {
            for (jj=0; jj<4; jj++) {
               inf = XDS_ARR[ii][sprintf("ch%d",jj+21)] 
               p "       mezz2: channel" jj+1 ": " inf
            }
         }
      }
      else {
         p " "
         p "     board " ii ": not used"
      }
   }

   p " "
   p "   * Working in: "
   inf = XDS_ARR["mode"]
   if (inf == 0) {
      p "       software mode"  
   } 
   else if (inf == 1) {
      p "       hardware mode"  
   } 
   else if (inf == 2) {
      p "       external hardware mode"  
   } 
   else {
      p "       UNKNOWN MODE !!!!"  
   }

   inf = XDS_ARR["master_trig"]
   p " "
   p "   * Master trig board is : " inf
   p "---------------------------------------- "  
}'

#===============================================================
# XDS_askforconf
#===============================================================
#%UU% 
#%MDESC%Proposes to change some parameters of the global XDS boards
#configuration.
def XDS_askforconf'{
   local ii inf rep jj

#  Change boards in use?
   rep = 0
   rep = getval("Do you want to change the boards or channels in use(0:no, 1:yes)?",rep)
   if (rep == 1){
      for (ii=0; ii<XDS_NBDEV; ii++) {
         rep = XDS_ARR[ii]["used"]  
         p " "
         rep = getval(sprintf("use board %d (0:no 1:yes)?",ii),rep)
         if (rep == 1) {
            XDS_enable ii
#           for mezzanin 1            
            for (jj =0; jj<4; jj++) {
               rep = XDS_ARR[ii][sprintf("ch%d",jj+11)]
               rep = getval(sprintf("   mezz1: use channel %d (0:no, 1: yes)?",jj+1),rep)
               if (rep == 1){
                  XDS_enable_ch ii 1 jj+1
               }
               else {
                  XDS_disable_ch ii 1 jj+1
               }
            }
            if (XDS_ARR[ii]["mezz2"] == 1) {
#           for mezzanin 2 
               for (jj =0; jj<4; jj++) {
                  rep = XDS_ARR[ii][sprintf("ch%d",jj+21)]
                  rep = getval(sprintf("   mezz2: use channel %d (0:no, 1: yes)?",jj+1),rep)
                  if (rep == 1){
                     XDS_enable_ch ii 2 jj+1
                  }
                  else {
                     XDS_disable_ch ii 2 jj+1
                  }
               }
            }
         }
         else {
            XDS_disable ii
         }
      }
   }

#  Changing the mode ?   
   rep = 0
   p " "
   rep = getval("do you want to change the mode (0:no, 1:yes)",rep)
   if (rep == 1) {
      rep = XDS_ARR["mode"]
      rep = getval("which mode (0:soft, 1:hard, 2:external hard)?",rep)
      if (rep == 0) {
         XDS_setmodesoft   
      } 
      else  if (rep == 1) {
         XDS_setmodehard   
      }
      else if (rep == 2) {
         XDS_setmodehardext 
      } 
   }

#  Changing the master trig board ? 
#  master trig board is meaningful only if hardware or external hardware mode
   if (XDS_ARR["mode"] != 0) {  
      rep = 0
      p " "
      rep = getval("do you want to change the master trig board (0:no, 1:yes)",rep)
      if (rep == 1) {
         rep = XDS_ARR["master_trig"]
         rep = getval(sprintf("which board among the used ones [0..%d]?",XDS_NBDEV-1),rep)
         XDS_setmastertrig rep
      }
   }

#  check in any case that master trig board is correct
   if ( ( (XDS_ARR["mode"] == 1) || (XDS_ARR["mode"] == 2)) && \
        (XDS_ARR[XDS_ARR["master_trig"]]["used"] == 0) ){
      p "YOUR MASTER TRIG BOARD IS NOT IN USE. YOU SHOULD DEFINE IT !!!"
      exit 
   }
}'

#===============================================================
# XDSh_applyarray
#===============================================================
#%UU%
#%MDESC%applies the XDS_ARR information on the boards in use
#%BR%- hw bit -
#%BR%- timer bit -
#%BR%- master/slave bit -
#%BR%- channels in use -
def XDSh_applyarray'{
   local ii mystr mm

#  if mode hardware, need to check that master trig is in use !!!
   if ((XDS_ARR["mode"] == 1) || (XDS_ARR["mode"] == 2) ){
      if (XDS_ARR[XDS_ARR["master_trig"]]["used"] == 0) {
         mm = XDS_ARR["master_trig"]
         p "master trig board " mm " not used !!!! exit"
         exit
      }
   }

#  now we can program the boards
   for (ii=0; ii< XDS_NBDEV; ii++) {
      if (XDS_ARR[ii]["used"] == 1) {
#        hardware bit
         XDSh_selectmez(ii,1)
         _XDSh_sethwbit ii XDS_ARR[ii]["hwbit_mezz1"]
         if (XDS_ARR[ii]["mezz2"]) {
            XDSh_selectmez(ii,2)
            _XDSh_sethwbit ii XDS_ARR[ii]["hwbit_mezz2"]
         }
         
#        timer
         XDSh_selectmez(ii,1)
         _XDSh_settimerbit ii XDS_ARR[ii]["timerbit_mezz1"]
         if (XDS_ARR[ii]["mezz2"]) {
            XDSh_selectmez(ii,2)
            _XDSh_settimerbit ii XDS_ARR[ii]["timerbit_mezz2"]
         }
         
#        master/slave
         XDSh_selectmez(ii, 1)
         _XDSh_sethmasterbit ii XDS_ARR[ii]["masterbit_mezz1"]
         if (XDS_ARR[ii]["mezz2"]) {
            XDSh_selectmez(ii, 2)
            _XDSh_sethmasterbit ii XDS_ARR[ii]["masterbit_mezz2"]
         }
         
#        channels in use
         XDSh_selectmez(ii, 1)
         _XDSh_setchannel ii XDS_ARR[ii]["ch11"] XDS_ARR[ii]["ch12"] XDS_ARR[ii]["ch13"] XDS_ARR[ii]["ch14"]
         if (XDS_ARR[ii]["mezz2"]) {
            XDSh_selectmez(ii, 2)
            _XDSh_setchannel ii XDS_ARR[ii]["ch21"] XDS_ARR[ii]["ch22"] XDS_ARR[ii]["ch23"] XDS_ARR[ii]["ch24"]
         }
      }
   }
}'

#===============================================================
# _XDS_isused
#===============================================================
#%IU% (XDS_index)
#%MDESC%returns 1 if used, 0 if not in use
def _XDS_isused(n)'{
  
  _XDS_checkifset
  
  return(XDS_ARR[n]["used"])
}'

#===============================================================
# XDS_enable
#===============================================================
#%UU% <XDS_index>
#%MDESC%define a board as in use
def XDS_enable'{

   if ($# == 1){
      XDS_ARR[$1]["used"] = 1
   }
}'

#===============================================================
# XDS_disable
#===============================================================
#%UU% <XDS_index>
#%MDESC%define a board as unused
def XDS_disable'{

   if ($# == 1){
      XDS_ARR[$1]["used"] = 0
   }
}'

#===============================================================
# XDS_enable_ch
#===============================================================
#%UU% <XDS_index> <mezz 1:2> <ch1:4>
#%MDESC%enables channel for a board,mezzanin
#%BR%- XDS_index: 0..
#%BR%- mezz: 1,2
#%BR%- ch: 1,2,3,4
def XDS_enable_ch'{
   local mych mymez
   
   if ($# == 3){
      mych = $2*10+$3
      XDS_ARR[$1][sprintf("ch%d",mych)] = 1
   }
}'

#===============================================================
# XDS_disable_ch
#===============================================================
#%UU% <XDS_index> <mezz 1:2> <ch1:4> 
#%MDESC%disable a channel for a board,mezza
#%BR%- XDS_index: 0..
#%BR%- mezz: 1,2
#%BR%- ch: 1,2,3,4
def XDS_disable_ch'{
   local mych
   
   if ($# == 3){
      mych = $2*10+$3
      XDS_ARR[$1][sprintf("ch%d",mych)] = 0
   }
}'

#===============================================================
# XDSh_selectmez
#===============================================================
#%UU% (<XDS_index>, <val>)
#%MDESC%select mezzanine (val:1 or 2)
def XDSh_selectmez(xds_ii,mez)'{
  local myp val dig myw
	
   myp[0] = 2
   myp[1] = 4
	 
	 if (XDSDEB >0) {p xds_ii mez}
        
   _XDS_checkifset

    val = esrf_io(XDS_ARR[xds_ii]["dev"],"DevReadReg32",myp)
#    printf("csr=%08x \n", val)
    dig = (mez - 1) << 21
    myw[0] = 2
    myw[1] = 4
    myw[2] = (val & 0xFF9FFFFF) | (dig & 0x600000)
#    printf("write%08x\n", myw[2])
  
    esrf_io(XDS_ARR[xds_ii]["dev"],"DevWriteReg32",myw)
    val = esrf_io(XDS_ARR[xds_ii]["dev"],"DevReadReg32",myp)
    dig = (val>>21) & 0x3
#    printf("Board#%d - PUDS#%d now addressed\n", xds_ii, dig + 1)
}'

#===============================================================
# _XDSh_ismez2
#===============================================================
#%IU% (<XDS_index>)
#%MDESC%returns 1 if mezzanine 2 is present, 0 if not
def _XDSh_ismez2(xds_i)'{
  local val myboard myp
  
  XDSh_selectmez( xds_i ,1)
  myp[0] = 2
#read CTRL register and extract mezpup bit
  myp[1] = 4
  val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myp)
  if ( (val>>15 & 0x01) == 0) {
     return(1)
  }
  else{
     return(0)
  }
}'

#===============================================================
# XDS_setmodehard
#===============================================================
#%UU%
#%MDESC%Set mode hardware on all the XDS boards. They are supposed to 
#be hardware trigged (daisy chain) by the mezzanine 1 of the master trig XDS board.
#%BR%the mezzanine 1 of master trig board is supposed to be software started
#-hw bit- is set to 1 to everybody but the mezzanine 1 of the master trig board.
def XDS_setmodehard'{
   local ii first

   first = 0   
   for (ii=0; ii<XDS_NBDEV; ii++) {
      if ( ii == XDS_ARR["master_trig"]){
         XDS_ARR[ii]["hwbit_mezz1"] = 0 
         XDS_ARR[ii]["hwbit_mezz2"] = 1 
      }
      else {
         XDS_ARR[ii]["hwbit_mezz1"] = 1 
         XDS_ARR[ii]["hwbit_mezz2"] = 1 
      }
  }
  XDS_ARR["mode"] = 1
}'

#===============================================================
# XDS_setmodehardext
#===============================================================
#%UU%
#%MDESC%Set mode hardware on all the XDS boards. They are supposed to 
#be hardware trigged (daisy chain) by the mezzanine 1 of the master trig board.
#-hw bit- will be set to 1 to every used board.
def XDS_setmodehardext'{
   local ii 
   
   for (ii=0; ii<XDS_NBDEV; ii++) {
        XDS_ARR[ii]["hwbit_mezz1"] = 1 
        XDS_ARR[ii]["hwbit_mezz2"] = 1 
   }
   XDS_ARR["mode"] = 2
}'

#===============================================================
# XDS_setmodesoft
#===============================================================
#%UU%
#%MDESC%Set mode sofware on the all the XDS boards:
#%BR%-hw bit- will be set to 0 for every used board.
def XDS_setmodesoft'{
   local ii 
   
   for (ii=0; ii<XDS_NBDEV; ii++) {
        XDS_ARR[ii]["hwbit_mezz1"] = 0 
        XDS_ARR[ii]["hwbit_mezz2"] = 0 
   }
   XDS_ARR["mode"] = 0
}'

#===============================================================
# XDS_setmastertrig
#===============================================================
#%UU% <XDS_index>
#%MDESC%Redefines the master trig board.
def XDS_setmastertrig'{
   local ii oldmaster myboard
   
   myboard = $1
   if (_XDS_isused(myboard) == 0){
      p "this board is not in use. exit"
      exit
   }
      
   XDS_ARR["master_trig"] = $1
   
#  need to redefine the mezzanines if mode hard with software trig 
#  of the master trig card
   if (XDS_ARR["mode"] == 1) {
      XDS_setmodehard   
   }
}'

#===============================================================
# _XDSh_sethwbit
#===============================================================
#%IU% <XDS_index> <val:0,1>
#%MDESC%set hardware bit to <val> on the selected mezzanine
#%BR%do nothing if board not in use
def _XDSh_sethwbit'{
   local myboard myval val myp

   if (XDSDEB >0) {p "---> in _XDSh_sethwbit"}
   myboard = $1
   myval = ($2 << 1) & 0x02
   myp[0] = 2
   myp[1] = 4
   if (_XDS_isused(myboard)) {
      val = esrf_io(XDS_ARR[myboard]["dev"],"DevReadReg32",myp)
      val = val & 0xFFFFFFFD
      myp[2] = val | myval 

      esrf_io(XDS_ARR[myboard]["dev"],"DevWriteReg32",myp)
   }      
}'

#===============================================================
# _XDSh_settimerbit
#===============================================================
#%IU% <XDS_index> <val:0,1>
#%MDESC%set timer bit to <val> on the selected mezzanine
#%BR%do nothing if board not in use
def _XDSh_settimerbit'{
   local myboard myval val myp

   if (XDSDEB >0) {p "---> in _XDSh_settimerbit"}
   myboard = $1
   myval = ($2 << 2) & 0x04
   myp[0] = 2
   myp[1] = 4
   if (_XDS_isused(myboard)) {
      val = esrf_io(XDS_ARR[myboard]["dev"],"DevReadReg32",myp)
      val = val & 0xFFFFFFFB
      myp[2] = val | myval

      esrf_io(XDS_ARR[myboard]["dev"],"DevWriteReg32",myp)
   }      
}'

#===============================================================
# _XDSh_sethmasterbit
#===============================================================
#%IU% <XDS_index> <val:0,1>
#%MDESC%set timer bit to <val> on the selected mezzanine
#%BR%do nothing if board not in use
def _XDSh_sethmasterbit'{
   local myboard myval val myp myw

   if (XDSDEB >0) {p "---> in _XDSh_sethmasterbit"}
   myboard = $1
   myval = ($2 << 3) & 0x08
   myp[0] = 2
   myp[1] = 4
   if (_XDS_isused(myboard)) {
      val = esrf_io(XDS_ARR[myboard]["dev"],"DevReadReg32",myp)
      val = val & 0xFFFFFFF7
      myw[0] = 2
      myw[1] = 4
      myw[2] = val | myval

      esrf_io(XDS_ARR[myboard]["dev"],"DevWriteReg32",myw)
   }      
}'

#===============================================================
# _XDSh_setchannel
#===============================================================
#%IU% <XDS_index> <ch1> <ch2> <ch3> <ch4>
#%MDESC%set channels on or off on an already selected mezzanine
#%BR%do nothing if board not in use
def _XDSh_setchannel'{
   local myboard myval val myctrl myp myw mych1 mych2 mych3 mych4

   if (XDSDEB >0) {p "---> in _XDSh_setchannel"}
   myboard = $1
   mych1 = $2
   mych2 = $3
   mych3 = $4
   mych4 = $5
   if (_XDS_isused(myboard)) {
#     myctrl = (mych1 << 3) | (mych2 << 2) | (mych3 << 1) | (mych4)
# debugged by GG 170409
     myctrl = (mych3 << 3) | (mych2 << 2) | (mych1 << 1) | (mych4)
     myp[0] = 2
     myp[1] = 0x18
     val = esrf_io(XDS_ARR[myboard]["dev"],"DevReadReg32",myp)
#clear existing
     val = val & 0xFFFFFF00
     myw[0] = 2
     myw[1] = 0x18
#set new
     myw[2] = val | ((myctrl<<4) & 0XF0) | (~myctrl & 0xF)
     if (XDSDEB >0) {printf("my=%02x,chan=%08x\n", ~myctrl & 0xF, myw[2])}
     esrf_io(XDS_ARR[myboard]["dev"],"DevWriteReg32",myw)
   }      
}'

#===============================================================
# _XDSh_razhisto
#===============================================================
#%IU% <XDS_index>
#%MDESC%Raz histogram memory of an already selected mezzanine
#%BR%do nothing if board not in use
def _XDSh_razhisto'{
   local myboard val myp myw dig

   if (XDSDEB >0) {p "---> in _XDSh_razhisto"}
   myboard = $1
   if (_XDS_isused(myboard)) {
     myp[0] = 2
     myp[1] = 4
     val = esrf_io(XDS_ARR[myboard]["dev"],"DevReadReg32",myp)
#clear existing raz_histo_bit(should not be)
     val = val & 0xFFFFFFDFF
     myw[0] = 2
     myw[1] = 4
#set raz_histo_bit
     myw[2] = val | 0x200
     esrf_io(XDS_ARR[myboard]["dev"],"DevWriteReg32",myw)
		 sleep(0.01)
#check raz_histo_done after a while
     myp[1] = 0x18
     val = esrf_io(XDS_ARR[myboard]["dev"],"DevReadReg32",myp)
     dig = (val >> 31) & 0x1
		 if (dig != 1) {
		   printf("problem in raz histo, Board#%d.\n", myboard);
		   if (XDSDEB >0) {printf("CSR_reg=%X, CHAN_reg=%X.\n", myw[2], val)};
		 }
#clear raz_histo_bit
     myw[2] = myw[2] & 0xFFFFFFDFF
     esrf_io(XDS_ARR[myboard]["dev"],"DevWriteReg32",myw)
   }      
}'

#===============================================================
# XDS_setparam
#===============================================================
#%UU% <silent>
#%MDESC%Proposes to change some parameters of the XDS boards global
#configuration before applying it to the hardware
#%BR%if give one parameter to the macro, applies the XDS_ARR conf
#without asking for confirmation
def XDS_setparam'{

   if ($# == 0) {
      XDS_showconf
      p " "

      XDS_askforconf
   }
   
   p " "
   p "Applying XDS_ARR parameters to the boards"
   XDSh_applyarray

}'

#===============================================================
# XDSsetdim
#===============================================================
def XDSsetdim '{
   
   shared float array XDS_ch[4][XDS_size]
   ulong array tablu[XDS_NBDEV*2+1][XDS_size*4]
   long array tablu_tim[XDS_NBDEV*2+1]
	
}'

#===============================================================
# XDSCsrR
#===============================================================
#%UU% <XDS_index>
#%MDESC%read csr of an already selected mezzanine
def XDSCsrR'{
   local myp val dig xds_i

   myp[0] = 2
   myp[1] = 4

   _XDS_checkifset
   xds_i = $1
        
   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myp)
   printf("--- XDS CSR_reg is: [0x%08x]\n", val)
   dig = (val>>21) & 0x3
   printf("PUDS#%d currently addressed\n", dig + 1)
   dig = (val>>15) & 0x1
   printf(dig ? "\tNo other PUDS plugged\n" : "\tAnother PUDS is plugged\n")
   dig = (val>>14) & 0x1
   printf(dig ? "\tMain DLL LOCKED OK\n" : "\t!!!! Main DLL UNLOCKED!!!\n")
   dig = (val>>13) & 0x1
   printf(dig ? "\tAcquisition running\n" : "\tNo acquisition\n")
   dig = (val>>12) & 0x1
   printf("\tAcquisition stop bit ")
   printf(dig ? "ON\n" : "OFF\n")
}'

#===============================================================
# XDSLedR
#===============================================================
#%UU% <XDS_index> 
#%MDESC%read LED_register of an already selected mezzanine
#%END%
def XDSLedR'{
  local myp val xds_i

   _XDS_checkifset
   xds_i = $1

   myp[0] = 2
   myp[1] = 0x20

   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myp)
   printf("--- XDS LED_reg is: [0x%08x]\n", val)
}'

#===============================================================
# XDSRegR
#===============================================================
#%UU% <XDS_index> <CSR_add>
#%MDESC%provide address and read any XDS register of an already selected mezzanine
#%END%
def XDSRegR(bb, mez, adreg)'{
  local myp, val
   myp[0] = 2
   myp[1] = adreg

   XDSh_selectmez(bb,mez)

   val = esrf_io(XDS_ARR[bb]["dev"],"DevReadReg32",myp)
   printf("--- XDS reg%08x is: [0x%08x]\n", adreg, val)
}'

#===============================================================
# XDSRegW
#===============================================================
#%UU% (<XDS_index>,<val>)
#%MDESC%write the value <val> in TST Register on board <XDS_index>
def XDSRegW(bb, mez, adreg, val32)'{
     local mytw
   
     mytw[0] = 2
     mytw[1] = adreg
     mytw[2] = val32 

     XDSh_selectmez(bb,mez)

     esrf_io(XDS_ARR[bb]["dev"],"DevWriteReg32",mytw)
}'

#===============================================================
# XDSLedW
#===============================================================
#%UU% <XDS_index> <val>
#%MDESC%Write LED_register of an already selected mezzanine
#%END%
def XDSLedW'{
   local myp xds_i
   
   _XDS_checkifset
   xds_i = $1

   myp[0] = 2
   myp[1] = 0x20
   myp[2] = $2 

   esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32",myp)
}'

#===============================================================
# XDSTstR
#===============================================================
#%UU%<XDS_index>
#%MDESC%
# seg=2, add=24h=36d
#MACRO: read TST Register
#%END%
def XDSTstR'{
   local myp val xds_i dig

   xds_i = $1
   if (_XDS_isused(xds_i)) {

     myp[0] = 2
     myp[1] = 0x24

     val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myp)
     printf("--- XDS TST_reg is: [0x%08x]\n", val)
     dig = (val>>20) & 0xF
     printf("DIG_out(0) is %01x\n", dig)
     dig = (val>>16) & 0xF
     printf("DIG_out(1) is %01x\n", dig)
     dig = val & 0x1
     printf("TEST_out(1) is ")
     printf((dig==0x1) ? "enabled.\n" : "disabled.\n")
     dig = (val>>08) & 0xF
     printf("\tTEST_out(1) is %01x\n", dig)
     dig = (val>>1) & 0x1
     printf("TEST_out(2) (=TRIGGER_OUT) is ")
     printf((dig==0x1) ? "enabled.\n" : "disabled.\n")
     dig = (val>>2) & 0x7
     printf("STEP_out_en is %01x\n", dig)
	}
}'

#===============================================================
# XDSTstW
#===============================================================
#%UU% <val>
#%MDESC%applies the TST_register setup (32bits) on the boards in use
def XDSTstW'{
   local ii

   for (ii=0; ii< XDS_NBDEV; ii++) {
      if (XDS_ARR[ii]["used"] == 1) {
         XDSh_selectmez(ii,1)
         _XDSTstW(ii, $1)
        if (XDS_ARR[ii]["mezz2"]) {
            XDSh_selectmez(ii,2)
            _XDSTstW(ii, $1)
         }
      }
   }
}'

#===============================================================
# _XDSTstW
#===============================================================
#%UU% (<XDS_index>,<val>)
#%MDESC%write the value <val> in TST Register on board <XDS_index>
def _XDSTstW(bb, val32)'{
     local mytw
   
     mytw[0] = 2
     mytw[1] = 0x24
     mytw[2] = val32 

     esrf_io(XDS_ARR[bb]["dev"],"DevWriteReg32",mytw)
}'

#===============================================================
# XDSIdR
#===============================================================
#%UU% <XDS_index>
#%MDESC%
# seg=2, add=2Ch=44d
#MACRO: read SDAC_ld Register
#%END%
def XDSIdR'{
   local myp val dig xds_i

   _XDS_checkifset
    xds_i = $1

   myp[0] = 2
   myp[1] = 0x2C

   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myp)
   printf("--- PUDS ID is : [0x%04x]\n", val)
	 
   dig = (val>>12) & 0xF
	 if (dig==0x2){
	    p "XDS"
	 }
	 else {
	     printf("board %d: !!!!!!!!!!!!PUDS IS NOT XDS !!!!\n",xds_i)
	 }
   #printf((dig==0x2) ? "\tXDS" : "\t!!!!!!!!!!!!PUDS IS NOT XDS !!!!\n")
   
}'

#===============================================================
# XDSSDacW
#===============================================================
#%UU% <XDS_index> <channel 1,2,3,4> <dac_type G,O,H,L> <12bit_val>
#%MDESC%
# seg=2, add=30h to 3Ch = 48d to 60d for SDAC_reg
# then seg=2, add=2Ch = 44d for SDAC_ld
#MACRO: write the value <val> in channel <cha> SDAC_reg
# at G(ain), O(ffset), H(igh_in_dscri), L(ow_in_discri)
# then load with SDAC_ld
#%END%
def XDSSDacW'{
   local myp cha val dac tru xds_i

    _XDS_checkifset
    xds_i = $1
   
   if($# != 4) {
      p "usage: XDSSDacW <XDS index> <channel 1,2,3,4> <dac_type G,O,H,L> <12bit_val>"
      exit
   }
   if($2 < 1) {
      p "usage:<channel 1,2,3,4>"
      exit
   }
   myp[0] = 2
   cha = $2
   dac = "$3"
   val = 0x$4 & 0xFFF
	 
   myp[1] = 0x30 + 4*((cha-1) % 4)
	 
   if(dac == "G") {
      tru = (0x9 << 28) | (val << 16)
   } else
   if(dac == "H") {
      tru = (0x9 << 12) | val
   } else
   if(dac == "O") {
      tru = (0xA << 28) | (val <<16)
   } else
   if(dac == "L") {
      tru = (0xA << 12) | val
   } else {
      p "usage:<dac_type G, O, H, L>"
   }
   if (XDSDEB >0) {printf ("sdac_add = %d ; sdac_val = %08x\n", myp[1], tru)}
   myp[2] = tru

   esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32", myp)

   myp[0] = 2
   myp[1] = 0x2C
   myp[2] = 0 

   esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32",myp)
}'

#===============================================================
# _XDS_setstatchan
#===============================================================
#%UU% (<XDS_index>,<mezz:1,2>,<ch1:4>)
#%MDESC%for that board/mezz, sets the channel number to be used for statistics
def _XDS_setstatchan(xds_i,mezz,mych)'{
     local myst val
   
   _XDS_checkifset

   if ( !_xds_check_board(xds_i) || !_xds_check_mezz(mezz) || !_xds_check_ch(mych) ){
      exit
   }
   
   if ( (mezz == 1) || ((mezz == 2) && (XDS_ARR[xds_i]["mezz2"] == 1))){
	    XDSh_selectmez(xds_i,mezz)
	 }
	 else{
	    p "board: " xds_i ": only one mezzanin !!!"
			exit 
	 }

   myst[0] = 2
   myst[1] = 0x08


#  read register and clear bits 4 and 5
   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myst)
	 printf("before setstatchan: %x\n",val)
   val = val & 0xFFFFFFCF

#  rewrite it, with the desired channel
   myst[2] = val | ((mych % 4)<< 4)
	 printf("setstatchan: %x\n",myst[2])
   esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32",myst)
}'

#===============================================================
# _XDS_getstatcnt
#===============================================================
#%UU% (<XDS_index>,<mezz:1,2>,<val:0..5>)
#%MDESC%for that board/mezz, defines the statistics to be read
def _XDS_getstatcnt(xds_i,mezz,myval)'{
     local myst mycnt val
   
   _XDS_checkifset

   if ( !_xds_check_board(xds_i) || !_xds_check_mezz(mezz) ){
      exit
   }
	 
	 if (myval <0 || myval >5 ){
	    p "stat number should be [0..5]"
	 }
	 

   if ( (mezz == 1) || ((mezz == 2) && (XDS_ARR[xds_i]["mezz2"] == 1))){
	    XDSh_selectmez(xds_i,mezz)
	 }
	 else{
	    p "board: " xds_i ": only one mezzanin !!!"
			exit 
	 }

   mycnt[0] = 2
   mycnt[1] = 0x08

#  1- defines the statistics counter
#  read register and clear bits 0..3
   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",mycnt)
##	 printf("before getstatchan: %x\n",val)
   val = val & 0xFFFFFFF0

#  rewrite it
   mycnt[2] = val | myval
   esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32",mycnt)
	 printf("getstatchan: %x\n",mycnt[2])
	 
#  2- read it	 
   myst[0] = 2
   myst[1] = 0x10

   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myst)

   return(val)
	 
}'

#===============================================================
# _XDS_clearstat
#===============================================================
#%UU% (<XDS_index>,<mezz:1,2>)
#%MDESC%
#MACRO:for that board/mezzanin, clear statistics counters
#%END%
def _XDS_clearstat(xds_i,mezz)'{
   local mya val

   _XDS_checkifset

   if ( !_xds_check_board(xds_i) || !_xds_check_mezz(mezz) ){
      exit
   }

   if ( (mezz == 1) || ((mezz == 2) && (XDS_ARR[xds_i]["mezz2"] == 1))){
	    XDSh_selectmez(xds_i,mezz)
	 }
	 else{
	    p "board: " xds_i ": only one mezzanin !!!"
			exit 
	 }

   mya[0] = 2
   mya[1] = 0x10
   mya[2] = 0
	 
   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32",mya)

}'

#===============================================================
# XDS_setstat
#===============================================================
#%UU% <XDS_index> <mezz:1,2> <ch:1..4>
#%MDESC%
#MACRO:for that board/mezzanin, sets channel for statistics
#%END%
def XDS_setstat'{
   local  myindice

   _XDS_setstatchan($1,$2,$3)
   myindice = (2*$1) + $2
   XDS_stat[myindice] = $3
}'

#===============================================================
# XDS_getstat
#===============================================================
#%UU% <XDS_index> <mezz:1,2> 
#%MDESC%
#MACRO:for that board/mezzanin, gets statistics for the previously selected channel
#%END%
def XDS_getstat'{
   local ii val myindice

   if ( !_xds_check_board($1) || !_xds_check_mezz($2) ){
      exit
   }

   myindice = (2*$1) + $2
	 p "XDS_getstat: board: " $1 " mezz: " $2 " channel: " XDS_stat[myindice]
	 
   for (ii=0; ii<6; ii++) {
      val = _XDS_getstatcnt($1,$2,ii)
			printf("   %s : 0x%x, %d\n",XDS_statname[ii],val, val)
	 }
	 
	 _XDS_clearstat($1,$2)

}'

#===============================================================
# XDSTimeR
#===============================================================
#%UU% (XDS_index)
#%MDESC%read TIMER_register of an already selected mezzanine
def XDSTimeR(xds_i)'{
   local myp val 
   myp[0] = 2
   myp[1] = 0x28

   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myp)
   tim = val/50E+06
   if (XDSDEB >0) {printf("--- XDS AcqTime is: [%e] s\n", tim)}
   return(val)
}'

#===============================================================
# XDSRout
#===============================================================
#%UU% (<XDS_index>,<val>)
#%MDESC%
# seg=2, add_ch4=4Ch, add_ch3=48h, add_ch2=44h, add_ch1=40h
#MACRO: Readout all channels together
#Read Channel 4,3,2,1 (front panel order top to bottom)
def XDSRout(xds_i,mymezza)'{
  local myp myw valu vald val xch pudid chen j mysize ii rr jd
  local bmcroi roind
  float array tabla[2*XDS_size]
	ulong array XDS_blocarr[0x800]

  if (XDSDEB >0) {p "XDSRout In " XDS_ARR[xds_i]["dev"]}
	if (XDSDEB >0) {p "board: " xds_i " mezza: " mymezza}
  _XDS_checkifset
#  xds_i = $1
#  mymezza = $2
  myindice = (2*xds_i) +mymezza

  myp[0] = 2
  myw[0] = 2

  XDSh_selectmez( xds_i, mymezza)
	
#	p "RAZ !!!"
#	if (mymezza == 2){
#	   _XDSh_razhisto mymezza
#	}
  
#=== get version
  myp[1] = 0x2C
  val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myp)
  pudid = (val>>12) & 0xF
  xch = val & 0xF
	if (XDSDEB > 0) {
	   p " board: " xds_i " mezza: " mymezza " pudid = " pudid " xch = " xch
  }
	
  if((pudid==0x2) & (xch==0x4)) {
     XDS_ch = 0


#    === readout channel#1
#    === clear read pointer
     myw[1] = 0x40
		 myw[2] = 0
     esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32", myw)
#    === read data
     myp[1] = 0x40
		 myp[2] =0x800
     bmcroi = 100*xds_i + 10* mymezza + 1
     for (rr=0; rr<XDSROIS_nb; rr++) {
       ROI_FAST[bmcroi][rr] = 0
     }
		 for (ii=0; ii<4; ii++) {
		    mysize = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadBloc32",myp,XDS_blocarr)
        if (!XDSSCAN) {
          for (j=0; j<0x800; j++) {
		        tablu[myindice][j+ii*0x800] = XDS_blocarr[j]
				  }
        }
        else {
          for (rr=0; rr<XDSROIS_nb; rr++) {
            if ((XDSROIS_LO[bmcroi][rr] >= 0x800*ii) && (XDSROIS_LO[bmcroi][rr] < 0x800*(ii+1))) {
              if (XDSROIS_HI[bmcroi][rr] < 0x800*(ii+1)) {
                for (jd=XDSROIS_LO[bmcroi][rr]; jd <= XDSROIS_HI[bmcroi][rr]; jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
              else {
                for (jd=XDSROIS_LO[bmcroi][rr]; jd < 0x800*(ii+1); jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
            }
            else {
              if ((XDSROIS_HI[bmcroi][rr] >= 0x800*ii) && (XDSROIS_HI[bmcroi][rr] < 0x800*(ii+1))) {
                for (jd=0x800*ii; jd <= XDSROIS_HI[bmcroi][rr]; jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
            }
          }
        }
		 }
#    bretelle
		 tablu[myindice][XDS_size-1] = tablu[myindice][XDS_size-2]
     
#    === readout channel#2
#    === clear read pointer
     myw[1] = 0x44
     esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32", myw)
#    === read data
     myp[1] = 0x44
		 myp[2] = 0x800
     bmcroi = 100*xds_i + 10* mymezza + 2
     for (rr=0; rr<XDSROIS_nb; rr++) {
       ROI_FAST[bmcroi][rr] = 0
     }
		 for (ii=0; ii<4; ii++) {
		    mysize = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadBloc32",myp,XDS_blocarr)		 
        if (!XDSSCAN) {
          for (j=0; j<0x800; j++) {
            tablu[myindice][j+ii*0x800+XDS_size] = XDS_blocarr[j]
				  }
        }
        else {
          for (rr=0; rr<XDSROIS_nb; rr++) {
            if ((XDSROIS_LO[bmcroi][rr] >= 0x800*ii) && (XDSROIS_LO[bmcroi][rr] < 0x800*(ii+1))) {
              if (XDSROIS_HI[bmcroi][rr] < 0x800*(ii+1)) {
                for (jd=XDSROIS_LO[bmcroi][rr]; jd <= XDSROIS_HI[bmcroi][rr]; jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
              else {
                for (jd=XDSROIS_LO[bmcroi][rr]; jd < 0x800*(ii+1); jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
            }
            else {
              if ((XDSROIS_HI[bmcroi][rr] >= 0x800*ii) && (XDSROIS_HI[bmcroi][rr] < 0x800*(ii+1))) {
                for (jd=0x800*ii; jd <= XDSROIS_HI[bmcroi][rr]; jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
            }
          }
        }
     }
#    bretelle
		 tablu[myindice][2*XDS_size-1] = tablu[myindice][2*XDS_size-2]
		      
#    === readout channel#3
#    === clear read pointer
     myw[1] = 0x48
     esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32", myw)
#    === read data
     myp[1] = 0x48
		 myp[2] = 0x800
     bmcroi = 100*xds_i + 10* mymezza + 3
     for (rr=0; rr<XDSROIS_nb; rr++) {
       ROI_FAST[bmcroi][rr] = 0
     }
		 for (ii=0; ii<4; ii++) {
		    mysize = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadBloc32",myp,XDS_blocarr)		 
        if (!XDSSCAN) {
          for (j=0; j<0x800; j++) {
            tablu[myindice][j+ii*0x800+(2*XDS_size)] = XDS_blocarr[j]
          }
        }
        else {
          for (rr=0; rr<XDSROIS_nb; rr++) {
            if ((XDSROIS_LO[bmcroi][rr] >= 0x800*ii) && (XDSROIS_LO[bmcroi][rr] < 0x800*(ii+1))) {
              if (XDSROIS_HI[bmcroi][rr] < 0x800*(ii+1)) {
                for (jd=XDSROIS_LO[bmcroi][rr]; jd <= XDSROIS_HI[bmcroi][rr]; jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
              else {
                for (jd=XDSROIS_LO[bmcroi][rr]; jd < 0x800*(ii+1); jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
            }
            else {
              if ((XDSROIS_HI[bmcroi][rr] >= 0x800*ii) && (XDSROIS_HI[bmcroi][rr] < 0x800*(ii+1))) {
                for (jd=0x800*ii; jd <= XDSROIS_HI[bmcroi][rr]; jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
            }
          }
        }
		 }
#    bretelle
		 tablu[myindice][3*XDS_size-1] = tablu[myindice][3*XDS_size-2]
		 
#    === readout channel#4
#    === clear read pointer
     myw[1] = 0x4C
     esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32", myw)
#    === read data
     myp[1] = 0x4C
		 myp[2] = 0x800
     bmcroi = 100*xds_i + 10* mymezza + 4
     for (rr=0; rr<XDSROIS_nb; rr++) {
       ROI_FAST[bmcroi][rr] = 0
     }
		 for (ii=0; ii<4; ii++) {
		    mysize = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadBloc32",myp,XDS_blocarr)		 
        if (!XDSSCAN) {
          for (j=0; j<0x800; j++) {
            tablu[myindice][j+ii*0x800+(3*XDS_size)] = XDS_blocarr[j]
          }
        }
        else {
          for (rr=0; rr<XDSROIS_nb; rr++) {
            if ((XDSROIS_LO[bmcroi][rr] >= 0x800*ii) && (XDSROIS_LO[bmcroi][rr] < 0x800*(ii+1))) {
              if (XDSROIS_HI[bmcroi][rr] < 0x800*(ii+1)) {
                for (jd=XDSROIS_LO[bmcroi][rr]; jd <= XDSROIS_HI[bmcroi][rr]; jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
              else {
                for (jd=XDSROIS_LO[bmcroi][rr]; jd < 0x800*(ii+1); jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
            }
            else {
              if ((XDSROIS_HI[bmcroi][rr] >= 0x800*ii) && (XDSROIS_HI[bmcroi][rr] < 0x800*(ii+1))) {
                for (jd=0x800*ii; jd <= XDSROIS_HI[bmcroi][rr]; jd++) {
                  ROI_FAST[bmcroi][rr] = ROI_FAST[bmcroi][rr] + XDS_blocarr[jd - (0x800*ii)]
                }
              }
            }
          }
        }
		 } 
#    bretelle
		 tablu[myindice][4*XDS_size-1] = tablu[myindice][4*XDS_size-2]		     
  }
  else {
        printf("board %d:\t!!!!!!!!!!!!PUDS IS NOT XDS !!!!\n",xds_i)
  }
    if (XDSDEB >0) {p "XDSRout leaving " }

}'

#===============================================================
# XDScton
#===============================================================
#%UU%
#%MDESC%enables pseudo count.
def XDScton'{
   local ii 

   cdef("user_getcounts","XDSctcalc_getcounts;","cubxds",0)
   cdef("user_precount","XDScount_precount;","cubxds",0)
   XDSON = 1

}'

#===============================================================
# XDSscanon
#===============================================================
#%UU%
#%MDESC%enables pseudo count.
def XDSscanon'{
   local ii 

   XDSSCAN = 1

}'

#===============================================================
# XDSctoff
#===============================================================
#%UU% 
#%MDESC%disables pseudo count.
def XDSctoff'{
   local ii 

   cdef("user_getcounts","","cubxds","delete")
   cdef("user_precount","","cubxds","delete")
   XDSON = 0

}'

#===============================================================
# XDSscanoff
#===============================================================
#%UU%
#%MDESC%enables pseudo count.
def XDSscanoff'{
   local ii 

   XDSSCAN = 0

}'

#===============================================================
# XDSbody
#===============================================================
#%IU% 
#%MDESC% For blmenu (use blmenu.mac).
def XDSbody(mode) '{

   if (mode == 1) {
      if (XDSON) {
         XDSctoff
      }
      else {
         XDScton
      }
      
   }
   return(sprintf("%s",XDSON?"ON":"OFF"))
}'

#===============================================================
# XDScount_precount
#===============================================================
#%IU%
#%MDESC%precount pseudo mechanism.Enables acqui on all boards mezzanines
#and finishing with the mezzanin 1 of master trig board
def XDScount_precount'{
   local ii
   
   
#  first tablu and tablu_roi are set to 0
   tablu = 0
#  now raz histogram memory on all used boards
   for (ii=0; ii<XDS_NBDEV; ii++) {
      if ( (XDS_ARR[ii]["used"] == 1) ) {
         XDSh_selectmez( ii, 1)
         _XDSh_razhisto ii
         if (XDS_ARR[ii]["mezz2"] == 1) {
            XDSh_selectmez( ii, 2)
            _XDSh_razhisto ii
         }
      }   
   }

#  then loop acq_en on all the boards but the master trig
   for (ii=0; ii<XDS_NBDEV; ii++) {
      if ( (ii != XDS_ARR["master_trig"]) && (XDS_ARR[ii]["used"] == 1) ) {
         XDSh_selectmez( ii, 1)
         XDSAcq_precount ii
         if (XDS_ARR[ii]["mezz2"] == 1) {
            XDSh_selectmez( ii, 2)
            XDSAcq_precount ii
         }
      }   
   }

#  now the master trig board
#  mezzanin 2 if any
#  we test that master trig board is in use because it could be
#  not used (allowed only in software mode)
   if ( (XDS_ARR[XDS_ARR["master_trig"]]["mezz2"] == 1) && \
        (XDS_ARR[XDS_ARR["master_trig"]]["used"] == 1) ) {
      XDSh_selectmez( XDS_ARR["master_trig"], 2)
      XDSAcq_precount XDS_ARR["master_trig"]
   }

#  mezzanin 1
   if (XDS_ARR[XDS_ARR["master_trig"]]["used"] == 1){
      XDSh_selectmez( XDS_ARR["master_trig"], 1)
      XDSAcq_precount XDS_ARR["master_trig"]
   }
}'

#===============================================================
# XDSAcq_precount
#===============================================================
#%IU% <XDS_index>
#%MDESC%enables acquisitions on a board, on the already selected 
#mezzanin.
#%BR%- Stop acqui
#%BR%- Read CSR
#%BR%- set acq_en bit in CSR
#%END%
def XDSAcq_precount'{
   local myp val dig ryp xds_i mez

   _XDS_checkifset
   xds_i = $1
	 
#  acquisition should not run   
   XDSAcqStop(xds_i)

   myp[0] = 2
   myp[1] = 4

   val = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",myp)
   val = val & 0xFFFFFFFE
#  now set acq_en_bit 
   myp[2] = val | 0x1

   esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32",myp)
}'

#===============================================================
# XDSAcqStop
#===============================================================
#%UU% (XDS_index)
#%MDESC%stop acquisition on the specified board, on the 
#already selected mezzanin
def XDSAcqStop(xds_i)'{
   local ryp dig

   _XDS_checkifset

   ryp[0] = 2
   ryp[1] = 4
   dig = esrf_io(XDS_ARR[xds_i]["dev"],"DevReadReg32",ryp)
#  clear acq_en_bit 
   ryp[2] = dig & 0xFFFFFFFE

   esrf_io(XDS_ARR[xds_i]["dev"],"DevWriteReg32",ryp)

}'

#===============================================================
# XDSctcalc_getcounts
#===============================================================
#%IU%
#%MDESC%pseudo reading data mechanism.
#gets the data for mezzanin 1, and mezzanin 2 (if exists)
def XDSctcalc_getcounts'{
   local ii

#  first stops the master trig board
#  mezzanin 1
   if (XDS_ARR[XDS_ARR["master_trig"]]["used"] == 1) {
      XDSh_selectmez( XDS_ARR["master_trig"], 1)
      XDSAcqStop(XDS_ARR["master_trig"])

#     mezzanin 2 if any
      if (XDS_ARR[XDS_ARR["master_trig"]]["mezz2"] == 1) {
         XDSh_selectmez(XDS_ARR["master_trig"], 2)
         XDSAcqStop(XDS_ARR["master_trig"])
      }
   }

#  then stop the others
   for (ii=0; ii<XDS_NBDEV; ii++) {
      if ((ii != XDS_ARR["master_trig"]) && XDS_ARR[ii]["used"] == 1){
         XDSh_selectmez(ii,1)
         XDSAcqStop(ii)

#        mezzanin 2 if any
         if (XDS_ARR[ii]["mezz2"] == 1) {
            XDSh_selectmez(ii,2)
            XDSAcqStop(ii)
         }
      }
   }

#  now get the result and calculate per board and mezzanin
   total_roi = 0
   for (ii=0; ii<XDS_NBDEV; ii++) {
      if (XDS_ARR[ii]["used"] == 1) {
         XDSh_selectmez(ii,1)
         _XDSctcalc_getcounts(ii,1)
         XDS_calc(ii,1)
         if (XDS_ARR[ii]["mezz2"] == 1){
            XDSh_selectmez(ii,2)
            _XDSctcalc_getcounts(ii,2)
            XDS_calc(ii,2)
         }
      }
   }

   for (ii=0; ii< XDSROIS_nb; ii++) {
      if (cnt_num(XDS_ROI["mne"][ii]) != -1){
         S[cnt_num(XDS_ROI["mne"][ii])] = total_roi[ii]
      }

      for (jj=0; jj<XDS_NBDEV;jj++){
         for (kk=0; kk<2; kk++) {
            local cntbm
            cntbm = sprintf("%s_%d%d",XDS_ROI["mne"][ii],jj,kk+1)
            if (cnt_num(cntbm) != -1){
               S[cnt_num(cntbm)] = tablu_roibm[2*jj + kk+1][ii]
	    }
	    local ll
	    for (ll=0; ll<4; ll++) {
	       local cntbmc
	       cntbmc = sprintf("%s%d%d%d",XDS_ROI["mne"][ii],jj,kk+1,ll+1)
               if (cnt_num(cntbmc) != -1){
                  S[cnt_num(cntbmc)] = tablu_roi[jj*100+(kk+1)*10+(ll+1)][ii]
	       }
	    }
	 }
      }
   }

}'

#===============================================================
# XDSctnico_getcounts
#===============================================================
#%IU%
#%MDESC%pseudo reading data mechanism.
#gets the data for mezzanin 1, and mezzanin 2 (if exists)
def XDSctnico_getcounts'{
   local ii nicoch nicotot

#  first stops the master trig board
#  mezzanin 1
   if (XDS_ARR[XDS_ARR["master_trig"]]["used"] == 1) {
      XDSh_selectmez( XDS_ARR["master_trig"], 1)
      XDSAcqStop(XDS_ARR["master_trig"])

#     mezzanin 2 if any
      if (XDS_ARR[XDS_ARR["master_trig"]]["mezz2"] == 1) {
         XDSh_selectmez(XDS_ARR["master_trig"], 2)
         XDSAcqStop(XDS_ARR["master_trig"])
      }
   }

#  then stop the others
   for (ii=0; ii<XDS_NBDEV; ii++) {
      if ((ii != XDS_ARR["master_trig"]) && XDS_ARR[ii]["used"] == 1){
         XDSh_selectmez(ii,1)
         XDSAcqStop(ii)

#        mezzanin 2 if any
         if (XDS_ARR[ii]["mezz2"] == 1) {
            XDSh_selectmez(ii,2)
            XDSAcqStop(ii)
         }
      }
   }

#  now get the result and calculate per board and mezzanin
   total_roi = 0
   for (ii=0; ii<XDS_NBDEV; ii++) {
      if (XDS_ARR[ii]["used"] == 1) {
         XDSh_selectmez(ii,1)
         _XDSctcalc_getcounts(ii,1)
         XDS_calc(ii,1)
         if (XDS_ARR[ii]["mezz2"] == 1){
            XDSh_selectmez(ii,2)
            _XDSctcalc_getcounts(ii,2)
            XDS_calc(ii,2)
         }
      }
   }

   for (ii=0; ii< XDSROIS_nb; ii++) {
       
      local cntbm
      cntbm = sprintf("%s_A",XDS_ROI["mne"][ii])
      if (cnt_num(cntbm) != -1){
			  nicotot = 0
				nicoch = 0
        #loop on histo, A1-D0-224
				bmcind = 100*2 + 10*2 + 3
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*2+2][(3*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, A2-D1-223
				bmcind = 100*2 + 10*2 + 2
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*2+2][(2*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, A3-D2-222
				bmcind = 100*2 + 10*2 + 1
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*2+2][(1*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, A4-D3-221
				bmcind = 100*2 + 10*2 + 0
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*2+2][(0*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, A5-D4-214
				bmcind = 100*2 + 10*1 + 3
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*2+1][(3*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        S[cnt_num(cntbm)] = nicotot
	    }
      cntbm = sprintf("%s_B",XDS_ROI["mne"][ii])
      if (cnt_num(cntbm) != -1){
			  nicotot = 0
				nicoch = 0
        #loop on histo, B1-D5-213
				bmcind = 100*2 + 10*1 + 2
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*2+1][(2*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, B2-D6-212
				bmcind = 100*2 + 10*1 + 1
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*2+1][(1*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, B3-D7-211
				bmcind = 100*2 + 10*1 + 0
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*2+1][(0*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, B4-D8-121
				bmcind = 100*1 + 10*2 + 0
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*1+2][(0*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, B5-D9-122
				bmcind = 100*1 + 10*2 + 1
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*1+2][(1*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        S[cnt_num(cntbm)] = nicotot
	    }
      cntbm = sprintf("%s_C",XDS_ROI["mne"][ii])
      if (cnt_num(cntbm) != -1){
			  nicotot = 0
				nicoch = 0
        #loop on histo, C1-D10-123
				bmcind = 100*1 + 10*2 + 2
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*1+2][(2*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, C2-D11-124
				bmcind = 100*1 + 10*2 + 3
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*1+2][(3*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, C3-D12-111
				bmcind = 100*1 + 10*1 + 0
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*1+1][(0*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, C4-D13-112
				bmcind = 100*1 + 10*1 + 1
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*1+1][(1*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, C5-D14-113
				bmcind = 100*1 + 10*1 + 2
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*1+1][(2*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        S[cnt_num(cntbm)] = nicotot
	    }
      cntbm = sprintf("%s_D",XDS_ROI["mne"][ii])
      if (cnt_num(cntbm) != -1){
			  nicotot = 0
				nicoch = 0
        #loop on histo, D1-D15-114
				bmcind = 100*1 + 10*1 + 3
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*1+1][(3*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, D2-D16-021
				bmcind = 100*0 + 10*2 + 0
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*0+2][(0*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, D3-D17-022
				bmcind = 100*0 + 10*2 + 1
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*0+2][(1*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, D4-D18-023
				bmcind = 100*0 + 10*2 + 2
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*0+2][(2*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, D5-D19-024
				bmcind = 100*0 + 10*2 + 3
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*0+2][(3*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        S[cnt_num(cntbm)] = nicotot
	    }
      cntbm = sprintf("%s_E",XDS_ROI["mne"][ii])
      if (cnt_num(cntbm) != -1){
			  nicotot = 0
				nicoch = 0
        #loop on histo, E3-D20-011
				bmcind = 100*0 + 10*1 + 0
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*0+1][(0*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, E4-D21-321
				bmcind = 100*3 + 10*2 + 0
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*3+2][(0*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, E5-D22-013
				bmcind = 100*0 + 10*1 + 2
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*0+1][(2*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        S[cnt_num(cntbm)] = nicotot
	    }
      cntbm = sprintf("%s_F",XDS_ROI["mne"][ii])
      if (cnt_num(cntbm) != -1){
			  nicotot = 0
				nicoch = 0
        #loop on histo, F1-D23-014
				bmcind = 100*0 + 10*1 + 3
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*0+1][(3*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, F2-D28-012
				bmcind = 100*0 + 10*1 + 1
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*0+1][(1*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, F3-D25-312
				bmcind = 100*3 + 10*1 + 1
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*3+1][(1*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, F4-D26-313
				bmcind = 100*3 + 10*1 + 2
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*3+1][(2*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, F5-D27-314
				bmcind = 100*3 + 10*1 + 3
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*3+1][(3*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        S[cnt_num(cntbm)] = nicotot
	    }
      cntbm = sprintf("%s_G",XDS_ROI["mne"][ii])
      if (cnt_num(cntbm) != -1){
			  nicotot = 0
				nicoch = 0
        #loop on histo, G1-D24-311
				bmcind = 100*3 + 10*1 + 0
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*3+1][(0*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, G2-D29-323
				bmcind = 100*3 + 10*2 + 2
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*3+2][(2*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, G3-D30-322
				bmcind = 100*3 + 10*2 + 1
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*3+2][(1*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        #loop on histo, G4-D31-324
				bmcind = 100*3 + 10*2 + 3
        for (jjn=XDSROIS_LO[bmcind][ii];jjn<XDSROIS_HI[bmcind][ii];jjn++) {
          nicoch = nicoch + tablu[2*3+2][(3*XDS_size)+jjn]
				}
				nicotot = nicotot + nicoch
				nicoch = 0
        S[cnt_num(cntbm)] = nicotot
	    }
	 }
}'

#===============================================================
# _XDSctcalc_getcounts
#===============================================================
#%IU%(xds_index,mezza)
#%MDESC%get data for a particular mezzanin (1 or 2)
#%BR%this macro provides also 4 blocks of data corresponding to each channel
#of the mezzanin.
#%BR%- xds_index : 0..
#%BR%- mezza: 1,2
def _XDSctcalc_getcounts(xds_i,mezzaa)'{
   local tim ii

   XDSh_selectmez(xds_i,mezzaa)
   tim = XDSTimeR(xds_i)
   if (XDSDEB >0) {p tim}
   tablu_tim[xds_i*2+mezzaa] = tim
#  read
   XDSRout( xds_i,mezzaa)
}'

#===============================================================
# XDS_calc
#===============================================================
#%IU%(xds_index,mezza)
#%MDESC%calculate data for a particular board/mezzanin 
#%BR%- xds_index : 0..
#%BR%- mezza: 1,2
def XDS_calc(xds_i,mezzab)'{
   if (XDSDEB >0) {p "in XDS_calc"}
   if (mezzab == 1) {
      for (jj=0; jj<4; jj++) {
         if (XDS_ARR[xds_i][sprintf("ch%d",jj+11)] == 1) {
#           data for this channel is requested         
            XDS_calcdef(xds_i,mezzab,jj+1)
         }
      }
      XDS_calcdefbm(xds_i,mezzab)
   }
   else if (mezzab == 2) {
      for (jj=0; jj<4; jj++) {
         if (XDS_ARR[xds_i][sprintf("ch%d",jj+21)] == 1) {
#           data for this channel is requested         
            XDS_calcdef(xds_i,mezzab,jj+1)
         }
      }   
      XDS_calcdefbm(xds_i,mezzab)
   }
}'

#===============================================================
# XDS_calcdef
#===============================================================
#%IU%(XDS_index,mezzac,ch)
#%MDESC%calculates the ROIs  for a particular board/mezzanin/channel 
#%BR%raw data to be extracted from tablu
#%BR%- XDS_index : 0..
#%BR%- mezzac: 1,2
#%BR%- ch: 1,2,3,4 
def XDS_calcdef(i0_i,mezzac,ch)'{

   local ii jj mezindice bmcind

   mezindice = 2*i0_i + mezzac
   bmcind = i0_i*100 + mezzac*10 + ch

   if (!XDSSCAN) {
     for (ii=0; ii<XDSROIS_nb; ii++) {
       tablu_roi[bmcind][ii] = 0
       for (jj=XDSROIS_LO[bmcind][ii];jj<XDSROIS_HI[bmcind][ii];jj++) {
         tablu_roi[bmcind][ii] = tablu_roi[bmcind][ii] + tablu[mezindice][((ch-1)*XDS_size)+jj]
       }
       total_roi[ii] = total_roi[ii] + tablu_roi[bmcind][ii]
     }
   }
   else {
     for (ii=0; ii<XDSROIS_nb; ii++) {
       total_roi[ii] = total_roi[ii] + ROI_FAST[bmcind][ii]
     }
   }
}'

#===============================================================
# XDS_calcdefbm
#===============================================================
#%IU%(XDS_index,mezzac)
#%MDESC%calculates the ROIs  for a particular board/mezzanin
#%BR%raw data to be extracted from tablu
#%BR%- XDS_index : 0..
#%BR%- mezzac: 1,2
def XDS_calcdefbm(i0_i,mezzac)'{

   local ii jj mezindice bmcind kk

   mezindice = 2*i0_i + mezzac

   for (kk=0; kk<XDSROIS_nb; kk++) {
       tablu_roibm[mezindice][kk]= 0
   } 
     
   #loop on channels (bmc)
   for (kk=0; kk<4; kk++){
      bmcind = i0_i*100 + mezzac*10 + (kk+1)
      #loop on ROISs
      for (ii=0; ii<XDSROIS_nb; ii++) {
         #loop on histo
         if (!XDSSCAN) {
           for (jj=XDSROIS_LO[bmcind][ii];jj<XDSROIS_HI[bmcind][ii];jj++) {
             tablu_roibm[mezindice][ii] = tablu_roibm[mezindice][ii] + tablu[mezindice][((kk)*XDS_size)+jj]
	         }
         }
         else {
           tablu_roibm[mezindice][ii] = tablu_roibm[mezindice][ii] + ROI_FAST[bmcind][ii]
         }
      }
   }
   
}'


#===============================================================
# XDS_putconf
#===============================================================
#%UU%<filename>
#%MDESC%stores the present XDS configuration on <filename>
#(under ~blissadm/local/spec/userconf)
def XDS_putconf'{
   local ii mystr myofile mycompletefile ret jj
   
   if ($# == 0) {
      p "usage: XDS_putconf <filename>"
      exit
   }
   myofile = "$1"
   p myofile
   mycompletefile = "~blissadm/local/spec/userconf/" myofile
   if (unix(sprintf("test -s %s",mycompletefile))){
      p "Writing configuration to file " mycompletefile
   }
   else{
      p "file already exists. exit"
      exit
   }    
   ret = open(mycompletefile)
   if (ret == -1) {
      p "cannot open file" mycompletefile
      p "exit"
      exit
   }
   on(mycompletefile);offt
   
   printf("#XDS");printf("\n")
   printf("#dev ")
   for (ii=0; ii<XDS_NBDEV; ii++){
      if (XDS_ARR[ii]["used"] == 1) {
        printf("%s ",XDS_ARR[ii]["dev"])
      }
   }
   printf("\n")

   printf("#mezz2 ")
   for (ii=0; ii<XDS_NBDEV; ii++){
      if (XDS_ARR[ii]["used"] == 1) {
        printf("%d ",XDS_ARR[ii]["mezz2"])
      }
   }
   printf("\n")

   for (jj=1; jj<5; jj++) {
      printf("#m1ch%d ",jj)
      for (ii=0; ii<XDS_NBDEV; ii++){
         if (XDS_ARR[ii]["used"] == 1) {
           printf("%d ",XDS_ARR[ii][sprintf("ch%d",jj+10)])
         }
      }
      printf("\n")
   }

   for (jj=1; jj<5; jj++) {
      printf("#m2ch%d ",jj)
      for (ii=0; ii<XDS_NBDEV; ii++){
         if (XDS_ARR[ii]["used"] == 1) {
           printf("%d ",XDS_ARR[ii][sprintf("ch%d",jj+20)])
         }
      }
      printf("\n")
   }
   
   printf("#mode %d\n",XDS_ARR["mode"])   
   printf("#master_trig %d\n",XDS_ARR["master_trig"])   
      
   ont;close(mycompletefile)
}'

#===============================================================
# _XDS_compat_nbdev
#===============================================================
#%IU% (nb_devref,nb_dev)
#%MDESC% verifies if the number of elements are compatible
#to the reference number.
#%BR% return: 0 if not ok, 1 if ok
def _XDS_compat_nbdev(nb_devref,nb_dev)'{
    if ( (nb_devref == 0) || (nb_dev == nb_devref) ){
       return(1)
    }
    else {
       return(0)
    }
}'

#===============================================================
#  XDS_getFIR
#===============================================================
#%UU%<filename>
#%MDESC%reads a configuration file (under ~blissadm/local/spec/userconf)
#and applies it to the hardware
def XDS_getFIR'{
   local myf
   
   if ($# != 1) {
      p "usage: XDS_getFIR <filename>"
      exit
   }
   p "-> Reading file " "$1"
   _XDS_getFIR $*
	 XDS_ARR["FIR"] = "$1"
   
   p "->Applying FIR coefs "
   XDSh_applyFIR
}'

#===============================================================
# _XDS_getFIR
#===============================================================
#%IU% <filename>
#%MDESC%reads the FIR file in ~blissadm/local/spec/userconf 
def _XDS_getFIR'{
   local myfile myf ii cont ret ret0 tmpcoef
	 
   global XDS_sampling XDS_puldecay XDS_pulrise XDS_pulflat XDS_firsigma
   long array XDS_fircoef[96]
   
   myf = "$1"
   myfile = "/users/blissadm/local/spec/userconf/CUB/XDS/FIR/" myf
   p "reading file " myfile
	 cont[0]=0
   ret0 = getline(myfile,"open")
   if (ret0 != -1) {
	    for (ii=0;ii<4;ii++) {
         ret0 = getline(myfile)
         if (ret0 == -1) {
            getline(myfile,"close")
						exit  
         }		 
#        to remove the trailing newline, to be able to correctly compare strings.
         ret = substr(ret0,1,length(ret0)-1)
         sscanf(ret,"%f",cont[ii])
			}
			XDS_sampling = cont[0]
			XDS_puldecay = cont[1]
			XDS_pulrise = cont[2]
			XDS_pulflat = cont[3]
			XDS_firsigma = 0
	    for (ii=0;ii<96;ii++) {
         ret0 = getline(myfile)
         if (ret0 == -1) {
            getline(myfile,"close")
						exit  
         }		 
#        to remove the trailing newline, to be able to correctly compare strings.
         ret = substr(ret0,1,length(ret0)-1)
         sscanf(ret,"%d",tmpcoef)
				 XDS_fircoef[ii] = (tmpcoef >> 2)
				 if (XDSDEB >0) {p "fir ii="ii " coef="XDS_fircoef[ii]}
				 XDS_firsigma = XDS_firsigma + XDS_fircoef[ii]
			}
			p "sigma = "XDS_firsigma
      getline(myfile,"close")
   }
}'


#===============================================================
#  XDS_readroimatlab
#===============================================================
#%UU%<filename>
#%MDESC%reads a roi file (under ~blissadm/local/spec/userconf/CUB/XDS/ROI)
def XDS_readroimatlab'{
   local myf
   
   if ($# != 1) {
      p "usage: XDS_readroimatlab <filename>"
      exit
   }
   p "-> Reading file " "$1"
   _XDS_readroimatlab $*
	 XDS_ARR["roifile"] = "$1"
	 
   
}'

#===============================================================
# _XDS_readroimatlab
#===============================================================
#%IU% <filename>
#%MDESC%reads the roi file in ~blissadm/local/spec/userconf/CUB/XDS/ROI 
def _XDS_readroimatlab'{
   local myfile myf ii jj kk  cont ret ret0 tmpcoef
	 local nbroi myindex 
	 
   myf = "$1"
   myfile = "/users/blissadm/local/spec/userconf/CUB/XDS/ROI/" myf
   p "reading file " myfile
	 cont[0]=0
   ret0 = getline(myfile,"open")
   if (ret0 != -1) {
       ret0 = getline(myfile)
#      to remove the trailing newline, to be able to correctly compare strings.
       ret = substr(ret0,1,length(ret0)-1)
       sscanf(ret,"%d",nbroi)
	     XDSROISinit nbroi

	     for (ii=0;ii<XDS_NBDEV;ii++) {
			   for (jj=0; jj<2; jj++) {
				    for (kk=0; kk<4; kk++) {
							 myindex = (ii*100) +(jj+1)*10 + (kk+1)
							 for (ll =0; ll < nbroi; ll++) {
                  ret0 = getline(myfile)
                  if (ret0 == -1) {
                     getline(myfile,"close")
									   p "unexpected end of roi file"
						         exit  
                  }
#                 to remove the trailing newline, to be able to correctly compare strings.
                  ret = substr(ret0,1,length(ret0)-1)
									XDSROIS_LO[myindex][ll] = ret
									p "XDSROIS_LO[" myindex "][" ll "] = " XDSROIS_LO[myindex][ll]
                  ret0 = getline(myfile)
                  if (ret0 == -1) {
                     getline(myfile,"close")
									   p "unexpected end of roi file"
						         exit  
                  }
#                 to remove the trailing newline, to be able to correctly compare strings.
                  ret = substr(ret0,1,length(ret0)-1)
									XDSROIS_HI[myindex][ll] = ret
									p "XDSROIS_HI[" myindex "][" ll "] = " XDSROIS_HI[myindex][ll]
							 }
						}
				 }
			}
      getline(myfile,"close")
   }
}'

#===============================================================
# XDSh_applyFIR
#===============================================================
#%UU%
#%MDESC%applies the FIR coefs on the boards in use
def XDSh_applyFIR'{
   local ii

   for (ii=0; ii< XDS_NBDEV; ii++) {
      if (XDS_ARR[ii]["used"] == 1) {
         XDSh_selectmez(ii,1)
         _XDSh_applyFIR(ii)
        if (XDS_ARR[ii]["mezz2"]) {
            XDSh_selectmez(ii,2)
            _XDSh_applyFIR(ii)
         }
      }
   }
}'

#===============================================================
# _XDSh_applyFIR
#===============================================================
#%IU% (<XDS_index>)
#%MDESC%applies the FIR coefs on a selected board / mez
def _XDSh_applyFIR(bb) '{
   local myw fj
	 
   myw[0] = 2

   myw[1] = 0xC
   myw[2] = 0
   esrf_io(XDS_ARR[bb]["dev"],"DevWriteReg32",myw)
   for (fj=0; fj<96; fj++) {
			if (fj==32) {
         myw[1] = 0xC
         myw[2] = 1
         esrf_io(XDS_ARR[bb]["dev"],"DevWriteReg32",myw)
      }
			if (fj==64) {
         myw[1] = 0xC
         myw[2] = 2
         esrf_io(XDS_ARR[bb]["dev"],"DevWriteReg32",myw)
      }
      myw[1] = 0x80 + (fj%32)*4
      myw[2] = XDS_fircoef[95-fj]
      esrf_io(XDS_ARR[bb]["dev"],"DevWriteReg32",myw)
   }
#now calculate pulse width and write it to all 4 channels _register
   for (fj=0;fj<4;fj++) {
	    myw[1] = 0x50 + 4*fj
	    myw[2] = XDS_pulflat + 2*XDS_pulrise + 4
      esrf_io(XDS_ARR[bb]["dev"],"DevWriteReg32",myw)
   }
}'


#===============================================================
#  XDS_get_hwctrl
#===============================================================
#%UU%<filename>
#%MDESC%reads a configuration file (under ~blissadm/local/spec/userconf/HDW)
#and applies it to the hardware
def XDS_get_hwctrl'{
   local myf
   
   if ($# != 1) {
      p "usage: XDS_get_hwctrl <filename>"
      exit
   }
   p "-> Reading file " "$1"
   _XDS_get_hwctrl $*
	 XDS_ARR["hwctrl"] = "$1"
   
   p "->Applying controls to hardware "
   XDSh_apply_hwctrl
}'

#===============================================================
# _XDS_get_hwctrl
#===============================================================
#%IU% <filename>
#%MDESC%reads the hardware control file in ~blissadm/local/spec/userconf/HDW
#and puts in SPEC array structure
def _XDS_get_hwctrl'{
   local myfile myf ii chcont ret ret0 truch res finish jj

   myf = "$1"
   myfile = "/users/blissadm/local/spec/userconf/CUB/XDS/HDW/" myf
   p "reading file " myfile
   ret0 = getline(myfile,"open")
   jj = 0
	 finish = 0
   while ( (ret0 != -1) && (jj < XDS_NBDEV*8) && (finish == 0) ){
      ret0 = getline(myfile)
      if (ret0 == -1) {
         getline(myfile,"close")
         p "end of config. file"
         finish = 1  
      }
      else {
          if (XDSDEB >0) {p "Reading a new bloc " jj}
          res = substr(ret0,1,length(ret0)-1)
          sscanf(res,"%d",chcont[0])
      
          for (ii=1;ii<8;ii++) {
            ret0 = getline(myfile)
            if (ret0 == -1) {
               getline(myfile,"close")
               p "error reading hardware config. file"
               exit
            }
#           to remove the trailing newline, to be able to correctly compare strings.
            res = substr(ret0,1,length(ret0)-1)
            sscanf(res,"%x",chcont[ii])
          }
#         1st data in blobklet is Si Drift Detector channel. Translate to bmc
          truch = _SDDch2bmc(chcont[0])
          XDSch_gain[truch] = chcont[1]
          XDSch_offset[truch] = chcont[2]
          XDSch_ramplo[truch] = chcont[3]
          XDSch_ramphi[truch] = chcont[4]
          XDSch_VRD[truch] = chcont[5]
          XDSch_VRE[truch] = chcont[6]
          XDSch_trig[truch] = chcont[7]

          ret0 = 0
          jj ++
			}
   }
   getline(myfile,"close")
}'

#===============================================================
# XDS_write_hwctrl
#===============================================================
#%IU% <filename>
#%MDESC%writes a hardware control file in ~blissadm/local/spec/userconf/HDW
def XDS_write_hwctrl'{
   local myfile myf ii ret truch 

   myf = "$1"
   myfile = "/users/blissadm/local/spec/userconf/CUB/XDS/HDW/" myf

   if (unix(sprintf("test -s %s",myfile))){
      p "Writing hardware configuration to file " myfile
   }
   else{
      p "file already exists. exit"
      exit
   }    
   ret = open(myfile)
   if (ret == -1) {
      p "cannot open file" myfile
      p "exit"
      exit
   }
   on(myfile);offt

#  hardcoded for 35 detectors
   for (ii=0; ii<35; ii++) {
       truch = _SDDch2bmc(ii)
       p XDSch_gain[truch]
       p XDSch_offset[truch]
       p XDSch_ramplo[truch]
       p XDSch_ramphi[truch]
       p XDSch_VRD[truch]
       p XDSch_VRE[truch]
       p XDSch_trig[truch]
	 }
   ont;close(mycompletefile)

}'


#===============================================================
# _SDDch2bmc
#===============================================================
#%UU% (<SDDetector channel>)
#%MDESC%lookup table : SDDetector vs board / mez / chan
def _SDDch2bmc(sddnb)'{

   if (sddnb == 23) return(14)
   if (sddnb == 22) return(13)
   if (sddnb == 21) return(321)
   if (sddnb == 20) return(11)
   if (sddnb == 19) return(24)
   if (sddnb == 18) return(23)
   if (sddnb == 17) return(22)
   if (sddnb == 8) return(121)
   if (sddnb == 9) return(122)
   if (sddnb == 10) return(123)
   if (sddnb == 11) return(124)
   if (sddnb == 12) return(111)
   if (sddnb == 13) return(112)
   if (sddnb == 14) return(113)
   if (sddnb == 15) return(114)
   if (sddnb == 16) return(21)
   if (sddnb == 7) return(211)
   if (sddnb == 6) return(212)
   if (sddnb == 5) return(213)
   if (sddnb == 4) return(214)
   if (sddnb == 3) return(221)
   if (sddnb == 2) return(222)
   if (sddnb == 1) return(223)
   if (sddnb == 0) return(224)
   if (sddnb == 25) return(312)
   if (sddnb == 26) return(313)
   if (sddnb == 27) return(314)
   if (sddnb == 28) return(12)
   if (sddnb == 29) return(323)
   if (sddnb == 30) return(322)
   if (sddnb == 31) return(324)
   if (sddnb == 32) return(414)
   if (sddnb == 33) return(411)
   if (sddnb == 34) return(412)
   if (sddnb == 35) return(413)
   if (sddnb == 24) return(311)
}'

#===============================================================
# XDSh_apply_hwctrl
#===============================================================
#%UU%
#%MDESC%applies the XDSch  arrays to the boards in use
def XDSh_apply_hwctrl'{
   local hii

#  now we can program the boards
   for (hii=0; hii< XDS_NBDEV; hii++) {
      if (XDS_ARR[hii]["used"] == 1) {
#     1st mezzanine set all channels (default if not used, new for others)
         _XDSh_setmez_ctrl(hii, 1)

#     2d mezzanine if there
         if (XDS_ARR[hii]["mezz2"]) {
            _XDSh_setmez_ctrl(hii, 2)
         }
      }
   }
}'

#===============================================================
# XDS_sethisto
#===============================================================
#%UU%
#%MDESC%set histo mode and fir_en + blr_en on the boards in use
def XDS_sethisto'{
   local hii

#  now we can program the boards
   for (hii=0; hii< XDS_NBDEV; hii++) {
      if (XDS_ARR[hii]["used"] == 1) {
#     1st mezzanine set all channels (default if not used, new for others)
         XDSh_selectmez( hii, 1)
         _XDS_sethisto(hii)

#     2d mezzanine if there
         if (XDS_ARR[hii]["mezz2"]) {
            XDSh_selectmez( hii, 2)
            _XDS_sethisto(hii)
         }
      }
   }
	 XDSHISTO = 1
}'

#===============================================================
#  _XDS_sethisto
#===============================================================
#%IU% (<XDS_index>)
#%MDESC%applies histo mode bit and fir_en + blr_en to the selected board / mezzanine
def _XDS_sethisto(hii)'{
   local mypw mypr val
   mypw[0] = 2
   mypr[0] = 2
	 mypw[1] = 4
	 mypr[1] = 4
	 
	 val = esrf_io(XDS_ARR[hii]["dev"],"DevReadReg32",mypr)
#  set histo and default fir_en + blr_en
   mypw[2] = val | 0x00000130
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
}'
 
#===============================================================
# XDS_setscope
#===============================================================
#%UU%
#%MDESC%set scope mode + trigonpul on the boards in use
def XDS_setscope'{
   local hii

#  now we can program the boards
   for (hii=0; hii< XDS_NBDEV; hii++) {
      if (XDS_ARR[hii]["used"] == 1) {
#     1st mezzanine set all channels (default if not used, new for others)
         XDSh_selectmez(hii,1)
         _XDS_setscope(hii)

#     2d mezzanine if there
         if (XDS_ARR[hii]["mezz2"]) {
            XDSh_selectmez(hii,2)
            _XDS_setscope(hii)
         }
      }
   }
	 XDSHISTO = 0
}'

#===============================================================
#  _XDS_setscope
#===============================================================
#%IU% (<XDS_index>)
#%MDESC%applies scope mode bit and trigonpul to the selected board / mezzanine
def _XDS_setscope(hii)'{
   local mypw mypr val
   mypw[0] = 2
   mypr[0] = 2
	 mypw[1] = 4
	 mypr[1] = 4
	 
	 val = esrf_io(XDS_ARR[hii]["dev"],"DevReadReg32",mypr)
#  set scope and default trigonpul
   mypw[2] = (val & 0xFFFFFE0F) | 0x000000b0
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
}'
 
#===============================================================
# XDS_setblr
#===============================================================
#%UU%
#%MDESC%set scope mode + view blr on the boards in use
def XDS_setblr'{
   local hii

#  now we can program the boards
   for (hii=0; hii< XDS_NBDEV; hii++) {
      if (XDS_ARR[hii]["used"] == 1) {
#     1st mezzanine set all channels (default if not used, new for others)
         XDSh_selectmez(hii,1)
         _XDS_setblr(hii)

#     2d mezzanine if there
         if (XDS_ARR[hii]["mezz2"]) {
            XDSh_selectmez(hii,2)
            _XDS_setblr(hii)
         }
      }
   }
	 XDSHISTO = 0
}'

#===============================================================
#  _XDS_setblr
#===============================================================
#%IU% (<XDS_index>)
#%MDESC%applies scope mode bit and view blr to the selected board / mezzanine
def _XDS_setblr(hii)'{
   local mypw mypr val
   mypw[0] = 2
   mypr[0] = 2
	 mypw[1] = 4
	 mypr[1] = 4
	 
	 val = esrf_io(XDS_ARR[hii]["dev"],"DevReadReg32",mypr)
#  set scope and default trigonpul
   mypw[2] = (val & 0xFFFFFE0F) | 0x00000070
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
}'
 
#===============================================================
#  _XDSh_setmez_ctrl
#===============================================================
#%IU% (<XDS_index>,<mezza>)
#%MDESC%applies the XDSch  arrays to the selected board / mezzanine
def _XDSh_setmez_ctrl(hii, mez)'{
   local mypw mybm

   mypw[0] = 2
   mybm = hii*100 + mez*10
	 
   if (XDSDEB >0) {p "---> _XDSh_setmez_ctrl " hii mez}
   XDSh_selectmez(hii,mez)
#  SDAC gain and ramp_low
   mypw[1] = 0x30
   mypw[2] = (9<<28) | (XDSch_gain[mybm+1]<<16) | (9<<12) | XDSch_ramplo[mybm+1]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x34
   mypw[2] = (9<<28) | (XDSch_gain[mybm+2]<<16) | (9<<12) | XDSch_ramplo[mybm+2]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x38
   mypw[2] = (9<<28) | (XDSch_gain[mybm+3]<<16) | (9<<12) | XDSch_ramplo[mybm+3]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x3C
   mypw[2] = (9<<28) | (XDSch_gain[mybm+4]<<16) | (9<<12) | XDSch_ramplo[mybm+4]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x2C
   mypw[2] = 0
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
#  SDAC offset and ramp_high
   mypw[1] = 0x30
   mypw[2] = (0xA<<28) | (XDSch_offset[mybm+1]<<16) | (0xA<<12) | XDSch_ramphi[mybm+1]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x34
   mypw[2] = (0xA<<28) | (XDSch_offset[mybm+2]<<16) | (0xA<<12) | XDSch_ramphi[mybm+2]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x38
   mypw[2] = (0xA<<28) | (XDSch_offset[mybm+3]<<16) | (0xA<<12) | XDSch_ramphi[mybm+3]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x3C
   mypw[2] = (0xA<<28) | (XDSch_offset[mybm+4]<<16) | (0xA<<12) | XDSch_ramphi[mybm+4]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x2C
   mypw[2] = 0
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
#  TRIG register
   mypw[1] = 0x14
   mypw[2] = XDSch_trig[mybm+4]<<24 | XDSch_trig[mybm+3]<<16 | XDSch_trig[mybm+2]<<8 | XDSch_trig[mybm+1]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
#  VRD
   mypw[1] = 0x60
   mypw[2] = XDSch_VRD[mybm+1]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x64
   mypw[2] = XDSch_VRD[mybm+2]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x68
   mypw[2] = XDSch_VRD[mybm+3]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x6C
   mypw[2] = XDSch_VRD[mybm+4]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
#  VRE
   mypw[1] = 0x70
   mypw[2] = XDSch_VRE[mybm+1]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x74
   mypw[2] = XDSch_VRE[mybm+2]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x78
   mypw[2] = XDSch_VRE[mybm+3]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x7C
   mypw[2] = XDSch_VRE[mybm+4]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
}'

#===============================================================
#  XDS_setgainfactor
#===============================================================
#%IU% <XDS_index> <mezza> <ch> <gain>
#%MDESC%applies the gain factor to the selected board / mezzanine
def XDS_setgainfactor '{
   local bo mezz ch ga
	 
	 bo = $1
	 mezz = $2
	 ch = $3
	 ga = $4
   if ( !_xds_check_board(bo) || !_xds_check_mezz(mezz) || !_xds_check_ch(ch) ){
      exit
   }
	 if (ga <=0) {
	    p "gainfactor must be positive"
			exit
	 }
	 _XDSh_setgainfactor(bo, mezz, ch, ga)
}'

#===============================================================
#  XDS_setallgainfactor
#===============================================================
#%IU% <gainfactor>
#%MDESC%applies the gain factor to all
def XDS_setallgainfactor '{
   local bo1 ch1 ga1

   if ($# == 0) {
		  p "usage: XDS_setallgainfactor <gainfactor>"
		}
   ga1 = $1

   for (bo1=0; bo1< XDS_NBDEV; bo1++) {
      if (XDS_ARR[bo1]["used"] == 1) {
#        1st mezzanine
         for (ch1=1; ch1<5;ch1++){
            XDS_setgainfactor bo1 1 ch1 ga1
			   }

#        2d mezzanine if there
         if (XDS_ARR[bo1]["mezz2"]) {
            for (ch1=1; ch1<5; ch1++){
               XDS_setgainfactor bo1 2 ch1 ga1
						}
         }
      }
   }
}'

#===============================================================
#  _XDSh_setgainfactor
#===============================================================
#%IU% (<XDS_index>,<mezza>,<ch>,<gainfactor>)
#%MDESC%applies the XDSch  arrays of gain and ramplo to the selected board / mezzanine
def _XDSh_setgainfactor(hii, mez,ch, ga)'{
   local mypw mybm

   if ( !_xds_check_board(hii) || !_xds_check_mezz(mez) || !_xds_check_ch(ch) ){
      exit
   }

   mypw[0] = 2
   mybm = hii*100 + mez*10
	 
   p "---> _XDSh_setgainfactor " hii " "  mez " " ch " " ga
   XDSh_selectmez(hii,mez)
#  SDAC gain and ramp_low
   mypw[1] = 0x30 + (ch-1)*4
	 XDSch_gain[mybm+ch] = int(XDSch_gain[mybm+ch] * ga)
   mypw[2] = (9<<28) | (XDSch_gain[mybm+ch]<<16) | (9<<12) | XDSch_ramplo[mybm+ch]
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)
   mypw[1] = 0x2C
   mypw[2] = 0
   esrf_io(XDS_ARR[hii]["dev"],"DevWriteReg32",mypw)

}'

#%UU%<filename>
#%MDESC% save gain structure to file
def XDS_savegain'{
   local myfileroot ret

   if ($# !=1 ) {
	    p "usage: XDS_savegain <filename>"
	 } 
   myfileroot = "$1"
	 
   ret = open(myfileroot)
   if (ret == -1) {
      p "cannot open file" myfileroot
      p "exit"
      exit
   }
	 p "on file " myfileroot
   on(myfileroot);offt
	 p XDSch_gain
	 p XDSch_ramplo

   ont;close(myfileroot)

}'

#%UU%<filename>
#%MDESC% get gain structure from file
def XDS_getgain'{
   local myfileroot 

   if ($# !=1) {
	    p "usage: XDS_getgain <filename>"
	 } 
   myfileroot = "$1"

   p "reading " myfileroot	 
   qdofile(myfileroot)

}'


#===============================================================
#  XDS_getconf
#===============================================================
#%UU%<filename>
#%MDESC%reads a configuration file (under ~blissadm/local/spec/userconf)
#and applies it to the hardware
def XDS_getconf'{
   local myf
   
   if ($# != 1) {
      p "usage: XDS_getconf <filename>"
      exit
   }
   p "-> Reading file " "$1"
   _XDS_getconf $*
   
   p "->Verify compatibility with present hardware"
   if (_XDS_compatarchi() == 0) {
      p "hardware not compatible. exit"
      exit
   }
   else {
      p "hardware is compatible"
   }
   
   p "->Copy to spec structure"
   _XDS_cpconf
   
   XDS_showconf
   
   p "->Applying to hardware "
   XDSh_applyarray
}'

#===============================================================
# _XDS_getconf
#===============================================================
#%IU% <filename>
#%MDESC%reads the file in ~blissadm/local/spec/userconf 
def _XDS_getconf'{
   local myfile ii cont ret myf myarr mybn ret0
   global XDS_m_dev XDS_m_mezz2 
   global XDS_m1_ch1 XDS_m1_ch2 XDS_m1_ch3 XDS_m1_ch4 
   global XDS_m2_ch1 XDS_m2_ch2 XDS_m2_ch3 XDS_m2_ch4 
   global XDS_m_mode XDS_m_master_trig XDS_nb_dev XDS_m_corres
   
   myf = "$1"
   myfile = "~blissadm/local/spec/userconf/" myf
   p "reading file " myfile
   cont = 1
   ret0 = getline(myfile,"open")
   XDS_nb_dev = 0
   if (ret0 != -1)
   {
      ret0 = getline(myfile)
#     to remove the trailing newline, to be able to correctly compare strings.
      ret = substr(ret0,1,length(ret0)-1)
      if (XDSDEB >0) {p ret}
      mynb = split(ret, myarr)
      if (myarr[0] != "#XDS") {
         p "this is not a XDS file. exit"
         exit
      }
      while(cont == 1) {
         ret0 = getline(myfile)
         if (ret0 == -1) {
            cont = 0
            getline(myfile,"close")  
         }
         else {
            ret = substr(ret0,1,length(ret0)-1)
            if (XDSDEB >0) {p ret}
            mynb = split(ret,myarr)
            myflag = myarr[0] 
            if (myflag == "#dev") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #dev elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m_dev[jj-1] = myarr[jj]
               }
            }       
            else if (myflag == "#mezz2") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #mezz2 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m_mezz2[jj-1] = myarr[jj]
               }
            
            }       
            else if (myflag == "#m1ch1") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #m1ch1 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m1_ch1[jj-1] = myarr[jj]
               }
            
            }       
            else if (myflag == "#m1ch2") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #m1ch2 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m1_ch2[jj-1] = myarr[jj]
               }
            
            }       
            else if (myflag == "#m1ch3") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #m1ch3 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m1_ch3[jj-1] = myarr[jj]
               }
            
            }       
            else if (myflag == "#m1ch4") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #m1ch4 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m1_ch4[jj-1] = myarr[jj]
               }
            
            }   
            else if (myflag == "#m2ch1") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #m2ch1 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m2_ch1[jj-1] = myarr[jj]
               }
            
            }       
            else if (myflag == "#m2ch2") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #m2ch2 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m2_ch2[jj-1] = myarr[jj]
               }
            
            }       
            else if (myflag == "#m2ch3") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #m2ch3 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m2_ch3[jj-1] = myarr[jj]
               }
            
            }       
            else if (myflag == "#m2ch4") {
               if ( _XDS_compat_nbdev(XDS_nb_dev,mynb-1) == 0) {
                  p "bad number of #m2ch4 elements. exit"
                  exit
               } 
               XDS_nb_dev = mynb-1
               for (jj=1; jj<mynb; jj++) {
                  XDS_m2_ch4[jj-1] = myarr[jj]
               }
            
            }       
            else if (myflag == "#mode") {
               if (mynb != 2) {
                  p "bad number of #mode elements. exit"
                  exit
               }
               XDS_m_mode = myarr[1] 
            }       
            else if (myflag == "#master_trig") {
               if (mynb !=2) {
                  p "bad number of #master_trig elements(" mynb "). exit"
                  exit
               } 
               XDS_m_master_trig = myarr[1]
               if (XDS_m_master_trig >= XDS_nb_dev) {
                  p "bad value of master trig element"
                  exit
               }
            }
            else {
               p "unknown line: " ret " ignored."
            }       
        }
      }         
   }
}'

#===============================================================
# _XDS_compatarchi()
#===============================================================
#%IU%
#%MDESC% checks if the architecture loaded in XDS_m_xx is compatible
#with the present devices. it checks:
#%BR% - presence of requested devices
#%BR% - number of mezzanin on the devices.
#%BR% creates an array XDS_m_corres for corrspondance XDS_m_xx  -> XDS_ARR
def _XDS_compatarchi()'{
   local ii jj found

#  first check that all the devices are here   
   for (ii=0; ii<XDS_nb_dev; ii++) {
       found = 0
       for (jj=0; jj<XDS_NBDEV; jj++) {
          if (XDS_ARR[jj]["dev"] == XDS_m_dev[ii]) {
             XDS_m_corres[ii] = jj
             found = 1
             break
          }
       }
       if (found == 0) {
          p "device " XDS_m_dev[ii] " missing!!"
          return(0)
       }
   }
   
#  and that the mezzanines are here
   for (ii=0; ii<XDS_nb_dev; ii++) {
      if (XDS_m_mezz2[ii] != XDS_ARR[XDS_m_corres[ii]]["mezz2"]) {
         p "device " XDS_m_dev[ii] " should have " XDS_m_mezz2[ii]+1 " mezzanin !!"
         return(0)
      }
   }   
   return(1)
}'

#===============================================================
# _XDS_cpconf
#===============================================================
#%IU%
#%MDESC%copies the configuration loaded in the XDS_ARR array
def _XDS_cpconf'{
   local ii

#  first set as unused all the elements   
   for (ii=0; ii<XDS_NBDEV; ii++){
      XDS_ARR[ii]["used"] = 0
   }
   
#  the work on the really used ones
   for (ii=0; ii<XDS_nb_dev; ii++) {
#     in use
      XDS_ARR[XDS_m_corres[ii]]["used"] = 1
#     the channels
      XDS_ARR[XDS_m_corres[ii]]["ch11"] = XDS_m1_ch1[ii]
      XDS_ARR[XDS_m_corres[ii]]["ch12"] = XDS_m1_ch2[ii]
      XDS_ARR[XDS_m_corres[ii]]["ch13"] = XDS_m1_ch3[ii]
      XDS_ARR[XDS_m_corres[ii]]["ch14"] = XDS_m1_ch4[ii]
      XDS_ARR[XDS_m_corres[ii]]["ch21"] = XDS_m2_ch1[ii]
      XDS_ARR[XDS_m_corres[ii]]["ch22"] = XDS_m2_ch2[ii]
      XDS_ARR[XDS_m_corres[ii]]["ch23"] = XDS_m2_ch3[ii]
      XDS_ARR[XDS_m_corres[ii]]["ch24"] = XDS_m2_ch4[ii]  
   }

#  master trig      
   XDS_setmastertrig XDS_m_corres[XDS_m_master_trig]
   
#  mode
   XDS_ARR["mode"] = XDS_m_mode
   if (XDS_ARR["mode"] == 0) {
      XDS_setmodesoft
   }
   else if (XDS_ARR["mode"] == 1) {
      XDS_setmodehard
   }
   else if (XDS_ARR["mode"] == 2) {
      XDS_setmodehardext
   }
}'

#===============================================================
# XDS_showrois
#===============================================================
#%UU%
#%MDESC%Shows the ROI contents by board/mezzanin/channel
def XDS_showrois'{
   local bii cii roii
   
   for (roii=0; roii<XDSROIS_nb; roii++) {
	    printf("Total_ROI[%d] = %d.\n", roii, total_roi[roii])
      for (bii=0; bii<XDS_NBDEV; bii++) {
         if (XDS_ARR[bii]["used"] == 1) {
						printf("\tBoard#%d, mez#1 :", bii)
				    for (cii=0;cii<4;cii++) {
               if (XDS_ARR[bii][sprintf("ch%d",cii+11)] == 1) {
						      printf("ch#%d : %d  ", cii, tablu_roi[bii*100 + 10 + cii+1][roii])
						   }
						}
            printf(".\n")
            if (XDS_ARR[bii]["mezz2"] == 1){
					     printf("\tBoard#%d, mez#2 :", bii)
				       for (cii=0;cii<4;cii++) {
                  if (XDS_ARR[bii][sprintf("ch%d",cii+21)] == 1) {
						         printf("ch#%d : %d  ", cii, tablu_roi[bii*100 + 20 + cii+1][roii])
						      }
					   	 }
               printf(".\n")
					  }
				 }
      }
   }
}'

#%IU%(board)
#%MDESC%chack validity of a board number: returns 1 if board number is 
#a valid number
def _xds_check_board(bo)'{
   if ( (board< 0) || (board >= XDS_NBDEV)){
      p "board number should be  [0.." XDS_NBDEV-1 "]. it is " board
      return(0)
   }
   else {
      return(1)
   }
}'

#%IU%(mezz)
#%MDESC%check validity of a mezzanin number :returns 1 if mezzanin is [1,2],
# 0 else
def _xds_check_mezz(mezz)'{
   if ( (mezz != 1) && (mezz != 2) ){
      p "mezzanin number should be [1,2]. it is " mezz
      return(0)
   }
   else{
      return(1)
   }
}'

#%IU%(ch)
#%MDESC%check validity of a channel number: returns 1 if ch is [1,2,3,4],
# 0 else
def _xds_check_ch(ch)'{
   if ( (ch < 1)|| (ch > 4) ){
      p "channel number should be [1..4]. it is " ch
      return(0)
   }
   else{
      return(1)
   }
}'

#%UU% <board> <mez>
#%MDESC% Plot the channels in use of a mezzanin of a board
#
def xdsplot '{
   local bo mez ii mystr mystr1
  
   bo = $1
   mez = $2
   
   if ( !_xds_check_board(bo) || !_xds_check_mezz(mez) ){
      exit
   }
   
   cdef("cleanup_once","plot_cntl(\"filter1\");","_xds_plot")
   
   if ( (mez == 2) && (XDS_ARR[bo]["mezz2"] == 0) ){
      p "board " bo " has only one mezzanin !!"
      exit
   }

   for (ii=0; ii <4; ii++){   
      mystr1 = sprintf("ch%d%d",mez,ii+1)
#      if (XDS_ARR[bo][mystr1] == 1) {
      if (1) {
         mystr = sprintf("filter%d,open",ii+1)
         if (XDSDEB >0) {p mystr}
         plot_cntl(mystr)
         _xds_plotch(bo,mez,ii+1,XDS_ARR[bo][mystr1])
         plot_cntl("filter1")
      }
   }
     
}'


#%IU% (board, mezzanin, ch, 1)
#%MDESC% plot the selected channel to an opened filter
#%BR%check on validity of board,mezzanin and  parameters are supposed
#to be already done.
def _xds_plotch(bo, mezz,ch, topp)'{
   local ii toto
   ulong array XDS_PLOTARR[2][XDS_size]        

   if ( !_xds_check_board(bo) || !_xds_check_mezz(mezz) || !_xds_check_ch(ch) ){
      exit
   }
   plot_cntl("erase")
   plot_cntl("+lines")
   plot_cntl("-ebars")
   plot_cntl("-dots")
   plot_cntl("-ylog")
   plot_range("auto", "auto", "auto", "auto")
   plot_cntl("colors=49:16:9:3:2:7:8:9:5:4:2")
   plot_move(0, 0, sprintf("XDS b:%d m:%d ch:%d",bo,mezz,ch))
	 
	 if (XDSDEB >0) {p "_xds_plotch bo: " bo " mezz: " mezz "ch: " ch "topp: " topp}
	 if (topp == 1) {

      array_op("fill",XDS_PLOTARR[0][],1)
			toto = 0
      for (ii=0; ii<XDS_size; ii++) {
         XDS_PLOTARR[1][ii] = tablu[2*bo+mezz][XDS_size*(ch-1)+ii]
				 toto = toto + XDS_PLOTARR[1][ii]
         if (XDSDEB >0) {p "XDS_PLOTARR[1][" ii "] = " XDS_PLOTARR[1][ii]}
      }
#	    p "..ch .." ch
#	    p "..toto .." toto
#     for (ii=0; ii<10; ii++) {
#       printf("tablu[%d][%d] = %x ch:%d ii:%d\n",2*bo+mezz,XDS_size*(ch-1)+ii,\
#			    tablu[2*bo+mezz][XDS_size*(ch-1)+ii], ch,ii )
#       printf("XDS_PLOTARR[1][%d] = %x\n",ii,XDS_PLOTARR[1][ii])
#     }	 
      array_plot(XDS_PLOTARR[][])
#     p XDS_PLOTARR[][]
   }
	 else {
   plot_move(0, 0, sprintf("XDS b:%d m:%d ch:%d DISABLED",bo,mezz,ch))
	 
	 }
}'

#%UU%<board> <mezza> <ch>
#%MDESC%mcaguion done in MCA_DATA filled with the last acquired data
def XDS_mca'{
   local bo mezz ch ii
	 
	 bo=$1
	 mezz=$2
	 ch=$3

   if ( !_xds_check_board(bo) || !_xds_check_mezz(mezz) || !_xds_check_ch(ch) ){
      exit
   }

   #shared float array MCA_DATA[XDS_size]
   shared float array M_DATA[XDS_size][2]
	 
#  copy this data in M_DATA
   for (ii=0; ii<XDS_size; ii++) {
	    M_DATA[ii][0]= ii
      M_DATA[ii][1] = tablu[2*bo+mezz][XDS_size*(ch-1)+ii]
      #M_DATA[ii] = tablu[2*bo+mezz][XDS_size*(ch-1)+ii]
   }
	 #mcaguion

}'

#%UU%<filename>
#%MDESC%
def XDS_saveroi'{
   local myfileroot myfile ii jj kk ret ll myfilehead

   if ($# !=1 ) {
	    p "usage: XDS_saveroi <filename>"
	 } 
   myfileroot = "$1"
	 
   ret = open(myfileroot)
   if (ret == -1) {
      p "cannot open file" myfileroot
      p "exit"
      exit
   }
	 p "on file " myfileroot
   on(myfileroot);offt
	 p XDSROIS_LO
	 p XDSROIS_HI

   ont;close(myfileroot)

}'

#%UU%<filename>
#%MDESC%
def XDS_getroi'{
   local myfileroot myfile ii jj kk ret ll myfilehead

   if ($# !=1) {
	    p "usage: XDS_getroi <filename>"
	 } 
   myfileroot = "$1"

   p "reading " myfileroot	 
   qdofile(myfileroot)

}'

#%UU%<root_file_name>
#%MDESC%saves in the present directory
#%BR%- <root>_head.txt
#%BR%- <root>_<board>_<mezza>_<ch>
def XDS_savespec'{

   local myfileroot myfile ii jj kk ret ll myfilehead

   myfileroot = "$1"
	 
#  header
   myfilehead = sprintf("%s_head.txt",myfileroot)
   ret = open(myfilehead)
   if (ret == -1) {
      p "cannot open file" myfilehead
      p "exit"
      exit
   }
	 p "on file " myfilehead
   on(myfilehead);offt
	 p XDS_ARR
	 for (ii=0; ii<XDS_NBDEV; ii++) {
	   for (jj=1; jj<3; jj++){
		    for (kk=1; kk<5; kk++){
				   printf("XDSch_gain[%d%d%d]=%x\n",ii,jj,kk,XDSch_gain[100*ii+10*jj+kk])
				   printf("XDSch_offset[%d%d%d]=%x\n",ii,jj,kk,XDSch_offset[100*ii+10*jj+kk])
				   printf("XDSch_ramplo[%d%d%d]=%x\n",ii,jj,kk,XDSch_ramplo[100*ii+10*jj+kk])
				   printf("XDSch_ramphi[%d%d%d]=%x\n",ii,jj,kk,XDSch_ramphi[100*ii+10*jj+kk])
				   printf("XDSch_VRD[%d%d%d]=%x\n",ii,jj,kk,XDSch_VRD[100*ii+10*jj+kk])
				   printf("XDSch_VRE[%d%d%d]=%x\n",ii,jj,kk,XDSch_VRE[100*ii+10*jj+kk])
				   printf("XDSch_trig[%d%d%d]=%x\n",ii,jj,kk,XDSch_trig[100*ii+10*jj+kk])
				}
		 }
	 }

   ont;close(myfilehead)

#  the data	 
   for (ii=0; ii<XDS_NBDEV; ii++){
	    for (jj=1; jj< 3; jj++) {
			   for (kk=1; kk<5; kk++){
#remove .txt extension (for matlab)
				    #myfile = sprintf("%s_%d_%d_%d.txt",myfileroot,ii,jj,kk)
				    myfile = sprintf("%s_%d_%d_%d",myfileroot,ii,jj,kk)
            ret = open(myfile)
            if (ret == -1) {
               p "cannot open file" myfile
               p "exit"
               exit
            }
						p "on file " myfile
            on(myfile);offt
            for (ll=0; ll<XDS_size; ll++) {
   					   printf("%d\n",tablu[2*ii+jj][XDS_size*(kk-1)+ll])
						}
            ont;close(myfile)
				 }
			}
	 }
}'

#%UU%<root_file_name>
#%MDESC%saves in the present directory
#%BR%- <root>_head.txt
#%BR%- <root>_<board>_<mezza>_<ch>
def XDS_saveone'{

   local myfileroot myfile ii jj kk ret ll myfilehead

   myfileroot = "$1"
	 
#  the data	 
   ii=2
	    jj=1
			   kk=4
#remove .txt extension (for matlab)
				    myfile = sprintf("%s",myfileroot)
            ret = open(myfile)
            if (ret == -1) {
               p "cannot open file" myfile
               p "exit"
               exit
            }
						p "on file " myfile
            on(myfile);offt
            for (ll=0; ll<XDS_size; ll++) {
   					   printf("%d\n",tablu[2*ii+jj][XDS_size*(kk-1)+ll])
						}
            ont;close(myfile)
}'




#==============================================================================
#==============================================================================
# 2010/04/15 rh
#     patch to include the data in the datafile - TODO - check it!!!
#==============================================================================
#==============================================================================

def XDS_file_data '{

   local ii jj kk ll 

#  the data	 
   ii=2
	    jj=1
			   kk=4

						fprintf(DATAFILE, "@A ")
            for (ll=0; ll<XDS_size; ll++) {
							 fprintf(DATAFILE,"%d ",tablu[2*ii+jj][XDS_size*(kk-1)+ll])
						}
						fprintf (DATAFILE, "\n")
}'

def XDS_filedataon'{

   cdef("user_scan_loop","XDS_file_data;","cub_filedata",0)

}'

def XDS_filedataoff'{
   local ii 

   cdef("user_scan_loop","","cub_filedata","delete")
}'

#==============================================================================
#==============================================================================


#%UU% <0/1>
#%MDESC% set debug mode
def XDS_debug'{
   global XDSDEB
	 
	 XDSDEB = $1
}'

#%MACROS%
#%IMACROS%
#%AUTHOR% G.Goujon, MCD
#%TOC%