esrf

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

#%TITLE% maxipix.mac
#%NAME%
#   Macros to extend ccd.mac for maxipix functionality
#
#%BRIEF% MAXIPIX macros to extend ccd.mac
#
#%CATEGORY% Detection, Ccd
#
#%LOG%
# $Revision: 1.15 $
#%DESCRIPTION%
# This macro extend ccd.mac for maxipix. The acquisition control is
# still used through ccd.mac. This macros adds:
# %BR% * Configuration menu
# %BR% * Medipix Dac pseudo motor
# %BR% * Special mpxtake which is a ccdtake optimized for soft multiframe
#%SETUP%
#%B%mpxsetup%B% for general setup.
#%BR%%B%mpxdacsetup%B% to add a medipix dac as a pseudo-motor.
#%END%
#
#$Log: maxipix.mac,v $
#Revision 1.15  2010/02/10 16:16:41  papillon
#* mpxtakesum added:
#- take serie of images (mpxtake) and save it
#- computes online sum (shared array) and saveit
#
#Revision 1.14  2009/12/16 15:52:41  papillon
#* added possibility to setup DS run pars in counters
#
#Revision 1.13  2009/12/08 10:21:30  papillon
#* open GUI in mpxtake only if set in ccdmenu
#
#Revision 1.12  2008/11/18 15:55:33  papillon
#* Improve mpxtake macros : cleanup, interval time, display rate
#
#Revision 1.11  2008/09/03 15:34:46  papillon
#* added trigger and timepix mode
#* dac as counters (debug purpose)
#* check device in dac pseudo-motors
#* check active ccd in mpxtake
#
#Revision 1.10  2008/08/12 13:29:34  rey
#documentation changes
#
#Revision 1.9  2008/07/18 13:46:50  perez
#Add gate_mote and gate_level
#
#Revision 1.8  2008/05/13 10:00:54  papillon
#* Changes after added auto-save mode in ccd.mac
#
#Revision 1.7  2007/07/17 09:22:05  perez
#Fix bug in _mpx_init_getpars() when multiple CCD
#
#Revision 1.6  2007/05/30 09:01:08  guilloud
#add _mpx_roirename
#return name and number in _mpx_roiadd
#
#Revision 1.5  2007/05/25 11:04:15  guilloud
#change identation
#
#Revision 1.4  2007/05/03 14:37:54  papillon
#* mpxtake: display rate added
#* mpxtake: filename if saving
#* shutter_mode changed on priam
#
#Revision 1.3  2007/04/27 12:54:48  lagier
#ROI Management.
#
#Revision 1.2  2007/04/20 13:48:33  papillon
#* Documentation .... tout arrive !!
#
#Revision 1.1  2007/04/20 13:39:13  papillon
#Initial revision
#
#


#%UU% <ccd_spec_unit>
def mpxsetup '{
    global MPX_UNIT MPX_DACMOT[] MPX_CNT[]

    if ($#!=1) {
	print "Usage: $0 <ccd_spec_unit>"
    }
    MPX_UNIT= $1
    _mpx_initmsg()
    _mpx_initpars()
    # --- done in ccdresetup now
    # --- _mpx_initccd()
    list_init MPX_DACMOT
    list_init MPX_CNT
}'

#%IU%
def _mpx_initccd() '{
    image_par(MPX_UNIT, "soft_preset", 1)
    image_par(MPX_UNIT, "add_time", 0.)
    image_par(MPX_UNIT, "ext_trig", 0)
    ccd_createarray MPX_UNIT
}'

#%IU%
def _mpx_initpars() '{
    global MPX_PAR[]
    _mpx_init_getpars("maxipix")
    _mpx_init_getpars("control")
    _mpx_init_getpars("chip")
    _mpx_init_getpars("run")
}'

#%IU%
def _mpx_initmsg() '{
    global MPX_MSG[]
    MPX_MSG["shutter_mode"]= "0= each image, 1= sequence"
    MPX_MSG["shutter_level"]= "0= normal, 1= inverted"
    MPX_MSG["ready_mode"]= "0= exposure, 1= exposure+readout"
    MPX_MSG["ready_level"]= "0= normal, 1= inverted"
    MPX_MSG["shutter_time"]= "sec"
    MPX_MSG["min_interval_time"]= "sec, Read-only"
    MPX_MSG["interval_time"]= "sec"
    MPX_MSG["gate_mode"]= "0= inactive, 1= active"
    MPX_MSG["gate_level"]= "0= normal, 1= inverted"
    MPX_MSG["trigger_mode"]= "0= soft, 1= sequence, 2= each image, 3=start+stop"
    MPX_MSG["trigger_level"]= "0= normal, 1= inverted"
    MPX_MSG["timepix_mode"]= "0= medipix, 1= tot, 2= 1-hit, 3= timepix"
}'

#%IU%
def _mpx_init_getpars(type) '{
    local val npar ipar pars[]
    val= image_par(MPX_UNIT, "talk", type)
    npar= split(val, pars, ":")
    MPX_PAR[type]["npar"]= npar
    for (ipar=0; ipar<npar; ipar++)
	MPX_PAR[type][ipar+1]= pars[ipar]
}'

#%UU% <motor_mne> <dac_name>
#%MDESC% 
# Add the specified medipix DAC as a pseudo-motor
# %BR% Several pseudo-motors can be added.
# 
def mpxdacsetup '{
    local motmne dacname motnum found

    if ($#!=2) {
	print "Usage: $0 <motor_mne> <dac_name>"
	exit
    }

    motmne= "$1"
    dacname= "$2"

    found= _mpx_checkname("chip", dacname)

    motnum= motor_num(motmne)
    if (motnum==-1) {
	tty_cntl("md"); printf("MAXIPIX ERROR> "); tty_cntl("me")
	printf("Unknown motor mnemonic name <%s>\n", motmne)
    }

    if (found && motnum!=-1) {
	list_add(MPX_DACMOT, motmne)
	MPX_DACMOT[motmne]["dac"]= dacname
	cdef("user_getpangles", sprintf("_mpx_dacget(\"%s\");", motmne), motmne, 0x01)
	cdef("user_checkall", sprintf("_mpx_dacmove(\"%s\");", motmne), motmne, 0x01)
    }

    setup_tail("mpxdac", motmne)
}'

#%IU%
def mpxdacunsetup '{
    local motmne
    motmne= "$1"
    cdef("", "", motmne, "delete")
    list_remove(MPX_DACMOT, motmne)
}'

#%IU%
def _mpx_checkname(type, name) '{
    local found ipar

    found= 0
    for (ipar=1; ipar<=MPX_PAR[type]["npar"]; ipar++) {
	if (MPX_PAR[type][ipar]==name)
	    found= 1
    }
    if (!found) {
	tty_cntl("md"); printf("MAXIPIX ERROR> "); tty_cntl("me")
	printf("Unknown parameter name <%s>\n", name)
    }
    return (found)
}'

#%IU%
def mpxcntsetup '{
    local cntmne ptype pname name found cntnum 

    if ($#!=3) {
	print "Usage: $0 <cnt_mne> <type> <name>"
	exit
    }
    cntmne= "$1"
    ptype= "$2"
    pname= "$3"

    found= _mpx_checkname(ptype, pname)

    cntnum= cnt_num(cntmne)
    if (cntnum==-1) {
	tty_cntl("md"); printf("MAXIPIX ERROR> "); tty_cntl("me")
	printf("Unknown counter mnemonic name <%s>\n", cntmne)
    }

    if (found && cntnum!=-1) {
	list_add(MPX_CNT, cntmne)
	MPX_CNT[cntmne]["name"]= pname
	MPX_CNT[cntmne]["type"]= ptype
	cdef("user_getcounts", sprintf("_mpx_getcnt(\"%s\");", cntmne), cntmne, 0x22)
    }

    setup_tail("mpxcnt", cntmne)
}'
    
#%IU%
def mpxcntunsetup '{
    local cntmne
    cntmne= "$1"
    cdef("", "", cntmne, "delete")
    list_remove(MPX_CNT, cntmne)
}'

def _mpx_getcnt(cntmne) '{
    local value
    if (image_par(MPX_UNIT, "responsive")) {
        value= _mpx_getpar(MPX_CNT[cntmne]["type"], MPX_CNT[cntmne]["name"])
    } else {
        value= 0
    }
    S[cnt_num(cntmne)]= value
}'

#%IU%
def _mpx_dacget(motmne) '{
    local value
    if (image_par(MPX_UNIT, "responsive")) {
        value= _mpx_getpar("chip", MPX_DACMOT[motmne]["dac"])
        MPX_DACMOT[motmne]["old"]= value
        MPX_DACMOT[motmne]["err"]= 0
    } else {
	value= 0
        MPX_DACMOT[motmne]["err"]= 1
    }
    A[motor_num(motmne)]= value
}'

#%IU%
def _mpx_dacmove(motmne) '{
    if ((!MPX_DACMOT[motmne]["err"])&&(A[motor_num(motmne)]!=MPX_DACMOT[motmne]["old"]))
	_mpx_setpar("chip", MPX_DACMOT[motmne]["dac"], sprintf("%g", A[motor_num(motmne)]))
}'

#%UU%
#%MDESC%
# Gives access to all maxipix parameters not used in standard ccd interface. 
# It includes:
# %BR% * extra control parameters like shutter
# %BR% * detector configuration files
# %BR% * medipix chip DACs
# %BR% * medipix ROI setup
#
def mpxmenu '{
    local nl, option

    option = 1

    while (option) {
        nl= 0
	clscreen()
        tty_move(20, nl++, "\[md\]< MAXIPIX >\[me\]")
        tty_move(0,nl++, sprintf("Device: \[md\]%s\[me\]", image_par(MPX_UNIT, "device_id")))

	nl+= 2
	tty_move(0, nl++, "(1) Configuration files")
	tty_move(0, nl++, "(2) Control parameters")
	tty_move(0, nl++, "(3) Medipix Chip parameters")
	tty_move(0, nl++, "(4) Medipix ROI setup")

	option= getval("\n\n\tOption ---> ", 0)

	if (option==1) 
            _mpx_config_menu("maxipix")
	else if (option==2) 
            _mpx_config_menu("control")
	else if (option==3) 
            _mpx_config_menu("chip")
	else if (option==4) 
            _mpx_roimenu()
        
    }
}'

#%IU%
def _mpx_config_menu(type) '{
    local nl option
    local ipar npar value msg
    option= 1

    npar= MPX_PAR[type]["npar"]

    while (option) {
	nl= 0
	clscreen()
	tty_move(20, nl++, "\[md\]< MAXIPIX >\[me\]")
	tty_move(15, nl++, sprintf("%s configuration", type))
	nl+=2

	for (ipar=1; ipar<=npar; ipar++) {
	    tty_move(0, nl, sprintf("(%2d) %s", ipar, MPX_PAR[type][ipar]))
	    value= _mpx_getpar(type, MPX_PAR[type][ipar])
	    tty_move(30, nl, sprintf("\[md\]%s\[me\]", value))
	    if (MPX_PAR[type][ipar] in MPX_MSG)
		tty_move(40, nl, sprintf("[%s]", MPX_MSG[MPX_PAR[type][ipar]]))
	    nl++
	}
	
	option= getval("\n\n\tOption ---> ", 0)
	if ((option>0)&&(option<=npar)) {
	    msg= (MPX_PAR[type][option] in MPX_MSG) ? MPX_MSG[MPX_PAR[type][option]] : ""
	    value= getval(sprintf("\tSet %s to", MPX_PAR[type][option]), msg)
	    _mpx_setpar(type, MPX_PAR[type][option], value)
	}
    }
}'

#%UU% <type> <name> <value>
#%MDESC%
# Set any maxipix specific parameter
def mpxset '{
    if ($#!=3) {
	print "Usage: $0 <type> <name> <value>"
        exit
    }
    _mpx_setpar("$1", "$2", "$3")
}'

#%UU% <type> <name>
#%MDESC%
# Get any maxipix specific parameter
def mpxget '{
    if ($#!=2) {
	print "Usage: $0 <type> <name>"
	exit
    }
    print _mpx_getpar("$1", "$2")
}'

#%IU%
def _mpx_getpar(type, name) '{
    return image_par(MPX_UNIT, "talk", sprintf("%s:%s", type, name))
}'

#%IU%
def _mpx_setpar(type, name, value) '{
    image_par(MPX_UNIT, "talk", sprintf("%s:%s=%s", type, name, value))
}'

#%IU%
#%MDESC%
# Save all frames for last acquisition. Usefull after a ccdtake 0.1 1000 for 
# example. 
# Filename as to be correctly defined in ccdmenu.
# Better to use %B%mpxtake%B% instead.
def mpxsaveall '{
    local _mode

    _mode= CCDSAVE_MODE[MPX_UNIT]
    CCDSAVE_MODE[__ccd_u]= 3
    esrf_io(image_par(MPX_UNIT, "device_id"), "timeout", 360)
    __ccdsave
    esrf_io(image_par(MPX_UNIT, "device_id"), "timeout", 2)
    CCDSAVE_MODE[__ccd_u]= _mode
}'

#%UU%
#%MDESC%
# Same as %B%mpxtake%B% plus computes a sum of frames
# and save it if saving enabled (ccdmenu)
def mpxtakesum '{
    if ($#==2) {
        mpxtake $1 $2 0. -1
    }
    else if ($#==3) {
        mpxtake $1 $2 $3 -1
    }
    else {
        print "Usage: $0 <exposure_time> <nb_frames> [<interval_time>]"
        exit
    }
}'

#%UU%
#%MDESC%
# %BR% Take a serie of images in multi-frame mode (most efficient than ccdtake with maxipix) with:
# %BR% * Possible setting of interval time between frames
# %BR% * Reading of frame for display during acquisition (~4 frames/sec read independant of acquisition rate or at specified display rate)
# %BR% * Saving of frame if enabled (ccdmenu)
def mpxtake '{
    local _nimg _rate _fname _it_time _sumit

    if (!$#) {
	print "Usage: $0 <exposure_time> [<nb_frames>] [<interval_time>] [<display_rate>]"
        exit
    }

    if (CCD_U != MPX_UNIT) {
	print "Active CCD does not seem to be a Maxipix !!"
	print "... check ccdmenu or mpxsetup"
	exit
    }

    if (int($2)!=$2) {
	print "Ooops !! nb_frames is not an integer !!"
	print "         don\'t you mixed exposure_time and nb_frames ??"
	exit
    }
    _nimg= int($2)
    if (!_nimg) _nimg= 1

    if ($#>2) {
	if ($3 != $3+0.) {
	    print "Ooops !! interval_time seems not a float value !!"
	    exit
	}
	_it_time= "$3"
    } else {
	_it_time= "0."
    }

    if ($4==-1) {
	_sumit= 1
	_rate= -1
    }
    else {
    	if (CCDREAD_MODE[CCD_U]==1) {
	    _rate= 0
        } else {
	    _rate= ($#==4) ? $4+0. : 0.25
        }
    }
    if (CCDSAVE[CCD_U]==1) {
	if ((CCDSAVE_MODE[CCD_U]==1)||(CCDSAVE_MODE[CCD_U]==4)) {
	    if (CCDSAVE_MODE[CCD_U]!=4) {
		printf("!!! WARNING: Saving not optimized !!!\n")
		printf("    --> Should better use <Dserver auto-save mode>\n\n")
	    }
	    _fname= sprintf("%s/%s%.4d%s", image_par(CCD_U, "file_dir"), \
                                           image_par(CCD_U, "file_prefix"), \
		    		           image_par(CCD_U, "file_inum"), \
                                           image_par(CCD_U, "file_suffix"))
	    printf("Images saved in <%s> %s\n", _fname, (CCDSAVE_MODE[CCD_U]==4)?"(auto)":"")
	}
    }

    if (CCD_GUI[CCD_U]["on"])
      ccd_display_start(CCD_U)

    _mpxtake($1, _nimg, _it_time, _rate, _sumit)
}'

#%IU%
def _mpxtake(expo, nimg, it_time, drate, sumit) '{
    local _ext_trig _it_back _clnup

    if (sumit) _mpxtake_initsum()

    _ext_trig= image_par(CCD_U, "ext_trig")
    _it_back= _mpx_getpar("control", "interval_time")
    _clnup= sprintf("_mpxtake_cleanup(%d,%s); ", _ext_trig, _it_back)
    cdef("cleanup_once", _clnup, "mpxtake")

    image_par(CCD_U, "ext_trig", 0)
    _mpx_setpar("control", "interval_time", it_time)
    ccdstart expo nimg

    if (sumit) _mpx_wait(-1, 1)
    else _mpx_wait(drate, 0)

    cdef("cleanup_once", "", "mpxtake", "delete")
    _mpxtake_cleanup(_ext_trig, _it_back)

    if (sumit && CCDSAVE[CCD_U])
	_mpxtake_savesum(expo, nimg, it_time)
}'

#%IU%
def _mpxtake_cleanup(etrig, itstr) '{
    image_par(MPX_UNIT, "ext_trig", etrig)
    image_par(MPX_UNIT, "images", 1)
    _mpx_setpar("control", "interval_time", itstr)
}'

#%IU%
def _mpxtake_initsum() '{
    local xsize ysize aname

    xsize = array_op("rows",@ARRAYNAME)
    ysize = array_op("cols",@ARRAYNAME)
    aname = sprintf("image_sum%d", CCD_U)

    shared ulong array @aname[xsize][ysize]
    @aname= 0
}'

#%IU%
def _mpxtake_addtosum(arrname) '{
    local sname
    sname= sprintf("image_sum%d", CCD_U)
    @sname += @arrname
}'

#%IU%
def _mpxtake_savesum(expo, nimg, it_time) '{
    local aname fname dir prefix number suffix idx

    if (CCDSAVE_MODE[CCD_U]==0) {
        dir= CCD_DIR[CCD_U]
        prefix= CCD_PREFIX[CCD_U]
        number= CCD_N[CCD_U]-1
        suffix= CCD_SUFFIX[CCD_U]
    }
    else if (CCDSAVE_MODE[CCD_U]==4) {
        dir= image_par(CCD_U, "file_dir")
        prefix= image_par(CCD_U, "file_prefix")
        number= image_par(CCD_U, "file_inum")-1
        suffix= image_par(CCD_U, "file_suffix")
    }
    idx= index(suffix, ".")
    if (idx==0)
        suffix= "." suffix
    else if (idx>1)
        suffix= "_" suffix
    fname= sprintf("%s/%s%04d_sum%s",dir, prefix, number, suffix)

    _mpxtake_sumheader(expo, nimg, it_time)

    printf(".......> Saving SUM <%s>\n", fname)
    aname= sprintf("image_sum%d", CCD_U)
    if (fmt_write(fname,"ESRF", @aname, MPX_SUMHEADER))
        printf(".......> Saving SUM FAILED !!\n")
}'

#%IU%
def _mpxtake_sumheader(expo, nimg, it_time) '{
    local i
    global MPX_SUMHEADER[]
    if (MOTORS) {
            MPX_SUMHEADER["motor_mne"]= ""
            MPX_SUMHEADER["motor_pos"]= ""
            for (i = 0; i < MOTORS; i++) {
                MPX_SUMHEADER["motor_mne"]= MPX_SUMHEADER["motor_mne"] " " motor_mne(i)
                MPX_SUMHEADER["motor_pos"]= MPX_SUMHEADER["motor_pos"] sprintf(" %g",A[i])
            }
            idx+= 2
    }

    if (COUNTERS) {
            MPX_SUMHEADER["counter_mne"]= ""
            MPX_SUMHEADER["counter_pos"]= ""
            for (i = 0; i < COUNTERS; i++) {
                MPX_SUMHEADER["counter_mne"]= MPX_SUMHEADER["counter_mne"] " " cnt_mne(i)
                MPX_SUMHEADER["counter_pos"]= MPX_SUMHEADER["counter_pos"] sprintf(" %g",S[i])
            }
    }
    MPX_SUMHEADER["expo_per_frame"]= sprintf("%g", expo)
    MPX_SUMHEADER["number_of_frames"]= sprintf("%d", nimg)
    MPX_SUMHEADER["time_between_frames"]= sprintf("%g", it_time)
}'

#%IU%
def _mpx_wait(rate, sumit) '{
    global MPX_IDX[]
    MPX_IDX["nacq"]= -1
    MPX_IDX["nread"]= -1
    MPX_IDX["ndisp"]= -1
    MPX_IDX["disprate"]= rate
    MPX_IDX["disptime"]= 0.
    MPX_IDX["nsave"]= -1
    MPX_IDX["autosave"]= ((CCDSAVE_MODE[CCD_U]==4)&&CCDSAVE[CCD_U])
    MPX_IDX["sum"]= sumit
    while (wait(0x24)) {
        sleep(COUNTERSPOLLTIME)
        _mpx_wait_loop
    }
    _mpx_wait_loop
    printf("\n")
}'

#%IU%
def _mpx_wait_loop '{
    MPX_IDX["nacq"]= image_par(CCD_U, "get_current")
	if (MPX_IDX["autosave"])
		MPX_IDX["nsave"]= _mpx_getpar("run", "fsaved")
    if (MPX_IDX["nacq"]!=-1) {
    	_mpx_wait_msg
        if (MPX_IDX["nacq"]>MPX_IDX["nread"])
            _mpx_wait_read(MPX_IDX["nread"]+1, MPX_IDX["nacq"])
    }
}'

#%IU%
def _mpx_wait_read(from, to) '{
    local fidx arrname dispdone
    arrname= sprintf("image_data%d", CCD_U)
    for (fidx= from; fidx<=to; fidx++) {
        image_par(CCD_U, "get_offset", fidx)
	MPX_IDX["nread"]= fidx

	if ((MPX_IDX["disprate"]>0.) && !dispdone) {
	    tps= time()
	    if (tps - MPX_IDX["disptime"] > MPX_IDX["disprate"]) {
        		image_get(CCD_U, @arrname)
			MPX_IDX["ndisp"]= fidx
			MPX_IDX["disptime"]= tps
			_mpx_wait_msg
			dispdone= 1
		}
	}
	if (MPX_IDX["disprate"]==-1) {
	    image_get(CCD_U, @arrname)
	    MPX_IDX["ndisp"]= fidx
	    _mpx_wait_msg
            if (MPX_IDX["sum"])
	        _mpxtake_addtosum(arrname)
	}
	if (CCDSAVE[CCD_U]&&(!MPX_IDX["autosave"])) {
            	ccdsave
            	MPX_IDX["nsave"]= fidx
            	_mpx_wait_msg
        }
    }
}'

#%IU%
def _mpx_wait_msg '{
    tty_cntl("md"); printf("MAXIPIX> "); tty_cntl("me")
    MPX_IDX["nacq"]= image_par(CCD_U, "get_current")
    if (MPX_IDX["nacq"]!=-1) {
	printf("Acquire #%d ", MPX_IDX["nacq"])
    } else {
        printf("Acquire DONE ")
    }
    if (MPX_IDX["ndisp"]!=-1)
        printf("Display #%d ", MPX_IDX["ndisp"])
    if (MPX_IDX["nsave"]!=-1)
        printf("Save #%d ", MPX_IDX["nsave"])
    printf("\r")
}'


#%UU% <roimne> <xbeg> <xend> <ybeg> <yend> 
#%MDESC% Defines a new roi. If no argument given, runs a menu.
#%BR% Arguments are:
#%BR% %B%roimne%B% : counter mnemonic for the roi (to be defined in spec config)
#%BR% %B%xbeg%B%   : 
#%BR% %B%xend%B%   : 
#%BR% %B%ybeg%B%   : 
#%BR% %B%yend%B%   : 
#
def mpxroi '{
    global MPX_ROI 

    if (list_n(MPX_ROI)<0) {
        list_init MPX_ROI
    }

    if ($#>=2) {
        _mpx_roiadd("$1", $2, $3, $4, $5)
    }
    else {
        _mpx_roimenu()
    }
}'

#%UU%
#%MDESC% Resets ROI definition.
def _mpx_roireset () '{
    local nroi roi

    nroi=list_n(MPX_ROI)

    for (roi=1; roi<=nroi; roi++) {
        cdef ("","",list_item(MPX_ROI,roi),"delete")
        if ((num=cnt_num(list_item(MPX_ROI,roi)))!=-1) S[num]=0;
    }

    list_init MPX_ROI
}'

#%IU% (mne, xmin, xmax, ymin, ymax)
#%MDESC% Add a new ROI or modify any existing one. Returns the index of the roi.
#
def _mpx_roiadd(mne, xmin, xmax, ymin, ymax) '{
    
    local rettab

    list_add(MPX_ROI, mne)

    MPX_ROI[mne]["xmin"]= xmin
    MPX_ROI[mne]["xmax"]= xmax
    MPX_ROI[mne]["ymin"]= ymin
    MPX_ROI[mne]["ymax"]= ymax

    cdef("user_getcounts", \
         sprintf("_mpx_getcounts(%s,%d,%d,%d,%d)\n", mne, xmin, xmax, ymin, ymax),\
         mne, 0x22 )
    
    rettab["number"] = MPX_ROI[mne]
    rettab["name"]   = mne 

    return (rettab)

}'

#%IU% (mne)
#%MDESC% Change the name of an existing Roi.
#
def _mpx_roirename (oldMne, newMne) '{
    
    number = MPX_ROI[oldmne]

    xmin = MPX_ROI[oldMne]["xmin"]
    xmax = MPX_ROI[oldMne]["xmax"]
    ymin = MPX_ROI[oldMne]["ymin"]
    ymax = MPX_ROI[oldMne]["ymax"]

    _mpx_roiremove(cmne)
    _mpx_roiadd(newMne, xmin, xmax, ymin, ymax)

    newNumber = MPX_ROI[newMne]

    return (newNumber)
}'

#%UU%
#%MDESC% Menu to Add/Modify/Delete/Save/Load rois
#
def _mpx_roimenu ()'{
    global MPX_ROI 
    local nb key ans upd
    local cmne cdet cmin cmax clvt cdt norm imne
    local cdis ndis ddis ii sidx

    upd= 0

    while (1) {
	nb= _mpx_roishow()
	tty_move(0,nb++, "\[md\]A\[se\]dd/\[md\]R\[se\]emove/\[md\]M\[se\]odify ROI(s),") 
	tty_move(0,nb++, "\[md\]L\[se\]oad from/\[md\]S\[se\]ave to file,  or \[md\]Q\[se\]uit (0)? ")

	while ((key=input(-1))=="") {}
	key=substr(key,1,1)
	printf("\n\n")

	if (key=="q"||key=="Q"||asc(key)==10) break
	else if (key=="r"||key=="R") {
		cmne= getval("Counter mnemonic",0)
		if (cmne!="0") _mpx_roiremove(cmne)
  		upd= 1
	}
	else if (key=="a"||key=="A") {
			cmne= getval(" > Counter mnemonic    ", 0)
			if (cmne) {
				xmin= getval(" > X min  ", MPX_PAR["xmin"])
				xmax= getval(" > X max  ", MPX_PAR["xmax"])
				ymin= getval(" > Y min  ", MPX_PAR["ymin"])
				ymax= getval(" > Y max  ", MPX_PAR["ymax"])
				_mpx_roiadd(cmne, xmin, xmax, ymin, ymax)
				upd= 1
			}
	}
	else if (key=="m"||key=="M") {
		cmne= getval(" > Counter mnemonic       ", 0)
		if (list_check(MPX_ROI, cmne)>0) {
		  xmin= getval(" > X min          ", MPX_ROI[cmne]["xmin"])
		  xmax= getval(" > X max          ", MPX_ROI[cmne]["xmax"])
		  ymin= getval(" > Y min          ", MPX_ROI[cmne]["ymin"])
		  ymax= getval(" > Y max          ", MPX_ROI[cmne]["ymax"])
  		  _mpx_roiadd(cmne, xmin, xmax, ymin, ymax)
		  upd= 1
		}
	}
	else if (key=="s"||key=="S") {
		file= getval("Save ROIs to file [0:default file]", 0)
		if (file=="0") mpxroisave
		else mpxroisave file
		input("... Press Enter ...")
	}
	else if (key=="l"||key=="L") {
		file= getval("Load ROIs from file [0:default file]", 0)
		if (file=="0") mpxroiload
		else mpxroiload file
		input("... Press Enter ...")
	}
    }
}'

#%IU% ()
#%MDESC%
#   Shows ROI definition
def _mpx_roishow() '{
    local nroi nb roi
    local ich idet status

    if ((nroi=list_n(MPX_ROI))<0) {
        list_init MPX_ROI
    }

    clscreen()
    tty_move(20,0,"\[md\]< MAXIPIX ROI >\[me\]")
    tty_move(0,2,"           Counter     Xmin   Xmax   Ymin   Ymax.")
    
    nb= 3
    for (roi=1; roi<=nroi; roi++) {
        local xmax xmin ymax ymin
        xmin= list_getpar(MPX_ROI,roi,"xmin")
        xmax= list_getpar(MPX_ROI,roi,"xmax")
        ymin= list_getpar(MPX_ROI,roi,"ymin")
        ymax= list_getpar(MPX_ROI,roi,"ymax")
        status = (cnt_num(list_item(MPX_ROI,roi))>-1)?"":"    Not in config !!!"
        tty_move(0, nb++, sprintf("\[md\]%18s   %6s %6s %6s %6s\[me\] %s", \
                          list_item(MPX_ROI,roi), xmin,xmax,ymin,ymax,status))
    	
    }
    tty_move(0,nb++,"--------------------------------------------------------")
    nb++
    return (nb)
}'

#%IU%
#%MDESC% Remove roi definition
def _mpx_roiremove(cmne) '{
    local sidx ich
    
    if (cmne=="*") {
        _mpx_roireset ()
    }
    else {
        list_remove(MPX_ROI, cmne)
        cdef ("","",cmne,"delete")
        if ((num=cnt_num(cmne))!=-1) S[num]=0;
    }
}'

#%UU% [<filename>]
#%MDESC% Save rois definition in a file. If <filename> is not specified, 
# save to the standard location
#
def mpxroisave '{
    local filename mne roi rmne

    if ($#==1){
        filename="$1"
    }
    else {
        filename= sprintf("%s/local/spec/userconf/mpxroi.def.%s", BLISSADM, USER)
    }

    if (!unix(sprintf("test -r %s", filename))) {
        unix(sprintf("/bin/rm -f %s", filename))
    }

    if (on(filename)==-1) {
        _mpx_print("Error", sprintf("Cannot open file %s", filename))
    }
    else {
        offt
        printf("# -------- MPX ROIs ----------\n")
        printf("# name xmin xmax ymin ymax\n")
        for (roi=1; roi<=list_n(MPX_ROI); roi++) {
            mne= list_item(MPX_ROI, roi)
            printf("%s %d %d %d %d \n", mne, MPX_ROI[mne]["xmin"],  \
                   MPX_ROI[mne]["xmax"], MPX_ROI[mne]["ymin"],      \
                   MPX_ROI[mne]["ymax"])
        }
        ont; close(filename)
        _mpx_print("ROI", sprintf("Saved to %s", filename))
    }
}'

#%UU% [<filename>]
#%MDESC% Load rois from a file. If <filename> is not specified, load from the 
# standard location
#%BR% Loading rois from file will erase current roi settings.
def mpxroiload '{
    local filename line pars[]
    local cmne cdet cmin cmax cnorm
    
    if ($#==1) {
        filename="$1"
    }
    else {
        filename= sprintf("%s/local/spec/userconf/mpxroi.def.%s", BLISSADM, USER)
    }
    
    if (unix(sprintf("test -r %s", filename))) {
        _mpx_print("Error", sprintf("Cannot find file %s", filename))
    }
    else {
        _mpx_roireset()

        for (line=getline(filename);line!=-1;line=getline(filename)) {
            if (substr(line,0,1)=="#") continue;
            if (split(line,pars)==5) {
                _mpx_roiadd(pars[0], int(pars[1]),int(pars[2]), int(pars[3]), \
                            int(pars[4]))
            }
        }

        getline(filename, "close")
        _mpx_print("ROI", sprintf("%d rois have been loaded from %s",   \
                                  list_n(MPX_ROI), filename))

    }
}'

#%IU%
#%MDESC%
def _mpx_print (a,b) '{
    printf ("%s: %s\n",a,b)
}'



#%IU%
#%MDESC% sum counts over ROI into corresponding spec counter.
def _mpx_getcounts(mne,_cb,_ce,_rb,_re) '{
  	local arrayname num _sum _avg _scale 
	local roiarrayname 

	# this is to avoid doing it when the camera is off
	if (!CCD_ON[MPX_UNIT])
		return 0

	num = cnt_num(mne)
	if (num == -1)
		return -1

  	arrayname=sprintf("image_data%d",MPX_UNIT)

	# this is done to optimise when not used
	roiarrayname = sprintf("image_data%d_roi", MPX_UNIT)
	ushort array @roiarrayname[_re-_rb+1][_ce-_cb+1]
	@roiarrayname = @arrayname[_rb:_re][_cb:_ce]
	arrayname = roiarrayname

       	_sum = array_op("sum",@arrayname)
# 	_scale = array_op("rows",@arrayname) * array_op("cols",@arrayname) 
#	_avg = _sum / _scale

       	S[num] = _sum
        return _sum
}'


#%MACROS%
#%IMACROS%
#%TOC%
#%AUTHOR% E.Papillon, $Revision: 1.15 $, $Date: 2010/02/10 16:16:41 $