Ejemplo n.º 1
0
def getting_amplitude_and_dt(ax: plt.Axes, x: np.ndarray, cold: np.ndarray,
                             hot: np.ndarray) -> plt.Axes:
    """Adds hot and cold trace to axes with a straight line before and after transition to emphasise amplitude etc"""

    ax.set_title("Hot and cold part of transition")
    ax.set_xlabel('Sweep Gate (mV)')
    ax.set_ylabel('I (nA)')

    ax.plot(x, cold, color='blue', label='Cold', linewidth=1)
    ax.plot(x, hot, color='red', label='Hot', linewidth=1)

    # Add straight lines before and after transition to emphasise amplitude
    transition_width = 0.30
    before_transition_id = U.get_data_index(x,
                                            np.mean(x) - transition_width,
                                            is_sorted=True)
    after_transition_id = U.get_data_index(x,
                                           np.mean(x) + transition_width,
                                           is_sorted=True)

    line = lm.models.LinearModel()
    top_line = line.fit(cold[:before_transition_id],
                        x=x[:before_transition_id],
                        nan_policy='omit')
    bottom_line = line.fit(cold[after_transition_id:],
                           x=x[after_transition_id:],
                           nan_policy='omit')

    ax.plot(x, top_line.eval(x=x), linestyle=':', color='black')
    ax.plot(x, bottom_line.eval(x=x), linestyle=':', color='black')

    # Add vertical arrow between dashed lines
    # x_val = (np.mean(x) + x[-1]) / 2  # 3/4 along
    x_val = 0.20
    y_bot = bottom_line.eval(x=x_val)
    y_top = top_line.eval(x=x_val)
    arrow = ax.annotate(text='',
                        xy=(x_val, y_bot),
                        xytext=(x_val, y_top),
                        arrowprops=dict(arrowstyle='<|-|>', lw=1))
    text = ax.text(x=x_val + 0.02, y=(y_top + y_bot) / 2, s='dI/dN')

    ax.set_xlim(-0.5, 0.5)
    ax.legend(loc='center left')

    # Add horizontal lines to show thetas
    # TODO: should decide if I want to do this from fit results, or if it is just to give an idea theta..

    return ax
Ejemplo n.º 2
0
    def one_d_data_vs_n(self):
        if self.datnum:
            self.which = ['i_sense_cold', 'dndt', 'occupation']

            try:
                x, data_dndt = _get_x_and_data(self.datnum, self.experiment_name, 'dndt')
            except NotFoundInHdfError:
                logger.warning(f'Dat{self.datnum}: dndt data not found, probably a transition only dat')
                return go.Figure()

            nrg_func = NRG_func_generator(which='dndt')
            nrg_dndt = nrg_func(x, self.mid, self.g, self.theta, self.amp, self.lin, self.const, self.occ_lin)
            nrg_func = NRG_func_generator(which='occupation')
            occupation = nrg_func(x, self.mid, self.g, self.theta, self.amp, self.lin, self.const, self.occ_lin)

            # Rescale dN/dTs to have a peak at 1
            nrg_dndt = nrg_dndt * (1 / np.nanmax(nrg_dndt))
            x_max = x[get_data_index(data_dndt, np.nanmax(data_dndt))]
            x_range = abs(x[-1] - x[0])
            indexs = get_data_index(x, [x_max - x_range / 50, x_max + x_range / 50])
            avg_peak = np.nanmean(data_dndt[indexs[0]:indexs[1]])
            # avg_peak = np.nanmean(data_dndt[np.nanargmax(data_dndt) - round(x.shape[0] / 50):
            #                                 np.nanargmax(data_dndt) + round(x.shape[0] / 50)])
            data_dndt = data_dndt * (1 / avg_peak)
            if (new_max := np.nanmax(np.abs([np.nanmax(data_dndt), np.nanmin(data_dndt)]))) > 5:  # If very noisy
                data_dndt = data_dndt / (new_max / 5)  # Reduce to +-5ish

            interp_range = np.where(np.logical_and(occupation < 0.99, occupation > 0.01))
            if len(interp_range[0]) > 5:  # If enough data to actually plot something
                interp_data = occupation[interp_range]
                interp_x = x[interp_range]

                interper = interp1d(x=interp_x, y=interp_data, assume_sorted=True, bounds_error=False)

                occ_x = interper(x)

                plotter = OneD(dat=None)

                fig = plotter.figure(xlabel='Occupation', ylabel='Arbitrary',
                                     title=f'dN/dT vs N: G={self.g:.2f}mV, '
                                           f'{THETA}={self.theta:.2f}mV, '
                                           f'{THETA}/G={self.theta / self.g:.2f}'
                                           f' -- Dat{self.datnum}')
                fig.add_trace(plotter.trace(x=occ_x, data=data_dndt, name='Data dN/dT', mode='lines+markers'))
                fig.add_trace(plotter.trace(x=occ_x, data=nrg_dndt, name='NRG dN/dT', mode='lines'))
                return fig
Ejemplo n.º 3
0
 def get_dats_closest_to_temp(self, temp: float) -> SingleTraceData:
     """Return the dats at the closest temperature to requested. If it is more than 10% off then warn user"""
     v = list(self.temp_dat_dict.keys())[U.get_data_index(
         list(self.temp_dat_dict.keys()), temp)]
     if v not in self._single_trace_datas.keys():
         if (diff := abs(temp - v)) > temp / 10:
             logging.warning(
                 f'Closest temperature to requested is {v:.2f} which is {diff:.2f} from requested {temp:.2f}'
             )
         dats = self.temp_dat_dict[v]
         self._single_trace_datas[v] = SingleTraceData(dats, temperature=v)
Ejemplo n.º 4
0
def plot_csq_trace(dat: DatHDF, cutoff: Optional[float] = None) -> Data1D:
    plotter = OneD(dat=dat)
    plotter.TEMPLATE = 'simple_white'
    fig = plotter.figure(xlabel='CSQ Gate (mV)',
                         ylabel='Current (nA)',
                         title='CS current vs CSQ gate')
    x = dat.Data.x
    data = dat.Data.i_sense
    if cutoff:
        upper_lim = U.get_data_index(x, cutoff)
        x, data = x[:upper_lim], data[:upper_lim]
    fig.add_trace(plotter.trace(data=data, x=x))
    fig.show()
    return Data1D(x=x, data=data)
Ejemplo n.º 5
0
def do_calc(datnum):
    dat = get_dat(datnum)
    fit = dat.Transition.avg_fit
    mid = fit.best_values.mid
    width = fit.best_values.theta * 15
    x1, x2 = U.get_data_index(dat.Transition.avg_x, [mid - width, mid + width],
                              is_sorted=True)
    x = dat.Transition.avg_x[x1:x2]
    data = dat.Transition.avg_data[x1:x2]
    new_fit = dat.Transition.get_fit(which='avg',
                                     name='narrow_centered',
                                     overwrite=True,
                                     x=x,
                                     data=data)
    print(f'Fitting Dat{dat.datnum} from {x[0]:.2f} -> {x[-1]:.2f}mV')
    return new_fit
Ejemplo n.º 6
0
    def vp_transition_fit(self) -> DataInfo:
        dat = self.vp_dat
        self.vp_info = self.DataInfo(dat, xlabel='V_P (mV)')
        vp = self.vp_info
        vp.full_data = dat.Data.i_sense
        vp.full_x = dat.Data.x

        vp.smoothed_data, vp.smoothed_x = U.resample_data(vp.full_data, vp.full_x, max_num_pnts=100,
                                                          resample_method='bin')
        vp.rough_center = vp.smoothed_x[np.nanargmin(np.diff(vp.smoothed_data))]

        ids = U.get_data_index(vp.full_x, [vp.rough_center - 4, vp.rough_center + 4])
        vp.fit_data = vp.full_data[ids[0]:ids[1]]
        vp.fit_x = vp.full_x[ids[0]:ids[1]]

        vp.fit = self._fit(vp.fit_data, vp.fit_x)
        return self.vp_info
Ejemplo n.º 7
0
def plot_slice(datnum, data_name, slice_val) -> go.Figure:
    if datnum:
        dat = get_dat(datnum)
        data = dat.Data.get_data(data_name)
        if data.ndim > 1:
            x = dat.Data.get_data('x')
            y = dat.Data.get_data('y')
            if slice_val is None:
                slice_val = y[0]
            slice_val = U.get_data_index(y, slice_val)
            z = dat.Data.get_data('i_sense')[slice_val]

            x, z = [U.bin_data_new(arr, int(round(z.shape[-1] / 500))) for arr in (x, z)]

            plotter = DashOneD(dat=dat)
            fig = plotter.plot(data=z, x=x, mode='lines', title=f'Dat{datnum}: Slice at y = {y[slice_val]:.1f}')
            return fig
    return go.Figure()
Ejemplo n.º 8
0
    def _center_2d_data(x, data2d, occupation2d) -> Data2D:
        assert all(a.ndim == 2 for a in [data2d, occupation2d])
        new_data = []
        for data, occupation in zip(data2d, occupation2d):
            idx = U.get_data_index(occupation,
                                   0.5)  # Get values near to occ = 0.5
            interper = interp1d(occupation[idx - 1:idx + 2],
                                x[idx - 1:idx + 2],
                                bounds_error=False,
                                fill_value=(0, 1))  # will include occ = 0.5
            half_x = interper(0.5)
            new_x = x - half_x

            data_interper = interp1d(new_x,
                                     data,
                                     bounds_error=False,
                                     fill_value=(data[0], data[-1]))
            new_data.append(data_interper(x))
        return Data2D(x=x, y=np.arange(len(new_data)), data=np.array(new_data))
Ejemplo n.º 9
0
def plot_slice(fig, slice_val, slice_tog):
    if slice_tog == [True]:
        if not slice_val:
            slice_val = 0
        d = fig.get('data', None)
        if d:
            d = d[0]
            x = d.get('x', None)
            y = d.get('y', None)
            z = d.get('z', None)

            if all([a is not None for a in [x, y, z]]):
                # x, z = [U.bin_data_new(arr, int(round(z.shape[-1] / 500))) for arr in (x, z)]
                slice_index = U.get_data_index(y, slice_val)
                data = z[slice_index]

                fig = go.Figure()
                fig.add_trace(go.Scatter(mode='lines', x=x, y=data))
                fig.update_layout(title=f'Slice at y = {y[slice_index]:.1f}')
                return fig
    return go.Figure()
Ejemplo n.º 10
0
def plotting_center_shift():
    nrg_func = NRG_func_generator('occupation')
    params = lm.Parameters()
    params.add_many(
        ('mid', 0, True, -200, 200, None, 0.001),
        ('theta', 3.9, False, 1, 500, None, 0.001),
        ('amp', 1, True, 0, 3, None, 0.001),
        ('lin', 0, True, 0, 0.005, None, 0.00001),
        ('occ_lin', 0, True, -0.0003, 0.0003, None, 0.000001),
        ('const', 0, True, -2, 10, None, 0.001),
        ('g', 1, True, 0.2, 2000, None, 0.01),
    )
    model = lm.Model(nrg_func)

    x = np.linspace(-10, 5000, 10000)
    gs = np.linspace(0, 200, 201)
    thetas = np.logspace(0.1, 2, 20)
    # thetas = np.linspace(1, 500, 10)
    # thetas = [1, 2, 5, 10, 20]
    all_mids = []
    for theta in thetas:
        params['theta'].value = theta
        mids = []
        for g in gs:
            params['g'].value = g
            occs = model.eval(x=x, params=params)
            mids.append(x[U.get_data_index(occs, 0.5, is_sorted=True)])

        all_mids.append(mids)
    plotter = OneD(dat=None)
    fig = plotter.figure(xlabel='Gamma /mV',
                         ylabel='Shift of 0.5 OCC',
                         title='Shift of 0.5 Occupation vs Theta and G')
    fig.update_layout(legend=dict(title='Theta /mV'))
    for mids, theta in zip(all_mids, thetas):
        fig.add_trace(
            plotter.trace(data=mids, x=gs, name=f'{theta:.1f}', mode='lines'))
    fig.show()
    return fig
Ejemplo n.º 11
0
def do_calc(datnum):
    """Just a function which can be passed to a process pool for faster calculation"""
    save_name = 'SPS.0045'

    dat = get_dat(datnum)

    setpoints = [0.0045, None]

    # Get other inputs
    setpoint_times = square_wave_time_array(dat.SquareEntropy.square_awg)
    sp_start, sp_fin = [U.get_data_index(setpoint_times, sp) for sp in setpoints]
    logger.debug(f'Setpoint times: {setpoints}, Setpoint indexs: {sp_start, sp_fin}')

    # Run Fits
    pp = dat.SquareEntropy.get_ProcessParams(name=None,  # Start from default and modify from there
                                             setpoint_start=sp_start, setpoint_fin=sp_fin,
                                             transition_fit_func=i_sense,
                                             save_name=save_name)
    out = dat.SquareEntropy.get_Outputs(name=save_name, inputs=None, process_params=pp, overwrite=False)
    dat.Entropy.get_fit(which='avg', name=save_name, data=out.average_entropy_signal, x=out.x, check_exists=False)
    [dat.Entropy.get_fit(which='row', row=i, name=save_name,
                         data=row, x=out.x, check_exists=False) for i, row in enumerate(out.entropy_signal)]
Ejemplo n.º 12
0
    for dat in all_dats:
        w_val = 100
        strong_fit = dat.NrgOcc.get_fit(name=strong_fit_name)
        if strong_fit.best_values.g > strong_gamma_cutoff:
            fit_name = strong_fit_name
        else:
            fit_name = weak_fit_name

        int_data = get_integrated_data(
            dat,
            fit_name=fit_name,
            zero_point=-w_val,
            csq_datnum=csq_datnum,
            which_linear_theta_fit=which_linear_theta_fit)

        idx = U.get_data_index(int_data.x, w_val)  # Measure entropy at x = xxx
        if idx >= int_data.x.shape[
                -1] - 1:  # or the end if it doesn't reach xxx
            idx -= 10
        int_entropy = np.nanmean(int_data.data[idx - 10:idx + 10])

        avg_dndt = get_avg_entropy_data(dat,
                                        center_func=_center_func,
                                        csq_datnum=csq_datnum)
        fit = dat.Entropy.get_fit(calculate_only=True,
                                  data=avg_dndt.data,
                                  x=avg_dndt.x)

        cg_vals.append(dat.Logs.dacs['ESC'])
        int_entropies.append(int_entropy)
        fit_entropies.append(fit.best_values.dS)