#attenlist = attenlist[:4]
for atten in attenlist:
    print "setting attenuator to",atten
    ri.set_dac_attenuator(atten)
    measured_freqs = sweeps.prepare_sweep(ri,f0binned,offsets,nsamp=nsamp)
    print "loaded waveforms in", (time.time()-start),"seconds"
    
    sweep_data = sweeps.do_prepared_sweep(ri, nchan_per_step=atonce, reads_per_step=8)
    orig_sweep_data = sweep_data
    meas_cfs = []
    idxs = []
    delays = []
    for m in range(len(f0s)):
        fr,s21,errors = sweep_data.select_by_freq(f0s[m])
        thiscf = f0s[m]
        res = fit_best_resonator(fr[1:-1],s21[1:-1],errors=errors[1:-1]) #Resonator(fr,s21,errors=errors)
        delay = res.delay
        delays.append(delay)
        s21 = s21*np.exp(2j*np.pi*res.delay*fr)
        res = fit_best_resonator(fr,s21,errors=errors)
        fmin = fr[np.abs(s21).argmin()]
        print "s21 fmin", fmin, "original guess",thiscf,"this fit", res.f_0, "delay",delay,"resid delay",res.delay
        if use_fmin:
            meas_cfs.append(fmin)
        else:
            if abs(res.f_0 - thiscf) > 0.1:
                if abs(fmin - thiscf) > 0.1:
                    print "using original guess"
                    meas_cfs.append(thiscf)
                else:
                    print "using fmin"
    delay = -31.3
    print "median delay is ", delay

    df = data_file.DataFile(suffix=suffix)
    df.nc.mmw_atten_turns = mmw_atten_turns
    df.log_hw_state(ri)
    sweep_data = sweeps.do_prepared_sweep(ri, nchan_per_step=atonce, reads_per_step=2)
    df.add_sweep(sweep_data)
    meas_cfs = []
    idxs = []
    for m in range(len(f0s)):
        fr, s21, errors = sweep_data.select_by_freq(f0s[m])
        thiscf = f0s[m]
        s21 = s21 * np.exp(2j * np.pi * delay * fr)
        res = fit_best_resonator(fr, s21, errors=errors)  #Resonator(fr,s21,errors=errors)
        fmin = fr[np.abs(s21).argmin()]
        print "s21 fmin", fmin, "original guess", thiscf, "this fit", res.f_0
        if use_fmin:
            meas_cfs.append(fmin)
        else:
            if abs(res.f_0 - thiscf) > 0.1:
                if abs(fmin - thiscf) > 0.1:
                    print "using original guess"
                    meas_cfs.append(thiscf)
                else:
                    print "using fmin"
                    meas_cfs.append(fmin)
            else:
                print "using this fit"
                meas_cfs.append(res.f_0)
    print "median delay is ", delay

    df = data_file.DataFile(suffix=suffix)
    df.nc.mmw_atten_turns = mmw_atten_turns
    df.log_hw_state(ri)
    sweep_data = sweeps.do_prepared_sweep(ri,
                                          nchan_per_step=atonce,
                                          reads_per_step=2)
    df.add_sweep(sweep_data)
    meas_cfs = []
    idxs = []
    for m in range(len(f0s)):
        fr, s21, errors = sweep_data.select_by_freq(f0s[m])
        thiscf = f0s[m]
        s21 = s21 * np.exp(2j * np.pi * delay * fr)
        res = fit_best_resonator(
            fr, s21, errors=errors)  #Resonator(fr,s21,errors=errors)
        fmin = fr[np.abs(s21).argmin()]
        print "s21 fmin", fmin, "original guess", thiscf, "this fit", res.f_0
        if use_fmin:
            meas_cfs.append(fmin)
        else:
            if abs(res.f_0 - thiscf) > 0.1:
                if abs(fmin - thiscf) > 0.1:
                    print "using original guess"
                    meas_cfs.append(thiscf)
                else:
                    print "using fmin"
                    meas_cfs.append(fmin)
            else:
                print "using this fit"
                meas_cfs.append(res.f_0)
    ri.set_dac_attenuator(atten)
    measured_freqs = sweeps.prepare_sweep(ri, f0binned, offsets, nsamp=nsamp)
    print "loaded waveforms in", (time.time() - start), "seconds"

    sweep_data = sweeps.do_prepared_sweep(ri,
                                          nchan_per_step=atonce,
                                          reads_per_step=4)
    orig_sweep_data = sweep_data
    meas_cfs = []
    idxs = []
    delays = []
    for m in range(len(f0s)):
        fr, s21, errors = sweep_data.select_by_freq(f0s[m])
        thiscf = f0s[m]
        res = fit_best_resonator(
            fr[1:-1], s21[1:-1],
            errors=errors[1:-1])  #Resonator(fr,s21,errors=errors)
        delay = res.delay
        delays.append(delay)
        s21 = s21 * np.exp(2j * np.pi * res.delay * fr)
        res = fit_best_resonator(fr, s21, errors=errors)
        fmin = fr[np.abs(s21).argmin()]
        print "s21 fmin", fmin, "original guess", thiscf, "this fit", res.f_0, "delay", delay, "resid delay", res.delay
        if use_fmin:
            meas_cfs.append(fmin)
        else:
            if abs(res.f_0 - thiscf) > 0.1:
                if abs(fmin - thiscf) > 0.1:
                    print "using original guess"
                    meas_cfs.append(thiscf)
                else:
Esempio n. 5
0
atten_list = np.linspace(15, 46, 8)  #[30]#[35.5,33.5,46.5,43.5,40.5,37.5]
#atten_list = [33.0]
for atten in atten_list:
    df = data_file.DataFile()
    ri.set_dac_attenuator(atten)
    sweep_data = sweeps.do_prepared_sweep(ri,
                                          nchan_per_step=atonce,
                                          reads_per_step=8)
    df.add_sweep(sweep_data)
    meas_cfs = []
    idxs = []
    for m in range(len(f0s)):
        fr, s21, errors = sweep_data.select_by_freq(f0s[m])
        thiscf = f0s[m]
        res = fit_best_resonator(fr[2:-2], s21[2:-2], errors=errors[2:-2])
        delay = res.delay
        #        delays.append(delay)
        s21 = s21 * np.exp(2j * np.pi * res.delay * fr)
        res = fit_best_resonator(fr, s21, errors=errors)
        fmin = fr[np.abs(s21).argmin()]
        print "s21 fmin", fmin, "original guess", thiscf, "this fit", res.f_0, "delay", delay, "resid", res.delay
        if abs(res.f_0 - thiscf) > 0.1:
            if abs(fmin - thiscf) > 0.1:
                print "using original guess"
                meas_cfs.append(thiscf)
            else:
                print "using fmin"
                meas_cfs.append(fmin)
        else:
            print "using this fit"
sys.stdout.flush()
time.sleep(1)

atten_list = np.linspace(15,46,8)#[30]#[35.5,33.5,46.5,43.5,40.5,37.5]
#atten_list = [33.0]
for atten in atten_list:
    df = data_file.DataFile()
    ri.set_dac_attenuator(atten)
    sweep_data = sweeps.do_prepared_sweep(ri, nchan_per_step=atonce, reads_per_step=8)
    df.add_sweep(sweep_data)
    meas_cfs = []
    idxs = []
    for m in range(len(f0s)):
        fr,s21,errors = sweep_data.select_by_freq(f0s[m])
        thiscf = f0s[m]
        res = fit_best_resonator(fr[2:-2],s21[2:-2],errors=errors[2:-2])
        delay = res.delay
#        delays.append(delay)
        s21 = s21*np.exp(2j*np.pi*res.delay*fr)
        res = fit_best_resonator(fr,s21,errors=errors)
        fmin = fr[np.abs(s21).argmin()]
        print "s21 fmin", fmin, "original guess",thiscf,"this fit", res.f_0,"delay",delay,"resid",res.delay
        if abs(res.f_0 - thiscf) > 0.1:
            if abs(fmin - thiscf) > 0.1:
                print "using original guess"
                meas_cfs.append(thiscf)
            else:
                print "using fmin"
                meas_cfs.append(fmin)
        else:
            print "using this fit"
def extract_and_pickle(nc_filename):
    """
    The format is that the file contains equal numbers of sweeps and timestreams. The first sweep is used to locate
    the resonances and is taken with the source off at the lowest power level, i.e. the maximum attenuation. The
    first timestream is taken under the same conditions except that the source is modulated. Subsequent sweeps and
    timestreams are paired.

    :param nc_filename: the file name of the netCDF4 file with the above format.
    :return: a dictionary
    """
    try:
        all_noise_on = []
        all_noise_off = []
        all_noise_modulated = []
        all_coarse_sweep_params = []
        coarse_sweep_index = 0
        modulated_timestream_index = 0

        print("Processing {}".format(nc_filename))
        rnc = ReadoutNetCDF(nc_filename)
        resonator_indices = sorted(set(rnc.sweeps[0].index))
        n_attenuations = len(rnc.sweeps) - 1

        for resonator_index in resonator_indices:
            noise_on = []
            for on_index in range(1, n_attenuations, 2):
                noise_on.append(SweepNoiseMeasurement(nc_filename, resonator_index=resonator_index,
                                                      sweep_group_index=on_index, timestream_group_index=on_index))
            all_noise_on.extend(noise_on)

            noise_off = []
            for off_index in range(2, n_attenuations + 1, 2):
                noise_off.append(SweepNoiseMeasurement(nc_filename, resonator_index=resonator_index,
                                                       sweep_group_index=off_index, timestream_group_index=off_index))
            all_noise_off.extend(noise_off)

            # Create the modulated measurement from the modulated timestream and the noise off sweep at the same power.
            # Skip deglitching.
            attenuations = [snm.atten for snm in noise_off]
            off_max_attenuation_index = 1 + 2 * attenuations.index(max(attenuations)) + 1
            noise_modulated = SweepNoiseMeasurement(nc_filename, resonator_index=resonator_index,
                                                    sweep_group_index=off_max_attenuation_index,
                                                    timestream_group_index=modulated_timestream_index,
                                                    deglitch_threshold=None)
            noise_modulated.folded_projected_timeseries = noise_modulated.projected_timeseries.reshape(
                (-1, noise_modulated.timestream_modulation_period_samples))
            folded = noise_modulated.folded_projected_timeseries.mean(0)
            high, low, rising_edge = find_high_low(folded)
            noise_modulated.folded_projected_timeseries = np.roll(noise_modulated.folded_projected_timeseries,
                                                                  -rising_edge, axis=1)
            noise_modulated.folded_normalized_timeseries = np.roll(
                noise_modulated.normalized_timeseries.reshape((-1,
                                                               noise_modulated.timestream_modulation_period_samples)),
                -rising_edge, axis=1)
            all_noise_modulated.append(noise_modulated)

            # Add the ZBD voltage from the modulated timestream to the modulated and static on measurements:
            zbd_voltage = rnc.timestreams[modulated_timestream_index].zbd_voltage[0]
            noise_modulated.zbd_voltage = zbd_voltage
            for snm in noise_on:
                snm.zbd_voltage = zbd_voltage

            # Save only the Parameters object from a fit to the coarse sweep.
            freq, s21, err = rnc.sweeps[coarse_sweep_index].select_by_index(resonator_index)
            coarse_resonator = fit_best_resonator(freq, s21, errors=err)
            all_coarse_sweep_params.append(coarse_resonator.result.params)

        rnc.close()
        data = {'noise_on_measurements': all_noise_on,
                'noise_off_measurements': all_noise_off,
                'noise_modulated_measurements': all_noise_modulated,
                'coarse_sweep_params': all_coarse_sweep_params}
        # We decided to keep the .pkl files in /home/data regardless of origin.
        pkl_filename = os.path.join('/home/data/pkl', os.path.splitext(os.path.split(nc_filename)[1])[0] + '.pkl')
        save_noise_pkl(pkl_filename, data)
        print("Saved {}".format(pkl_filename))
    except KeyboardInterrupt:
        print("Aborting {}".format(nc_filename))
Esempio n. 8
0
    def __init__(self,swg,tsg,hwg,chip,id,index=0,phasecorr=phasecorr,scale=scale,filtlen=2**16,loss = -42, 
                 ntones=None, use_bif=False, delay_estimate = -7.11):
        self.id = id
        self.swp_epoch = swg.groups['datablocks'].variables['epoch'][0]
        self.start_temp =  get_temperature_at(self.swp_epoch)
        self.ts_epoch = tsg.variables['epoch'][:][-1]
        self.end_temp = get_temperature_at(self.ts_epoch)
        self.index = index
        self.chip = chip
        self.phasecorr = phasecorr
        if scale is None:
            self.scale = 1/tsg.variables['wavenorm'][index]
        else:
            self.scale = scale
        self.filtlen = filtlen
        self.loss = loss
        
        try:
            hwidx = bisect.bisect(hwg.variables['epoch'][:],self.swp_epoch)
            if hwidx == hwg.variables['epoch'].shape[0]:
                hwidx = -1
            if ntones is None:
                ntones = hwg.variables['ntones'][hwidx]
            self.atten = hwg.variables['dac_atten'][hwidx]
            self.power_dbm = loss - self.atten - ntone_power_correction(ntones)
        except:
            print "failed to find attenuator settings"
            self.atten = np.nan
            self.power_dbm = np.nan
        
        idx = swg.variables['index'][:]
        self.fr = swg.variables['frequency'][:]
        self.s21 = swg.variables['s21'][:].view('complex128')*np.exp(-1j*self.fr*phasecorr)*self.scale
        self.fr = self.fr[idx==index]#[1:]#[4:-4]
        self.s21 = self.s21[idx==index]#[1:]#[4:-4]
        
        tones = tsg.variables['tone'][:]
        nsamp = tsg.variables['nsamp'][:]
        fs = tsg.variables['fs'][:]
        fmeas = fs*tones/nsamp
        tone_index = np.argmin(abs(fmeas-self.fr.mean()))
        ts = tsg.variables['data'][tone_index,:].view('complex128')
        self.fs = fs[tone_index]
        self.nfft = tsg.variables['nfft'][tone_index]
        window = int(2**np.ceil(np.log2(self.fs*1e6/(2*self.nfft))))
        if window > ts.shape[0]:
            window = ts.shape[0]//2
        ts = deglitch_window(ts,window,thresh=6)
        self.fr = np.hstack((self.fr,[fmeas[tone_index]]))
        self.s21 = np.hstack((self.s21,[ts[:2048].mean()]))
        
        blkidx = swg.groups['datablocks'].variables['sweep_index'][:]
        blks = swg.groups['datablocks'].variables['data'][:][blkidx==index,:].view('complex')
        errors = blks.real.std(1) + 1j*blks.imag.std(1)
        self.errors = errors
        self.errors = np.hstack((self.errors,[ts[:2048].real.std()+ts[:2048].imag.std()]))
        order = self.fr.argsort()
        self.fr = self.fr[order]
        self.s21 = self.s21[order]
        self.errors = self.errors[order]
        def delay_guess(*args):
            if use_bif:
                p = khalil.bifurcation_guess(*args)
            else:
                p = khalil.delayed_generic_guess(*args)
            p['delay'].value = delay_estimate
            return p
        
        if use_bif:
            rr = Resonator(self.fr[2:-2],self.s21[2:-2],model=khalil.bifurcation_s21,guess=delay_guess,errors=errors[2:-2])
        else:
            rr = Resonator(self.fr[2:-2],self.s21[2:-2],errors=errors[2:-2],guess=delay_guess)
        self.delay = rr.delay
        self.s21 = self.s21*np.exp(2j*np.pi*rr.delay*self.fr)
#        if use_bif:
#            rr = Resonator(self.fr,self.s21,model=khalil.bifurcation_s21,guess=khalil.bifurcation_guess,errors=errors)
#        else:
#            rr = Resonator(self.fr,self.s21,mask=rr.mask)#errors=errors)
        rr = fit_best_resonator(self.fr,self.s21,errors=errors)#,min_a=0)
        self.Q_i = rr.Q_i
        self.params = rr.result.params
        
        
        self.ch = tones[tone_index]
        self.nsamp = nsamp[tone_index]
        self.f0 = self.fs*self.ch/float(self.nsamp)
        self.tss_raw = ts*np.exp(-1j*self.f0*phasecorr + 2j*np.pi*self.delay*self.f0)
        self.tsl_raw = fftfilt(scipy.signal.firwin(filtlen,1.0/filtlen), self.tss_raw)[filtlen:]
        
        self.s0 = self.tss_raw.mean() #rr.model(f=self.f0)
        self.sres = rr.model(f=rr.f_0)
        self.ds0 = rr.model(f=self.f0+1e-6)-rr.model(f=self.f0)
        #tsl_hz = np.real((self.tsl_raw - self.s0)/self.ds0)
        #self.ds0s = rr.model(f=self.f0+(tsl_hz+1)*1e-6)-rr.model(f=self.f0+tsl_hz*1e-6)
        self.frm = np.linspace(self.fr.min(),self.fr.max(),1000)
        self.s21m = rr.model(f=self.frm) - self.s0
        
        self.tss = (self.tss_raw-self.s0) * np.exp(-1j*np.angle(self.ds0))
        self.tss = self.tss/np.abs(self.ds0)/(self.f0*1e6)
        #self.tss = (self.tss_raw[:len(self.tsl_raw)] - self.tsl_raw)/self.ds0s
        fr,S,evals,evects,angles,piq = iqnoise.pca_noise(self.tss, NFFT=None, Fs=self.fs*1e6/(2*self.nfft))
        
        self.pca_fr = fr
        self.pca_S = S
        self.pca_evals = evals
        self.pca_evects = evects
        self.pca_angles = angles
        self.pca_piq = piq
        
        self.prr_fine,self.fr_fine = mlab.psd(self.tss.real,NFFT=2**18,window=mlab.window_none,Fs=self.fs*1e6/(2*self.nfft))
        self.pii_fine,fr = mlab.psd(self.tss.imag,NFFT=2**18,window=mlab.window_none,Fs=self.fs*1e6/(2*self.nfft))
        self.prr_coarse,self.fr_coarse = mlab.psd(self.tss.real,NFFT=2**12,window=mlab.window_none,Fs=self.fs*1e6/(2*self.nfft))
        self.pii_coarse,fr = mlab.psd(self.tss.imag,NFFT=2**12,window=mlab.window_none,Fs=self.fs*1e6/(2*self.nfft))
        
        self.tss_raw = self.tss_raw[:2048].copy()
        self.tss = self.tss[:2048].copy()
        self.tsl_raw = self.tsl_raw[::(filtlen/4)].copy()
Esempio n. 9
0
 def _restore_resonator_model(self):
     self._resonator_model = fit_best_resonator(self.sweep_freqs_MHz,self.sweep_s21,errors=self.sweep_errors,
                                               delay_estimate=self.fit_params['delay'].value)
Esempio n. 10
0
    def __init__(self,sweep_filename,sweep_group_index=0,timestream_filename=None,timestream_group_index=0,
                 resonator_index=0,low_pass_cutoff_Hz=4.0,
                 dac_chain_gain = -49, delay_estimate=-7.29,
                 deglitch_threshold=5, cryostat=None, mask_sweep_indicies=None):
        """
        sweep_filename : str
            NetCDF4 file with at least the sweep data. By default, this is also used for the timestream data.
            
        sweep_group_index : int (default 0)
            Index of the sweep group to process
            
        timestream_filename : str or None (optional)
            If None, use sweep_filename for the timestream data
            otherwise, this is the NetCDF4 file with the timestream data
            
        timestream_group_index : int (default 0)
            Index of the timestream group to process
        
        resonator_index : int (default 0)
            index of the resonator to process data for
            
        low_pass_cutoff_Hz : float
            Cutoff frequency used for low pass filtering the timeseries for display
            
        dac_chain_gain : float
            Estimate of the gain from output of DAC to device. 
            Default value of -49 represents -2 dB loss intrinsic to analog signal conditioning
            board, 7 dB misc cable loss and 40 dB total cold
            attenuation.
        
        delay_estimate : float
            Estimate of basic cable delay to help fitting proceed more smoothly. Default value
            is appropriate for the wideband noise firmware
            
        deglitch_threshold : float
            Threshold for glitch detection in units of median absolute deviation.
            
        cryostat : str
            (Optional) Override the cryostat used to take this data. By default, the cryostat
            is guessed based on the machine you are processing data on. The guess is made by
            the get_experiment_info_at function
            
            
        """
        
        self.sweep_filename = sweep_filename
        if timestream_filename:
            self.timestream_filename = timestream_filename
        else:
            self.timestream_filename = self.sweep_filename
        self.sweep_group_index = sweep_group_index
        self.timestream_group_index = timestream_group_index
        self._sweep_file = None
        self._timestream_file = None
        
        self.sweep_epoch = self.sweep.start_epoch
        pkg1,pkg2,load1,load2 = get_temperatures_at(self.sweep.start_epoch)
        self.sweep_primary_package_temperature = pkg1
        self.sweep_secondary_package_temperature = pkg2
        self.sweep_primary_load_temperature = load1
        self.sweep_secondary_load_temperature = load2
        self.start_temp = self.sweep_primary_package_temperature
        self.resonator_index = resonator_index
        
        description,is_dark,optical_load = experiments.get_experiment_info_at(self.sweep_epoch, cryostat=cryostat)
        self.chip_name = description
        self.is_dark = is_dark
        self.optical_load = optical_load
        self.dac_chain_gain = dac_chain_gain
        
        try:
            self.atten, self.total_dac_atten = self._sweep_file.get_effective_dac_atten_at(self.sweep_epoch)
            self.power_dbm = dac_chain_gain - self.total_dac_atten
        except:
            print "failed to find attenuator settings"
            self.atten = np.nan
            self.total_dac_atten = np.nan
            self.power_dbm = np.nan
            
        self.sweep_freqs_MHz, self.sweep_s21, self.sweep_errors = self.sweep.select_by_index(resonator_index)
        
        # find the time series that was measured closest to the sweep frequencies
        # this is a bit sloppy...
        timestream_index = np.argmin(abs(self.timestream.measurement_freq-self.sweep_freqs_MHz.mean()))
        self.timestream_index = timestream_index
        
        original_timeseries = self.timestream.get_data_index(timestream_index)
        self.adc_sampling_freq_MHz = self.timestream.adc_sampling_freq[timestream_index]
        self.noise_measurement_freq_MHz = self.timestream.measurement_freq[timestream_index]
        self.nfft = self.timestream.nfft[timestream_index]
        self.timeseries_sample_rate = self.timestream.sample_rate[timestream_index]
        
        self.timestream_epoch = self.timestream.epoch[timestream_index]
        self.timestream_duration = original_timeseries.shape[0]/self.timeseries_sample_rate
        # The following hack helps fix a long standing timing bug which was recently fixed/improved
        if self.timestream_epoch < 1399089567:
            self.timestream_epoch -= self.timestream_duration
        # end hack
        self.timestream_temperatures_sample_times = np.arange(self.timestream_duration)
        pkg1,pkg2,load1,load2 = get_temperatures_at(self.timestream_epoch + self.timestream_temperatures_sample_times)
        self.timestream_primary_package_temperature = pkg1
        self.timestream_secondary_package_temperature = pkg2
        self.timestream_primary_load_temperature = load1
        self.timestream_secondary_load_temperature = load2
        self.end_temp = self.timestream_primary_package_temperature[-1]

        
        # We can use the timestream measurement as an additional sweep point.
        # We average only the first 2048 points of the timeseries to avoid any drift.
        if False:
            self.sweep_freqs_MHz = np.hstack((self.sweep_freqs_MHz,[self.noise_measurement_freq_MHz]))
            self.sweep_s21 = np.hstack((self.sweep_s21,[original_timeseries[:2048].mean()]))
            self.sweep_errors = np.hstack((self.sweep_errors,
                                               [original_timeseries[:2048].real.std()/np.sqrt(2048)
                                                +1j*original_timeseries[:2048].imag.std()/np.sqrt(2048)]))
        
        # Now put all the sweep data in increasing frequency order so it plots nicely
        order = self.sweep_freqs_MHz.argsort()
        self.sweep_freqs_MHz = self.sweep_freqs_MHz[order]
        self.sweep_s21 = self.sweep_s21[order]
        self.sweep_errors = self.sweep_errors[order]

        if mask_sweep_indicies is None:
            rr = fit_best_resonator(self.sweep_freqs_MHz,self.sweep_s21,errors=self.sweep_errors,delay_estimate=delay_estimate)
        else:
            mask = np.ones(self.sweep_s21.shape,dtype=np.bool)
            mask[mask_sweep_indicies] = False
            rr = fit_best_resonator(self.sweep_freqs_MHz[mask],self.sweep_s21[mask],errors=self.sweep_errors[mask],delay_estimate=delay_estimate)
        self._resonator_model = rr
        self.Q_i = rr.Q_i
        self.fit_params = rr.result.params
        
        decimation_factor = self.timeseries_sample_rate/low_pass_cutoff_Hz
        normalized_timeseries = rr.normalize(self.noise_measurement_freq_MHz,original_timeseries)
        self.low_pass_normalized_timeseries = low_pass_fir(normalized_timeseries, num_taps=1024, cutoff=low_pass_cutoff_Hz, 
                                                          nyquist_freq=self.timeseries_sample_rate, decimate_by=decimation_factor)
        self.normalized_timeseries_mean = normalized_timeseries.mean()

        projected_timeseries = rr.project_s21_to_delta_freq(self.noise_measurement_freq_MHz,normalized_timeseries,
                                                            s21_already_normalized=True)
        
        # calculate the number of samples for the deglitching window.
        # the following will be the next power of two above 1 second worth of samples
        window = int(2**np.ceil(np.log2(self.timeseries_sample_rate)))
        # reduce the deglitching window if we don't have enough samples
        if window > projected_timeseries.shape[0]:
            window = projected_timeseries.shape[0]//2
        self.deglitch_window = window
        self.deglitch_threshold = deglitch_threshold
        if deglitch_threshold:
            deglitched_timeseries = deglitch_window(projected_timeseries,window,thresh=deglitch_threshold)
        else:
            deglitched_timeseries = projected_timeseries
        
        
        self.low_pass_projected_timeseries = low_pass_fir(deglitched_timeseries, num_taps=1024, cutoff=low_pass_cutoff_Hz, 
                                                nyquist_freq=self.timeseries_sample_rate, decimate_by=decimation_factor)
        self.low_pass_timestep = decimation_factor/self.timeseries_sample_rate
        
        self.normalized_model_s21_at_meas_freq = rr.normalized_model(self.noise_measurement_freq_MHz)
        self.normalized_model_s21_at_resonance = rr.normalized_model(rr.f_0)
        self.normalized_ds21_df_at_meas_freq = rr.approx_normalized_gradient(self.noise_measurement_freq_MHz)
        
        self.sweep_normalized_s21 = rr.normalize(self.sweep_freqs_MHz,self.sweep_s21)

        self.sweep_model_freqs_MHz = np.linspace(self.sweep_freqs_MHz.min(),self.sweep_freqs_MHz.max(),1000)
        self.sweep_model_normalized_s21 = rr.normalized_model(self.sweep_model_freqs_MHz) 
        self.sweep_model_normalized_s21_centered = self.sweep_model_normalized_s21 - self.normalized_timeseries_mean
        
        fractional_fluctuation_timeseries = deglitched_timeseries / (self.noise_measurement_freq_MHz*1e6)
        self._fractional_fluctuation_timeseries = fractional_fluctuation_timeseries
        fr,S,evals,evects,angles,piq = iqnoise.pca_noise(fractional_fluctuation_timeseries, 
                                                         NFFT=None, Fs=self.timeseries_sample_rate)
        
        self.pca_freq = fr
        self.pca_S = S
        self.pca_eigvals = evals
        self.pca_eigvects = evects
        self.pca_angles = angles
        self.pca_piq = piq
        
        self.freqs_coarse,self.prr_coarse,self.pii_coarse = self.get_projected_fractional_fluctuation_spectra(NFFT=2**12)
        
        self._normalized_timeseries = normalized_timeseries[:2048].copy()
        self._close_files()
Esempio n. 11
0
def extract_and_pickle(nc_filename):
    """
    The format is that the file contains equal numbers of sweeps and timestreams. The first sweep is used to locate
    the resonances and is taken with the source off at the lowest power level, i.e. the maximum attenuation. The
    first timestream is taken under the same conditions except that the source is modulated. Subsequent sweeps and
    timestreams are paired.

    :param nc_filename: the file name of the netCDF4 file with the above format.
    :return: a dictionary
    """
    try:
        all_noise_on = []
        all_noise_off = []
        all_noise_modulated = []
        all_coarse_sweep_params = []
        coarse_sweep_index = 0
        modulated_timestream_index = 0

        print("Processing {}".format(nc_filename))
        rnc = ReadoutNetCDF(nc_filename)
        resonator_indices = sorted(set(rnc.sweeps[0].index))
        n_attenuations = len(rnc.sweeps) - 1

        for resonator_index in resonator_indices:
            noise_on = []
            for on_index in range(1, n_attenuations, 2):
                noise_on.append(
                    SweepNoiseMeasurement(nc_filename,
                                          resonator_index=resonator_index,
                                          sweep_group_index=on_index,
                                          timestream_group_index=on_index))
            all_noise_on.extend(noise_on)

            noise_off = []
            for off_index in range(2, n_attenuations + 1, 2):
                noise_off.append(
                    SweepNoiseMeasurement(nc_filename,
                                          resonator_index=resonator_index,
                                          sweep_group_index=off_index,
                                          timestream_group_index=off_index))
            all_noise_off.extend(noise_off)

            # Create the modulated measurement from the modulated timestream and the noise off sweep at the same power.
            # Skip deglitching.
            attenuations = [snm.atten for snm in noise_off]
            off_max_attenuation_index = 1 + 2 * attenuations.index(
                max(attenuations)) + 1
            noise_modulated = SweepNoiseMeasurement(
                nc_filename,
                resonator_index=resonator_index,
                sweep_group_index=off_max_attenuation_index,
                timestream_group_index=modulated_timestream_index,
                deglitch_threshold=None)
            noise_modulated.folded_projected_timeseries = noise_modulated.projected_timeseries.reshape(
                (-1, noise_modulated.timestream_modulation_period_samples))
            folded = noise_modulated.folded_projected_timeseries.mean(0)
            high, low, rising_edge = find_high_low(folded)
            noise_modulated.folded_projected_timeseries = np.roll(
                noise_modulated.folded_projected_timeseries,
                -rising_edge,
                axis=1)
            noise_modulated.folded_normalized_timeseries = np.roll(
                noise_modulated.normalized_timeseries.reshape(
                    (-1,
                     noise_modulated.timestream_modulation_period_samples)),
                -rising_edge,
                axis=1)
            all_noise_modulated.append(noise_modulated)

            # Add the ZBD voltage from the modulated timestream to the modulated and static on measurements:
            zbd_voltage = rnc.timestreams[
                modulated_timestream_index].zbd_voltage[0]
            noise_modulated.zbd_voltage = zbd_voltage
            for snm in noise_on:
                snm.zbd_voltage = zbd_voltage

            # Save only the Parameters object from a fit to the coarse sweep.
            freq, s21, err = rnc.sweeps[coarse_sweep_index].select_by_index(
                resonator_index)
            coarse_resonator = fit_best_resonator(freq, s21, errors=err)
            all_coarse_sweep_params.append(coarse_resonator.result.params)

        rnc.close()
        data = {
            'noise_on_measurements': all_noise_on,
            'noise_off_measurements': all_noise_off,
            'noise_modulated_measurements': all_noise_modulated,
            'coarse_sweep_params': all_coarse_sweep_params
        }
        # We decided to keep the .pkl files in /home/data regardless of origin.
        pkl_filename = os.path.join(
            '/home/data/pkl',
            os.path.splitext(os.path.split(nc_filename)[1])[0] + '.pkl')
        save_noise_pkl(pkl_filename, data)
        print("Saved {}".format(pkl_filename))
    except KeyboardInterrupt:
        print("Aborting {}".format(nc_filename))