def connect_to_station(config_file=None): """ Loads a QCoDeS station configuration file, or starts a new station. Parameters --------- config_file: The file path to the desired configuration file. Returns --------- A loaded or new QCoDeS station for conducting experiments. """ if os.path.isfile(os.environ['MeasureItHome'] + '\\cfg\\qcodesrc.json'): qc.config.update_config(os.environ['MeasureItHome'] + '\\cfg\\') station = Station() try: station.load_config_file(config_file) except Exception: print( "Couldn't open the station configuration file. Started new station." ) return station
def __init__( self, parent: Optional[QtCore.QObject] = None, port: int = 5555, allowUserShutdown: bool = False, addresses: List[str] = [], initScript: Optional[str] = None, ) -> None: super().__init__(parent) if addresses is None: addresses = [] if initScript == None: initScript = '' self.SAFEWORD = ''.join( random.choices([chr(i) for i in range(65, 91)], k=16)) self.serverRunning = False self.port = int(port) self.station = Station() self.allowUserShutdown = allowUserShutdown self.listenAddresses = list(set(['127.0.0.1'] + addresses)) self.initScript = initScript self.broadcastPort = self.port + 1 self.broadcastSocket = None self.parameterSet.connect( lambda n, v: logger.info(f"Parameter '{n}' set to: {str(v)}")) self.parameterGet.connect( lambda n, v: logger.debug(f"Parameter '{n}' retrieved: {str(v)}")) self.funcCalled.connect( lambda n, args, kw, ret: logger.debug(f"Function called:" f"'{n}', args: {str(args)}, " f"kwargs: {str(kw)})'."))
def get_station(): # Create a station magnetism_station = Station() # Get the associated instruments for instrument in setup_instruments(): magnetism_station.add_component(instrument) # Give the user the station return magnetism_station
def get_station(): # Create a station cryo_station = Station() # Associate the instruments with the station for instrument in setup_instruments(): cryo_station.add_component(instrument) # Send the station to the user return cryo_station
def __set_qcodes(self): initialise_or_create_database_at(self.__database) self.station = Station() #### instruments needs change # A dummy instrument dac with two parameters ch1 and ch2 self.dac = DummyInstrument('dac', gates=['amp']) # A dummy instrument dmm with two parameters ch1 and Ch2 self.dmm = DummyInstrument('dmm', gates=['v1']) #These are the parameters which come ready to use from the intruments drivers #dac.add_parameter('amp',label='Amplitude', unit="V", get_cmd=None, set_cmd=None) self.dac.add_parameter('freq', label='Frequency', unit="Hz", get_cmd=None, set_cmd=None) #puts current time in a string to facilitate control of the samples #makes the sample name now = datetime.now() now = now.strftime("%Y-%m-%d_%H-%M-%S") print(now) #the experiment is a unit of data inside the database it's made #out self.exp = load_or_create_experiment(experiment_name=self.__exp_name, sample_name=now) self.dmm.v1 = dmm_parameter('dmm_v1', self.dac)
def test_integration_station_and_measurement(two_empty_temp_db_connections, inst): """ An integration test where the runs in the source DB file are produced with the Measurement object and there is a Station as well """ source_conn, target_conn = two_empty_temp_db_connections source_path = path_to_dbfile(source_conn) target_path = path_to_dbfile(target_conn) source_exp = Experiment(conn=source_conn) # Set up measurement scenario station = Station(inst) meas = Measurement(exp=source_exp, station=station) meas.register_parameter(inst.back) meas.register_parameter(inst.plunger) meas.register_parameter(inst.cutter, setpoints=(inst.back, inst.plunger)) with meas.run() as datasaver: for back_v in [1, 2, 3]: for plung_v in [-3, -2.5, 0]: datasaver.add_result((inst.back, back_v), (inst.plunger, plung_v), (inst.cutter, back_v+plung_v)) extract_runs_into_db(source_path, target_path, 1) target_ds = DataSet(conn=target_conn, run_id=1) assert datasaver.dataset.the_same_dataset_as(target_ds)
def init(): a_property = Parameter('a_property', set_cmd=None, get_cmd=None, initial_value=0) another_property = Parameter('another_property', set_cmd=None, get_cmd=None, initial_value='abc', vals=validators.Strings()) station = Station(a_property, another_property) return station
def __init__(self, parent=None, port=5555, allowUserShutdown=False): super().__init__(parent) self.SAFEWORD = ''.join( random.choices([chr(i) for i in range(65, 91)], k=16)) self.serverRunning = False self.port = port self.station = Station() self.allowUserShutdown = allowUserShutdown self.parameterSet.connect( lambda n, v: logger.info(f"Parameter '{n}' set to: {str(v)}")) self.parameterGet.connect( lambda n, v: logger.debug(f"Parameter '{n}' retrieved: {str(v)}")) self.funcCalled.connect( lambda n, args, kw, ret: logger.debug(f"Function called:" f"'{n}', args: {str(args)}, " f"kwargs: {str(kw)})'."))
def take_buffer_keysight(self): """ takes a frequency sweep, not setting any values on the hardware """ from qcodes import Station station = Station() station.add_component(self.vna) # import pdb; pdb.set_trace() meas = Measurement(station=station) # qcodes measurement # self.vna.points.set(20) self.vna.auto_sweep(False) meas.register_parameter(self.vna.real) meas.register_parameter(self.vna.imaginary) meas.register_parameter(self.vna.magnitude) meas.register_parameter(self.vna.phase) # actually get the data with meas.run( ) as datasaver: # try to run the measurement (? but this doesn't yet write to the database) self.vna.active_trace.set(1) # there are Tr1 and Tr2 # self.vna.traces.tr1.run_sweep() imag = self.vna.imaginary() real = self.vna.real() mag = self.vna.magnitude() phase = self.vna.phase() datasaver.add_result( (self.vna.magnitude, mag), (self.vna.phase, phase), (self.vna.real, real), (self.vna.imaginary, imag)) dataid = datasaver.run_id pd = datasaver.dataset.get_parameter_data() snapshot = datasaver.dataset.snapshot plot_by_id(dataid)
def import_json(cls, json_dict, station=Station()): """Loads desired attributes into current SweepQueue.""" sq = SweepQueue(json_dict['inter_delay']) for item_json in json_dict['queue']: item_module = importlib.import_module(item_json['module']) item_class = getattr(item_module, item_json['class']) item = item_class.import_json(item_json, station) sq.append(item) return sq
def load_station_and_connect_instruments(self, config_file=None): self.station = Station() try: self.station.load_config_file(config_file) except Exception as e: self.show_error( "Error", "Couldn't open the station configuration file. Started new station.", e) return if self.station.config is None: return for name, instr in self.station.config['instruments'].items(): try: dev = self.station.load_instrument(name) self.devices[str(name)] = dev except Exception as e: self.show_error( 'Instrument Error', f'Error connecting to {name}, ' 'either the name is already in use or the device is unavailable.', e) self.update_instrument_menu()
def fill_station(param_set, param_meas): station = Station() allinstr=qc.instrument.base.Instrument._all_instruments for key,val in allinstr.items(): instr = qc.instrument.base.Instrument.find_instrument(key) station.add_component(instr) measparstring = "" for parameter in param_set: station.add_component(parameter) measparstring += parameter.name + ',' for parameter in param_meas: try: # Prevent station crash when component of parameter is not unique station.add_component(parameter) measparstring += parameter.name + ',' except Exception as e: print('Error ignored when filling station: \n', e) pass return measparstring
def fill_station_zerodim(param_meas): station = Station() allinstr=qc.instrument.base.Instrument._all_instruments for key,val in allinstr.items(): instr = qc.instrument.base.Instrument.find_instrument(key) station.add_component(instr) measparstring = "" for parameter in param_meas: station.add_component(parameter) measparstring += parameter.name + ',' return measparstring
def test_nest(): n_sample_points = 100 x = ManualParameter("x") sweep_values_x = np.linspace(-1, 1, n_sample_points) y = ManualParameter("y") sweep_values_y = np.linspace(-1, 1, n_sample_points) m = ManualParameter("m") m.get = lambda: np.sin(x()) n = ManualParameter("n") n.get = lambda: np.cos(x()) + 2 * np.sin(y()) sweep_object = sweep(x, sweep_values_x)(m, sweep(y, sweep_values_y)(n)) experiment = new_experiment("sweep_measure", sample_name="sine") station = Station() meas = SweepMeasurement(exp=experiment, station=station) meas.register_sweep(sweep_object) with meas.run() as datasaver: for data in sweep_object: datasaver.add_result(*data.items()) data_set = datasaver._dataset assert data_set.paramspecs["x"].depends_on == "" assert data_set.paramspecs["y"].depends_on == "" assert data_set.paramspecs["m"].depends_on == "x" assert data_set.paramspecs["n"].depends_on == "x, y" data_x = data_set.get_data('x') data_y = data_set.get_data('y') assert data_x[::n_sample_points + 1] == [[xi] for xi in sweep_values_x] assert data_y[::n_sample_points + 1] == [[None] for _ in sweep_values_x] coordinate_layout = itertools.product(sweep_values_x, sweep_values_y) expected_x, expected_y = zip(*coordinate_layout) assert [ix for c, ix in enumerate(data_x) if c % (n_sample_points + 1)] == [[xi] for xi in expected_x] assert [iy for c, iy in enumerate(data_y) if c % (n_sample_points + 1)] == [[yi] for yi in expected_y]
def test_column_mismatch(two_empty_temp_db_connections, some_interdeps, inst): """ Test insertion of runs with no metadata and no snapshot into a DB already containing a run that has both """ source_conn, target_conn = two_empty_temp_db_connections source_path = path_to_dbfile(source_conn) target_path = path_to_dbfile(target_conn) target_exp = Experiment(conn=target_conn) # Set up measurement scenario station = Station(inst) meas = Measurement(exp=target_exp, station=station) meas.register_parameter(inst.back) meas.register_parameter(inst.plunger) meas.register_parameter(inst.cutter, setpoints=(inst.back, inst.plunger)) with meas.run() as datasaver: for back_v in [1, 2, 3]: for plung_v in [-3, -2.5, 0]: datasaver.add_result((inst.back, back_v), (inst.plunger, plung_v), (inst.cutter, back_v+plung_v)) datasaver.dataset.add_metadata('meta_tag', 'meta_value') Experiment(conn=source_conn) source_ds = DataSet(conn=source_conn) source_ds.set_interdependencies(some_interdeps[1]) source_ds.mark_started() source_ds.add_results([{name: 2.1 for name in some_interdeps[1].names}]) source_ds.mark_completed() extract_runs_into_db(source_path, target_path, 1) # compare target_copied_ds = DataSet(conn=target_conn, run_id=2) assert target_copied_ds.the_same_dataset_as(source_ds)
def test_toParamDict_paramsBasic(): """Test serializing a few parameters added to a station""" paramNames = [f"parameter_{i}" for i in range(4)] paramValues = [123, None, True, 'abcdef'] params = [] for n, v in zip(paramNames, paramValues): params.append(Parameter(n, unit="unit", set_cmd=None, initial_value=v)) station = Station(*params) # test simple format paramDict_test = toParamDict(station, simpleFormat=True) paramDict_expt = {} for n, v in zip(paramNames, paramValues): paramDict_expt[n] = v assert paramDict_test == paramDict_expt
def init_from_json(cls, fn, station=Station()): """ Loads previously saved sweep information. Sends the sweep attributes to the import_json module. Parameters --------- fn: Filename path where sweep information is stored. station: Initializes a QCoDeS station. Returns --------- Located data is sent to import_json method. """ with open(fn) as json_file: data = json.load(json_file) return SweepQueue.import_json(data, station)
def test_inferred(): x = ManualParameter("x", unit="V") @setter([("xmv", "mV")], inferred_parameters=[("x", "V")]) def xsetter(milivolt_value): volt_value = milivolt_value / 1000.0 # From mV to V x.set(volt_value) return volt_value m = ManualParameter("m") m.get = lambda: np.sin(x()) sweep_values = np.linspace(-1000, 1000, 100) # We sweep in mV sweep_object = nest(sweep(xsetter, sweep_values), m) experiment = new_experiment("sweep_measure", sample_name="sine") station = Station() meas = SweepMeasurement(exp=experiment, station=station) meas.register_sweep(sweep_object) with meas.run() as datasaver: for data in sweep_object: datasaver.add_result(*data.items()) data_set = datasaver._dataset assert data_set.paramspecs["x"].depends_on == "" assert data_set.paramspecs["x"].inferred_from == "xmv" assert data_set.paramspecs["xmv"].depends_on == "" assert data_set.paramspecs["m"].depends_on == "x" expected_xmv = [[xi] for xi in sweep_values] expected_x = [[xi / 1000] for xi in sweep_values] assert data_set.get_data('xmv') == expected_xmv assert data_set.get_data('x') == expected_x
def test_simple(): x = ManualParameter("x") sweep_values = np.linspace(-1, 1, 100) m = ManualParameter("m") m.get = lambda: np.sin(x()) sweep_object = nest(sweep(x, sweep_values), m) experiment = new_experiment("sweep_measure", sample_name="sine") station = Station() meas = SweepMeasurement(exp=experiment, station=station) meas.register_sweep(sweep_object) with meas.run() as datasaver: for data in sweep_object: datasaver.add_result(*data.items()) data_set = datasaver._dataset assert data_set.paramspecs["x"].depends_on == "" assert data_set.paramspecs["m"].depends_on == "x" expected_x = [[xi] for xi in sweep_values] assert data_set.get_data('x') == expected_x
class StationServer(QtCore.QObject): """The main server object. Encapsulated in a separate object so we can run it in a separate thread. Port should always be an odd number to allow the next even number to be its corresponding publishing port. """ # We use this to quit the server. # If this string is sent as message to the server, it'll shut down and close # the socket. Should only be used from within this module. # It's randomized in the instantiated server for a little bit of safety. SAFEWORD = 'BANANA' #: Signal(str, str) -- emit messages for display in the gui (or other stuff the gui #: wants to do with it. #: Arguments: the message received, and the reply sent. messageReceived = QtCore.Signal(str, str) #: Signal(int) -- emitted when the server is started. #: Arguments: the port. serverStarted = QtCore.Signal(str) #: Signal() -- emitted when we shut down. finished = QtCore.Signal() #: Signal(Dict) -- emitted when a new instrument was created. #: Argument is the blueprint of the instrument. instrumentCreated = QtCore.Signal(object) #: Signal(str, Any) -- emitted when a parameter was set #: Arguments: full parameter location as string, value. parameterSet = QtCore.Signal(str, object) #: Signal(str, Any) -- emitted when a parameter was retrieved #: Arguments: full parameter location as string, value. parameterGet = QtCore.Signal(str, object) #: Signal(str, List[Any], Dict[str, Any], Any) -- emitted when a function was called #: Arguments: full function location as string, arguments, kw arguments, return value. funcCalled = QtCore.Signal(str, object, object, object) def __init__( self, parent: Optional[QtCore.QObject] = None, port: int = 5555, allowUserShutdown: bool = False, addresses: List[str] = [], initScript: Optional[str] = None, ) -> None: super().__init__(parent) if addresses is None: addresses = [] if initScript == None: initScript = '' self.SAFEWORD = ''.join( random.choices([chr(i) for i in range(65, 91)], k=16)) self.serverRunning = False self.port = int(port) self.station = Station() self.allowUserShutdown = allowUserShutdown self.listenAddresses = list(set(['127.0.0.1'] + addresses)) self.initScript = initScript self.broadcastPort = self.port + 1 self.broadcastSocket = None self.parameterSet.connect( lambda n, v: logger.info(f"Parameter '{n}' set to: {str(v)}")) self.parameterGet.connect( lambda n, v: logger.debug(f"Parameter '{n}' retrieved: {str(v)}")) self.funcCalled.connect( lambda n, args, kw, ret: logger.debug(f"Function called:" f"'{n}', args: {str(args)}, " f"kwargs: {str(kw)})'.")) def _runInitScript(self): if os.path.exists(self.initScript): path = os.path.abspath(self.initScript) env = dict(station=self.station) exec(open(path).read(), env) else: logger.warning( f"path to initscript ({self.initScript}) not found.") @QtCore.Slot() def startServer(self) -> None: """Start the server. This function does not return until the ZMQ server has been shut down.""" logger.info(f"Starting server.") logger.info(f"The safe word is: {self.SAFEWORD}") context = zmq.Context() socket = context.socket(zmq.REP) for a in self.listenAddresses: addr = f"tcp://{a}:{self.port}" socket.bind(addr) logger.info(f"Listening at {addr}") # creating and binding publishing socket to broadcast changes broadcastAddr = f"tcp://*:{self.broadcastPort}" logger.info(f"Starting publishing server at {broadcastAddr}") self.broadcastSocket = context.socket(zmq.PUB) self.broadcastSocket.bind(broadcastAddr) self.serverRunning = True if self.initScript not in ['', None]: logger.info(f"Running init script") self._runInitScript() self.serverStarted.emit(addr) while self.serverRunning: message = recv(socket) message_ok = True response_to_client = None response_log = None # Allow the test client from within the same process to make sure the # server shuts down. This is if message == self.SAFEWORD: response_log = 'Server has received the safeword and will shut down.' response_to_client = ServerResponse(message=response_log) self.serverRunning = False logger.warning(response_log) elif self.allowUserShutdown and message == 'SHUTDOWN': response_log = 'Server shutdown requested by client.' response_to_client = ServerResponse(message=response_log) self.serverRunning = False logger.warning(response_log) # If the message is a string we just echo it back. # This is used for testing sometimes, but has no functionality. elif isinstance(message, str): response_log = f"Server has received: {message}. No further action." response_to_client = ServerResponse(message=response_log) logger.info(response_log) # We assume this is a valid instruction set now. elif isinstance(message, ServerInstruction): instruction = message try: instruction.validate() logger.info(f"Received request for operation: " f"{str(instruction.operation)}") logger.debug(f"Instruction received: " f"{str(instruction)}") except Exception as e: message_ok = False response_log = f'Received invalid message. Error raised: {str(e)}' response_to_client = ServerResponse(message=None, error=e) logger.warning(response_log) if message_ok: # We don't need to use a try-block here, because # errors are already handled in executeServerInstruction. response_to_client = self.executeServerInstruction( instruction) response_log = f"Response to client: {str(response_to_client)}" if response_to_client.error is None: logger.info(f"Response sent to client.") logger.debug(response_log) else: logger.warning(response_log) else: response_log = f"Invalid message type." response_to_client = ServerResponse(message=None, error=response_log) logger.warning(f"Invalid message type: {type(message)}.") logger.debug(f"Invalid message received: {str(message)}") send(socket, response_to_client) self.messageReceived.emit(str(message), response_log) self.broadcastSocket.close() socket.close() self.finished.emit() return True def executeServerInstruction(self, instruction: ServerInstruction) \ -> Tuple[ServerResponse, str]: """ This is the interpreter function that the server will call to translate the dictionary received from the proxy to instrument calls. :param instruction: The instruction object. :returns: The results returned from performing the operation. """ args = [] kwargs = {} # We call a helper function depending on the operation that is requested. if instruction.operation == Operation.get_existing_instruments: func = self._getExistingInstruments elif instruction.operation == Operation.create_instrument: func = self._createInstrument args = [instruction.create_instrument_spec] elif instruction.operation == Operation.call: func = self._callObject args = [instruction.call_spec] elif instruction.operation == Operation.get_blueprint: func = self._getBluePrint args = [instruction.requested_path] elif instruction.operation == Operation.get_param_dict: func = self._toParamDict args = [instruction.serialization_opts] elif instruction.operation == Operation.set_params: func = self._fromParamDict args = [instruction.set_parameters] else: raise NotImplementedError try: returns = func(*args, **kwargs) response = ServerResponse(message=returns) except Exception as err: response = ServerResponse(message=None, error=err) return response def _getExistingInstruments(self) -> Dict: """ Get the existing instruments in the station. :returns: A dictionary that contains the instrument name and its class name. """ comps = self.station.components info = {k: v.__class__ for k, v in comps.items()} return info def _createInstrument(self, spec: InstrumentCreationSpec) -> None: """Create a new instrument on the server.""" sep_class = spec.instrument_class.split('.') modName = '.'.join(sep_class[:-1]) clsName = sep_class[-1] mod = importlib.import_module(modName) cls = getattr(mod, clsName) args = [] if spec.args is None else spec.args kwargs = dict() if spec.kwargs is None else spec.kwargs new_instrument = qc.find_or_create_instrument(cls, name=spec.name, *args, **kwargs) if new_instrument.name not in self.station.components: self.station.add_component(new_instrument) self.instrumentCreated.emit( bluePrintFromInstrumentModule(new_instrument.name, new_instrument)) def _callObject(self, spec: CallSpec) -> Any: """Call some callable found in the station.""" obj = nestedAttributeFromString(self.station, spec.target) args = spec.args if spec.args is not None else [] kwargs = spec.kwargs if spec.kwargs is not None else {} ret = obj(*args, **kwargs) # Check if a new parameter is being created. self._newOrDeleteParameterDetection(spec, args, kwargs) if isinstance(obj, Parameter): if len(args) > 0: self.parameterSet.emit(spec.target, args[0]) # Broadcast changes in parameter values. self._broadcastParameterChange( ParameterBroadcastBluePrint(spec.target, 'parameter-update', args[0])) else: self.parameterGet.emit(spec.target, ret) # Broadcast calls of parameters. self._broadcastParameterChange( ParameterBroadcastBluePrint(spec.target, 'parameter-call', ret)) else: self.funcCalled.emit(spec.target, args, kwargs, ret) return ret def _getBluePrint( self, path: str ) -> Union[InstrumentModuleBluePrint, ParameterBluePrint, MethodBluePrint]: obj = nestedAttributeFromString(self.station, path) if isinstance(obj, tuple(INSTRUMENT_MODULE_BASE_CLASSES)): return bluePrintFromInstrumentModule(path, obj) elif isinstance(obj, tuple(PARAMETER_BASE_CLASSES)): return bluePrintFromParameter(path, obj) elif callable(obj): return bluePrintFromMethod(path, obj) else: raise ValueError(f'Cannot create a blueprint for {type(obj)}') def _toParamDict(self, opts: ParameterSerializeSpec) -> Dict[str, Any]: if opts.path is None: obj = self.station else: obj = [nestedAttributeFromString(self.station, opts.path)] includeMeta = [k for k in opts.attrs if k != 'value'] return serialize.toParamDict(obj, *opts.args, includeMeta=includeMeta, **opts.kwargs) def _fromParamDict(self, params: Dict[str, Any]): return serialize.fromParamDict(params, self.station) def _broadcastParameterChange(self, blueprint: ParameterBroadcastBluePrint): """ Broadcast any changes to parameters in the server. The message is composed of a 2 part array. The first item is the name of the instrument the parameter is from, with the second item being the string of the blueprint in dict format. This is done to allow subscribers to subscribe to specific instruments. :param blueprint: The parameter broadcast blueprint that is being broadcast """ self.broadcastSocket.send_string(blueprint.name.split('.')[0], flags=zmq.SNDMORE) self.broadcastSocket.send_string((blueprint.toDictFormat())) logger.info( f"Parameter {blueprint.name} has broadcast an update of type: {blueprint.action}," f" with a value: {blueprint.value}.") def _newOrDeleteParameterDetection(self, spec, args, kwargs): """ Detects if the call action is being used to create a new parameter or deletes an existing parameter. If so, it creates the parameter broadcast blueprint and broadcast it. :param spec: CallSpec object being passed to the call method. :param args: args being passed to the call method. :param kwargs: kwargs being passed to the call method. """ if spec.target.split('.')[-1] == 'add_parameter': name = spec.target.split('.')[0] + '.' + '.'.join(spec.args) pb = ParameterBroadcastBluePrint(name, 'parameter-creation', kwargs['initial_value'], kwargs['unit']) self._broadcastParameterChange(pb) elif spec.target.split('.')[-1] == 'remove_parameter': name = spec.target.split('.')[0] + '.' + '.'.join(spec.args) pb = ParameterBroadcastBluePrint(name, 'parameter-deletion') self._broadcastParameterChange(pb)
# Virtual AWG settings = HardwareSettings() virtual_awg = VirtualAwg([awg_adapter.instrument], settings) marker_delay = 16e-6 virtual_awg.digitizer_marker_delay(marker_delay) marker_uptime = 1e-2 virtual_awg.digitizer_marker_uptime(marker_uptime) # Station gates = VirtualIVVI('gates', gates=['P1', 'P2'], model=None) station = Station(virtual_awg, scope_reader.adapter.instrument, awg_adapter.instrument, gates) #%% Enable the stimulus demodulator = 1 signal_output = 1 oscillator = demodulator update_stimulus(is_enabled=True, signal_output=signal_output, amplitude=0.1, oscillator=oscillator) #%% Sensing a resonance signal_input = signal_output scanjob = scanjob_t(wait_time_startscan=1) scanjob.add_sweep(param=stimulus.set_oscillator_frequency(oscillator), start=140e6, end=180e6, step=0.2e6)
self.setpoints = (tuple(), tuple()) self.setpoint_shapes = (tuple(), tuple()) self.setpoint_labels = (("I channel", ), ('Q channel', )) self.setpoint_units = (("mV", ), ("mV", )) self.setpoint_names = (("I_channel", ), ("Q_channel", )) self.i = 2 def get_raw(self): self.i += 1 return (self.i, self.i + 100) import qcodes from qcodes import Parameter, Station from qcodes.tests.instrument_mocks import DummyInstrument station = Station() instr = DummyInstrument('instr', gates=['input', 'output', 'gain']) instr.gain(42) # station.add_component(p) station.add_component(instr) from core_tools.data.SQL.connect import SQL_conn_info_local, SQL_conn_info_remote, sample_info, set_up_local_storage # set_up_local_storage("xld_user", "XLDspin001", "vandersypen_data", "6dot", "XLD", "6D2S - SQ21-XX-X-XX-X") # set_up_local_storage("xld_user", "XLDspin001", "vandersypen_data", "6dot", "XLD", "testing") set_up_local_storage('stephan', 'magicc', 'test', 'Intel Project', 'F006', 'SQ38328342') now = str(datetime.datetime.now()) path = os.path.join(os.getcwd(), 'test.db') initialise_or_create_database_at(path) load_or_create_experiment('tutorial ' + now, 'no sample')
def record_S21_sweep_power_sweep_frequency(self): # -- setting vna parameters # vna.sweep_mode.set('CONT') self.vna.power.set(self.vnapower) self.vna.center.set(self.center_frequency) self.vna.span.set(self.frequency_span) self.vna.points.set(self.num_freq_points) self.vna.if_bandwidth.set(self.ifbandwidth) self.vna.trace.set(self.measuredtrace) self.vna.auto_sweep.set(False) from qcodes import Station station = Station() station.add_component(self.vna) # import pdb; pdb.set_trace() meas = Measurement(station=station) # qcodes measurement # vna.groupdelay.set(groupdelayref) #does not work yet meas = Measurement() # register the first independent parameter meas.register_parameter(self.vna.power) # register the second independent parameter meas.register_parameter(self.vna.real, setpoints=(self.vna.power, )) # ^ (? Why would vna.real be an independent parameter?) Does it not get measured (dependent) as a function of freq? meas.register_parameter( self.vna.imaginary, setpoints=(self.vna.power, )) # now register the dependent one meas.register_parameter( self.vna.phase, setpoints=(self.vna.power, )) # now register the dependent one meas.register_parameter( self.vna.magnitude, setpoints=(self.vna.power, )) # now register the dependent one # -- taking data with meas.run() as datasaver: for v1 in np.linspace(self.powersweepstart, self.powersweepstop, self.num_power_points, endpoint=True): self.vna.active_trace.set(1) power = self.vna.power.set(v1) print(self.vna.power.get()) # check # vna.auto_sweep.set(False) # vna.auto_sweep.set(True) # some bug not taking the last row therefore two sweeps self.vna.traces.tr1.run_sweep() # power=vna.power() # vna.auto_sweep.set(False) imag = self.vna.imaginary() real = self.vna.real() phase = self.vna.phase() mag = self.vna.magnitude() # vna.active_trace.set(2) # vna.traces.tr2.run_sweep() power = self.vna.power( ) # should still be the same as a few lines above # time.sleep(2) datasaver.add_result( (self.vna.magnitude, mag), (self.vna.phase, phase), (self.vna.real, real), (self.vna.imaginary, imag), (self.vna.power, power)) print(self.vna.power.get()) plot_by_id(datasaver.run_id) pd = datasaver.dataset.get_parameter_data() # import pdb; pdb.set_trace() # noqa BREAKPOINT magnitude_table = np.vstack( (np.ravel(pd[self.vna_name + "_tr1_magnitude"][self.vna_name + "_power"]), np.ravel(pd[self.vna_name + "_tr1_magnitude"][self.vna_name + "_tr1_frequency"]), np.ravel(pd[self.vna_name + "_tr1_magnitude"][self.vna_name + "_tr1_magnitude"]))) phase_table = np.vstack( (np.ravel(pd[self.vna_name + "_tr1_phase"][self.vna_name + "_power"]), np.ravel(pd[self.vna_name + "_tr1_phase"][self.vna_name + "_tr1_frequency"]), np.ravel(pd[self.vna_name + "_tr1_phase"][self.vna_name + "_tr1_phase"]))) real_table = np.vstack( (np.ravel(pd[self.vna_name + "_tr1_real"][self.vna_name + "_power"]), np.ravel(pd[self.vna_name + "_tr1_real"][self.vna_name + "_tr1_frequency"]), np.ravel(pd[self.vna_name + "_tr1_real"][self.vna_name + "_tr1_real"]))) imaginary_table = np.vstack( (np.ravel(pd[self.vna_name + "_tr1_imaginary"][self.vna_name + "_power"]), np.ravel(pd[self.vna_name + "_tr1_imaginary"][self.vna_name + "_tr1_frequency"]), np.ravel(pd[self.vna_name + "_tr1_imaginary"][self.vna_name + "_tr1_imaginary"]))) np.savetxt( os.path.join( self.raw_path_with_date, str(datasaver.run_id) + '_powersweep' + '_' + str(self.exp_name) + '_magnitude.txt'), magnitude_table) np.savetxt( os.path.join( self.raw_path_with_date, str(datasaver.run_id) + '_powersweep' + '_' + str(self.exp_name) + '_phase.txt'), phase_table) np.savetxt( os.path.join( self.raw_path_with_date, str(datasaver.run_id) + '_powersweep' + '_' + str(self.exp_name) + '_real.txt'), real_table) np.savetxt( os.path.join( self.raw_path_with_date, str(datasaver.run_id) + '_powersweep' + '_' + str(self.exp_name) + '_imaginary.txt'), imaginary_table)
def import_json(cls, json_dict, station=Station()): """ Loads previously exported Station setup. Reassigns all dictionary values exported as JSON to their appropriate objects. """ def load_parameter(name, instr_name, instr_type, station): if instr_name in station.components.keys(): if isinstance(station.components[instr_name], instr_type): return station.components[instr_name].parameters[name] for i_name, instr in station.components.items(): if isinstance(instr, instr_type): return instr.parameters[name] sweep_class = json_dict['class'] sweep_module = json_dict['module'] if 'Sweep1D' in sweep_class: sp = json_dict['set_param'] module = importlib.import_module(sweep_module) sc = getattr(module, sweep_class) instr_module = importlib.import_module(sp['instr_module']) instrument = getattr(instr_module, sp['instr_class']) set_param = load_parameter(sp['param'], sp['instr_name'], instrument, station) sweep = sc(set_param, sp['start'], sp['stop'], sp['step'], **json_dict['attributes']) elif 'Sweep0D' in sweep_class: module = importlib.import_module(sweep_module) sc = getattr(module, sweep_class) sweep = sc(**json_dict['attributes']) elif 'Sweep2D' in sweep_class: module = importlib.import_module(sweep_module) sc = getattr(module, sweep_class) in_param = json_dict['inner_sweep'] in_instr_module = importlib.import_module(in_param['instr_module']) in_instrument = getattr(in_instr_module, in_param['instr_class']) inner_param = load_parameter(in_param['param'], in_param['instr_name'], in_instrument, station) out_param = json_dict['outer_sweep'] out_instr_module = importlib.import_module(out_param['instr_module']) out_instrument = getattr(out_instr_module, out_param['instr_class']) outer_param = load_parameter(out_param['param'], out_param['instr_name'], out_instrument, station) inner_list = [inner_param, in_param['start'], in_param['stop'], in_param['step']] outer_list = [outer_param, out_param['start'], out_param['stop'], out_param['step']] sweep = sc(inner_list, outer_list, **json_dict['attributes']) elif 'SimulSweep' in sweep_class: module = importlib.import_module(sweep_module) sc = getattr(module, sweep_class) set_params_dict = {} for p, items in json_dict['set_params'].items(): instr_module = importlib.import_module(items['instr_module']) instrument = getattr(instr_module, items['instr_class']) param = load_parameter(p, items['instr_name'], instrument, station) set_params_dict[param] = {} set_params_dict[param]['start'] = items['start'] set_params_dict[param]['stop'] = items['stop'] set_params_dict[param]['step'] = items['step'] sweep = sc(set_params_dict, **json_dict['attributes']) else: return for p, instr in json_dict['follow_params'].items(): instr_module = importlib.import_module(instr[1]) instrument = getattr(instr_module, instr[2]) param = load_parameter(p, instr[0], instrument, station) sweep.follow_param(param) return sweep
for record in records: plot.plot(record.set_arrays[0].flatten(), record.flatten(), color=next(color_cycler), label=record.name) plot.legend(loc='upper right') plot.draw() plot.pause(0.001) # CREATE THE SCOPE READER AND STATION device_id = 'dev2338' scope_reader = UHFLIScopeReader(device_id) uhfli = scope_reader.adapter.instrument station = Station(uhfli, update_snapshot=False) # INITIALIZE THE SCOPE READER file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'uhfli.dat') configuration = load_configuration(file_path) scope_reader.initialize(configuration) # PREPARE THE SCOPE FOR READOUT scope_reader.number_of_averages = 1 scope_reader.input_range = (0.5, 1.0) scope_reader.sample_rate = 450e6 scope_reader.period = 1e-5
# -*- coding: utf-8 -*- #%% imports import inspect import numpy as np from qcodes import Station, Instrument from qcodes.utils import validators from instrumentserver import QtWidgets from instrumentserver.serialize import (saveParamsToFile, loadParamsFromFile, toParamDict, fromParamDict) from instrumentserver.gui import widgetDialog from instrumentserver.params import ParameterManager from instrumentserver.gui.instruments import ParameterManagerGui from instrumentserver.client import Client, ProxyInstrument #%% run the PM locally Instrument.close_all() pm = ParameterManager('pm') station = Station() station.add_component(pm) dialog = widgetDialog(ParameterManagerGui(pm)) #%% instantiate PM in the server. Instrument.close_all() cli = Client() pm = ProxyInstrument('pm', cli=cli, remotePath='pm') dialog = widgetDialog(ParameterManagerGui(pm))
def generate_DB_file_with_runs_and_snapshots(): """ Generate a .db-file with a handful of runs some of which have snapshots. Generated runs: #1: run with a snapshot that has some content #2: run with a snapshot of an empty station #3: run without a snapshot """ v4fixturepath = os.path.join(utils.fixturepath, 'version4') os.makedirs(v4fixturepath, exist_ok=True) path = os.path.join(v4fixturepath, 'with_runs_and_snapshots.db') if os.path.exists(path): os.remove(path) from qcodes.dataset.sqlite_base import is_column_in_table from qcodes.dataset.measurements import Measurement from qcodes.dataset.experiment_container import Experiment from qcodes import Parameter, Station from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies exp = Experiment(path_to_db=path, name='experiment_1', sample_name='no_sample_1') conn = exp.conn # Now make some parameters to use in measurements params = [] for n in range(4): params.append(Parameter(f'p{n}', label=f'Parameter {n}', unit=f'unit {n}', set_cmd=None, get_cmd=None)) # We are going to make 3 runs run_ids = [] # Make a run with a snapshot with some content full_station = Station(*params[0:1], default=False) assert Station.default is None meas = Measurement(exp, full_station) meas.register_parameter(params[0]) meas.register_parameter(params[1]) meas.register_parameter(params[2], basis=(params[1],)) meas.register_parameter(params[3], setpoints=(params[1], params[2])) with meas.run() as datasaver: for x in np.random.rand(4): for y in np.random.rand(4): z = np.random.rand() datasaver.add_result((params[1], x), (params[2], y), (params[3], z)) run_ids.append(datasaver.run_id) # Make a run with a snapshot of empty station empty_station = Station(default=False) assert Station.default is None meas = Measurement(exp, empty_station) meas.register_parameter(params[0]) meas.register_parameter(params[1]) meas.register_parameter(params[2]) meas.register_parameter(params[3], setpoints=(params[1], params[2])) with meas.run() as datasaver: for x in np.random.rand(4): for y in np.random.rand(4): z = np.random.rand() datasaver.add_result((params[1], x), (params[2], y), (params[3], z)) run_ids.append(datasaver.run_id) # Make a run without a snapshot (i.e. station is None) assert Station.default is None meas = Measurement(exp) meas.register_parameter(params[0]) meas.register_parameter(params[1]) meas.register_parameter(params[2], basis=(params[1],)) meas.register_parameter(params[3], setpoints=(params[1], params[2])) with meas.run() as datasaver: for x in np.random.rand(4): for y in np.random.rand(4): z = np.random.rand() datasaver.add_result((params[1], x), (params[2], y), (params[3], z)) run_ids.append(datasaver.run_id) # Check correctness of run_id's assert [1, 2, 3] == run_ids, 'Run ids of generated runs are not as ' \ 'expected after generating runs #1-3' # Ensure snapshot column assert is_column_in_table(conn, 'runs', 'snapshot')
class StationServer(QtCore.QObject): """The main server object. Encapsulated in a separate object so we can run it in a separate thread. """ # we use this to quit the server. # if this string is sent as message to the server, it'll shut down and close # the socket. Should only be used from within this module. # it's randomized in the instantiated server for a little bit of safety. SAFEWORD = 'BANANA' #: Signal(str, str) -- emit messages for display in the gui (or other stuff the gui #: wants to do with it. #: Arguments: the message received, and the reply sent. messageReceived = QtCore.Signal(str, str) #: Signal(int) -- emitted when the server is started. #: Arguments: the port. serverStarted = QtCore.Signal(str) #: Signal() -- emitted when we shut down finished = QtCore.Signal() #: Signal(Dict) -- emitted when a new instrument was created. #: Argument is the blueprint of the instrument instrumentCreated = QtCore.Signal(object) #: Signal(str, Any) -- emitted when a parameter was set #: Arguments: full parameter location as string, value parameterSet = QtCore.Signal(str, object) #: Signal(str, Any) -- emitted when a parameter was retrieved #: Arguments: full parameter location as string, value parameterGet = QtCore.Signal(str, object) #: Signal(str, List[Any], Dict[str, Any], Any) -- emitted when a function was called #: Arguments: full function location as string, arguments, kw arguments, return value funcCalled = QtCore.Signal(str, object, object, object) def __init__(self, parent=None, port=5555, allowUserShutdown=False): # , publisher_port=5554): super().__init__(parent) self.SAFEWORD = ''.join( random.choices([chr(i) for i in range(65, 91)], k=16)) self.serverRunning = False self.port = port self.station = Station() self.allowUserShutdown = allowUserShutdown # self.publisher_port = publisher_port self.parameterSet.connect( lambda n, v: logger.info(f"Parameter '{n}' set to: {str(v)}")) self.parameterGet.connect( lambda n, v: logger.debug(f"Parameter '{n}' retrieved: {str(v)}")) self.funcCalled.connect( lambda n, args, kw, ret: logger.debug(f"Function called:" f"'{n}', args: {str(args)}, " f"kwargs: {str(kw)})'.")) @QtCore.Slot() def startServer(self): """Start the server. This function does not return until the ZMQ server has been shut down.""" addr = f"tcp://*:{self.port}" logger.info(f"Starting server at {addr}") logger.info(f"The safe word is: {self.SAFEWORD}") context = zmq.Context() socket = context.socket(zmq.REP) socket.bind(addr) #creating and binding publishing socket # publisher_addr = f"tcp://*:{self.publisher_port}" # publisher_socket = context.socket(zmq.PUB) # publisher_socket.bind(publisher_addr) self.serverRunning = True self.serverStarted.emit(addr) while self.serverRunning: message = recv(socket) message_ok = True response_to_client = None response_log = None # allow the test client from within the same process to make sure the # server shuts down. This is if message == self.SAFEWORD: response_log = 'Server has received the safeword and will shut down.' response_to_client = ServerResponse(message=response_log) self.serverRunning = False logger.warning(response_log) elif self.allowUserShutdown and message == 'SHUTDOWN': response_log = 'Server shutdown requested by client.' response_to_client = ServerResponse(message=response_log) self.serverRunning = False logger.warning(response_log) # if the message is a string we just echo it back. # this is used for testing sometimes, but has no functionality. elif isinstance(message, str): response_log = f"Server has received: {message}. No further action." response_to_client = ServerResponse(message=response_log) logger.info(response_log) # we assume this is a valid instruction set now. elif isinstance(message, ServerInstruction): instruction = message try: instruction.validate() logger.info(f"Received request for operation: " f"{str(instruction.operation)}") logger.debug(f"Instruction received: " f"{str(instruction)}") except Exception as e: message_ok = False response_log = f'Received invalid message. Error raised: {str(e)}' response_to_client = ServerResponse(message=None, error=e) logger.warning(response_log) if message_ok: # we don't need to use a try-block here, because # errors are already handled in executeServerInstruction response_to_client = self.executeServerInstruction( instruction) response_log = f"Response to client: {str(response_to_client)}" if response_to_client.error is None: logger.info(f"Response sent to client.") logger.debug(response_log) else: logger.warning(response_log) else: response_log = f"Invalid message type." response_to_client = ServerResponse(message=None, error=response_log) logger.warning(f"Invalid message type: {type(message)}.") logger.debug(f"Invalid message received: {str(message)}") send(socket, response_to_client) # print("sending message") # publisher_socket.send_string("Anyone copy?") self.messageReceived.emit(str(message), response_log) # publisher_socket.close() socket.close() self.finished.emit() return True def executeServerInstruction(self, instruction: ServerInstruction) \ -> ServerResponse: """ This is the interpreter function that the server will call to translate the dictionary received from the proxy to instrument calls. :param instruction: The instruction object. :returns: the results returned from performing the operation. """ args = [] kwargs = {} # we call a helper function depending on the operation that is requested if instruction.operation == Operation.get_existing_instruments: func = self._getExistingInstruments elif instruction.operation == Operation.create_instrument: func = self._createInstrument args = [instruction.create_instrument_spec] elif instruction.operation == Operation.call: func = self._callObject args = [instruction.call_spec] elif instruction.operation == Operation.get_blueprint: func = self._getBluePrint args = [instruction.requested_path] elif instruction.operation == Operation.get_param_dict: func = self._toParamDict args = [instruction.serialization_opts] elif instruction.operation == Operation.set_params: func = self._fromParamDict args = [instruction.set_parameters] else: raise NotImplementedError try: returns = func(*args, **kwargs) response = ServerResponse(message=returns) except Exception as err: response = ServerResponse(message=None, error=err) return response def _getExistingInstruments(self) -> Dict: """ Get the existing instruments in the station, :returns : a dictionary that contains the instrument name and its class name. """ comps = self.station.components info = {k: v.__class__ for k, v in comps.items()} return info def _createInstrument(self, spec: InstrumentCreationSpec) -> None: """Create a new instrument on the server""" sep_class = spec.instrument_class.split('.') modName = '.'.join(sep_class[:-1]) clsName = sep_class[-1] mod = importlib.import_module(modName) cls = getattr(mod, clsName) args = [] if spec.args is None else spec.args kwargs = dict() if spec.kwargs is None else spec.kwargs new_instrument = qc.find_or_create_instrument(cls, name=spec.name, *args, **kwargs) if new_instrument.name not in self.station.components: self.station.add_component(new_instrument) self.instrumentCreated.emit( bluePrintFromInstrumentModule(new_instrument.name, new_instrument)) def _callObject(self, spec: CallSpec) -> Any: """call some callable found in the station.""" obj = nestedAttributeFromString(self.station, spec.target) args = spec.args if spec.args is not None else [] kwargs = spec.kwargs if spec.kwargs is not None else {} ret = obj(*args, **kwargs) if isinstance(obj, Parameter): if len(args) > 0: self.parameterSet.emit(spec.target, args[0]) else: self.parameterGet.emit(spec.target, ret) else: self.funcCalled.emit(spec.target, args, kwargs, ret) return ret def _getBluePrint( self, path: str ) -> Union[InstrumentModuleBluePrint, ParameterBluePrint, MethodBluePrint]: obj = nestedAttributeFromString(self.station, path) if isinstance(obj, tuple(INSTRUMENT_MODULE_BASE_CLASSES)): return bluePrintFromInstrumentModule(path, obj) elif isinstance(obj, tuple(PARAMETER_BASE_CLASSES)): return bluePrintFromParameter(path, obj) elif callable(obj): return bluePrintFromMethod(path, obj) else: raise ValueError(f'Cannot create a blueprint for {type(obj)}') def _toParamDict(self, opts: ParameterSerializeSpec) -> Dict[str, Any]: if opts.path is None: obj = self.station else: obj = [nestedAttributeFromString(self.station, opts.path)] includeMeta = [k for k in opts.attrs if k != 'value'] return serialize.toParamDict(obj, *opts.args, includeMeta=includeMeta, **opts.kwargs) def _fromParamDict(self, params: Dict[str, Any]): return serialize.fromParamDict(params, self.station)
stimulus = UHFLIStimulus(device_id) # Setup the UHFLIStimulus demodulator = 1 demod_channel = 1 output_amplitude = 0.3 output_channel = 1 demodulation_parameter = 'R' # 'phi', 'x' or 'y' also possible stimulus.set_signal_output_amplitude(demod_channel, demodulator, output_amplitude) stimulus.set_demodulation_enabled(demod_channel, True) stimulus.set_signal_output_enabled(demod_channel, demodulator, True) stimulus.set_output_enabled(output_channel, True) # Setup Station and scanjob station = Station() station.gates = FakeGates() scanjob = qtt.measurements.scans.scanjob_t() scanjob.add_sweep(param=stimulus.set_oscillator_frequency(demod_channel), start=150e6, end=195e6, step=.2e6) scanjob.add_minstrument( scope_reader.acquire_single_sample(demod_channel, demodulation_parameter, partial=True)) # Scan and plot ds = qtt.measurements.scans.scan1D(station, scanjob) set_points_name = 'oscillator{}_freq'.format(demod_channel) data_points_name = 'demod{}_{}'.format(demod_channel, demodulation_parameter)
osc.ch3.connect_inst(circuit) osc.ch1.t_start.set(-10) osc.ch1.t_stop.set(10) osc.ch2.t_start.set(-10) osc.ch2.t_stop.set(10) osc.ch3.t_start.set(-10) osc.ch3.t_stop.set(10) osc.ch4.t_start.set(-10) osc.ch4.t_stop.set(10) amp = 1 PSG1.amp(amp) PSG2.amp(amp) station = Station() station.snapshot() station.add_component(osc) # Criar um database initialise_or_create_database_at("~/teste.db") exp = load_or_create_experiment(experiment_name='osc realtime intro 2', sample_name="osc realtime 1") def calculateGain(): Y = osc.ch3.wavesample() n_mean = int(len(Y) / 2) value = 2 * np.mean(Y[n_mean:])