This page was generated from docs/examples/basic_examples/Configuring_QCoDeS.ipynb. Interactive online version: Binder badge.

QCoDeS config

The QCoDeS config module uses JSON files to store QCoDeS configuration modeled after the module structure with some high-level switches.

The config file controls various options to QCoDeS such as the default path and name of the database in which your data is stored and logging level of the debug output. QCoDeS is shipped with a default configuration. As we describe below, you may overwrite these default values to customize QCoDeS for your nanoelectronics research.

You may want to do something as simple as changing the default path of your database to something complex as including your own configuration variables. In this example notebook, we will explore some of the configuration variables, demonstrate how configuration values may be changed at runtime and saved to files, and explore using custom configuration values to suit your own needs.

QCoDeS loads both the defaults and the active configuration at the module import so that you can directly inspect them

[1]:
import qcodes as qc
Logging hadn't been started.
Activating auto-logging. Current session state plus future input saved.
Filename       : /home/runner/.qcodes/logs/command_history.log
Mode           : append
Output logging : True
Raw input log  : False
Timestamping   : True
State          : active
Qcodes Logfile : /home/runner/.qcodes/logs/241008-6854-qcodes.log
[2]:
qc.config.current_config
[2]:
{'core': {'default_fmt': 'data/{date}/#{counter}_{name}_{time}',
  'register_magic': False,
  'import_legacy_api': False,
  'db_location': '~/experiments.db',
  'db_debug': False,
  'loglevel': 'WARNING',
  'file_loglevel': 'INFO'},
 'logger': {'start_logging_on_import': 'always',
  'console_level': 'WARNING',
  'file_level': 'INFO',
  'logger_levels': {'pyvisa': 'INFO'}},
 'subscription': {'subscribers': {'QCPlot': {'factory': 'qcplotutils.qcodes_dataset.QCPlotDatasetSubscriber',
    'factory_kwargs': {'log': False},
    'subscription_kwargs': {'min_wait': 0,
     'min_count': 1,
     'callback_kwargs': {}}}},
  'default_subscribers': []},
 'gui': {'notebook': True,
  'plotlib': None,
  'pyqtmaxplots': 100,
  'defaultcolormap': 'hot'},
 'plotting': {'default_color_map': 'viridis',
  'rasterize_threshold': 5000,
  'auto_color_scale': {'enabled': False,
   'cutoff_percentile': [0.5, 0.5],
   'color_over': '#a1c4fc',
   'color_under': '#017000'}},
 'user': {'scriptfolder': '.', 'mainfolder': '.'},
 'station': {'enable_forced_reconnect': False,
  'default_folder': '.',
  'default_file': None,
  'use_monitor': False},
 'GUID_components': {'GUID_type': 'random_sample',
  'location': 0,
  'work_station': 0,
  'sample': 0},
 'dataset': {'write_in_background': False,
  'write_period': 5.0,
  'use_threads': False,
  'dond_plot': False,
  'dond_show_progress': False,
  'callback_percent': 5.0,
  'export_automatic': False,
  'export_type': None,
  'export_prefix': 'qcodes_',
  'export_path': '{db_location}',
  'export_name_elements': ['captured_run_id', 'guid'],
  'export_chunked_export_of_large_files_enabled': False,
  'export_chunked_threshold': 1000,
  'in_memory_cache': True,
  'load_from_exported_file': False},
 'telemetry': {'enabled': False,
  'instrumentation_key': '00000000-0000-0000-0000-000000000000'}}

The current config is build from multiple config files.

The config files are read in the following order:

  • Package defaults

  • User’s home directory

  • QCODES_CONFIG environment variable

  • Current working directory

Meaning that any value set in a config file in the package default is overwritten by the same value in the users home dir and so on.

Note: A change in the configuration requires reimporting the package, or restarting the notebook kernel.

[3]:
qc.config.defaults
[3]:
{'core': {'default_fmt': 'data/{date}/#{counter}_{name}_{time}',
  'register_magic': False,
  'import_legacy_api': False,
  'db_location': '~/experiments.db',
  'db_debug': False,
  'loglevel': 'WARNING',
  'file_loglevel': 'INFO'},
 'logger': {'start_logging_on_import': 'if_telemetry_set_up',
  'console_level': 'WARNING',
  'file_level': 'INFO',
  'logger_levels': {'pyvisa': 'INFO'}},
 'subscription': {'subscribers': {'QCPlot': {'factory': 'qcplotutils.qcodes_dataset.QCPlotDatasetSubscriber',
    'factory_kwargs': {'log': False},
    'subscription_kwargs': {'min_wait': 0,
     'min_count': 1,
     'callback_kwargs': {}}}},
  'default_subscribers': []},
 'gui': {'notebook': True,
  'plotlib': None,
  'pyqtmaxplots': 100,
  'defaultcolormap': 'hot'},
 'plotting': {'default_color_map': 'viridis',
  'rasterize_threshold': 5000,
  'auto_color_scale': {'enabled': False,
   'cutoff_percentile': [0.5, 0.5],
   'color_over': '#a1c4fc',
   'color_under': '#017000'}},
 'user': {'scriptfolder': '.', 'mainfolder': '.'},
 'station': {'enable_forced_reconnect': False,
  'default_folder': '.',
  'default_file': None,
  'use_monitor': False},
 'GUID_components': {'GUID_type': 'random_sample',
  'location': 0,
  'work_station': 0,
  'sample': 0},
 'dataset': {'write_in_background': False,
  'write_period': 5.0,
  'use_threads': False,
  'dond_plot': False,
  'dond_show_progress': False,
  'callback_percent': 5.0,
  'export_automatic': False,
  'export_type': None,
  'export_prefix': 'qcodes_',
  'export_path': '{db_location}',
  'export_name_elements': ['captured_run_id', 'guid'],
  'export_chunked_export_of_large_files_enabled': False,
  'export_chunked_threshold': 1000,
  'in_memory_cache': True,
  'load_from_exported_file': False},
 'telemetry': {'enabled': False,
  'instrumentation_key': '00000000-0000-0000-0000-000000000000'}}

One can inspect what the configuration options mean at runtime

[4]:
print(qc.config.describe("core"))
controls core settings of qcodes.
Current value: {'default_fmt': 'data/{date}/#{counter}_{name}_{time}', 'register_magic': False, 'import_legacy_api': False, 'db_location': '~/experiments.db', 'db_debug': False, 'loglevel': 'WARNING', 'file_loglevel': 'INFO'}. Type: object. Default: Not defined.

The default configuration is explained in more detail in the api docs

Configuring QCoDeS

Defaults are the settings that are shipped with the package, which you can overwrite programmatically.

A way to customize QCoDeS is to write your own JSON files, they are expected to be in the directories printed below and documented above. One will be empty because one needs to define first the environment variable in the OS.

They are ordered by “weight”, meaning that the last file always wins if it’s overwriting any preconfigured defaults or values in the other files.

Simply copy the file to the directories and you are good to go.

[5]:
print(
    "\n".join(
        [qc.config.home_file_name, qc.config.env_file_name, qc.config.cwd_file_name]
    )
)
/home/runner/qcodesrc.json

/home/runner/work/Qcodes/Qcodes/docs/examples/basic_examples/qcodesrc.json

The easiest way to add something to the configuration is to use the provided helper:

[6]:
qc.config.add(
    "base_location",
    "/dev/random",
    value_type="string",
    description="Location of data",
    default="/dev/random",
)

This will add a base_location with value /dev/random to the current configuration, and validate it’s value to be of type string, will also set the description and what one would want to have as default. The new entry is saved in the ‘user’ part of the configuration.

[7]:
print(qc.config.describe("user.base_location"))
Location of data.
Current value: /dev/random. Type: string. Default: /dev/random.

You can also manually update the configuration from a specific file by supplying the path of the directory as the argument of qc.config.update_config method as follows:

[8]:
qc.config.update_config(path="C:\\Users\\jenielse\\")
[8]:
{'core': {'default_fmt': 'data/{date}/#{counter}_{name}_{time}',
  'register_magic': False,
  'import_legacy_api': False,
  'db_location': '~/experiments.db',
  'db_debug': False,
  'loglevel': 'WARNING',
  'file_loglevel': 'INFO'},
 'logger': {'start_logging_on_import': 'always',
  'console_level': 'WARNING',
  'file_level': 'INFO',
  'logger_levels': {'pyvisa': 'INFO'}},
 'subscription': {'subscribers': {'QCPlot': {'factory': 'qcplotutils.qcodes_dataset.QCPlotDatasetSubscriber',
    'factory_kwargs': {'log': False},
    'subscription_kwargs': {'min_wait': 0,
     'min_count': 1,
     'callback_kwargs': {}}}},
  'default_subscribers': []},
 'gui': {'notebook': True,
  'plotlib': None,
  'pyqtmaxplots': 100,
  'defaultcolormap': 'hot'},
 'plotting': {'default_color_map': 'viridis',
  'rasterize_threshold': 5000,
  'auto_color_scale': {'enabled': False,
   'cutoff_percentile': [0.5, 0.5],
   'color_over': '#a1c4fc',
   'color_under': '#017000'}},
 'user': {'scriptfolder': '.', 'mainfolder': '.'},
 'station': {'enable_forced_reconnect': False,
  'default_folder': '.',
  'default_file': None,
  'use_monitor': False},
 'GUID_components': {'GUID_type': 'random_sample',
  'location': 0,
  'work_station': 0,
  'sample': 0},
 'dataset': {'write_in_background': False,
  'write_period': 5.0,
  'use_threads': False,
  'dond_plot': False,
  'dond_show_progress': False,
  'callback_percent': 5.0,
  'export_automatic': False,
  'export_type': None,
  'export_prefix': 'qcodes_',
  'export_path': '{db_location}',
  'export_name_elements': ['captured_run_id', 'guid'],
  'export_chunked_export_of_large_files_enabled': False,
  'export_chunked_threshold': 1000,
  'in_memory_cache': True,
  'load_from_exported_file': False},
 'telemetry': {'enabled': False,
  'instrumentation_key': '00000000-0000-0000-0000-000000000000'}}

Saving changes

All the changes made to the defaults are stored, and one can then decide to save them to the desired location.

[9]:
help(qc.config.save_to_cwd)
Help on method save_to_cwd in module qcodes.configuration.config:

save_to_cwd() -> 'None' method of qcodes.configuration.config.Config instance
    Save config and schema to files in current working dir

[10]:
help(qc.config.save_to_env)
Help on method save_to_env in module qcodes.configuration.config:

save_to_env() -> 'None' method of qcodes.configuration.config.Config instance
    Save config and schema to files in path specified in env variable

[11]:
help(qc.config.save_to_home)
Help on method save_to_home in module qcodes.configuration.config:

save_to_home() -> 'None' method of qcodes.configuration.config.Config instance
    Save config and schema to files in home dir

Using custom variables in your experiment:

Simply get the value you have set before with dot notation. For example:

[12]:
qc.config.add(
    "base_location",
    "/dev/random",
    value_type="string",
    description="Location of data",
    default="/dev/random",
)

qc.config.current_config
[12]:
{'core': {'default_fmt': 'data/{date}/#{counter}_{name}_{time}',
  'register_magic': False,
  'import_legacy_api': False,
  'db_location': '~/experiments.db',
  'db_debug': False,
  'loglevel': 'WARNING',
  'file_loglevel': 'INFO'},
 'logger': {'start_logging_on_import': 'always',
  'console_level': 'WARNING',
  'file_level': 'INFO',
  'logger_levels': {'pyvisa': 'INFO'}},
 'subscription': {'subscribers': {'QCPlot': {'factory': 'qcplotutils.qcodes_dataset.QCPlotDatasetSubscriber',
    'factory_kwargs': {'log': False},
    'subscription_kwargs': {'min_wait': 0,
     'min_count': 1,
     'callback_kwargs': {}}}},
  'default_subscribers': []},
 'gui': {'notebook': True,
  'plotlib': None,
  'pyqtmaxplots': 100,
  'defaultcolormap': 'hot'},
 'plotting': {'default_color_map': 'viridis',
  'rasterize_threshold': 5000,
  'auto_color_scale': {'enabled': False,
   'cutoff_percentile': [0.5, 0.5],
   'color_over': '#a1c4fc',
   'color_under': '#017000'}},
 'user': {'scriptfolder': '.',
  'mainfolder': '.',
  'base_location': '/dev/random'},
 'station': {'enable_forced_reconnect': False,
  'default_folder': '.',
  'default_file': None,
  'use_monitor': False},
 'GUID_components': {'GUID_type': 'random_sample',
  'location': 0,
  'work_station': 0,
  'sample': 0},
 'dataset': {'write_in_background': False,
  'write_period': 5.0,
  'use_threads': False,
  'dond_plot': False,
  'dond_show_progress': False,
  'callback_percent': 5.0,
  'export_automatic': False,
  'export_type': None,
  'export_prefix': 'qcodes_',
  'export_path': '{db_location}',
  'export_name_elements': ['captured_run_id', 'guid'],
  'export_chunked_export_of_large_files_enabled': False,
  'export_chunked_threshold': 1000,
  'in_memory_cache': True,
  'load_from_exported_file': False},
 'telemetry': {'enabled': False,
  'instrumentation_key': '00000000-0000-0000-0000-000000000000'}}

Changing core values

One can change the core values at runtime, but there is no guarantee that they are going to be valid. Since user configuration shadows the default one that comes with QCoDeS, apply care when changing the values under core section. This section is, primarily, meant for the settings that are determined by QCoDeS core developers.

[13]:
qc.config.current_config.core.loglevel = "INFO"

But one can manually validate via

[14]:
qc.config.validate()

Which will raise an exception in case of bad inputs

[15]:
qc.config.current_config.core.loglevel = "YOLO"
qc.config.validate()
# NOTE that you how have a broken config!
---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Cell In[15], line 2
      1 qc.config.current_config.core.loglevel = "YOLO"
----> 2 qc.config.validate()
      3 # NOTE that you how have a broken config!

File /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/qcodes/configuration/config.py:220, in Config.validate(self, json_config, schema, extra_schema_path)
    217     else:
    218         logger.warning(EMPTY_USER_SCHEMA.format(extra_schema_path))
--> 220 jsonschema.validate(json_config, schema)

File /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/jsonschema/validators.py:1332, in validate(instance, schema, cls, *args, **kwargs)
   1330 error = exceptions.best_match(validator.iter_errors(instance))
   1331 if error is not None:
-> 1332     raise error

ValidationError: 'YOLO' is not one of ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG']

Failed validating 'enum' in schema['properties']['core']['properties']['loglevel']:
    {'type': 'string',
     'description': 'deprecated - use logger.console_level',
     'default': 'DEBUG',
     'enum': ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG']}

On instance['core']['loglevel']:
    'YOLO'
[ ]: