def proc_file(file):

    fobj = bu.hsDat(file, load=True)

    vperp = fobj.dat[:, 0]
    elec3 = fobj.dat[:, 1] * tabor_mon_fac

    inds = np.abs(full_freqs - fspin) < 200.0

    elec3_fft = np.fft.rfft(elec3)
    true_fspin = full_freqs[np.argmax(np.abs(elec3_fft))]

    pm_freq = fobj.pm_freq

    amp, phase_mod = bu.demod(vperp, true_fspin, fsamp, plot=plot_demod, \
                              filt=True, bandwidth=bandwidth, \
                              notch_freqs=notch_freqs, notch_qs=notch_qs, \
                              tukey=True, tukey_alpha=5.0e-4, \
                              detrend=detrend, detrend_order=1, harmind=2.0)

    drive_amp, drive_phase_mod = \
                    bu.demod(elec3, true_fspin, fsamp, plot=plot_demod, \
                              filt=True, bandwidth=bandwidth, \
                              notch_freqs=notch_freqs, notch_qs=notch_qs, \
                              tukey=True, tukey_alpha=5.0e-4, \
                              detrend=detrend, detrend_order=1, harmind=1.0)

    phase_mod_fft = np.fft.rfft(phase_mod)[out_inds] * fac
    drive_phase_mod_fft = np.fft.rfft(drive_phase_mod)[out_inds] * fac

    return (phase_mod_fft, drive_phase_mod_fft, pm_freq)
def proc_file(file):

    fobj = bu.hsDat(file, load=True)

    vperp = fobj.dat[:, 0]
    elec3 = fobj.dat[:, 1]

    phi_dg = fobj.attribs['phi_dg']

    inds = np.abs(full_freqs - fspin) < 200.0

    elec3_fft = np.fft.rfft(elec3)
    true_fspin = full_freqs[np.argmax(np.abs(elec3_fft) * inds)]
    print(true_fspin)
    # true_fspin = np.average(full_freqs[inds], weights=np.abs(elec3_fft)[inds])
    true_fspin = 25000.1

    # try:
    amp, phase_mod = bu.demod(vperp, true_fspin, fsamp, plot=plot_demod, \
                                  filt=True, bandwidth=bandwidth, \
                                  notch_freqs=notch_freqs, notch_qs=notch_qs, \
                                  tukey=True, tukey_alpha=5.0e-4, \
                                  detrend=detrend, detrend_order=1, harmind=2.0, \
                                  force_2pi_wrap=force_2pi_wrap)
    # except:
    #     phase_mod = 1e-3 * np.random.randn(len(vperp))

    phase_mod_fft = np.fft.rfft(phase_mod)[out_inds] * fac

    drive_fft = elec3_fft[drive_out_inds] * fac * tabor_mon_fac

    return (phase_mod_fft, drive_fft, phi_dg)
def proc_file(file):

    fobj = bu.hsDat(file, load=True)

    vperp = fobj.dat[:,0]
    elec3 = fobj.dat[:,1]*tabor_mon_fac

    inds = np.abs(full_freqs - fspin) < 200.0

    elec3_fft = np.fft.rfft(elec3)*fac
    true_fspin = np.average(full_freqs[inds], weights=np.abs(elec3_fft)[inds])

    amp, phase_mod = bu.demod(vperp, true_fspin, fsamp, plot=plot_demod, \
                              filt=True, bandwidth=bandwidth,
                              tukey=True, tukey_alpha=5.0e-4, \
                              detrend=True, detrend_order=1, harmind=2.0)

    phase_mod_fft = np.fft.rfft(phase_mod)[out_inds] * fac
    freqs = full_freqs[out_inds]

    drive_fft = elec3_fft[drive_out_inds] * fac
    drive_freqs = full_freqs[drive_out_inds]


    upper_ind = np.argmin(np.abs(freqs - 200.0))

    ### Fit a power law to the sideband ASD, ignoring the DC bin
    popt, pcov = optimize.curve_fit(line, np.log(freqs[1:upper_ind]), \
                                    np.log(np.abs(phase_mod_fft[1:upper_ind])), \
                                    maxfev=10000, p0=[0.0, 0.0])

    ### Remove the power law from the data
    if np.abs(popt[0]) > 0.5:
        phase_mod_fft *= 1.0 / (np.exp(popt[1]) * freqs**popt[0])

    ### Find the peaks
    phase_mod_peaks = \
            bu.find_fft_peaks(freqs, phase_mod_fft, window=window, \
                              lower_delta_fac=lower_delta_fac, \
                              delta_fac=delta_fac, \
                              exclude_df=exclude_df)
    drive_peaks = \
            bu.find_fft_peaks(drive_freqs, drive_fft, window=window, \
                              lower_delta_fac=10.0, delta_fac=10.0, \
                              exclude_df=exclude_df)

    ### Put the power law back in to the peak amplitudes so they can
    ### be plotted over the original data with the plot_pdet() functions
    if len(phase_mod_peaks):
        if np.abs(popt[0]) > 0.5:
            phase_mod_peaks[:,1] *= (np.exp(popt[1]) * phase_mod_peaks[:,0]**popt[0])

    if plot_peaks:
        bu.plot_pdet([phase_mod_peaks, []], freqs, np.abs(phase_mod_fft), \
                     loglog=True, show=False)
        bu.plot_pdet([drive_peaks, []], drive_freqs, np.abs(drive_fft), \
                     loglog=True, show=True)

    return (phase_mod_peaks, drive_peaks)
Ejemplo n.º 4
0
        def proc_file(file):
            fobj = bu.hsDat(file, load=True)

            vperp = fobj.dat[:, 0]
            elec3 = fobj.dat[:, 1]

            elec3_filt = signal.filtfilt(b2, a2, elec3)

            if plot_raw_dat:
                fac = bu.fft_norm(nsamp, fsamp)
                plt.plot(time_vec[:10000], elec3[:10000])
                plt.figure()
                plt.plot(time_vec[:10000], vperp[:10000])
                plt.figure()
                plt.loglog(freqs, fac * np.abs(np.fft.rfft(vperp)))
                plt.figure()
                plt.loglog(freqs, fac * np.abs(np.fft.rfft(elec3)))
                plt.loglog(freqs, fac * np.abs(np.fft.rfft(elec3_filt)))
                plt.show()

                input()

            inds = np.abs(freqs - fspin) < 200.0

            elec3_fft = np.fft.rfft(elec3)
            true_fspin = freqs[np.argmax(np.abs(elec3_fft))]

            amp, phase_mod = bu.demod(vperp, true_fspin, fsamp, plot=plot_demod, \
                                  filt=True, bandwidth=bandwidth, \
                                  notch_freqs=notch_freqs, notch_qs=notch_qs, \
                                  tukey=True, tukey_alpha=5.0e-4, \
                                  detrend=detrend, detrend_order=1, harmind=2.0, \
                                  force_2pi_wrap=force_2pi_wrap)

            phase_mod_filt = signal.filtfilt(b3, a3, phase_mod)
            #phase_mod_filt = phase_mod

            amp_asd = np.abs(np.fft.rfft(amp))
            phase_asd = np.abs(np.fft.rfft(phase_mod))
            phase_asd_filt = np.abs(np.fft.rfft(phase_mod_filt))

            # popt_n, pcov_n = opti.curve_fit(gauss, freqs[notch_fit_inds], \
            #                                     phase_asd_filt[notch_fit_inds], \
            #                                     p0=[10000, notch_init, 2, 0])

            if apply_notch:
                notch = freqs[np.argmax(phase_asd_filt * notch_fit_inds)]
                notch_digital = (2.0 / fsamp) * (notch)

                for i in range(notch_nharm):
                    bn, an = signal.iirnotch(notch_digital * (i + 1), notch_q)
                    phase_mod_filt = signal.lfilter(bn, an, phase_mod_filt)

            phase_asd_filt_2 = np.abs(np.fft.rfft(phase_mod_filt))

            if correct_noise_color:
                phase_asd = phase_asd * freqs**noise_color_power
                phase_asd_filt = phase_asd_filt * freqs**noise_color_power
                phase_asd_filt_2 = phase_asd_filt_2 * freqs**noise_color_power

            if plot_phase:
                plt.plot(freqs, phase_mod)
                plt.xlabel('Frequency [Hz]')
                plt.ylabel('Phase [rad]')
                plt.tight_layout()

                plt.figure()
                plt.loglog(freqs, phase_asd)
                plt.loglog(freqs, phase_asd_filt)
                plt.loglog(freqs, phase_asd_filt_2)
                plt.xlabel('Frequency [Hz]')
                plt.ylabel('Phase ASD [arb]')
                plt.tight_layout()

                plt.show()

                input()

            freq_mask = (freqs > allowed_freqs[0]) * (freqs < allowed_freqs[1])

            max_ind = np.argmax(phase_asd_filt_2 * freq_mask)
            max_freq = freqs[max_ind]

            p0 = [10000, max_freq, 5.0, 0]

            try:
                popt, pcov = opti.curve_fit(lorentzian, freqs[max_ind-30:max_ind+30], \
                                            phase_asd_filt_2[max_ind-30:max_ind+30], p0=p0, \
                                            maxfev=10000)

                fit_max = popt[1]
                fit_std = np.abs(popt[2])
            except:
                print('bad fit...')
                fit_max = max_freq
                fit_std = 5.0 * (freqs[1] - freqs[0])
                popt = p0

            if plot_sideband_fit:
                plot_freqs = np.linspace(freqs[max_ind - 30],
                                         freqs[max_ind + 30], 100)
                plt.loglog(freqs, phase_asd_filt_2)
                plt.loglog(plot_freqs, lorentzian(plot_freqs, *popt))
                print(fit_max, fit_std)
                plt.show()

                input()

            # if fit_max < 10:
            #     return

            # if len(wobble_freq):
            #     if (np.abs(fit_max - wobble_freq[-1]) / wobble_freq[-1]) > 0.1:
            #         # plt.loglog(freqs, phase_asd)
            #         # plt.loglog(freqs, phase_asd_filt)
            #         # plt.loglog(freqs, phase_asd_filt_2)
            #         # plt.show()
            #         return

            elec3_filt_fft = np.fft.rfft(elec3_filt)

            fit_ind = 100000
            short_freqs = np.fft.rfftfreq(fit_ind, d=1.0 / fsamp)
            zeros = np.zeros(fit_ind)
            voltage = np.array([zeros, zeros, zeros, elec3_filt[:fit_ind], \
                       zeros, zeros, zeros, zeros])
            efield = bu.trap_efield(voltage * tabor_mon_fac, only_x=True)

            #efield_mag = np.linalg.norm(efield, axis=0)

            efield_asd = bu.fft_norm(fit_ind, fsamp) * np.abs(
                np.fft.rfft(efield[0]))

            # max_ind = np.argmax(np.abs(elec3_filt_fft))
            short_max_ind = np.argmax(efield_asd)
            # freq_guess = freqs[max_ind]
            # phase_guess = np.mean(np.angle(elec3_filt_fft[max_ind-2:max_ind+2]))
            # amp_guess = np.sqrt(2) * np.std(efield[0])
            # p0 = [amp_guess, freq_guess, phase_guess, 0]

            # popt_l, pcov_l = opti.curve_fit(lorentzian, short_freqs[short_max_ind-100:short_max_ind+100], \
            #                                 efield_asd[short_max_ind-100:short_max_ind+100], \
            #                                 p0=[amp_guess, freq_guess, 100, 0], maxfev=10000)

            # start_sine = time.time()
            # popt, pcov = opti.curve_fit(sine, time_vec[:fit_ind], efield[0], \
            #                                 sigma=0.01*efield[0], p0=p0)

            # print popt[0], popt_l[0] * (fsamp / fit_ind)

            #print popt[0], np.sqrt(pcov[0,0])
            # amp_fit = efield_asd[short_max_ind] * np.sqrt(2.0 * fsamp / fit_ind)
            amp_fit = np.sqrt(2) * np.std(efield[0])
            # plt.plot(efield[0])
            # plt.show()

            err_val = np.mean(np.array([efield_asd[short_max_ind-10:short_max_ind], \
                                efield_asd[short_max_ind+1:short_max_ind+11]]).flatten())
            amp_err = np.sqrt(
                (err_val * fsamp / fit_ind)**2)  # + (0.01*amp_fit)**2)
            # print amp_fit, amp_err
            # stop_sine = time.time()
            # print "Field sampling: ", stop_sine - start_sine

            return [2.0 * amp_fit, np.sqrt(2) * amp_err, fit_max, fit_std]
            fobj = h5py.File(file, 'r')
            dat = np.copy(fobj['sim_data'])
            fobj.close()
        else:
            dat = np.load(file)

        tvec = dat[0]
        theta = dat[1]
        phi = dat[2]

        px = p0 * np.cos(phi) * np.sin(theta)

        crossp = np.abs(px)

        carrier_amp, carrier_phase \
                = bu.demod(crossp, fsig, fsamp, harmind=2.0, filt=True, \
                           bandwidth=5000.0, plot=False)

        params, cov = bu.fit_damped_osc_amp(carrier_phase, fsamp, plot=False, \
                                            fit_band=[50.0, lib_calc*2.0])

        lib_freqs[-1].append(params[1])
        gammas.append(np.abs(params[2]))

        # if not len(longdat):
        #     longdat = crossp
        # else:
        #     longdat = np.concatenate( (longdat, crossp) )

    print('Expected gamma = {:0.2g}'.format(gamma))
    print(gammas)
def proc_file(file):

    fobj = bu.hsDat(file, load=True)

    vperp = fobj.dat[:, 0]
    elec3 = fobj.dat[:, 1]

    try:
        phi_dg = fobj.attribs['phi_dg']
    except:
        phi_dg = 0.0

    inds = np.abs(full_freqs - fspin) < 200.0

    cut = int(0.1 * fsamp)
    zeros = np.zeros_like(elec3[:cut])
    voltages = [
        zeros, zeros, zeros, elec3[:cut], -1.0 * elec3[:cut], zeros, zeros,
        zeros
    ]
    efield = bu.trap_efield(voltages, only_x=True)[0]
    drive_amp, drive_phase = bu.get_sine_amp_phase(efield)

    elec3_fft = np.fft.rfft(elec3)
    true_fspin = np.average(full_freqs[inds], weights=np.abs(elec3_fft)[inds])


    carrier_amp, carrier_phase_mod = \
            bu.demod(vperp, true_fspin, fsamp, plot=plot_carrier_demod, \
                     filt=True, bandwidth=bandwidth,
                     notch_freqs=notch_freqs, notch_qs=notch_qs, \
                     tukey=True, tukey_alpha=5.0e-4, \
                     detrend=True, detrend_order=1, harmind=2.0)

    # b1, a1 = signal.butter(3, np.array(libration_filt_band)*2.0/fsamp, btype='bandpass')
    sos = signal.butter(3,
                        libration_filt_band,
                        btype='bandpass',
                        fs=fsamp,
                        output='sos')
    # carrier_phase_mod_filt = signal.filtfilt(b1, a1, carrier_phase_mod)
    carrier_phase_mod_filt = signal.sosfiltfilt(sos, carrier_phase_mod)

    if len(libration_filt_band):
        libration_inds = (full_freqs > libration_filt_band[0]) \
                                * (full_freqs < libration_filt_band[1])
    else:
        libration_inds = np.abs(full_freqs -
                                libration_guess) < 0.5 * libration_bandwidth

    phase_mod_fft = np.fft.rfft(carrier_phase_mod) * fac

    lib_fit_x = full_freqs[libration_inds]
    lib_fit_y = np.abs(phase_mod_fft[libration_inds])

    try:
        try:
            peaks = bu.find_fft_peaks(lib_fit_x,
                                      lib_fit_y,
                                      delta_fac=5.0,
                                      window=50)
            ind = np.argmax(peaks[:, 1])
        except:
            peaks = bu.find_fft_peaks(lib_fit_x,
                                      lib_fit_y,
                                      delta_fac=3.0,
                                      window=100)
            ind = np.argmax(peaks[:, 1])

        true_libration_freq = peaks[ind, 0]

    except:
        true_libration_freq = lib_fit_x[np.argmax(lib_fit_y)]

    libration_amp, libration_phase = \
            bu.demod(carrier_phase_mod, true_libration_freq, fsamp, \
                     plot=plot_libration_demod, filt=True, \
                     filt_band=libration_filt_band, \
                     bandwidth=libration_bandwidth, \
                     tukey=False, tukey_alpha=5.0e-4, \
                     detrend=False, detrend_order=1.0, harmind=1.0)

    libration_ds, time_vec_ds = \
            signal.resample(carrier_phase_mod_filt, t=time_vec, num=out_nsamp)
    libration_amp_ds, time_vec_ds = \
            signal.resample(libration_amp, t=time_vec, num=out_nsamp)

    libration_ds = libration_ds[out_cut:int(-1 * out_cut)]
    libration_amp_ds = libration_amp_ds[out_cut:int(-1 * out_cut)]
    time_vec_ds = time_vec_ds[out_cut:int(-1 * out_cut)]

    if plot_downsample:
        plt.plot(time_vec,
                 carrier_phase_mod_filt,
                 color='C0',
                 label='Original')
        plt.plot(time_vec_ds,
                 libration_ds,
                 color='C0',
                 ls='--',
                 label='Downsampled')
        plt.plot(time_vec, libration_amp, color='C1')  #, label='Original')
        plt.plot(time_vec_ds, libration_amp_ds, color='C1',
                 ls='--')  #, label='Downsampled')
        plt.legend()
        plt.show()

        input()

    return (time_vec_ds, libration_ds, libration_amp_ds, \
                true_libration_freq, phi_dg, drive_amp)
        voltages = [
            zeros, zeros, zeros, elec3_cut, -1.0 * elec3_cut, zeros, zeros,
            zeros
        ]
        efield = bu.trap_efield(voltages, only_x=True)[0]
        efield_amp, _ = bu.get_sine_amp_phase(efield)

        dipole = np.load(dipole_file)[0]
        Ibead = bu.get_Ibead(date=date, rhobead=rhobead)['val']

        libration_guess = np.sqrt(efield_amp * dipole / Ibead) / (2.0 * np.pi)

    except:

        amp, phase_mod = bu.demod(vperp, true_fspin, fsamp, plot=plot_carrier_demod, \
                                  filt=True, bandwidth=bandwidth,
                                  tukey=True, tukey_alpha=5.0e-4, \
                                  detrend=True, detrend_order=1, harmind=2.0)

        phase_mod_fft = np.fft.rfft(phase_mod) * fac

        fig, ax = plt.subplots(1, 1)
        ax.loglog(full_freqs, np.abs(phase_mod_fft))
        ax.set_xlabel('Frequency [Hz]')
        ax.set_ylabel('Phase ASD [rad/$\\sqrt{\\rm Hz}$]')
        ax.set_title('Identify Libration Frequency')
        fig.tight_layout()
        plt.show()

        libration_guess = float(input('Libration guess: '))

libration_filt_band = [
def proc_mc(i):
    cdir = os.path.join(dirname, 'mc_{:d}'.format(i))

    param_path = os.path.join(cdir, 'params.p')
    params = pickle.load( open(param_path, 'rb') )

    pressure = params['pressure']
    drive_amp = params['drive_amp']
    drive_amp_noise = params['drive_amp_noise']
    drive_phase_noise = params['drive_phase_noise']
    discretized_phase = params['discretized_phase']
    drive_freq = params['drive_freq']
    fsig = params['drive_freq']
    p0 = params['p0']
    Ibead = params['Ibead']
    t_therm = params['t_therm']
    beta_rot = params['beta_rot']
    try:
        init_angle = params['init_angle']
    except Exception:
        init_angle = np.pi / 2.0

    try:
        fsamp = params['fsamp']
    except Exception:
        fsamp = 1.0e6

    beta_rot = pressure * np.sqrt(m0) / kappa
    phieq = -1.0 * np.arcsin(2.0 * np.pi * drive_freq * beta_rot / (drive_amp * p0))

    # print(phieq)

    offset_phi = 2.0 * np.pi * drive_freq * t_therm + init_angle

    # print(pressure, time_constant)


    def Ephi(t, t_therm=0.0):
        return 2.0 * np.pi * drive_freq * (t + t_therm)

    def energy(xi, t, ndim=3):
        omega = xi[ndim:]
        omega_frame = 2.0 * np.pi * drive_freq

        omega[1] -= omega_frame

        kinetic_term = 0.5 * Ibead * np.sum(omega**2, axis=0)
        potential_term = -1.0 * p0 * drive_amp * (np.sin(xi[0]) * np.cos(Ephi(t) - xi[1]))

        return kinetic_term + potential_term


    datfiles, lengths = bu.find_all_fnames(cdir, ext=ext, verbose=False, \
                                            sort_time=True, use_origin_timestamp=True)
    nfiles = lengths[0]

    integrated_energy = []
    all_energy = np.array([])
    all_t_energy = np.array([])
    all_amp = np.array([])
    all_t_amp = np.array([])

    plot = False
    for fileind, file in enumerate(datfiles):

        if fileind >= maxfile:
            break

        if plot_first_file:
            plot = not fileind

        try:
            if hdf5:
                fobj = h5py.File(file, 'r')
                dat = np.copy(fobj['sim_data'])
                fobj.close()
            else:
                dat = np.load(file)

        except Exception:
            print('Bad File!')
            print(file)
            continue

        nsamp = dat.shape[1]
        ndim = int((dat.shape[0] - 1) / 2)

        if plot_raw_dat:
            fig1, axarr1 = plt.subplots(2,1,sharex=True)
            axarr1[0].set_title('$\\theta$ - Azimuthal Coordinate (Locked)')
            axarr1[0].plot(dat[0], dat[1], zorder=2)
            axarr1[0].axhline(np.pi/2, color='k', alpha=0.7, ls='--', zorder=1, \
                                label='Equatorial plane')
            axarr1[0].set_ylabel('$\\theta$ [rad]')
            axarr1[1].plot(dat[0], dat[1+ndim])
            axarr1[1].set_xlabel('Time [s]')
            axarr1[1].set_ylabel('$\\omega_{\\theta}$ [rad/s]')
            if plot_thermalization_window:
                xlims = axarr1[0].get_xlim()
                ylims0 = axarr1[0].get_ylim()
                ylims1 = axarr1[1].get_ylim()
                xvec = np.linspace(xlims[0], t_therm, 10)
                top0 = np.ones_like(xvec) * ylims0[1]
                bot0 = np.ones_like(xvec) * ylims0[0]
                top1 = np.ones_like(xvec) * ylims1[1]
                bot1 = np.ones_like(xvec) * ylims1[0]
                axarr1[0].fill_between(xvec, bot0, top0, color='k', alpha=0.3, \
                                        label='Thermalization time')
                axarr1[1].fill_between(xvec, bot1, top1, color='k', alpha=0.3, \
                                        label='Thermalization time')
                axarr1[0].set_xlim(*xlims)
                axarr1[0].set_ylim(*ylims0)
                axarr1[1].set_ylim(*ylims1)
            axarr1[0].legend(fontsize=10, loc='lower right')
            fig1.tight_layout()

            fig2a, axarr2a = plt.subplots(2,1,sharex=True)
            axarr2a[0].set_title('$\\phi$ - Rotating Coordinate')
            axarr2a[0].plot(dat[0], dat[2])
            axarr2a[0].set_ylabel('$\\phi$ [rad]')
            axarr2a[1].plot(dat[0], dat[2+ndim])
            axarr2a[1].set_xlabel('Time [s]')
            axarr2a[1].set_ylabel('$\\omega_{\\phi}$ [rad/s]')
            if plot_thermalization_window:
                xlims = axarr2a[0].get_xlim()
                ylims0 = axarr2a[0].get_ylim()
                ylims1 = axarr2a[1].get_ylim()
                xvec = np.linspace(xlims[0], t_therm, 10)
                top0 = np.ones_like(xvec) * ylims0[1]
                bot0 = np.ones_like(xvec) * ylims0[0]
                top1 = np.ones_like(xvec) * ylims1[1]
                bot1 = np.ones_like(xvec) * ylims1[0]
                axarr2a[0].fill_between(xvec, bot0, top0, color='k', alpha=0.3, \
                                        label='Thermalization time')
                axarr2a[1].fill_between(xvec, bot1, top1, color='k', alpha=0.3, \
                                        label='Thermalization time')
                axarr2a[0].set_xlim(*xlims)
                axarr2a[0].set_ylim(*ylims0)
                axarr2a[1].set_ylim(*ylims1)
            axarr2a[0].legend(fontsize=10, loc='lower right')
            fig2a.tight_layout()

            fig2b, axarr2b = plt.subplots(2,1,sharex=True)
            axarr2b[0].set_title("$\\phi'$ - In Rotating Frame")
            axarr2b[0].plot(dat[0], dat[2] - 2.0*np.pi*drive_freq*dat[0] - offset_phi, zorder=2)
            axarr2b[0].axhline(phieq, color='k', alpha=0.7, ls='--', zorder=1, \
                                label='Expected Equilibrium value')
            axarr2b[0].set_ylabel('$\\phi$ [rad]')
            axarr2b[1].plot(dat[0], dat[2+ndim]-2.0*np.pi*drive_freq)
            axarr2b[1].set_xlabel('Time [s]')
            axarr2b[1].set_ylabel('$\\omega_{\\phi}$ [rad/s]')
            if plot_thermalization_window:
                xlims = axarr2b[0].get_xlim()
                ylims0 = axarr2b[0].get_ylim()
                ylims1 = axarr2b[1].get_ylim()
                xvec = np.linspace(xlims[0], t_therm, 10)
                top0 = np.ones_like(xvec) * ylims0[1]
                bot0 = np.ones_like(xvec) * ylims0[0]
                top1 = np.ones_like(xvec) * ylims1[1]
                bot1 = np.ones_like(xvec) * ylims1[0]
                axarr2b[0].fill_between(xvec, bot0, top0, color='k', alpha=0.3, \
                                        label='Thermalization time')
                axarr2b[1].fill_between(xvec, bot1, top1, color='k', alpha=0.3, \
                                        label='Thermalization time')
                axarr2b[0].set_xlim(*xlims)
                axarr2b[0].set_ylim(*ylims0)
                axarr2b[1].set_ylim(*ylims1)
            axarr2b[0].legend(fontsize=10, loc='lower right')
            fig2b.tight_layout()

            if ndim == 3:
                fig3, axarr3 = plt.subplots(2,1,sharex=True)
                axarr3[0].set_title('$\\psi$ - Roll About Dipole (Free)')
                axarr3[0].plot(dat[0], dat[3])
                axarr3[0].set_ylabel('$\\psi$ [rad]')
                axarr3[1].plot(dat[0], dat[3+ndim])
                axarr3[1].set_xlabel('Time [s]')
                axarr3[1].set_ylabel('$\\omega_{\\psi}$ [rad/s]')
                if plot_thermalization_window:
                    xlims = axarr3[0].get_xlim()
                    ylims0 = axarr3[0].get_ylim()
                    ylims1 = axarr3[1].get_ylim()
                    xvec = np.linspace(xlims[0], t_therm, 10)
                    top0 = np.ones_like(xvec) * ylims0[1]
                    bot0 = np.ones_like(xvec) * ylims0[0]
                    top1 = np.ones_like(xvec) * ylims1[1]
                    bot1 = np.ones_like(xvec) * ylims1[0]
                    axarr3[0].fill_between(xvec, bot0, top0, color='k', alpha=0.3, \
                                            label='Thermalization time')
                    axarr3[1].fill_between(xvec, bot1, top1, color='k', alpha=0.3, \
                                            label='Thermalization time')
                    axarr3[0].set_xlim(*xlims)
                    axarr3[0].set_ylim(*ylims0)
                    axarr3[1].set_ylim(*ylims1)
                axarr3[0].legend(fontsize=10, loc='lower right')
                fig3.tight_layout()

            plt.show()

            input()

        tvec = dat[0]
        theta = dat[1]
        phi = dat[2]

        energy_vec = energy(dat[1:], tvec, ndim=ndim)
        freqs = np.fft.rfftfreq(nsamp, d=1.0/fsamp)
        energy_psd = np.abs( np.fft.rfft(energy_vec-np.mean(energy_vec)) )**2 * bu.fft_norm(nsamp, fsamp)**2
        energy_asd = np.sqrt(energy_psd)
        # plt.loglog(freqs, energy_asd*freqs)
        # plt.show()

        integrated_energy.append(np.sqrt(np.sum(energy_psd) * (freqs[1] - freqs[0])))

        crossp = np.sin(phi)**2

        carrier_amp, carrier_phase \
                = bu.demod(crossp, fsig, fsamp, harmind=2.0, filt=True, \
                           bandwidth=4000.0, plot=plot, tukey=True, \
                           tukey_alpha=1e-3)

        params, cov = bu.fit_damped_osc_amp(carrier_phase, fsamp, plot=plot)

        libration_amp, libration_phase \
                = bu.demod(carrier_phase, params[1], fsamp, harmind=1.0, \
                           filt=True, filt_band=[100, 2000], plot=plot, \
                           tukey=True, tukey_alpha=1e-3)

        amp_ds, tvec_ds = signal.resample(libration_amp, 500, t=tvec, window=None)
        amp_ds_cut = amp_ds[5:-5]
        tvec_ds_cut = tvec_ds[5:-5]

        energy_ds, tvec_ds_2 = signal.resample(energy_vec, 100, t=tvec, window=None)
        energy_ds_cut = energy_ds[5:-5]
        tvec_ds_cut_2 = tvec_ds_2[5:-5]

        all_amp = np.concatenate( (all_amp, amp_ds_cut) )
        all_t_amp = np.concatenate( (all_t_amp, tvec_ds_cut) )

        all_energy = np.concatenate( (all_energy, energy_ds_cut))
        all_t_energy = np.concatenate( (all_t_energy, tvec_ds_cut_2) )

    return [pressure, all_t_amp, all_amp, all_t_energy, all_energy, integrated_energy, \
            drive_amp, drive_amp_noise, drive_phase_noise, discretized_phase]
def proc_mc(i):
    ### Build the path name, assuming the monte-carlo's are
    ### zero-indexed
    cdir = os.path.join(dirname, 'mc_{:d}'.format(i))

    ### Load the simulation parameters saved alongside the data
    param_path = os.path.join(cdir, 'params.p')
    params = pickle.load(open(param_path, 'rb'))

    ### Define some values that are necessary for analysis
    pressure = params['pressure']
    drive_amp = params['drive_amp']
    fsig = params['drive_freq']
    drive_freq = params['drive_freq']
    p0 = params['p0']
    Ibead = params['Ibead']
    kappa = params['kappa']
    fsamp = params['fsamp']
    fsamp_ds = fsamp

    try:
        t_therm = params['t_therm']
    except:
        t_therm = 0.0

    try:
        init_angle = params['init_angle']
    except Exception:
        init_angle = np.pi / 2.0

    beta_rot = pressure * np.sqrt(m0) / kappa
    phieq = -1.0 * np.arcsin(2.0 * np.pi * drive_freq * beta_rot /
                             (drive_amp * p0))

    time_constant = Ibead / beta_rot
    gamma_calc = 1.0 / time_constant

    # print(pressure, time_constant, t_therm)

    ### Load the data
    datfiles, lengths = bu.find_all_fnames(cdir, ext=ext, verbose=False, \
                                            sort_time=True, use_origin_timestamp=True)

    ### Invert the data file array so that the last files are processed first
    ### since the last files should be the most thermalized
    datfiles = datfiles[::-1]
    nfiles = lengths[0]

    ### Depeding on the requested behavior, instantiate some arrays
    if concatenate:
        long_t = []
        long_sig = []
        long_sig_2 = []
    if average:
        psd_array = []

    ### Loop over the datafiles
    for fileind, file in enumerate(datfiles):
        # print(file)
        ### Break the loop if we've acquired enough data
        if fileind > nspectra_to_combine - 1:
            break

        ### Load the data, taking into account the file type
        if hdf5:
            fobj = h5py.File(file, 'r')
            dat = np.copy(fobj['sim_data'])
            fobj.close()
        else:
            dat = np.load(file)

        ### Determine the length of the data
        nsamp = dat.shape[1]
        nsamp_ds = int(nsamp / downsample_fac)

        ### Load the angles and construct the x-component of the dipole
        ### based on the integrated angular positions
        tvec = dat[0]
        theta = dat[1]
        phi = dat[2]
        px = p0 * np.cos(phi) * np.sin(theta)

        E_phi = 2.0 * np.pi * drive_freq * (tvec + t_therm) + init_angle

        ones = np.ones(len(tvec))

        dipole = np.array([ones, theta, phi])
        efield = np.array([ones, ones * (np.pi / 2), E_phi])
        lib_angle = bu.angle_between_vectors(dipole, efield, coord='s')

        ### construct an estimate of the cross-polarized light
        crossp = np.sin(phi)**2

        ### Normalize to avoid numerical errors. Try to get the max to sit at 10
        crossp *= (10.0 / np.max(np.abs(crossp)))

        ### Build up the long signal if concatenation is desired
        if concatenate:
            if not len(long_sig):
                long_t = tvec
                long_sig = crossp
                long_phi = phi
                long_lib = lib_angle
            else:
                long_t = np.concatenate((tvec, long_t))
                long_sig = np.concatenate((crossp, long_sig))
                long_phi = np.concatenate((phi, long_phi))
                long_lib = np.concatenate((lib_angle, long_lib))

        ### Using a hilbert transform, demodulate the amplitude and phase of
        ### the carrier signal. Filter things if desired.
        carrier_amp, carrier_phase \
                = bu.demod(crossp, fsig, fsamp, harmind=2.0, filt=True, \
                           bandwidth=4000.0, plot=plot_demod, ncycle_pad=100, \
                           tukey=True, tukey_alpha=5e-4)

        # carrier_phase = phi - E_phi

        if plot_raw_data:
            phi_lab = '$\\phi$'
            theta_lab = '$\\theta - \\pi / 2$'
            lib_lab = '$\\left| \\measuredangle (\\vec{E}) (\\vec{d}) \\right|$'

            # plt.plot(carrier_phase)
            plt.plot(tvec, carrier_phase, alpha=1.0, label=phi_lab)
            plt.plot(tvec, theta - np.pi / 2, alpha=0.7, label=theta_lab)
            plt.plot(tvec, lib_angle, alpha=0.7, label=lib_lab)
            plt.title('In Rotating Frame', fontsize=14)
            plt.xlabel('Time [s]')
            plt.ylabel('Angular Coordinate [rad]')
            plt.legend(loc='lower right', fontsize=12)
            plt.tight_layout()
            # plt.show()

            freqs = np.fft.rfftfreq(nsamp, d=1.0 / fsamp)
            norm = bu.fft_norm(nsamp, fsamp)
            plt.figure()
            plt.loglog(freqs,
                       np.abs(np.fft.rfft(carrier_phase)) * norm,
                       label=phi_lab)
            plt.loglog(freqs,
                       np.abs(np.fft.rfft(theta - np.pi / 2)) * norm,
                       label=theta_lab)
            plt.loglog(freqs,
                       np.abs(np.fft.rfft(lib_angle)) * norm,
                       label=lib_lab)
            plt.xlabel('Frequency [Hz]')
            plt.ylabel('ASD [rad / $\\sqrt{ \\rm Hz}$]')
            plt.legend(loc='lower right', fontsize=12)
            plt.xlim(330, 1730)
            plt.ylim(5e-7, 3e-2)
            plt.tight_layout()
            plt.show()

            input()

        ### Downsample the data if desired
        if downsample:
            ### Use scipy's fourier-based downsampling
            carrier_phase_ds, tvec_ds = signal.resample(carrier_phase,
                                                        nsamp_ds,
                                                        t=tvec,
                                                        window=None)
            carrier_phase = np.copy(carrier_phase_ds)
            tvec = np.copy(tvec_ds)

            dt = tvec_ds[1] - tvec_ds[0]
            fsamp_ds = 1.0 / dt

            ### Compute the frequencies and ASD values of the downsampled signal
            freqs = np.fft.rfftfreq(nsamp_ds, d=dt)
            carrier_phase_asd = bu.fft_norm(nsamp_ds, fsamp_ds) * np.abs(
                np.fft.rfft(carrier_phase_ds))

        else:
            ### Compute the frequencies and ASD values
            freqs = np.fft.rfftfreq(nsamp, d=1.0 / fsamp)
            carrier_phase_asd = bu.fft_norm(nsamp, fsamp) * np.abs(
                np.fft.rfft(carrier_phase))

        ### Add the data from the current file to the array of PSDs
        if average:
            if not len(psd_array):
                psd_array = np.zeros(
                    (nspectra_to_combine, len(carrier_phase_asd)),
                    dtype=np.float64)
            psd_array[fileind, :] += carrier_phase_asd**2

    ### Compute the mean and uncertainty of the PSDs, then compute the ASD
    if average:
        avg_psd = np.mean(psd_array, axis=0)
        fit_asd = np.sqrt(avg_psd)

        ### Use propogation of uncertainty and the standard error on the mean
        asd_errs = 0.5 * fit_asd * (np.std(psd_array, axis=0) \
                    * np.sqrt(1.0 / nspectra_to_combine)) / avg_psd

    ### If concatenation was desired, first demodulate the amplitude and phase of the
    ### carrier signal, and then downsample the carrier phase.
    if concatenate:
        ### Compute the new values of nsamp
        nsamp = len(long_sig)
        if downsample:
            nsamp_ds = int(nsamp / downsample_fac)
        else:
            nsamp_ds = nsamp

        ### Hilbert transform demodulation
        carrier_amp_long, carrier_phase_long \
                = bu.demod(long_sig, fsig, fsamp, harmind=2.0, filt=False, \
                           bandwidth=5000.0, plot=False, ncycle_pad=ncycle_pad, \
                           tukey=True, tukey_alpha=1e-4)

        carrier_phase_long = long_phi - 2.0 * np.pi * drive_freq * (
            long_t + t_therm) - init_angle

        ### Downsampling
        carrier_phase_ds, tvec_ds = signal.resample(carrier_phase_long, nsamp_ds, \
                                                    t=long_t, window=None)
        long_lib_ds, tvec_ds_2 = signal.resample(long_lib, nsamp_ds, \
                                                 t=long_t, window=None)

        ### Compute the ASD of the downsampled signals
        fit_asd = bu.fft_norm(nsamp_ds, fsamp_ds) * np.abs(
            np.fft.rfft(carrier_phase_ds))
        fit_asd_2 = bu.fft_norm(nsamp_ds, fsamp_ds) * np.abs(
            np.fft.rfft(long_lib_ds))
        asd_errs = []

        ### Compute the new frequency arrays
        freqs = np.fft.rfftfreq(nsamp_ds, d=1.0 / fsamp_ds)

    ### Fit either the averaged ASD or the ASD of the concatenated signal
    params, cov = bu.fit_damped_osc_amp(fit_asd, fsamp_ds, plot=False, \
                                        sig_asd=True, linearize=True, \
                                        asd_errs=asd_errs, fit_band=[500.0,600.0], \
                                        gamma_guess=gamma_calc, \
                                        weight_lowf=True, weight_lowf_val=0.5, \
                                        weight_lowf_thresh=200)

    # plt.loglog(freqs, fit_asd_2)
    # plt.show()

    ### Fit either the averaged ASD or the ASD of the concatenated signal
    params_2, cov_2 = bu.fit_damped_osc_amp(fit_asd_2, fsamp_ds, plot=False, \
                                            sig_asd=True, linearize=True, \
                                            asd_errs=[], fit_band=[1050.0,1150.0], \
                                            gamma_guess=gamma_calc, freq_guess=2.0*params[1], \
                                            weight_lowf=True, weight_lowf_val=0.5, \
                                            weight_lowf_thresh=200)

    outdict = {'pressure': pressure, 'freqs': freqs, \
               'fit_asd': fit_asd, 'params': params, 'cov': cov, \
               'fit_asd_2': fit_asd_2, 'params_2': params_2, 'cov_2': cov_2, \
               'gamma_calc': gamma_calc, 'drive_freq': drive_freq}

    return outdict