def final_init(self): # Determine the plot dimensions if not self.plot_dims.value: if len(self.descriptor.axes) > 1: self.plot_dims.value = 2 else: self.plot_dims.value = 1 # Check the descriptor axes num_axes = len(self.descriptor.axes) if self.plot_dims.value > num_axes: logger.info( "Cannot plot in more dimensions than there are data axes.") self.plot_dims.value = num_axes if self.plot_dims.value == 1: self.points_before_clear = self.descriptor.axes[-1].num_points() else: self.points_before_clear = self.descriptor.axes[-1].num_points( ) * self.descriptor.axes[-2].num_points() logger.debug("Plot will clear after every %d points.", self.points_before_clear) self.x_values = self.descriptor.axes[-1].points if self.plot_dims.value == 2: self.y_values = self.descriptor.axes[-2].points self.plot_buffer = (np.nan * np.ones(self.points_before_clear)).astype( self.descriptor.dtype) self.idx = 0
def get_buffer(self, channel): stored_points = self.buffer_points self.interface.write("TRCB?{:d},0,{:d}".format(channel, stored_points)) #buf = self.interface.read_raw(numbytes=4) buf = self.interface.read_bytes(4*stored_points,chunk_size=4) logger.info(f"Raw buffer is {buf} with length {len(buf)} bytes.") return np.frombuffer(buf, dtype=np.float32)
def disconnect(self): if self._resource is not None: self._resource.close() logger.info("Disconnected %s from %s" % (self.name, self.resource_name)) else: logger.warning("No connection is established. Do nothing.")
def logistic_fidelity(self): #group data and assign state labels gnd_features = np.hstack([np.real(self.ground_data.T), np.imag(self.ground_data.T)]) ex_features = np.hstack([np.real(self.excited_data.T), np.imag(self.excited_data.T)]) #liblinear wants arrays in C order features = np.ascontiguousarray(np.vstack([gnd_features, ex_features])) state = np.ascontiguousarray(np.hstack([np.zeros(self.ground_data.shape[1]), np.ones(self.excited_data.shape[1])])) #Set up logistic regression with cross-validation using liblinear. #Cs sets the inverse of the regularization strength, which will be optimized #through cross-validation. Uses the default Stratified K-Folds #CV generator, with 3 folds. #This is set up to be as consistent with the MATLAB implementation #as I can make it. --GJR Cs = np.logspace(-1,2,5) logreg = LogisticRegressionCV(Cs, cv=3, solver='liblinear') logreg.fit(features, state) #fit the model predictions = logreg.predict(features) #in-place classification score = logreg.score(features,state) #mean accuracy of classification N = len(predictions) S = np.sum(predictions == state) #how many we got right #now calculate confidence intervals c = 0.95 flo = betaincinv(S+1, N-S+1, (1-c)/2., ) fhi = betaincinv(S+1, N-S+1, (1+c)/2., ) logger.info(("In-place logistic regression fidelity: " + "{:.2f}% ({:.2f}, {:.2f})".format(100*score, 100*flo, 100*fhi)))
def receive_data(self, channel, oc, exit, ready, run): sock = self._chan_to_rsocket[channel] sock.settimeout(2) self.last_timestamp.value = datetime.datetime.now().timestamp() last_print = datetime.datetime.now().timestamp() ready.value += 1 while not exit.is_set(): # push data from a socket into an OutputConnector (oc) # wire format is just: [size, buffer...] # TODO receive 4 or 8 bytes depending on sizeof(size_t) if not run.is_set(): continue # Block until we are running again #logger.info(f'Run set when recv={self.total_received.value}, exp={self.number_segments*self.record_length*self.number_averages*len(self.channels)}') try: msg = sock.recv(8) self.last_timestamp.value = datetime.datetime.now().timestamp() except: logger.info("Didn't find any data on socket within 2 seconds (this is normal during experiment shutdown).") continue msg_size = struct.unpack('n', msg)[0] buf = sock_recvall(sock, msg_size) while len(buf) < msg_size: # time.sleep(0.01) buf2 = sock_recvall(sock, msg_size-len(buf)) buf = buf+buf2 data = np.frombuffer(buf, dtype=np.float32) self.total_received.value += len(data) if datetime.datetime.now().timestamp() - last_print > 0.25: last_print = datetime.datetime.now().timestamp() # logger.info(f"Alz: {self.total_received.value}") oc.push(data) self.fetch_count.value += 1
def run_sweeps(self): #For now, only update histograms if we don't have a parameter sweep. if not self.sweeper.axes: self.init_plots() self.add_manual_plotter(self.re_plot) self.add_manual_plotter(self.im_plot) else: if any([ x.save_kernel.value for x in self.filters.values() if type(x) is SingleShotMeasurement ]): logger.warning( "Kernel saving is not supported if you have parameter sweeps!" ) super(SingleShotFidelityExperiment, self).run_sweeps() if not self.sweeper.axes: self._update_histogram_plots() if hasattr(self, 'extra_plot_server'): try: self.extra_plot_server.stop() except: pass if self.sweeper.axes and self.optimize: #select the buffers/writers whose sources are singleshot filters fid_buffers = [ buff for buff in self.buffers if self.settings['filters'][ buff.name]['source'].strip().split()[1] == 'fidelity' ] if not fid_buffers: raise NameError( "Please connect a buffer to the single-shot filter output in order to optimize fidelity." ) #set sweep parameters to the values that maximize fidelity. Then update the saved_settings with the new values for buff in fid_buffers: dataset, descriptor = buff.get_data(), buff.get_descriptor() opt_ind = np.argmax(dataset['Data']) for k, axis in enumerate(self.sweeper.axes): instr_tree = axis.parameter.instr_tree param_key = self.saved_settings['instruments'] for key in instr_tree[:-1]: # go through the tree param_key = param_key[key] opt_value = float(dataset[axis.name][opt_ind]) # special case to set APS ch12 amplitudes if instr_tree[-1] == 'amplitude' and instr_tree[ -2] in self.saved_settings['instruments'].keys(): param_key['tx_channels']['12']['1'][ 'amplitude'] = round(float(opt_value), 5) param_key['tx_channels']['12']['2'][ 'amplitude'] = round(float(opt_value), 5) else: param_key[instr_tree[-1]] = opt_value logger.info("Set{} to {}.".format( " ".join(str(x) for x in instr_tree), opt_value)) config.yaml_dump(self.saved_settings, config.configFile)
def write_to_file(self): awg_settings = self.settings['instruments'][self.AWG] awg_settings['tx_channels'][self.chan]['amp_factor'] = round(self.amplitude_factor.value, 5) awg_settings['tx_channels'][self.chan]['phase_skew'] = round(self.phase_skew.value, 5) awg_settings['tx_channels'][self.chan][self.chan[0]]['offset'] = round(self.I_offset.value, 5) awg_settings['tx_channels'][self.chan][self.chan[1]]['offset'] = round(self.Q_offset.value, 5) self.settings['instruments'][self.AWG] = awg_settings config.yaml_dump(self.settings, config.configFile) logger.info("Mixer calibration for {}-{} written to experiment file.".format(self.AWG, self.chan))
def fit_CR_amp(xpoints, data0, data1): xpoints = xpoints[2] x_fine = np.linspace(min(xpoints), max(xpoints), 1001) popt0 = np.polyfit(xpoints, data0, 1) # tentatively linearize popt1 = np.polyfit(xpoints, data1, 1) #average between optimum amplitudes xopt = -(popt0[1] / popt0[0] + popt1[1] / popt1[0]) / 2 logger.info('CR amplitude = {}'.format(xopt)) return xopt, popt0, popt1
def wait_for_acquisition(self, dig_run, timeout=5, ocs=None, progressbars=None): progress_updaters = {} if ocs and progressbars: for oc in ocs: if hasattr(progressbars[oc], 'goto'): progress_updaters[oc] = lambda x: progressbars[oc].goto(x) else: progress_updaters[oc] = lambda x: setattr(progressbars[oc], 'value', x) if self.gen_fake_data: total_spewed = 0 counter = {chan: 0 for chan in self._chan_to_wsocket.keys()} initial_points = {oc: oc.points_taken.value for oc in ocs} # print(self.number_averages, self.number_segments) for j in range(self.number_averages): # for i in range(self.number_segments): if self.ideal_data is not None: #add ideal data for testing if hasattr(self, 'exp_step') and self.increment_ideal_data: raise Exception("Cannot use both exp_step and increment_ideal_data") elif hasattr(self, 'exp_step'): total_spewed += self.spew_fake_data( counter, self.ideal_data[self.exp_step]) elif self.increment_ideal_data: total_spewed += self.spew_fake_data( counter, self.ideal_data[self.ideal_counter]) else: total_spewed += self.spew_fake_data( counter, self.ideal_data) else: total_spewed += self.spew_fake_data(counter, [0.0 for i in range(self.number_segments)]) time.sleep(0.0001) self.ideal_counter += 1 while not self.done(): if not dig_run.is_set(): self.last_timestamp.value = datetime.datetime.now().timestamp() if (datetime.datetime.now().timestamp() - self.last_timestamp.value) > timeout: logger.info(f"timeout when recv={self.total_received.value}, exp={self.number_segments*self.record_length*self.number_averages*len(self.channels)}") logger.error("Digitizer %s timed out. Timeout was %f, time was %f", self.name, timeout, (datetime.datetime.now().timestamp() - self.last_timestamp.value)) raise Exception("Alazar timed out.") if progressbars: for oc in ocs: progress_updaters[oc](oc.points_taken.value) #time.sleep(0.2) Does this need to be here at all? if progressbars: try: progressbars[oc].next() progressbars[oc].finish() except AttributeError: pass logger.info(f"Digitizer %s finished getting data when recv={self.total_received.value}, exp={self.number_segments*self.record_length*self.number_averages*len(self.channels)}.", self.name)
def write_to_log(self): """ Record the experiment in a log file """ logfile = os.path.join(config.LogDir, "experiment_log.tsv") if os.path.isfile(logfile): lf = pd.read_csv(logfile, sep="\t") else: logger.info("Experiment log file created.") lf = pd.DataFrame(columns = ["Filename", "Date", "Time"]) lf = lf.append(pd.DataFrame([[self.filename.value, time.strftime("%y%m%d"), time.strftime("%H:%M:%S")]],columns=["Filename", "Date", "Time"]),ignore_index=True) lf.to_csv(logfile, sep = "\t", index = False)
def _squash_round_robins(self): """Make it so that the round robins are set to 1.""" digitizers = [ _ for _ in self.settings['instruments'].keys() if 'nbr_round_robins' in self.settings['instruments'][_].keys() ] for d in digitizers: logger.info( "Set digitizer {} round robins to 1 for single shot experiment." .format(d)) self.settings['instruments'][d]['nbr_round_robins'] = 1
def run_sweeps(self): if not self.sweeper.axes: self.init_plots() self.start_manual_plotters() else: for f in self.filters: if isinstance(f, SingleShotMeasurement): f.save_kernel.value = False super(SingleShotFidelityExperiment, self).run_sweeps() self.get_results() if not self.sweeper.axes: self._update_histogram_plots() self.stop_manual_plotters() if self.set_threshold: self.stream_selectors[0].threshold = self.get_threshold()[0] if self.sample: c = bbndb.calibration.Calibration(value=self.get_fidelity()[0], sample=self.sample, name="Readout fid.", category="Readout") c.date = datetime.datetime.now() bbndb.get_cl_session().add(c) bbndb.get_cl_session().commit() elif self.optimize: fidelities = [f['Max I Fidelity'] for f in self.pdf_data] opt_ind = np.argmax(fidelities) for k, axis in enumerate(self.sweeper.axes): set_pair = axis.parameter.set_pair opt_value = axis.points[opt_ind] if set_pair[1] == 'amplitude' or set_pair[1] == "offset": # special case for APS chans param = [ c for c in self.chan_db.channels if c.label == set_pair[0] ][0] attr = 'amp_factor' if set_pair[ 1] == 'amplitude' else 'offset' setattr(param, f'I_channel_{attr}', opt_value) setattr(param, f'Q_channel_{attr}', opt_value) else: param = [ c for c in self.chan_db.all_instruments() if c.label == set_pair[0] ][0] setattr(param, set_pair[1], opt_value) logger.info( f'Set {set_pair[0]} {set_pair[1]} to optimum value {opt_value}' ) if self.set_threshold: self.stream_selectors[0].threshold = self.get_threshold( )[opt_ind] logger.info( f'Set threshold to {self.stream_selectors[0].threshold}')
def _save_kernel(self): import QGL.config as qconfig if not qconfig.KernelDir or not os.path.exists(qconfig.KernelDir): logger.warning("No kernel directory provided, please set auspex.config.KernelDir") logger.warning("Saving kernel to local directory.") dir = "./" else: dir = qconfig.KernelDir try: logger.info(self.filter_name) filename = self.filter_name + "_kernel.txt" header = "Single shot fidelity filter - {}:\nSource: {}".format(time.strftime("%m/%d/%y -- %H:%M"), self.filter_name) np.savetxt(os.path.join(dir, filename), self.kernel, header=header, comments="#") except (AttributeError, IOError) as ex: raise AttributeError("Could not save single shot fidelity kernel!") from ex
def configure_with_dict(self, settings_dict): """Accept a sdettings dictionary and attempt to set all of the instrument parameters using the key/value pairs.""" for name, value in settings_dict.items(): if name not in ["id", "label", "model", "address", "channel_db_id", "standalone"]: if "_id" in name: continue # Python is insane, and attempts to run a property's getter # when queried by hasattr. Avoid this behavior with the # "ask for forgiveness" paradigm. try: setattr(self, name, value) except (AttributeError, TypeError) as e: logger.info("Instrument {} property: {} could not be set to {}.".format(self.name,name,value)) pass
def fit_CR_phase(xpoints, data0, data1): xpoints = xpoints[1] x_fine = np.linspace(min(xpoints), max(xpoints), 1001) fit0 = SineFit(xpoints, data0, np.pi, 1.0 / xpoints[-1]) fit1 = SineFit(xpoints, data1, np.pi, 1.0 / xpoints[-1]) #find the phase for maximum contrast contrast = (fit0.model(x_fine) - fit1.model(x_fine)) / 2.0 logger.info(f"CR Contrast = {np.min(contrast)}") xopt = x_fine[np.argmin(contrast)] % (2 * np.pi) logger.info(f"CR phase = {xopt}") return xopt, fit0.fit_params, fit1.fit_params
def _squash_round_robins(self): """Make it so that the round robins are set to 1.""" digitizers = [ _ for _ in self.settings['instruments'].keys() if 'nbr_round_robins' in self.settings['instruments'][_].keys() ] for d in digitizers: logger.info( "Set digitizer {} round robins to 1 for single shot experiment." .format(d)) self.settings['instruments'][d]['nbr_round_robins'] = 1 # disable averagers for _, f in self.settings['filters'].items(): if f['type'] == 'Averager': f['enabled'] = False
async def run(self): # self.arb.stop() self.arb.set_scenario_start_index(0, channel=1) self.arb.set_scenario_start_index(0, channel=2) self.arb.advance() await asyncio.sleep(0.3) self.alz.acquire() await asyncio.sleep(0.3) self.arb.trigger() await self.alz.wait_for_acquisition(10.0) await asyncio.sleep(0.8) self.alz.stop() # Seemingly we need to give the filters some time to catch up here... await asyncio.sleep(0.02) logger.info("Stream has filled {} of {} points".format( self.voltage.points_taken, self.voltage.num_points()))
def connect(self, resource_name=None): if resource_name is not None: self.resource_name = resource_name # parse resource_name: expecting something like "HS9004A-009-1" model, serial, self.chan = self.resource_name.split("-") self.serial = model + '-' + serial success = self._lib.openDevice(self.serial.encode('ascii')) if success != 0: logger.info( "Could not open Holzworth at address: {}, might already be open on another channel." .format(self.serial)) # read frequency and power ranges self.fmin = float((self.ch_query(":FREQ:MIN?")).split()[0]) #MHz self.fmax = float((self.ch_query(":FREQ:MAX?")).split()[0]) #MHz self.pmin = float((self.ch_query(":PWR:MIN?")).split()[0]) #dBm self.pmax = float((self.ch_query(":PWR:MAX?")).split()[0]) #dBm
def make_plots(self): """Create plot on both linear and semilog scale """ logger.info("Semilog plot of |1> state probability requires calibrated data.") plt.figure(figsize=(2*6.4, 4.8)) plt.subplot(121) plt.plot(self.xpts, self.ypts, ".", markersize=15, label="Data") plt.plot(self.xpts, self.model(self.xpts), "-", linewidth=3, label="Fit") plt.xlabel(self.xlabel, fontsize=14) plt.ylabel(self.ylabel, fontsize=14) plt.annotate(self.annotation(), xy=(0.4, 0.10), xycoords='axes fraction', size=12) plt.subplot(122) plt.semilogy(self.xpts, -1/2*(self.ypts - self.fit_params["A0"]), ".", markersize=15, label="Data") plt.semilogy(self.xpts, -1/2*(self.model(self.xpts) - self.fit_params["A0"]), "-", linewidth=3, label="Fit") plt.xlabel(self.xlabel, fontsize=14) plt.ylabel('|1> probability', fontsize=14) plt.suptitle(self.title, fontsize=14)
def pulse_marker(mkr, length = 100e-9): """ Utility to generate a square pulse on a APS2 marker. Used for instance to switch a signal between spectrum analyzer and input line marker_name""" from QGL import TRIG from QGL.Compiler import compile_to_hardware APS = bbn.APS2(mkr.phys_chan.transmitter.address) APS.connect() APS.set_trigger_source('Software') seq = [[TRIG(mkr, length)]] APS.set_sequence_file(compile_to_hardware(seq, 'Switch/Switch').replace('meta.json', mkr.phys_chan.transmitter.label+'.aps2')) APS.run() APS.trigger() APS.stop() APS.disconnect() logger.info('Switched marker {} ({})'.format(mkr.label, mkr))
def pulse_marker(marker_name, length = 100e-9): """ Utility to generate a square pulse on a APS2 marker. Used for instance to switch a signal between spectrum analyzer and input line marker_name as defined in measure.yaml """ import QGL QGL.ChannelLibrary() settings = auspex.config.load_meas_file(auspex.config.find_meas_file()) mkr = settings['markers'][marker_name] marker = QGL.MarkerFactory(marker_name) APS_name = mkr.split()[0] APS = bbn.APS2() APS.connect(settings['instruments'][APS_name]['address']) APS.set_trigger_source('Software') seq = [[QGL.TRIG(marker,length)]] APS.set_seq_file(QGL.compile_to_hardware(seq, 'Switch\Switch').replace('meta.json', APS_name+'.h5')) APS.run() APS.trigger() APS.stop() APS.disconnect() logger.info('Switched marker {} ({})'.format(marker_name, mkr))
def __init__(self): global pipelineMgr self.pipeline = None self.meas_graph = None if not bbndb.get_cl_session(): raise Exception( "Auspex expects db to be created already by QGL. Please create a ChannelLibrary." ) self.session = bbndb.get_pl_session() # Check to see whether there is already a temp database available_pipelines = list( set([ pn[0] for pn in list( self.session.query(adb.Connection.pipeline_name).all()) ])) if "working" in available_pipelines: connections = self.get_connections_by_name('working') edges = [(c.node1.hash_val, c.node2.hash_val, { 'connector_in': c.node2_name, 'connector_out': c.node1_name }) for c in connections] nodes = [] nodes.extend(list(set([c.node1 for c in connections]))) nodes.extend(list(set([c.node2 for c in connections]))) self.meas_graph = nx.DiGraph() for node in nodes: node.pipelineMgr = self self.meas_graph.add_node(node.hash_val, node_obj=node) self.meas_graph.add_edges_from(edges) adb.__current_pipeline__ = self else: logger.info( "Could not find an existing pipeline. Please create one.") pipelineMgr = self
def __init__(self, qubit, sample_name=None, output_nodes=None, meta_file=None, optimize=True, set_threshold=True, **kwargs): self.pdf_data = [] self.qubit = qubit self.optimize = optimize self.set_threshold = set_threshold if meta_file: self.meta_file = meta_file else: self.meta_file = self._single_shot_sequence(self.qubit) super(SingleShotFidelityExperiment, self).__init__(self.meta_file, **kwargs) if not sample_name: sample_name = self.qubit.label if not bbndb.get_cl_session(): raise Exception("Attempting to load Calibrations database, \ but no database session is open! Have the ChannelLibrary and PipelineManager been created?" ) existing_samples = list(bbndb.get_cl_session().query( bbndb.calibration.Sample).filter_by(name=sample_name).all()) if len(existing_samples) == 0: logger.info("Creating a new sample in the calibration database.") self.sample = bbndb.calibration.Sample(name=sample_name) bbndb.get_cl_session().add(self.sample) elif len(existing_samples) == 1: self.sample = existing_samples[0] else: raise Exception( "Multiple samples found in calibration database with the same name! How?" )
def fit_CR_length(xpoints, data0, data1): xpoints = xpoints[0] x_fine = np.linspace(min(xpoints), max(xpoints), 1001) fit0 = SineFit(xpoints, data0, np.pi / 2.0, 1 / (2.0 * xpoints[-1])) fit1 = SineFit(xpoints, data1, np.pi / 2.0, 1 / (2.0 * xpoints[-1])) #find the first zero crossing delta = 2 * (x_fine[1] - x_fine[0]) idx0 = int(1.0 / np.abs(fit0.fit_params["f"]) / delta) idx1 = int(1.0 / np.abs(fit1.fit_params["f"]) / delta) yfit0 = fit0.model(x_fine[:idx0]) yfit1 = fit1.model(x_fine[:idx1]) #average between the two qc states, rounded to 10 ns xopt = round( (x_fine[np.argmin(abs(yfit0))] + x_fine[np.argmin(abs(yfit1))]) / 2 / 10e-9) * 10e-9 logger.info('CR length = {} ns'.format(xopt * 1e9)) return xopt, fit0.fit_params, fit1.fit_params
def fit_ramsey(xdata, ydata, two_freqs=False): if two_freqs: # Initial KT estimation freqs, Tcs, amps = KT_estimation(ydata, xdata, 2) p0 = [*freqs, *abs(amps), *Tcs, *np.angle(amps), np.mean(ydata)] try: popt, pcov = curve_fit(ramsey_2f, xdata, ydata, p0=p0) fopt = [popt[0], popt[1]] perr = np.sqrt(np.diag(pcov)) ferr = perr[:2] return fopt, ferr, popt except: logger.info( 'Two-frequency fit failed. Trying with single frequency.') # Initial KT estimation freqs, Tcs, amps = KT_estimation(ydata, xdata, 1) p0 = [freqs[0], abs(amps[0]), Tcs[0], np.angle(amps[0]), np.mean(ydata)] popt, pcov = curve_fit(ramsey_1f, xdata, ydata, p0=p0) fopt = [popt[0]] perr = np.sqrt(np.diag(pcov)) fopt = popt[:1] ferr = perr[:1] return fopt, ferr, popt
def connect(self, resource_name=None): """ Connect to the MUX via Ethernet HTTP resource_name: Network IP address and port, e.g. 100.100.10.10:80 """ if resource_name is not None: self.resource_name = resource_name if self.resource_name is None: self._resource = None logger.error( "Failed setting up connection to %s. resource_name is not provided." % self.name) return False try: logger.debug("HTTP connect to %s at %s" % (self.name, self.resource_name)) self._resource = http.client.HTTPConnection(self.resource_name) # Test connection logger.debug("Test connection to %s" % self.resource_name) self._resource.request("GET", "/") res = self._resource.getresponse() if res.status == 200: logger.info("Successfully set up connection to %s" % self.resource_name) data = res.read() return True else: self._resource = None logger.error( "For some reason, failed setting up connection to %s" % self.resource_name) return False except Exception as ex: self._resource = None logger.error("Failed setting up connection to %s. Exception: %s" % (self.resource_name, ex)) return False
def connect_to_plot_server(self): logger.debug("Found %d plotters", len(self.plotters)) # Create the descriptor and set uuids for each plot process plot_desc = {p.filter_name: p.desc() for p in self.plotters} for p in self.plotters: p.uuid = self.uuid try: context = zmq.Context() socket = context.socket(zmq.DEALER) socket.setsockopt(zmq.LINGER, 0) socket.identity = "Auspex_Experiment".encode() socket.connect("tcp://localhost:7761") socket.send_multipart( [self.uuid.encode(), json.dumps(plot_desc).encode('utf8')]) poller = zmq.Poller() poller.register(socket, zmq.POLLIN) evts = dict(poller.poll(5000)) poller.unregister(socket) if socket in evts: try: if socket.recv_multipart()[0] == b'ACK': logger.info("Connection established to plot server.") self.do_plotting = True else: raise Exception( "Server returned invalid message, expected ACK.") except: logger.info("Could not connect to server.") for p in self.plotters: p.do_plotting = False else: logger.info("Plot Server did not respond.") for p in self.plotters: p.do_plotting = False except: logger.warning( "Exception occured while contacting the plot server. Is it running?" ) for p in self.plotters: p.do_plotting = False time.sleep(0.5)
def _do_fit(self): if self.two_freqs: self.dict_option = True self._initial_guess = self._initial_guess_2f self._model = self._model_2f try: super()._do_fit() two_freq_chi2 = self.sq_error except: self.two_freqs = False logger.info("Two-frequency fit failed. Trying single-frequency fit.") if self.two_freqs and self.AIC: #Compare the one and two frequency fits self.dict_option = False self._initial_guess = self._initial_guess_1f self._model = self._model_1f super()._do_fit() one_freq_chi2 = self.sq_error aic = self._aicc(two_freq_chi2, 9, len(self.xpts)) - self._aicc(one_freq_chi2, 5, len(self.xpts)) if aic > 0 and not self.force: self.two_freqs = False rl = 100*np.exp(-aic/2) logger.info(f"Selecting one-frequency fit with relative likelihood = {rl:.2f}%") if rl>33: logger.info("Relative likelihood of 2nd frequency high, take more averages or set force = True.") else: self.dict_option = True self._initial_guess = self._initial_guess_2f self._model = self._model_2f super()._do_fit() if not self.two_freqs: self.dict_option = False self._initial_guess = self._initial_guess_1f self._model = self._model_1f super()._do_fit() if self.plots: self.make_plots()
def fit_CR(xpoints, data, cal_type): """Fit CR calibration curves for variable pulse length, phase, or amplitude""" data0 = data[:len(data) // 2] data1 = data[len(data) // 2:] if cal_type == CR_cal_type.LENGTH: xpoints = xpoints[0] x_fine = np.linspace(min(xpoints), max(xpoints), 1001) p0 = [1 / (2 * xpoints[-1]), 1, np.pi / 2, 0] popt0, _ = curve_fit(sinf, xpoints, data0, p0=p0) popt1, _ = curve_fit(sinf, xpoints, data1, p0=p0) #find the first zero crossing yfit0 = sinf( x_fine[:int(1 / abs(popt0[0]) / 2 / (x_fine[1] - x_fine[0]))], *popt0) yfit1 = sinf( x_fine[:int(1 / abs(popt1[0]) / 2 / (x_fine[1] - x_fine[0]))], *popt1) #average between the two qc states, rounded to 10 ns xopt = round( (x_fine[np.argmin(abs(yfit0))] + x_fine[np.argmin(abs(yfit1))]) / 2 / 10e-9) * 10e-9 logger.info('CR length = {} ns'.format(xopt * 1e9)) elif cal_type == CR_cal_type.PHASE: xpoints = xpoints[1] x_fine = np.linspace(min(xpoints), max(xpoints), 1001) p0 = [1 / (xpoints[-1]), 1, np.pi, 0] popt0, _ = curve_fit(sinf, xpoints, data0, p0=p0) popt1, _ = curve_fit(sinf, xpoints, data1, p0=p0) #find the phase for maximum contrast contrast = (sinf(x_fine, *popt0) - sinf(x_fine, *popt1)) / 2 logger.info('CR contrast = {}'.format(max(contrast))) xopt = x_fine[np.argmax(contrast)] - np.pi elif cal_type == CR_cal_type.AMP: xpoints = xpoints[2] x_fine = np.linspace(min(xpoints), max(xpoints), 1001) popt0 = np.polyfit(xpoints, data0, 1) # tentatively linearize popt1 = np.polyfit(xpoints, data1, 1) #average between optimum amplitudes xopt = -(popt0[1] / popt0[0] + popt1[1] / popt1[0]) / 2 logger.info('CR amplitude = {}'.format(xopt)) return xopt, popt0, popt1
def catch_ctrl_c(signum, frame): logger.info("Caught SIGINT. Shutting down.") self.shutdown() raise NameError("Shutting down.") sys.exit(0)