Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/explanation/atomic_interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,25 @@ microwave_pulse = Pulse(

///

#### Measurement

To perform a measurement, we not only have to turn on an optical channel, we also have to turn on a detector, this is handled by the [`MeasurePulse`][oqd_core.interface.atomic.protocol.MeasurePulse].

<!-- prettier-ignore -->
/// admonition | Example
type: example

Pulse that drives a fluorescent transition and turns on the detector for a duration $T$:

```python
detection_pulse = MeasurePulse(
beam=detection_beam,
duration=T,
)
```

///

### Composition of Protocols

The pulse program for a quantum experiment is usually more complex than a pulse of a single beam. This is handled with [`SequentialProtocol`][oqd_core.interface.atomic.protocol.SequentialProtocol] and [`ParallelProtocol`][oqd_core.interface.atomic.protocol.ParallelProtocol].
Expand Down
4 changes: 4 additions & 0 deletions docs/explanation/math_interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,13 @@ The compatible operators for the math interface consist of:
The compatible named functions include:

- trigonometric (`sin`, `cos`, `tan`)
- inverse trigonometric functions (`asin`, `acos`, `atan`, `atan2`)
- hyperbolic trigonometric (`sinh`, `cosh`, `tanh`)
- inverse hyperbolic trigonometric functions (`asinh`, `acosh`, `atanh`)
- exponential (`exp`)
- logarithm (`log`)
- complex number functions (`real`, `imag`, `conj`, `abs`)
- step function (`heaviside`)

///

Expand Down
10 changes: 8 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ classifiers = [

dependencies = [
"pydantic>=2.10.6",
"oqd-compiler-infrastructure@git+https://github.com/openquantumdesign/oqd-compiler-infrastructure",
"oqd-compiler-infrastructure",
"numpy",
"scipy",
]
Expand All @@ -60,8 +60,14 @@ include = ["oqd_core*"]
select = ["E4", "E7", "E9", "F", "I"]
fixable = ["ALL"]

[tool.uv.sources]
oqd-compiler-infrastructure = { git = "https://github.com/openquantumdesign/oqd-compiler-infrastructure" }

[dependency-groups]
dev = ["pre-commit>=4.1.0"]
dev = [
"jupyter>=1.1.1",
"pre-commit>=4.1.0",
]


[project.urls]
Expand Down
3 changes: 3 additions & 0 deletions src/oqd_core/compiler/atomic/canonicalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ def _get_duration(cls, model):
[cls._get_duration(p) for p in model.sequence],
)
if isinstance(model, ParallelProtocol):
if len(model.sequence) == 1:
return cls._get_duration(model.sequence[0])

return max(
*[cls._get_duration(p) for p in model.sequence],
)
Expand Down
10 changes: 9 additions & 1 deletion src/oqd_core/interface/atomic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@
# limitations under the License.

from .circuit import AtomicCircuit
from .protocol import Beam, ParallelProtocol, Protocol, Pulse, SequentialProtocol
from .protocol import (
Beam,
MeasurePulse,
ParallelProtocol,
Protocol,
Pulse,
SequentialProtocol,
)
from .species import Ba133IIBuilder, IonBuilder, Yb171IIBuilder
from .system import Ion, Level, Phonon, System, Transition

Expand All @@ -32,4 +39,5 @@
"IonBuilder",
"Yb171IIBuilder",
"Ba133IIBuilder",
"MeasurePulse",
]
16 changes: 14 additions & 2 deletions src/oqd_core/interface/atomic/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"Protocol",
"ParallelProtocol",
"SequentialProtocol",
"MeasurePulse",
]

########################################################################################
Expand Down Expand Up @@ -76,6 +77,16 @@ class Pulse(TypeReflectBaseModel):
duration: float


class MeasurePulse(Pulse):
"""
Class representing a fluorescent measurement for some duration.

Attributes:
duration: Period of time to turn the measurement on for.

"""


class Protocol(TypeReflectBaseModel):
"""
Class representing a light-matter interaction protocol/pulse program for the optical channels/beams.
Expand All @@ -92,7 +103,7 @@ class ParallelProtocol(Protocol):
sequence: List of pulses or subprotocols to compose together in a parallel fashion.
"""

sequence: List[Union[Pulse, ProtocolSubTypes]]
sequence: List[Union[PulseSubTypes, ProtocolSubTypes]]


class SequentialProtocol(Protocol):
Expand All @@ -103,7 +114,8 @@ class SequentialProtocol(Protocol):
sequence: List of pulses or subprotocols to compose together in a sequntial fashion.
"""

sequence: List[Union[Pulse, ProtocolSubTypes]]
sequence: List[Union[PulseSubTypes, ProtocolSubTypes]]


ProtocolSubTypes = Union[SequentialProtocol, ParallelProtocol]
PulseSubTypes = Union[Pulse, MeasurePulse]
17 changes: 17 additions & 0 deletions src/oqd_core/interface/atomic/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,23 @@ class Ion(TypeReflectBaseModel):
transitions: List[Transition]
position: List[float]

@property
def _level_dict(self):
return {level.label: level for level in self.levels}

@property
def _transition_dict(self):
return {transition.label: transition for transition in self.transitions}

def __getitem__(self, label):
if label in self._level_dict.keys():
return self._level_dict[label]

if label in self._transition_dict.keys():
return self._transition_dict[label]

raise KeyError("Invalid key, label not in levels or transitions.")


########################################################################################

Expand Down
Loading
Loading