add TCAS version of Gm measurement
authorDan White <dan@whiteaudio.com>
Fri, 20 Jun 2014 19:57:38 +0000 (14:57 -0500)
committerDan White <dan@whiteaudio.com>
Fri, 20 Jun 2014 19:57:38 +0000 (14:57 -0500)
python-lib/test-data/chip14/arb0/vios-offset-gm/tcas-gm.pdf [new file with mode: 0644]
python-lib/test-data/chip14/arb0/vios-offset-gm/tcas-gm.py [new file with mode: 0644]

diff --git a/python-lib/test-data/chip14/arb0/vios-offset-gm/tcas-gm.pdf b/python-lib/test-data/chip14/arb0/vios-offset-gm/tcas-gm.pdf
new file mode 100644 (file)
index 0000000..3c281d4
Binary files /dev/null and b/python-lib/test-data/chip14/arb0/vios-offset-gm/tcas-gm.pdf differ
diff --git a/python-lib/test-data/chip14/arb0/vios-offset-gm/tcas-gm.py b/python-lib/test-data/chip14/arb0/vios-offset-gm/tcas-gm.py
new file mode 100644 (file)
index 0000000..6324c1a
--- /dev/null
@@ -0,0 +1,211 @@
+#!/usr/bin/env python
+
+from pylab import *
+
+from glob import glob
+import yaml
+import scipy.signal as sig
+
+
+
+
+
+close('all')
+
+
+def circular_cycle(a, b):
+    from itertools import cycle
+
+    a_cycler = cycle(a)
+    b_cycler = cycle(b)
+
+    while True:
+        yield a_cycler.next() + b_cycler.next()
+
+def style_cycle():
+    lines = ('-', '--', '-.', ':')
+    colors = ('b', 'g', 'r', 'k', 'm', 'c')
+    return circular_cycle(lines, colors)
+
+
+def mkgm(vd, vout, tint, Cint=50e-12):
+    dvout = diff(vout / tint)
+    dvd = diff(vd)
+    gm = Cint * dvout / dvd
+    return (vd[:-1], gm)
+
+
+def smooth(x, npoints=21.0):
+    return sig.filtfilt(ones(npoints)/npoints, [1], x)
+
+
+# collect data to plot sorted by offset value
+d = {}
+for npz in glob('arb0-2013*.npz'):
+    data = np.load(npz)
+    cfg = yaml.load(open(npz.replace('.npz', '.yaml'), 'rb'))
+    ios = cfg['arb']['harmonics'][0]['otaA']['offset']
+
+    d[ios] = {'data':data, 'fname':npz}
+
+
+if 1:
+    figure(figsize=(3.5, 3.0))
+    subplots_adjust(top=0.98, bottom=0.13, left=0.15, right=0.98)
+
+
+    ax = subplot(311)
+    styler = style_cycle()
+
+    ios = 105
+    #for ios in sorted(d.keys()):
+        #if ios != 105:
+            #continue
+
+    data = d[ios]['data']
+    tint = data['tint']
+    vd = data['vd']
+    vout = data['vout']
+
+    iout = 50e-12 * vout / tint
+    plot(vd, 1e12*iout,
+            styler.next(),
+            label='%i'%ios)
+
+
+    hlines(0, -10, 10, linewidth=0.5, color='0.40')
+    vlines(0, -1000, 1000, linewidth=0.5, color='0.40')
+
+    xlim((-2.5, 2.5))
+    ax.set_xticklabels([''] * len(ax.get_xticks()))
+    yticks(range(-150, 200, 75))
+    ylim((-180, 180))
+    ylabel(r'(pA)')
+    labelx = -0.12
+    ax.yaxis.set_label_coords(labelx, 0.5)
+
+    text(0.2, 0.75,
+         r'$I_{out}$',
+         transform=ax.transAxes)
+
+    #mpl.rcParams['legend.fontsize'] = 'small'
+    #legend(title='offset code',
+           #loc='lower right',
+           #ncol=3,
+           #handletextpad=0.2,
+           #labelspacing=0.2,
+           #columnspacing=1.0)
+
+    ax = subplot(312)
+    styler = style_cycle() #reset iterator
+    #for ios in sorted(d.keys()):
+        #if ios == 100:
+            #continue
+
+    data = d[ios]['data']
+    tint = data['tint']
+    vd = data['vd']
+    vout = data['vout']
+
+    vdgm, dgm = mkgm(vd, vout, tint)
+
+    #plot(vdgm, dgm, 'b.', label='raw')
+    #plot(vd, 1e12*smooth(50e-12*vout/tint, 15.0)/vd,
+    plot(vdgm, 1e12*smooth(dgm, 15.0),
+            styler.next(),
+            label=ios)
+
+    xlim((-2.5, 2.5))
+    ax.set_xticklabels([''] * len(ax.get_xticks()))
+    hlines(0, -10, 10, linewidth=0.5, color='0.40')
+    vlines(0, -1000, 1000, linewidth=0.5, color='0.40')
+    ylim((-5, 100))
+    #ylabel(r'$g_m = dI_{out}/dV_d$ (pA/V)')
+    #ylabel(r'$\partial G_m / \partial V_{id}$ (pA/V)')
+    ylabel(r'(pA/V)')
+    ax.yaxis.set_label_coords(labelx, 0.5)
+    #xlabel('$V_d$ (V)')
+    text(0.2, 0.75,
+         r'$G_m$ (inc)',
+         transform=ax.transAxes)
+
+
+    ax = subplot(313)
+    styler = style_cycle()
+    #for ios in sorted(d.keys()):
+        #if ios == 100:
+            #continue
+
+    data = d[ios]['data']
+    tint = data['tint']
+    vd = data['vd']
+    vout = data['vout']
+
+    iout = 50e-12 * vout / tint
+    idx = find(vd == abs(vd).min())
+    iout = iout - iout[idx]
+
+    gm = 1e12 * iout / vd
+    st = styler.next()
+    #do not plot bad data around zero
+    plot(vd[:idx-1], gm[:idx-1],
+            st,
+            label='%i'%ios)
+    plot(vd[idx+2:], gm[idx+2:],
+            st)
+
+    #calc nonlinearity
+    gm = [gm[i] for i in range(len(gm))
+            if i not in (idx-1, idx, idx+1)]
+    vd = [vd[i] for i in range(len(vd))
+            if i not in (idx-1, idx, idx+1)]
+
+    gm = array(gm)
+    dplus = gm.max()/gm.mean() * 100 - 100
+    dminus = gm.min()/gm.mean() * 100 - 100
+    print gm.mean()
+    print '%i: %+5.1f %+5.1f %%' % (ios, dplus, dminus)
+
+    hlines(0, -10, 10, linewidth=0.5, color='0.40')
+    vlines(0, -1000, 1000, linewidth=0.5, color='0.40')
+
+    xlim((-2.5, 2.5))
+    ylim((-5, 100))
+    ylabel(r'(pA/V)')
+    ax.yaxis.set_label_coords(labelx, 0.5)
+    xlabel(r'$V_{id}$ (V)')
+    text(0.2, 0.75,
+         r'$G_m$ (eff)',
+         transform=ax.transAxes)
+
+
+    #subplot(313)
+    #styler = style_cycle() #reset iterator
+    #for ios in sorted(d.keys()):
+        ##if ios == 100:
+            ##continue
+
+        #data = d[ios]['data']
+        #tint = data['tint']
+        #vd = data['vd']
+        #vout = data['vout']
+
+        #vdgm, dgm = mkgm(vd, vout, tint)
+
+        ##plot(vdgm, dgm, 'b.', label='raw')
+        ##plot(vd, 1e12*smooth(50e-12*vout/tint, 15.0)/vd,
+        #plot(vdgm, 1e12*smooth(dgm, 15.0),
+                #styler.next(),
+                #label=ios)
+
+    #xlim((-2.5, 2.5))
+    #hlines(0, -10, 10, linewidth=0.5, color='0.40')
+    #vlines(0, -1000, 1000, linewidth=0.5, color='0.40')
+    #ylim((-5, 100))
+    ##ylabel(r'$g_m = dI_{out}/dV_d$ (pA/V)')
+    #ylabel(r'$G_m$ (pA/V)')
+    #xlabel('$V_d$ (V)')
+
+
+    savefig('tcas-gm.pdf')
+