esrf

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

#%TITLE% Conductuscurves.mac
#%NAME%
# Download calibration curves into a Conductus temperature controller.
#%DESCRIPTION%
# Each Conductus temperature controller is delivered with his own sensors. ID18
# wish to be able to use all sensors with all temperature controllers they have.
# Thus the calibration curves have to be loaded into the controller.
# %BR%
#%END%
#$Revision: 1.5 $
# $log:$

if (!(whatis("__condcurves_debug")  & 2)) rdef __condcurves_debug \'#$*\'
  

#%UU%
#%MDESC% toggle debug mode for the present macros.
def condcurves_debug '{
  if ((whatis("__condcurves_debug")>>16) <= 2) { # just a # sign -> off
    rdef __condcurves_debug "eprint"
    print "condcurves debug is ON"
  } else {
    rdef __condcurves_debug \'#$*\'
    print "condcurves debug is OFF"
  }
}
'

#%UU%
#%MDESC%
# Syntax : condgpib_setup <GPIB unit> <GPIB number>.%BR%
# Set the global COND_ADDR which is used for all gpib access.%BR%
def condgpib_setup '{
    global COND_COMM_MODE
    if ($# != 1) {
        eprint "Usage: condgpib_setup <Instrument GPIB number>"
        eprint "Use the full address here! Eg. 1:14"
    } else {
        global COND_GPIB_ADDR
        COND_GPIB_ADDR = "$1"
        COND_COMM_MODE = "GPIB"
    }
}
'

#%IU%
#%MDESC%
#Syntax : _cond_send(command)%BR%
#Internal function to send a command string to the Conductus. This imp.
#uses gpib at an address defined my the global variable %B%COND_ADDR.%B%
#Returns %B%CONDREADERROR%B% if the command could not be sent, otherwise
#%B%CONDOK%B% is returned.%BR%
def _cond_send(command) '{
    local numsent, reply
    global COND_GPIB_ADDR, COND_COMM_MODE

    __condcurves_debug "_cond_send(" command ")"
    if(COND_COMM_MODE == "GPIB"){
        numsent = gpib_put(COND_GPIB_ADDR,command)
        if(numsent == 0) {
            return "CONDREADERROR"
        } else{ 
            return "CONDOK"
        }
    }
    else if(COND_COMM_MODE == "SOCKET") {
        reply = _cond_read(command)
        if(reply != "CONDREADERROR") {
            return "CONDOK"
        } else {
            return "CONDREADERROR"
        }
    }
    else {
        print "DUMMY", command
        return "CONDOK"
    }
}
'

#%IU%
#%MDESC%
# Syntax : _cond_read(command)%BR%
# Internal function to send a command string to the Conductus and get the
# reply.%BR%
def _cond_read(command) '{
    global COND_COMM_MODE COND_GPIB_ADDR COND_SOCKET_ADDR
    local ans test numsenttosend

    ans = "CONDREADERROR"

    if(COND_COMM_MODE == "GPIB"){
        numsent = gpib_put(COND_GPIB_ADDR,command)
        if(numsent > 0){
            ans = gpib_get(COND_GPIB_ADDR)
            if (ans == "") {
                ans = "CONDREADERROR"
            }
        } else {
            print "_cond_read() : Error writing to GPIB"
                                  ans = "CONDREADERROR"
        }
    }
    else if(COND_COMM_MODE == "SOCKET"){
        ans = sock_par(COND_SOCKET_ADDR,"connect")
        if(ans == 1) {
            tosend = sprintf("%s\n",command)
            ans = sock_put(COND_SOCKET_ADDR,tosend)
            ans = sock_get(COND_SOCKET_ADDR,0)
            sock_par(COND_SOCKET_ADDR,"close")
            ans = substr(ans,0,length(ans)-1)
            if(ans == "SERVER_TIMEOUT"){
                print "_cond_read() : Server Timeout"
                ans = "CONDREADERROR"
            }
        } else {
            print "_cond_read() : Cannot connect to server."
            ans = "CONDREADERROR"
        }
    }
    else {
        ans = "all is ok"
    }
    __condcurves_debug "_cond_read(): answer " ans
    return ans
}
'

#%UU%
#%MDESC%
# Syntax : condlistallcurves%BR%
# List out all the curves used in the controller. There are 16 possible curves.
def condlistallcurves '{
    local i ncrvs crv ans

    global COND_GPIB_ADDR
    if ($# != 0) {
        printf("Usage: condlistallcurves")
    } else {
        ans = _cond_read("QCALT?;")
        split(ans,ncrvs,";")
        for (crv = 1; crv <= ncrvs[0]; crv ++ ) {
                printf("%3d", crv)
                        _condlistonecurve(15 + crv)
        }
    }
}'

#%UU%
#%MDESC%
# Syntax : condlistonecurve indexnumber
# List out the requested curve from the controller. There are 16 possible curves.
def condlistonecurve '{
    _condlistonecurve("$1")
}'

#%IU%
#%MDESC%
# Syntax : condlistonecurve(indexnumber)%BR%
# List out the requested curve from the controller. There are 16 possible curves.
def _condlistonecurve(crv) '{
    local i ncrvs sens_type[] volt_bias[] cal_tbl_units[] fmt
    local ans

    sens_type[0] = "2V Diode"
    sens_type[1] = "6V Diode"
    sens_type[2] = "R350"
    sens_type[3] = "R2500"
    sens_type[4] = "R1.0mV"

    volt_bias[0] = "10mV"
    volt_bias[1] = "3mV"
    volt_bias[2] = "1mV"
    volt_bias[3] = "320uV"
    volt_bias[4] = "100uV"
    volt_bias[5] = "32uV"
    volt_bias[6] = "10uV"

    cal_tbl_units[0] = "LogOhms"
    cal_tbl_units[1] = "Ohms"
    cal_tbl_units[2] = "Volts"

    fmt = "%2s %-20s %-10s %-10s %-5s %-8s\n"

    global COND_GPIB_ADDR

    ans = _cond_read(sprintf("QTBL? %d;\r\n",crv))
    if(ans == "CONDREADERROR"){
        eprint "Error reading curve header", crv
        exit
    }

    if (split(ans, curve, ";") != 6) {
        eprint "Funny answer from controller for curve", crv "."
        exit
    }

    printf(fmt, "", curve[3], curve[0], cal_tbl_units[curve[1]], \
                    curve[2], curve[4])
#  print "***" ans "***"
#  print curve
}'

#%UU%
#%MDESC%
# Syntax : condwritecurve [filename]%BR%
# Reads one sensor calibration curve from harddisk and writes it into the
# Conductus temperature controller. Only curves 10 to 26 can be written.
# %BR%
#%B%EXAMPLE:%B%%BR%
#%PRE%
#Sensor Type:   0 = 2V Diode, 1 = 6V Diode, 2 = R250, 3 = R2500, 4 = R1.0mV
#Voltage Bias:  0 = 10 mV, 1 = 3 mV, 2 = 1 mV, 3 = 320 uV, 4 = 100uV, 5 = 32uV, 6 = 10uV
#Cal Table Units: 0 = LogOhms, 1, Ohms, 2 Volts
#Sensor Description: 1 to 19 chars, spaces will be eliminated
#Multiplier:  non-zero
#%PRE%
def condwritecurve '{
    local i j ii scalt dummy fname
    local curve[] textline field[] ans

    if ($# == 0) {
        print "Use macro condlistallcurves to get a list of already stored curves!"
#		crv   = getval("Number of curve to be written?",11)
        fname = getval("Filename of temperature curve?","X12379.340")
    } else if ($# == 1) {
        fname = "$1"
    } else {
        print "Please give two or no args, first filename, then curve number"
        exit
    }

    if (!file_info(fname)) {
        eprint "File: ", fname, "does not exist!"
        exit
    }

    # scan in the informations from the head of the .340 file.
    {
        local stype sernum dfmt sdesc coeff npts voltbias
        voltbias  = 0
        coeff = -1
        dfmt = sdesc = npts = ""
        open(fname)
        i = 0
        textline = getline(fname, 0)
        while(1) {
            #print textline
            if (split(textline, field, ":") == 1) {
                break # no : stop!
            }
            #print "+++", field[0], field[1]
            if (field[0] == "Sensor Model") {
                local a[], num, i
                num = split(field[1], a, "-")
                for (i = 0; i < num; i ++) {
                    sscanf(a[i], "%s", a[i]) # strip blanks
                }
                if (a[0] == "DT" || a[0] == "TG") {
                    stype = 0
                }
                else if (a[0] == "PT" || a[1] == "1000") {
                    stype = 3
                }
                else if (a[0] == "PT") {
                    stype = 2
                }
                else if (a[0] == "CX" || a[0] == "CGR" || a[0] == "GR" || \
                        a[0] == "RX" || a[0] == "RF") {
                    stype = 4
                }
                else {
                    eprint "Sensor Model not recognised !!!!"
                    exit
                }
            }
            if (field[0] == "Data Format") {
                local a[]
                split(field[1], a)
                dfmt = 4 - a[0]
                if (dfmt > 2) {
                  eprint "Bad Cal Table Units ->", dfmt
                  exit
                }
            }
            if (field[0] == "Serial Number") {
                sscanf(field[1], "%s", sernum)
                sdesc = sernum "_" date("%d%b%Y")
                sdesc = substr(sdesc, 0, 19)
            }
            textline = getline(fname)
        }
        if (stype == "") {
            eprint "Data file", fname, "\"Sensor Model\" could not be determined!"
            eprint "Aborted !"
            exit
            exit
        } else if (dfmt == "") {
            eprint "Data file", fname, "\"Cal Table Units\" could not be determined!"
            eprint "Aborted !"
            exit
        } else if (sdesc == "") {
            eprint "Data file", fname, "\"Sensor Description\" could not be determined!"
            eprint "Aborted !"
            exit
        }

        scalt = sprintf("SCALT %s,2,%s,%s,%s,", stype, dfmt, sdesc, coeff)
        print "Command to write to Conductus LTC-20:", scalt

        if (!yesno("Would you like to write this to the instrument?", 0)) {
            exit
        }
        ans = _cond_send(scalt)
        if(ans != "CONDOK"){
            eprint "Error writing curve command first part."
            exit
        }
    }
    # read in the remaining lines, the data, hopefully.
    {
        local loop, ii, jj, jumpEveryN
        # jumpEveryN will decide how to write the values: all of them or jump
        # every jumpEveryNth value
        jumpEveryN = 1
        local double array arr[256][2]
        loop = 1 # index of point, valid entries 1 - 149
        while((textline = getline(fname)) != -1) {
            if (sscanf(textline, "%d %g %g", ii, arr[loop][0], arr[loop][1]) == 3) {
                if (ii == 0 && arr[loop][0] == 0 && arr[loop][1] == 0) {
                    continue
                }
            } else if (sscanf(textline, "%g %g", valunits, val_temp) == 2) {
                if (ii == 0 && arr[loop][0] == 0 && arr[loop][1] == 0) {
                    continue
                }
            } else {
                continue # thats probably a text line. just forget
            }
            loop ++
        }

        if (loop >= 100 && loop < 200) {
            local x, morestr, mystr, str[]
            x = 1
#            jumpEveryN = 2
            while(x <= 100) {
                jumpEveryN ++
                x = loop * jumpEveryN / (jumpEveryN+1)
            }
            x = loop * (jumpEveryN-1) / jumpEveryN
            if (jumpEveryN == 2) {
                mystr = "second"
            } else if (jumpEveryN == 3) {
                mystr = "third"
            } else if (jumpEveryN > 3) {
                mystr = jumpEveryN "th"
            }
            morestr = "Enter fraction of points you want to skip (every " mystr ")"
            eprint "Attention: more than 100 points (" loop - 1 ") given!!"
            
            jumpEveryN =  getval(morestr, jumpEveryN)
        }
        else if (loop > 200) {
            eprint "Can`t handle more than 200 points"
            exit
        }
        #print arr
        # there is no point number 0 !
        for (ii = 1, jj = 1; ii < loop; ii ++) {
            # AH: 25/05/2010 swapped temperature and volt/ohms
            # dummy = arr[ii][0] "," arr[ii][1] ","
            dummy = arr[ii][1] "," arr[ii][0] ","
            if (!(ii % jumpEveryN) && jumpEveryN > 1) { continue }
            ans = _cond_send(dummy)
            if(ans != "CONDOK"){
                eprint "Error writing calibration point", loop "."
                exit
            }
            printf(".")
            # printf("%3d", loop)
            jj ++
            sleep(.1)
        }
        ans = _cond_send("\$;\r\n")
        if(ans != "CONDOK") {
            eprint "Error writing curve command termination part."
            exit
        }
        print
        ans = _cond_read("QCALT?;")
        split(ans, ncrvs, "3;")
        #p "+++", jj
        _condlistonecurve(15 + ncrvs[0])
    }
    close(fname)

    print
    print "Curve was written to the Conductus temperature controller."; print

#  print "Definitions from actual curve", crv, "in Conductus tc :"
#  condlistonecurve crv
}
'

#%UU%
#%MDESC%
# Syntax : conddeletecurve index%BR%
def conddeletecurve '{
    local indnum
    if ($# != 1) {
        eprint "Usage: conddeletecurve [curv index number]"
        exit
    } else {
        indnum = $1
    }
    dummy = sprintf("DCALT %d;\r\n", indnum)
    if (!yesno("Would you like to delete the curve?", 0)) {
        exit
    }
    ans = _cond_send(dummy)
    if(ans != "CONDOK"){
        eprint "Error writing curve command first part."
        exit
    }
}
'
  


#%MACROS%
#%IMACROS%
#%AUTHOR% Holger Witsch, July 2005