Store calibration data
authorDan White <dan@whiteaudio.com>
Sat, 1 Sep 2012 04:21:06 +0000 (23:21 -0500)
committerDan White <dan@whiteaudio.com>
Sat, 1 Sep 2012 04:21:06 +0000 (23:21 -0500)
python-lib/calibrate.py

index 633f219ab997c42e0866e69df4923b2a99a9ca1d..d1c0c5b85dc6d46c02bbf088a682a5a5edd26359 100644 (file)
@@ -82,28 +82,22 @@ def secant_opt(func, x0, limits, x1scale=0.1, maxiter=100, k=1.0):
         #return int(round(max(min(x, xmax), xmin)))
 
     def eval(x):
-        print 'eval:', x[0:N_CHANNELS]
+        print 'eval:'
+        print x[0:N_CHANNELS]
         r = func(x)
-        print r.shape, x.shape
         guesses.append(x)
         results.append(r)
         return r
 
     q0 = eval(p0)
     r = xmax - xmin
-    print type(q0), q0
     p1 = saturate(p0 - sign(q0)*x1scale*r)
-    #if q0 > 0.0:
-        #p1 = saturate(p0 - x1scale * r)
-    #else:
-        #p1 = saturate(p0 + x1scale * r)
 
     q1 = eval(p1)
     for niter in range(maxiter):
         iz = find(q1==q0)
         q1.flat[iz] = q1.flat[iz] + 1e-6
-        #dp = converging*q1*(p1 - p0)/(q1 - q0)
-        dp = q1*(p1 - p0)/(q1 - q0)
+        #dp = q1*(p1 - p0)/(q1 - q0)
         dp = q1*abs(p1 - p0)/abs(q1 - q0)
         #dp = k*q1*(p1 - p0)/(q1 - q0)
         #dp = k*sign(q1)*abs(p1-p0)
@@ -118,20 +112,12 @@ def secant_opt(func, x0, limits, x1scale=0.1, maxiter=100, k=1.0):
         #unless the channel is done...
         dp *= converging
 
-        #if abs(dp) < 1.0:
-            #if dp < 0.0:
-                #dp = -1
-            #else:
-                #dp = 1
         p = saturate(p1 - dp)
         q = eval(p)
 
         # Convergence criteria
         #   x to varies by (+1,-1) or (-1,+1)
         #   or 3 consecutive guesses the same
-        #d0 = p1 - p0
-        #d1 = p - p1
-        #if all(abs(d0) == 1) and all(abs(d1) == 1) and (d0 == -1*d1):
         for i in range(x0.size):
             d0 = p1.flat[i] - p0.flat[i]
             d1 = p.flat[i]- p1.flat[i]
@@ -143,12 +129,7 @@ def secant_opt(func, x0, limits, x1scale=0.1, maxiter=100, k=1.0):
                 if (a0 <= a1) and (a <= a1):
                     converging.flat[i] = 0
                     evaluations.flat[i] = 3 + niter
-                    #print 'channel done:', i
-                    #print converging
-                    #return p0
-                #else:
-                    #print "false alarm, almost there..."
-                    ##return p1
+
         print converging[0:N_CHANNELS]
         if not (sum(converging[0:N_CHANNELS]) > 0.0): 
             return (p0, {'nevals': evaluations,
@@ -170,7 +151,6 @@ def offset2signed(v, bits):
 
 
 def mux_a_offset(x):
-    #xi = int(round(x))
     xi = int(x[0])
     mux.otaA.offset = xi
     mux.write()
@@ -213,7 +193,7 @@ def chain_a_offset(x, n, mux_offset):
         sleep(DELAY)
     mv = mean(values)
     print tpx(xi), tplot(mv)
-    return mv #- mux_offset
+    return mv
 
 
 def chain_outputs(n):
@@ -223,18 +203,13 @@ def chain_outputs(n):
 
     plotter = TermPlotter([-1000, 1000], width=80)
 
-    #outA = []
-    #outB = []
     outs = zeros((2, n+1))
-    print outs.shape, outs
     for i in range(n+1):
-        print 'i:', i
         mux.selA = i
         mux.selB = i
         mux.write()
 
         for j in range(2):
-            print 'k:', j
             adc.mux(4+j)
             sleep(0.1)
             adc.triggerMode(adc.MODE_MANUAL_MANUAL)
@@ -248,27 +223,12 @@ def chain_outputs(n):
                 values.append(v)
                 sleep(DELAY)
             mv = mean(values[-1*min(10, N_SAMPLES):-1])
-
-            #sleep(0.01)
             outs[j, i] = mv
-            #a = mv
-            #b = offset2signed(adc.read(), 16)
-        #print '%02i:'%i, a, b
-        #outA.append(a)
-        #outB.append(b)
 
     print outs[:,0:N_CHANNELS]
     return outs
-    #return array([array(outA), array(outB)])
 
 def chain_offsets(values, mux_offset):
-    #for i,n in enumerate(values):
-        #chain.h[i].otaA.offset = int(n)
-        #chain.h[i].cal = 1
-        #chain.h[i].otaA.se = 1
-        #chain.h[i].otaA.cint = 0
-        #chain.h[i].otaA.zero = 1
-    #chain.write()
     for i,n in enumerate(values[0]):
         chain.h[i].otaA.offset = int(n)
         chain.h[i].cal = 1
@@ -283,16 +243,13 @@ def chain_offsets(values, mux_offset):
         chain.h[i].otaB.zero = 0
     chain.write()
     sleep(1.0)
+
     outs = chain_outputs(N_CHANNELS-1)
+
     for i in range(2):
         outs[i,:] -= mux_offset[i]
-    #outs = [outA - mux_offset[0], outB - mux_offset[1]]
-    print 'here'
+
     return array(outs)
-    a = randint(-10, 10, (48,))
-    #for j in range(N_CHANNELS):
-        #a[j] = outA[j]
-    #return a - mux_offset
 
 dac.vina(1.25)
 dac.vinb(1.25)
@@ -314,61 +271,73 @@ adc.triggerMode(adc.MODE_MANUAL_MANUAL)
 
 
 
-N_CHANNELS = 4
+N_CHANNELS = 2
 N_SAMPLES = 10
 DELAY = 0.05
 
-if 0:
-    print
-    print 'Calibrating mux otaA'
-    adc.mux(4)
-    resA, tmp = secant_opt(mux_a_offset, zeros((1,), dtype=int), [-128, 127])
-    muxA_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)])
-    print '*** mux.otaA.offset =', muxA_offset, ' @', resA
-else:
-    resA = 53
-    muxA_offset = 0.0
-
-
-if 0:
-    print
-    print 'Calibrating mux otaB'
-    adc.mux(5)
-    #resB = secant_opt(mux_b_offset, 0, [-128, 127])
-    resB, tmp = secant_opt(mux_b_offset, zeros((1,), dtype=int), [-128, 127])
-    muxB_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)])
-    print '*** mux.otaB.offset =', muxB_offset, ' @', resB
-else:
-    resB = 59
-    muxB_offset = 0.0
-
-
-if 0:
-    offset_chain_a = []
-    for n in range(48):
+import datetime as dt
+
+while True:
+    if 1:
         print
-        print 'Calibrating chain %02i A' % n
-        adc.triggerMode(adc.MODE_IDLE)
+        print 'Calibrating mux otaA'
         adc.mux(4)
-        adc.triggerMode(adc.MODE_MANUAL_MANUAL)
-        mux.selA = n
-        mux.selB = n
+        resA, tmp = secant_opt(mux_a_offset, zeros((1,), dtype=int), [-128, 127])
+        muxA_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)])
+        print '*** mux.otaA.offset =', muxA_offset, ' @', resA
+    else:
+        resA = 53
+        muxA_offset = 0.0
+
+
+    if 1:
+        print
+        print 'Calibrating mux otaB'
+        adc.mux(5)
+        #resB = secant_opt(mux_b_offset, 0, [-128, 127])
+        resB, tmp = secant_opt(mux_b_offset, zeros((1,), dtype=int), [-128, 127])
+        muxB_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)])
+        print '*** mux.otaB.offset =', muxB_offset, ' @', resB
+    else:
+        resB = 59
+        muxB_offset = 0.0
+
+
+    if 0:
+        offset_chain_a = []
+        for n in range(48):
+            print
+            print 'Calibrating chain %02i A' % n
+            adc.triggerMode(adc.MODE_IDLE)
+            adc.mux(4)
+            adc.triggerMode(adc.MODE_MANUAL_MANUAL)
+            mux.selA = n
+            mux.selB = n
+            mux.otaA.mode = mux.otaA.MUX_BUF
+            mux.otaB.mode = mux.otaB.MUX_BUF
+            mux.write()
+            nos = secant_opt(lambda x: chain_a_offset(x, n, muxA_offset), resA, (-128, 127))
+            mean_os = mean([offset2signed(adc.read(), 16) for i in range(1000)])
+            print '*** chain.h[%02i].otaA.offset =' % n, mean_os, ' @', nos
+            chain_outputs(n)
+
+    if 1:
         mux.otaA.mode = mux.otaA.MUX_BUF
         mux.otaB.mode = mux.otaB.MUX_BUF
         mux.write()
-        nos = secant_opt(lambda x: chain_a_offset(x, n, muxA_offset), resA, (-128, 127))
-        mean_os = mean([offset2signed(adc.read(), 16) for i in range(1000)])
-        print '*** chain.h[%02i].otaA.offset =' % n, mean_os, ' @', nos
-        chain_outputs(n)
-
-if 1:
-    mux.otaA.mode = mux.otaA.MUX_BUF
-    mux.otaB.mode = mux.otaB.MUX_BUF
-    mux.write()
-    chain_os, stats = secant_opt(lambda x: chain_offsets(x, (muxA_offset, muxB_offset)), resA*ones((2,N_CHANNELS), dtype=int), (-128, 127), k=0.5)
-    print '-'*80
-    print 'offsets:', chain_os[:N_CHANNELS]
-    print 'N-evals:', stats['nevals'][:N_CHANNELS]
-    print '-'*80
-    print
+        chain_os, stats = secant_opt(lambda x: chain_offsets(x, (muxA_offset, muxB_offset)), resA*ones((2,N_CHANNELS), dtype=int), (-128, 127), k=0.5)
+        print '-'*80
+        print 'offsets:', chain_os[:N_CHANNELS]
+        print 'N-evals:', stats['nevals'][:N_CHANNELS]
+        print '-'*80
+        print
+
+    fname = '%s.npz' % (dt.datetime.now().strftime('%Y-%m-%d_%H%M%S'), )
+    print '*** writing to %s ***' % fname
+    savez(fname,
+            muxres=(resA, resB),
+            muxos=(muxA_offset, muxB_offset),
+            chaincal=chain_os,
+            **stats
+            )