How to Extend SQuADDS with Custom Component Types Beyond Built-in Qubits and Cavities
You can extend SQuADDS by creating a new QComponent subclass in squadds/components/, exposing it in squadds/components/__init__.py, optionally registering the short name in squadds/core/db.py, and instantiating it in your designs or the WebUI.
SQuADDS builds every quantum device from modular QComponent subclasses that reside in the squadds/components package. While the library ships with built-in types like QubitCavity and CavityClaw, extending SQuADDS with custom component types such as resonators, filters, or couplers requires only four straightforward steps. This guide demonstrates the exact file locations, method signatures, and code patterns needed to add a λ/4 CPW resonator to your workflow.
Creating a Custom QComponent Subclass
Every device in SQuADDS inherits from QComponent, which provides the geometry engine integration. To extend SQuADDS with custom component types, you must define a new subclass that specifies default options, component metadata, and a make() method.
Component Structure and Required Methods
A valid SQuADDS component requires three specific elements:
default_options– ADictcontaining default geometric and positional parameters (e.g.,trace_width,pos_x).component_metadata– ADictcontaining ashort_namekey used by the database to build dataset identifiers.make()– The method that constructs the geometry using Qiskit-Metal primitives.
In squadds/components/quarter_wave_resonator.py, the QuarterWaveResonator class demonstrates this structure by wrapping a RouteMeander primitive to create a resonant CPW structure.
Example: Building a Quarter-Wave Resonator
Create the file squadds/components/quarter_wave_resonator.py with the following implementation:
# File: squadds/components/quarter_wave_resonator.py
from qiskit_metal import Dict
from qiskit_metal.qlibrary.core import QComponent
from qiskit_metal.qlibrary.tlines.meandered import RouteMeander
class QuarterWaveResonator(QComponent):
"""
Simple λ/4 coplanar waveguide resonator.
"""
default_options = Dict(
chip="main",
length="4000um", # total resonator length (≈ λ/4 at 5 GHz on typical substrates)
trace_width="10um",
trace_gap="6um",
orientation=0, # degrees
pos_x="0um",
pos_y="0um",
)
component_metadata = Dict(short_name="quarter_res")
"""Component metadata – used for naming in the DB."""
def make(self):
"""Create the CPW resonator using Qiskit‑Metal primitives."""
p = self.p
# Create a straight CPW of the requested length
self.resonator = RouteMeander(
self.design,
f"{self.name}_res",
options=Dict(
total_length=p.length,
trace_width=p.trace_width,
trace_gap=p.trace_gap,
orientation=p.orientation,
start_anchor=self.position,
),
)
Key implementation details include inheriting from QComponent, wrapping options in the Dict class as used throughout SQuADDS, and providing the short_name metadata that squadds/core/db.py uses for dataset naming logic.
Registering Your Component in the SQuADDS Package
After defining the class, you must expose it at the package level so other modules can resolve the import. Edit squadds/components/__init__.py to include your new component:
# File: squadds/components/__init__.py
from .quarter_wave_resonator import QuarterWaveResonator # <-- expose the new component
# Existing imports (e.g. QubitCavity, CavityClaw, Airbridge) stay unchanged
Now QuarterWaveResonator can be imported directly as from squadds.components import QuarterWaveResonator.
Integrating with the Database and WebUI
To make your custom component appear automatically in UI selectors and dataset naming logic, add its short_name to the list returned by supported_components() in squadds/core/db.py.
# File: squadds/core/db.py (excerpt)
def supported_components(self):
"""Return list of component names recognized by SQuADDS."""
# Existing logic reads config names; we augment it manually for a custom component.
components = [c for c in self._components_from_configs()]
if "quarter_res" not in components:
components.append("quarter_res") # <-- Add our custom short name
return components
The supported_components() method is consumed by squadds/ui/app.py to populate dropdown menus and by the dataset-naming helpers in squadds/core/db.py. Adding the short name guarantees the component appears in the WebUI under “Component Type” without requiring a full config entry.
Using Custom Components in Simulations and Workflows
Once registered, instantiate your component exactly like built-in types. The simulation utilities in squadds/simulations/objects.py and squadds/simulations/utils.py accept any QComponent subclass, so your custom type works out-of-the-box for electromagnetic simulations and GDS export.
# Example script (run inside a SQuADDS environment)
import squadds
from squadds.components import QuarterWaveResonator
# Initialise a design (the same as other examples)
design = squadds.Design(name="my_resonator")
# Create the component
res = QuarterWaveResonator(design, "Res1")
# Render to GDS (optional)
res.to_gds("my_resonator", include_wirebond_pads=False)
When you start the WebUI (uv run python -m squadds.ui.app), selecting “quarter_res” from the dropdown automatically invokes the make() method defined in your subclass.
Summary
- Create a subclass of
QComponentwithdefault_options,component_metadata(includingshort_name), and amake()method that builds geometry using Qiskit-Metal primitives. - Expose the class by importing it in
squadds/components/__init__.pyto make it available throughout the package. - Register the
short_nameinsquadds/core/db.py’ssupported_components()method to enable UI dropdowns and dataset naming. - Instantiate the component in scripts or the WebUI; it integrates automatically with simulation helpers in
squadds/simulations/objects.pyandsquadds/simulations/utils.py.
Frequently Asked Questions
How do I make my custom component appear in the SQuADDS WebUI dropdown?
Add the component’s short_name (defined in component_metadata) to the list returned by supported_components() in squadds/core/db.py. The WebUI in squadds/ui/app.py reads this list to populate the “Component Type” selector, so no modifications to the UI code itself are required.
What Qiskit-Metal primitives can I use inside the make() method?
You can use any Qiskit-Metal object from qiskit_metal.qlibrary, such as RouteMeander, Rectangle, or CircleCute. The make() method simply needs to instantiate these primitives and attach them to self.design, allowing you to build complex geometries including meandered resonators, airbridges, or 3D blocks.
Will custom components work with SQuADDS simulation tools if I don't modify db.py?
Yes. The simulation utilities in squadds/simulations/objects.py and squadds/simulations/utils.py accept any QComponent instance regardless of registration status. However, omitting the supported_components() registration means the component will not appear in WebUI dropdowns and may not be recognized by dataset-naming logic in squadds/core/db.py.
Do I need to create a configuration file to add a new component type?
No. While SQuADDS supports config-driven component definitions, you can manually extend the system by directly editing squadds/components/__init__.py and squadds/core/db.py as shown above. This approach is ideal for rapid prototyping of single custom elements like λ/4 resonators or specialized couplers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →