#! /usr/bin/env python

import sys, os, os.path
import time

import numpy as np

import dice.testbench.motor as dtm
import dice.testbench.utils.grid as dtug
import dice.testbench.multimeter.keithley6514 as multi

# --------- Parse command line arguments ------------------

def usage():
    print >>sys.stderr, \
        'usage: simple-beam-map z=<z>'
    print >>sys.stderr, \
        "                    [xmin=<xmin> xmax=<xmax> ymin=<ymin> ymax=<ymax>]"
    print >>sys.stderr, \
        "                    [dx=<dx> dy=<dy>]"
    

# print sys.argv

if len(sys.argv) < 1:
    usage()
    sys.exit(1)


phd = "NIST"
phd_port = "/dev/ttyS3"
keithley_range = '2e-6'
z = -1590. # mm
samples = 100
time_sleep = 3.0
ref_period = 20
# xmin =     0. # mm
# xmax =   300. # mm
# ymin =     0. # mm
# ymax =   300. # mm
# zmin = -1593. # mm
# zmax =     0. # mm

xmin = 135. # mm
xmax = 165. # mm
ymin = 133. # mm
ymax = 163. # mm
xref = None
yref = None

# dx = 10. # mm
# dy = 10. # mm
dx = 1. # mm
dy = 1. # mm

for arg in sys.argv[1:]:
    if '=' not in arg:
        print >>sys.stderr, "error: invalid argument [%s]" % arg
        usage()
        sys.exit(2)
    eqparts = arg.split('=')
    if len(eqparts) != 2:
        print >>sys.stderr, "error: invalid argument format [%s]" % arg
        usage()
        sys.exit(3)
    
    param = eqparts[0].lower()
    if param not in ['phd', 'phd_port', 'keithley_range', "samples",
                     'led', 'z', 'current',
                     'xmin', 'xmax', 'ymin', 'ymax',
                     'dx', 'dy', 'time_sleep', 'ref_period','xref','yref'
                     ]:
        print >>sys.stderr, "error: invalid parameter [%s]" % arg
        usage()
        sys.exit(4)

    exec(arg)
    # print arg, param, eval(param)


if xref == None:
    xref = xmin + (xmax-xmin)/2    

if yref == None:
    yref = ymin + (ymax-ymin)/2    


# --------- Init testbench motors -------------------------

B = dtm.Bench()
B.open()
B.setup()

# ---------------------------------------------------------

# --------- Init multimeter Keithley 6514 -----------------

K = multi.Multimeter(port = phd_port)

K.open()
K.reset()
K.write("CURR:RANG %s" % keithley_range)
#K.write("CURR:RANG 2e-6")
#K.write("CURR:RANG 2e-10")
K.write("FUNC 'CURR:DC'")
K.write("SYST:ZCH OFF")
K.write("TRIG:COUN %d" % samples)
K.write(":SENS:CURR:NPLC 1") # 1 seems to be the default
K.write(":DISP:ENAB OFF")

# ---------------------------------------------------------

# xy_mm = 12800.0 # steps / mm
# z_mm  =  2560.0 # steps / mm

B.sensor_move_absolute('Z', z, unit = "mm")

filename = ("MONO-EXIT-SLIT-BEAM-MAP-z=%06dmm-dxdy=%fmm%fmm-%s-%f.data" %
            (z, dx, dy, phd, time.time() ) )
f = open(filename, "w")
print >>f, "# time   x(mm)   y(mm)    I(A)"

# ipos = 0

xlast,ylast = None, None
for (x,y) in dtug.Grid(xmin, xmax, dx,
                       ymin, ymax, dy,
                       order = "faster",
                       reference = {'x':xref,'y':yref, 'period':ref_period} ):
    print "LED map: GOTO to ", x, y
    if x != xlast: B.sensor_move_absolute('X', x, unit = "mm")
    if y != ylast: B.sensor_move_absolute('Y', y, unit = "mm")
    xlast = x
    ylast = y

    # extra delay for capacity discharge ?
    time.sleep(time_sleep)

    T = time.time()
    K.write("READ?")
    data_str = K.read()
    print "Received [%s]" % data_str
    parts = data_str.split(',')
    # if (len(parts) != 3*samples):
    #     print >>sys.stderr, "No data. stop."
    #     break
    flux = float(parts[0])
    print T, x, y, flux
    print >>f, T, x, y, flux
    f.flush()

f.close()

# ---------------------------------------------------------

K.close()
B.close()

# ---------------------------------------------------------

