EPII v0.2.0 User Guide¶
The Experiment Programming Interface for Instruments (EPII) v0.2.0 is a major update that brings backend-aware experiment discovery, canonical naming, and improved integration capabilities to LeeQ.
What's New in v0.2.0¶
Key Features¶
- Backend-Aware Discovery: Automatically filters experiments based on your setup type
- Canonical Naming: No more aliases - use full module-qualified experiment names
- Dynamic Discovery: Automatically finds all available experiments
- Enhanced Metadata: Rich experiment information with EPII_INFO
Breaking Changes¶
- All experiment aliases removed (
rabi,t1,ramsey, etc.) - Must use canonical names (
calibrations.NormalisedRabi,characterizations.SimpleT1) - Backend filtering may limit available experiments
Getting Started¶
Basic Usage¶
from leeq.epii.experiments import ExperimentRouter
# Initialize with your setup
router = ExperimentRouter(setup=my_setup)
# Discover available experiments
experiments = router.list_experiments()
print(f"Found {len(experiments)} experiments")
# Get a specific experiment
experiment_class = router.get_experiment("calibrations.NormalisedRabi")
Backend-Aware Operation¶
The router automatically detects your setup type and filters experiments accordingly:
# With simulation setup - only shows experiments with run_simulated
from leeq.setups.built_in.setup_simulation_high_level import HighLevelSimulationSetup
sim_setup = HighLevelSimulationSetup()
sim_router = ExperimentRouter(setup=sim_setup)
sim_experiments = sim_router.list_experiments() # Filtered for simulation compatibility
# With hardware setup - shows all experiments
hardware_router = ExperimentRouter(setup=hardware_setup)
all_experiments = hardware_router.list_experiments() # All experiments available
Experiment Naming¶
Canonical Names¶
All experiments now use module-qualified names that reflect their organization:
| Category | Example |
|---|---|
| Calibrations | calibrations.NormalisedRabi, calibrations.DragCalibrationSingleQubitMultilevel |
| Characterizations | characterizations.SimpleT1, characterizations.SpinEchoMultiLevel |
| Multi-Qubit Gates | multi_qubit_gates.CrossResonanceCalibration |
| Tomography | tomography.StateTomography, tomography.ProcessTomography |
| Optimal Control | optimal_control.GrapeOptimization |
Finding Experiment Names¶
# List all available experiments with descriptions
experiments = router.list_experiments()
for name, description in experiments.items():
print(f"{name}: {description}")
# Get detailed information about an experiment
info = router.get_experiment_info("calibrations.NormalisedRabi")
print(info['epii_info']) # Experiment metadata
print(info['run_docstring']) # Run method documentation
Usage Patterns¶
Running Experiments¶
Follow LeeQ's constructor-based pattern - never call run() methods directly:
# CORRECT: Pass all parameters to constructor
exp = QubitSpectroscopyFrequency(
dut_qubit=qubit,
start=4900.0,
stop=5100.0,
step=2.0,
num_avs=1000
)
# INCORRECT: Never do this
exp = QubitSpectroscopyFrequency()
exp.run_simulated(...) # WRONG!
Error Handling¶
try:
experiment_class = router.get_experiment("calibrations.NormalisedRabi")
if experiment_class:
exp = experiment_class(
dut_qubit=qubit,
amplitudes=np.linspace(0, 1, 51)
)
else:
print("Experiment not found or not compatible with current setup")
except Exception as e:
print(f"Experiment failed: {e}")
Checking Compatibility¶
# Check if an experiment is available (considers backend compatibility)
if "calibrations.NormalisedRabi" in router.experiment_map:
print("Rabi experiment available")
else:
print("Rabi experiment not available for this setup")
# Get experiment requirements
info = router.get_experiment_info("calibrations.NormalisedRabi")
epii_info = info['epii_info']
print(f"Description: {epii_info.get('description', 'N/A')}")
print(f"Parameters: {epii_info.get('parameters', {})}")
Advanced Features¶
Custom Experiment Discovery¶
# Initialize without automatic discovery
router = ExperimentRouter()
# Manually discover experiments (useful for debugging)
router._discover_experiments()
print(f"Discovered {len(router.experiment_map)} experiments")
Simulation vs Hardware¶
# Check if router is in simulation mode
if router.is_simulation:
print("Running in simulation mode")
print("Only experiments with run_simulated method are available")
else:
print("Running on hardware")
print("All experiments available")
# List simulation capabilities
for name, exp_class in router.experiment_map.items():
has_sim = router._has_own_run_simulated(exp_class)
print(f"{name}: {'✓' if has_sim else '✗'} simulation support")
Integration Examples¶
With Chronicle Logging¶
from leeq.experiments.builtin.calibrations import NormalisedRabi
# Experiments automatically integrate with Chronicle
exp = NormalisedRabi(
dut_qubit=qubit,
amplitudes=np.linspace(0, 1, 51)
)
# Results automatically logged to Chronicle
Batch Experiment Execution¶
# Run multiple experiments in sequence
experiment_names = [
"calibrations.NormalisedRabi",
"characterizations.SimpleT1",
"calibrations.SimpleRamseyMultilevel"
]
results = {}
for exp_name in experiment_names:
exp_class = router.get_experiment(exp_name)
if exp_class:
# Configure experiment based on type
if "rabi" in exp_name.lower():
exp = exp_class(dut_qubit=qubit, amplitudes=np.linspace(0, 1, 21))
elif "t1" in exp_name.lower():
exp = exp_class(dut_qubit=qubit, delays=np.logspace(-6, -3, 21))
# Store results
results[exp_name] = exp
Best Practices¶
- Always initialize router with your setup for proper backend filtering
- Use canonical names consistently throughout your code
- Check experiment availability before attempting to run
- Follow constructor-only pattern for experiment execution
- Handle errors gracefully with try/catch blocks
Troubleshooting¶
Common Issues¶
Experiment not found:
# Check available experiments
experiments = router.list_experiments()
if "my_experiment" not in experiments:
print("Available experiments:")
for name in experiments:
print(f" {name}")
No experiments available:
- Check if your setup is properly configured
- Verify EPII_INFO attributes on custom experiments
- For simulation: ensure experiments have run_simulated method
Import errors: - Ensure all LeeQ dependencies are installed - Check that experiment modules are in Python path
API Reference¶
For detailed API documentation, see: - EPII API Overview - ExperimentRouter Reference - Service Integration