Beispiel #1
0
 def _make_splines(self, xs, ys):
     """ Make the splines """
     base = splrep(xs, ys, s=0)
     tcks = {
         -1: splantider(base, 1),
         0: base,
         1: splder(base, 1),
         2: splder(base, 2),
         3: splder(base, 3)
     }
     return tcks
Beispiel #2
0
 def __init__(self,
              distribution_1,
              distribution_2=None,
              n_steps=1000,
              include_rate=0.5):
     self.distribution_1 = distribution_1
     self.distribution_2 = distribution_2
     if distribution_2 is None:
         self.interval = [distribution_1.min(), distribution_1.max()]
     else:
         self.interval = [
             min([distribution_1.min(),
                  distribution_2.min()]),
             max([distribution_1.max(),
                  distribution_2.max()])
         ]
     self.n_steps = n_steps
     self.include_rate = include_rate
     self.fraction = np.linspace(self.interval[0], self.interval[-1],
                                 n_steps)
     self.step = self.fraction[1] - self.fraction[0]
     self.cdf_1 = build_cdf(self.distribution_1)
     self.cdf_spline_1 = spline_by_distribution(self.cdf_1, self.interval)
     self.spline_1 = splder(self.cdf_spline_1, 1)
     self.density_fraction_1 = cdf_fraction(self.spline_1, self.fraction)
     self.area_1 = full_area(self.density_fraction_1, self.step, None,
                             self.include_rate)
     # self.scaled_cdf_1 = self.cdf_1
     # self.scaled_cdf_1['COUNT'] = self.scaled_cdf_1['COUNT'] / self.area_1
     self.scaled_density_fraction_1 = self.density_fraction_1 / self.area_1
     if distribution_2 is None:
         self.cdf_2 = None
         self.spline_2 = None
         self.density_fraction_2 = None
         self.area_2 = None
         # self.scaled_cdf_2 = None
         self.scaled_density_fraction_2 = None
     else:
         self.cdf_2 = build_cdf(self.distribution_2)
         self.cdf_spline_2 = spline_by_distribution(self.cdf_2,
                                                    self.interval)
         self.spline_2 = splder(self.cdf_spline_2, 1)
         self.density_fraction_2 = cdf_fraction(self.spline_2,
                                                self.fraction)
         self.area_2 = full_area(self.density_fraction_2, self.step, None,
                                 self.include_rate)
         # self.scaled_cdf_2 = self.cdf_2
         # self.scaled_cdf_2['COUNT'] = self.scaled_cdf_2['COUNT'] / self.area_2
         self.scaled_density_fraction_2 = self.density_fraction_2 / self.area_2
Beispiel #3
0
def plot_free_energy_curves(e_poly, chi_spline, E_samples, q_samples, Ps):
    fg = plt.figure()
    ax = fg.add_subplot(111)
    for e in E_samples:
        F = free_energy(q_samples, chi_spline, e_poly, e, Ps, False)
        ax.plot(q_samples, F, '.-', label=r'$E=${0:6.2e}'.format(e))
    ax.legend()
    ax.set_xlabel(r'$Q$')
    ax.set_ylabel(r'$F(Q;E)(E_\mathrm{H}/a_0^3)$')
    global now
    timestamp = now.strftime('%Y%m%d_%H%M%S')
    pathlib.Path(os.path.join('output',
                              'free_energy_curves')).mkdir(parents=True,
                                                           exist_ok=True)
    fg.savefig(
        os.path.join('output', 'free_energy_curves',
                     'free_energy_curves_' + timestamp))

    fg = plt.figure()
    ax = fg.add_subplot(111)
    chi_prime = splder(chi_spline)
    for e in E_samples:
        dF = free_energy_derivative(q_samples, chi_prime, np.polyder(e_poly),
                                    e, Ps, False)
        ax.plot(q_samples, dF, '.-', label=r'$E=${0:6.2e}'.format(e))
    ax.legend()
    ax.set_xlabel(r'$Q$')
    ax.set_ylabel(
        r'$\frac{\mathrm{d}F}{\mathrm{d}Q}(Q;E)(E_\mathrm{H}/a_0^3)$')

    timestamp = now.strftime('%Y%m%d_%H%M%S')
    pathlib.Path(os.path.join('output', 'dFdQ_curves')).mkdir(parents=True,
                                                              exist_ok=True)
    fg.savefig(
        os.path.join('output', 'dFdQ_curves', 'dFdQ_curves_' + timestamp))
Beispiel #4
0
 def derivative(self, n=1):
     """Returns derivative as a spline
 
 Arguments:
   n (int): order of the derivative
   
 Returns:
   Spline: the derivative of the spline with degree - n 
 """
     tck = splder(self.tck(), n)
     return Spline(tck=tck, points=self.points)
 def derivative(self, n = 1):
   """Returns derivative as a spline
   
   Arguments:
     n (int): order of the derivative
     
   Returns:
     Spline: the derivative of the spline with degree - n 
   """
   tck = splder(self.tck(), n);
   return Spline(tck = tck, points = self.points);
Beispiel #6
0
    def test_splder(self):
        for b in [self.b, self.b2]:
            # pad the c array (FITPACK convention)
            ct = len(b.t) - len(b.c)
            if ct > 0:
                b.c = np.r_[b.c, np.zeros((ct,) + b.c.shape[1:])]

            for n in [1, 2, 3]:
                bd = splder(b)
                tck_d = _impl.splder((b.t, b.c, b.k))
                assert_allclose(bd.t, tck_d[0], atol=1e-15)
                assert_allclose(bd.c, tck_d[1], atol=1e-15)
                assert_equal(bd.k, tck_d[2])
                assert_(isinstance(bd, BSpline))
                assert_(isinstance(tck_d, tuple))  # back-compat: tck in and out
Beispiel #7
0
    def test_splder(self):
        for b in [self.b, self.b2]:
            # pad the c array (FITPACK convention)
            ct = len(b.t) - len(b.c)
            if ct > 0:
                b.c = np.r_[b.c, np.zeros((ct,) + b.c.shape[1:])]

            for n in [1, 2, 3]:
                bd = splder(b)
                tck_d = _impl.splder((b.t, b.c, b.k))
                assert_allclose(bd.t, tck_d[0], atol=1e-15)
                assert_allclose(bd.c, tck_d[1], atol=1e-15)
                assert_equal(bd.k, tck_d[2])
                assert_(isinstance(bd, BSpline))
                assert_(isinstance(tck_d, tuple))  # back-compat: tck in and out
Beispiel #8
0
def correct_tuple_for_nonlin(tuple,
                             nonlin_corr=None,
                             verbose=False,
                             draw=False):
    """
    Compute the non-linearity correction  using the
    'c1' field, and applies it.
    Return value: corrected tuple
    """
    t00 = tuple[(tuple['i'] == 0) & (tuple['j'] == 0)]
    if nonlin_corr == None:
        if draw:
            nonlin_corr = eval_nonlin_draw(t00, verbose=verbose)
        else:
            nonlin_corr = eval_nonlin(t00, verbose=verbose)
    amps = np.unique(t00['ext']).astype(int)
    # sort the tuple by amp, i.e. extension
    index = tuple['ext'].argsort()
    stuple = tuple[index]
    tuple = stuple  # release memory ? not sure
    # find out where each amp starts and ends in the tuple
    ext = stuple['ext']
    diff = ext[1:] - ext[:-1]
    boundaries = [0] + [i + 1 for i in range(len(diff)) if diff[i] != 0
                        ] + [len(ext)]
    amps = np.unique(ext).astype(int)
    start = [None] * int(amps.max() + 1)
    end = [None] * int(amps.max() + 1)
    for k in range(len(boundaries) - 1):
        b = boundaries[k]
        amp = int(ext[b])
        start[amp] = b
        end[amp] = boundaries[k + 1]
        # print amp,start[amp], end[amp], ext[start[amp]],ext[end[amp]-1]
    # now applyr the nonlinearity correction
    for amp in amps:
        tamp = stuple[stuple['ext'] == amp]
        x = 0.5 * (tamp['mu1'] + tamp['mu2'])
        iamp = int(amp)
        s = nonlin_corr[iamp]
        mu_corr = interp.splev(x, s)  # model values
        dd = interp.splder(s)  # model derivative
        der = interp.splev(x, dd)  # model derivative values
        stuple['mu1'][start[iamp]:end[iamp]] = mu_corr
        stuple['mu2'][start[iamp]:end[iamp]] = mu_corr
        stuple['var'][start[iamp]:end[iamp]] *= (der**2)
        stuple['cov'][start[iamp]:end[iamp]] *= (der**2)
    return stuple
def corr_spline_interpolation(y1,y2, window_size):
    y1 = np.array([y1])
    y2 = np.array([y2])
    corr, delay = corr_no_interpolation(y1,y2, window_size)
    if window_size%2!=0:
        window_interp = np.arange(delay-(window_size-1)/2,delay+(window_size-1)/2)
    else:
        window_interp = np.arange(delay-(window_size)/2,delay+(window_size)/2-1)
    tck = interpolate.splrep(window_interp, corr[window_interp], s=0, k=4)
    dspl = interpolate.splder(tck)
    delay_spl = interpolate.sproot(dspl, mest = 20)
    if len(delay_spl) > 1: 
        delay = delay_spl[np.argmax(interpolate.splev(delay_spl, tck, der=0))]
    else:
        delay = delay_spl[0]
    return corr, delay-len(y1[0,:])+1
def corr_spline_interpolation(y1, y2, window_size):
    y1 = np.array([y1])
    y2 = np.array([y2])
    corr, delay = corr_no_interpolation(y1, y2, window_size)
    if window_size % 2 != 0:
        window_interp = np.arange(delay - (window_size - 1) / 2,
                                  delay + (window_size - 1) / 2)
    else:
        window_interp = np.arange(delay - (window_size) / 2,
                                  delay + (window_size) / 2 - 1)
    tck = interpolate.splrep(window_interp, corr[window_interp], s=0, k=4)
    dspl = interpolate.splder(tck)
    delay_spl = interpolate.sproot(dspl, mest=20)
    if len(delay_spl) > 1:
        delay = delay_spl[np.argmax(interpolate.splev(delay_spl, tck, der=0))]
    else:
        delay = delay_spl[0]
    return corr, delay - len(y1[0, :]) + 1
Beispiel #11
0
def make_nonlin_plot(filename, knots=20, channel=8):
    nt = croaks.NTuple.fromfile(filename)
    cut = (nt['mu1'] < 1.3e5) & (nt['sp1'] < 3.5) & (nt['sp2'] < 3.5)
    t8 = nt[cut & (nt['ext'] == channel)]
    dict = {}
    if knots is not None:
        dict['knots'] = knots
    s, x, yclap = fit_nonlin_corr(t8['mu1'], t8['c1'], fullOutput=True, **dict)
    model = interp.splev(x, s)
    fig = pl.figure(figsize=(8, 14))
    axes = fig.add_subplot(2, 1, 1)

    pl.plot(x, x / yclap - 1, '.', label='data')
    pl.plot(x, x / model - 1, '-r', label='model')
    pl.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
    my_fontsize = 'xx-large'
    pl.xlabel("$\mu$(ADU)", fontsize=my_fontsize)
    pl.xticks(fontsize=my_fontsize)
    pl.yticks(fontsize=my_fontsize)
    pl.ylabel("$\mu$/diode-1", fontsize=my_fontsize)
    pl.legend(loc='upper right', fontsize=my_fontsize)

    fig.add_subplot(2, 1, 2)
    mu = t8['mu1']
    mu_cor = interp.splev(mu, s)
    dd = interp.splder(s)
    der = interp.splev(mu, dd)
    var = 0.5 * t8['var']
    var_cor = var * (der**2)
    pl.plot(mu, var / mu, 'b.', label='before correction')
    pl.plot(mu_cor, var_cor / mu_cor, 'r.', label='after correction')
    pl.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
    pl.xlabel("$\mu$ (ADU)", fontsize=my_fontsize)
    pl.ylabel("$C_{00}/\mu$", fontsize=my_fontsize)
    pl.xticks(fontsize=my_fontsize)
    pl.yticks(fontsize=my_fontsize)
    pl.legend(loc='upper right', fontsize=my_fontsize)
    pl.tight_layout()
    fig.show()
    pl.savefig("nonlin_plot.pdf")
Beispiel #12
0
def fit_nonlin_corr(xin,
                    yclapin,
                    knots=20,
                    loop=20,
                    verbose=False,
                    fullOutput=False):
    """
    xin : the data to be "linearized"
    yclapin : the (hopefully) linear reference
    returns a  spline that can be used for correction uisng "scikit.splev"
    if full_output==True, returns spline,x,y  (presumably to plot)
    """
    # do we need outlier rejection ?
    # the xin has to be sorted, although the doc does not say it....
    index = xin.argsort()
    x = xin[index]
    yclap = yclapin[index]
    chi2_mask = np.isfinite(yclap)  # yclap = nan kills the whole thing
    xx = x
    yyclap = yclap
    for i in range(loop):
        xx = xx[chi2_mask]
        # first fit the scaled difference between the two channels we are comparing
        yyclap = yyclap[chi2_mask]
        length = xx[-1] - xx[0]
        t = np.linspace(xx[0] + 1e-5 * length, xx[-1] - 1e-5 * length, knots)
        s = interp.splrep(xx, yyclap, task=-1, t=t)
        model = interp.splev(xx, s)  # model values
        res = model - yyclap
        sig = mad(res)
        res = np.abs(res)
        if (res > (5 * sig)).sum() > 0:  # remove one at a time
            chi2_mask = np.ones(len(xx)).astype(bool)
            chi2_mask[np.argmax(res)] = False
            continue
        else:
            break
    # enforce the fit to got through (0,0) and make sure that 0 is inside
    # the definition domain of the spline.
    # print('means yy ',yyclap.mean(),' xx ', xx.mean())
    # print ('ymod[0]/xmod[0] ', interp.splev(xx[0],s)/xx[0],xx[0])
    old_der = yyclap.mean() / xx.mean()
    nx = len(xx)
    fact = 1
    nadd = nx / 2
    fit_val = interp.splev(xx[0], s)
    fake_x = np.linspace(-xx[0] * fact, xx[0] * fact, nadd)
    fake_y = np.linspace(-fit_val * fact, fit_val * fact, nadd)
    xx = np.hstack((fake_x, xx))
    yyclap = np.hstack((fake_y, yyclap))
    t = np.linspace(xx[0] + 1e-5 * length, xx[-1] - 1e-5 * length, knots)
    s = interp.splrep(xx, yyclap, task=-1, t=t[1:-2])
    # normalize to "no change" at x->0
    der0 = interp.splev(0., s, 1)
    norm_fact = 1. / der0
    # print("n before/after %d/%d"%(nx,len(xx)))
    norm_fact = yyclap.mean() / xx.mean()
    # print('comparison old_fact ', old_der, ' new_fact ',norm_fact)
    yyclap_norm = yyclap / norm_fact
    # model only the residual to the identity
    s = interp.splrep(xx, yyclap_norm - xx, task=-1, t=t)

    model = interp.splev(xx, s) + xx  # model values
    # compute gain residuals
    mask = (yyclap_norm != 0)
    print(
        "der0 = %f, val0 = %f" %
        (1 + interp.splev(0., interp.splder(s)), interp.splev(0., s)),
        "nonlin gain residuals : %g" %
        (model[mask] / yyclap_norm[mask] - 1).std())
    if verbose:
        print("fit_nonlin loops=%d sig=%f res.max = %f" % (i, sig, res.max()))
    if fullOutput:
        return s, xx, yyclap_norm
    return s
Beispiel #13
0
def get_pol_vs_e(e_poly,
                 chi_spline,
                 E_samples,
                 Ps,
                 debug,
                 method='TNC',
                 close_prev_figs=True):
    """
    Calculates equilibrium polarization value for various electric field values.
    Parameters
    ==========
    q_energy: array(float)
        Collective coordinate values corresponding to data in energy variable.
        Values must be between 0 and 1.
    energy: array(float)
        In hartrees. Bulk energy per unit cell for atomic configurations
        corresponding to q_energy entries.
    celldims: array(float)
        In bohr. Dimensions of unit cell.
    q_chi: array(float)
        Collective coordinate values corresponding to data in chi variable.
        Values must be between 0 and 1.
    chi: array(float)
        In esu. Electronic contribution to dielectric susceptibility for
        configurations along path between ferroelectric configurations.
    E_samples: array(float)
        In kV/cm. Values of electric field at which equilibrium polarisation
        value should be calculated.
    Ps: float
        In uC/cm^2. Spontaneous polarisation of ferroelectric.
    method: string
        Free energy minimization method. See scipy.optimize.minimize
        documentation.
    close_prev_figs: boolean
        If True, previous Matplotlib figures will be closed
    Returns
    =======
    ret: array(float)
        The equilibrium polarizations corresponding to values in E_samples.
    """
    global c
    global barye_on_au
    global kVpercm_on_statVpercm
    global uCpercm2_on_statCpercm2
    global kilopascal_on_au

    global now

    if close_prev_figs:
        plt.close('all')

    def wrapped_free_energy(q):
        return free_energy(q, chi_spline, e_poly, E, Ps, print_fmin_params)

    def wrapped_free_energy_derivative(q):
        return free_energy_derivative(q, chi_spline, e_polyder, E,
                                      print_fmin_params)

    q_range = np.linspace(-1.5, 1.5, 100)

    chi_prime = splder(chi_spline)
    p_vs_E = []
    supercoercive_flags = np.full(E_samples.shape, False)
    for i, e in enumerate(E_samples):
        # Find Q where dF/dQ = 0.
        left_dF = free_energy_derivative(q_range[:-1], chi_prime,
                                         np.polyder(e_poly), e, Ps, False)
        right_df = free_energy_derivative(q_range[1:], chi_prime,
                                          np.polyder(e_poly), e, Ps, False)
        signs = (left_dF * right_df <= 0.)
        q_idx = np.nonzero(signs)[0]
        p = q_range[q_idx] * Ps
        print_string = "E:{0} p:{1}".format(e, str(p))
        supercoercive_flags[i] = (len(p) == 1)
        to_add = np.zeros((len(p), 2))
        to_add[:, 0] = p
        to_add[:, 1] = e
        p_vs_E += [to_add]

    all_pol_vs_E = np.concatenate(p_vs_E, axis=0)
    supercoercive_fields = E_samples[supercoercive_flags]
    if len(supercoercive_fields) > 2 and (np.any(supercoercive_fields > 0.) and
                                          np.any(supercoercive_fields < 0.)):
        positive_Ec = np.min(supercoercive_fields[supercoercive_fields > 0.])
        negative_Ec = np.max(supercoercive_fields[supercoercive_fields < 0.])
        print("+Ec={0:.3e}, -Ec={1:.3e}".format(positive_Ec, negative_Ec))
        ret = (all_pol_vs_E, positive_Ec, negative_Ec)
    else:
        print("Could not calculate coercive field. Consider increasing Emax.")
        ret = (np.concatenate(p_vs_E, axis=0), None, None)

    return ret
Beispiel #14
0
def drift_fit2D(ev, data, validRange=9):
    '''
    Measures the spectrum drift over all frames and all non-destructive reads.

    Parameters
    ----------
    ev            : Event object
    data        : 4D data frames
    preclip     : Ignore first preclip values of spectrum
    postclip    : Ignore last postclip values of spectrum
    width         : Half-width in pixels used when fitting Gaussian
    deg         : Degree of polynomial fit
    validRange    : Trim spectra by +/- pixels to compute valid region of cross correlation

    Returns
    -------
    drift         : Array of measured drift values
    model         : Array of model drift values

    History
    -------
    Written by Kevin Stevenson        January 2017

    '''
    

    #if postclip != None:
    #    postclip = -postclip
    if ev.n_reads > 2:
        istart = 1
    else:
        istart = 0
    drift         = np.zeros((ev.n_files, ev.n_reads-1))
    #model         = np.zeros((ev.n_files, ev.n_reads-1))
    #goodmask    = np.zeros((ev.n_files, ev.n_reads-1),dtype=int)
    for n in range(istart,ev.n_reads-1):
        ref_data = np.copy(data[-1,n])
        ref_data[np.where(np.isnan(ref_data) == True)] = 0
        for m in range(ev.n_files):
            #Trim data to achieve accurate cross correlation without assumptions over interesting region
            #http://stackoverflow.com/questions/15989384/cross-correlation-of-non-periodic-function-with-numpy
            fit_data    = np.copy(data[m,n,:,validRange:-validRange])
            fit_data[np.where(np.isnan(fit_data) == True)] = 0
            # Cross correlate, result should be 1D
            vals        = sps.correlate2d(ref_data, fit_data, mode='valid').squeeze()
            xx_t        = range(len(vals))
            # Find the B-spline representation
            spline        = spi.splrep(xx_t, vals, k=4)
            # Compute the spline representation of the derivative
            deriv         = spi.splder(spline)
            # Find the maximum with a derivative.
            maximum     = spi.sproot(deriv)
            # Multiple derivatives, take one closest to argmax(vals)
            if len(maximum) > 1:
                #print(m,n,maximum,np.argmax(vals))
                maximum = maximum[np.argmin(np.abs(maximum-np.argmax(vals)))]
            drift[m,n]    = len(vals)/2 - maximum
            '''
            try:
                vals        = np.correlate(ref_spec, fit_spec, mode='valid')
                argmax        = np.argmax(vals)
                subvals     = vals[argmax-width:argmax+width+1]
                params, err = g.fitgaussian(subvals/subvals.max(), guess=[width/5., width*1., 1])
                drift[n,m,i]= len(vals)/2 - params[1] - argmax + width
                goodmask[n,m,i] = 1
            except:
                print('Spectrum ' +str(n)+','+str(m)+','+str(i)+' marked as bad.')
            '''

    return drift#, goodmask