.. _arguments: Arguments ========= Experiments and blocks in Atomiq define their arguments via a class-level ``arguments`` dictionary. Each entry in this dictionary defines one argument with a set of keywords that control its type, appearance in the dashboard, and scanning behavior. Basic syntax ------------ .. code-block:: python class MyExperiment(AtomiqExperiment): arguments = { "my_argument": {"default": 1.0, "unit": "V", "scale": 1, "precision": 3}, } The ``default`` keyword is **required** for every argument. The type of the default value determines the argument type: - ``bool`` → Boolean switch (non-scannable) - ``str`` → String input (non-scannable) - ``int`` or ``float`` → Numeric argument (scannable by default, see below) Available keywords ------------------ .. list-table:: :header-rows: 1 :widths: 15 15 70 * - Keyword - Applies to - Description * - ``default`` - All - **Required.** The default value. The Python type determines the argument type (see above). * - ``unit`` - Numeric - Physical unit string displayed in the dashboard (e.g. ``"us"``, ``"MHz"``, ``"V"``, ``"mW"``, ``"G"``). * - ``scale`` - Numeric - Scale factor. The value shown in the dashboard is ``value * scale``. Default: ``1``. * - ``precision`` - Numeric - Number of decimal places shown in the dashboard. Default: chosen automatically based on ``scale``. * - ``ndecimals`` - Numeric - Alias for ``precision``. * - ``step`` - Scannable - Step size for scanning. Default: ``1`` (in scaled units). * - ``min`` - Non-scannable numeric - Minimum allowed value. * - ``max`` - Non-scannable numeric - Maximum allowed value. * - ``type`` - Numeric - Set to ``"int"`` (or ``int``) to make a non-scannable integer argument. * - ``scannable`` - Numeric - Set to ``False`` to make a float argument non-scannable. * - ``options`` - Enumeration - List of allowed values. Creates a dropdown in the dashboard. If ``default`` is not given, the first option is used. * - ``group`` - All - Group name for organizing arguments in the dashboard. Arguments with the same group are displayed together. Default: the experiment/block name. Scannable vs. non-scannable arguments ------------------------------------- By default, numeric (``float``) arguments are **scannable**. To make a numeric argument non-scannable, use one of the following: .. code-block:: python arguments = { # Non-scannable float "voltage": {"default": 1.5, "unit": "V", "scannable": False}, # Non-scannable float (alternative: integer step + zero precision + scale 1) "count": {"default": 5, "step": 1, "precision": 0, "scale": 1}, } Enumeration arguments --------------------- Use the ``options`` keyword to create a dropdown selection: .. code-block:: python arguments = { "ramp_mode": {"options": ["fast", "slow", "custom"], "default": "fast"}, } Grouping arguments ------------------ Use the ``group`` keyword to organize arguments into collapsible groups in the dashboard: .. code-block:: python arguments = { "cooling_time": {"default": 5e-6, "unit": "us", "group": "Cooling"}, "cooling_power": {"default": 0.3, "group": "Cooling"}, "imaging_time": {"default": 100e-6, "unit": "us", "group": "Imaging"}, } Custom argument providers ------------------------- By default, Atomiq uses the :py:class:`~atomiq.arguments.NativeArgumentProvider` which reads arguments from the class-level ``arguments`` dictionary. You can replace this with a custom provider to load arguments from external sources like JSON files, databases, or HEROs. Set the provider globally: .. code-block:: python from atomiq import AtomiqExperiment from atomiq.arguments import ArgumentProvider class MyArgumentProvider(ArgumentProvider): def _build_arguments(self, target_class, arguments=None): if arguments is None: arguments = {} if hasattr(target_class, "arguments"): arguments.update(target_class.arguments) # ... load additional arguments from your source return arguments AtomiqExperiment.arg_provider = MyArgumentProvider() Or set it per class: .. code-block:: python class MyExperiment(AtomiqExperiment): arg_provider = MyArgumentProvider() ... Atomiq also ships with a :py:class:`~atomiq.arguments.json.JSONArgumentProvider` that loads arguments from a JSON file or URL (e.g. a CouchDB document): .. code-block:: python from atomiq.arguments.json import JSONArgumentProvider class MyExperiment(AtomiqExperiment): arg_provider = JSONArgumentProvider("http://user:pass@couchdb-server.com/my_database/document_name") ... See the :ref:`Argument providers example ` for a complete example.