qua-platform / quam

The Quantum Abstract Machine (QuAM) is a comprehensive framework designed to abstract and manage quantum programming environments, providing robust tools for configuring and running quantum operations effectively. It is built over the QUA programming language, offering an organized structure for handling complex quantum components and operations.
http://qua-platform.github.io/quam/
BSD 3-Clause "New" or "Revised" License
4 stars 2 forks source link

Feat: Add hardware ports and MW-FEM support #44

Closed nulinspiratie closed 2 months ago

nulinspiratie commented 2 months ago

This PR introduces the concept of ports to QuAM, which can be passed as an argument to the channel. This solves certain issues such as the LF-FEM and OPX+ ports having different properties. We also add MW-FEM support through the MWChannel,InMWChannel, and InOutMWChannel.

Channel Ports

In the section Channels, we have seen how to create analog channels and attach digital outputs to them. In these examples, the ports are defined by the OPX output tuple (connector, port). However, for more advanced use cases it is instead possible to define the ports using dedicated [Port][quam.components.ports.Port] QuAM components. This is primarily useful in two situations:

  1. Multiple channels are connected to the same physical port, and the user wants to define the port and its properties only once.
  2. The user wants to access port-specific properties that cannot directly be accessed through the [Channel][quam.components.channels.Channel]. Examples are the crosstalk, delay, and sampling rate of the port.

Example: Defining a Port

In this example, we want to use analog output ("con1", 3) of the OPX+ to create a single channel. We define the port using the [OPXPlusAnalogOutputPort][quam.components.ports.OPXPlusAnalogOutputPort] component, which allows us to set the offset and delay of the port.

from quam.components.ports import OPXPlusAnalogOutputPort
from quam.components import SingleChannel

port = OPXPlusAnalogOutputPort(port=("con1", 3), offset=0.2, delay=12)
channel = SingleChannel(opx_output=port)

Note that in this situation the port offset is defined by channel.port.offset, and is therefore part of the port. The [SingleChannel][quam.components.channels.SingleChannel] component also has the attribute SingleChannel.OPX_output_offset, but its value is ignored in this case. If we would have instead used SingleChannel.opx_output = ("con1", 3), then the offset would have been defined by channel.OPX_output_offset.