Interface

The interface package contains code for both user-interface and code-interface purposes.

Pulse programs

The code for dealing with pulse programs is composed of:

  • a parser (spacq.interface.pulse.parser.Parser),
  • an AST (spacq.interface.pulse.tree.ASTNode),
  • an environment (spacq.interface.pulse.tree.Environment), and
  • a presentation wrapper (spacq.interface.pulse.program.Program).

The details of pulse program handling are hidden behind the Program interface, which handles every step of a pulse program’s life cycle from parsing to execution.

When presented with the textual representation of a pulse program, the parser does its best to tranform it into an abstract syntax tree; if it cannot do so, it raises a spacq.interface.pulse.paser.PulseSyntaxError.

Once an AST is obtained, an empty Environment is created. The nodes of the AST are then visited with the Environment over several stages. These stages are:

  1. declarations:
    • Populate the environment with the variable declarations.
    • Verify that the declarations make sense.
  2. values:
    • Populate the environment with the value assignments.
    • Verify that the assigned values match the declared variables.
  3. commands:
    • Verify that all the commands make sense given the collected declarations and values.
  4. waveforms:
    • Based on all the collected information, generate the output waveforms.

Warning

The order of the stages must be preserved, since each stage makes the assumption that previous stages have been executed.

Resources

Resource

spacq.interface.resources.Resource is a generic resource with a getter and a setter, each of which can perform arbitrary code in order to get or set a value.

If a resource has units, all operations dealing with the value of the resource should use matching units. In particular, setting the value of a resource with a value whose units do not match those of the resource will raise a TypeError. The display units of a resource, however, have no impact on its values; the display units only affect the value displayed alongside the resource.

If a converter is supplied for a resource, the converter is used to transform user input (textual strings) into the valid type for the resource. Typical converters include float and spacq.devices.tools.str_to_bool. If a resource has units, the user input is automatically converted into a spacq.interface.units.Quantity; supplying a converter overrides this behaviour.

A resource may be wrapped with arbitrarily many wrappers. Wrapping and unwrapping are both non-destructive: the original resource is always unmodified, and a new Resource instance is created. For both getting and setting values, the getter and setter filters are applied in the same order they were added, excluding those which have been removed.

Acquisition Thread

spacq.interface.resources.AcquisitionThread is a threaded wrapper around a resource that allows the value of the resource to be fetched at regular intervals. This is particularly useful for live plots which show historical data.

In order to pause the acquisition, running_lock should be acquired from another thread (if no running lock is passed to __init__, pausing is disallowed); to resume, running_lock should be released. In order to stop the thread, done should be set to True.

Units

SIValues

spacq.interface.units.SIValues is a container for all SI prefixes (from 10-24 to 1024), all SI base units, and a selection of SI derived units.

Quantity

spacq.interface.units.Quantity is a wrapper around the Python package “quantities”. It is used internally (to communicate quantities between objects) and externally (allowing the user to enter arbitrary quantities).

Note

Rather than exposing the quantities.Quantity interface, spacq.interface.units.Quantity defines its own interface and uses a subset of the quantities.Quantity interface internally. Thus, spacq.interface.units.Quantity is not a drop-in substitude for quantities.Quantity.

Waveform generation

spacq.interface.waveform.Generator provides a mechanism for generating spacq.interface.waveform.Waveform objects. Each Generator will generate a single waveform as its methods are called; after the waveform is complete, it can be obtained via the waveform attribute.

Note

All values should be normalized to the interval [-1.0, 1.0].