Skip to content

Result

Result dataclass

Result(
    *,
    storage: StorageBackend,
    shot_filter: ShotFilter = _default_shot_filter()
)

Result view over stored shots.

Merge-oriented methods assume each selected task ID has the same subtask structure.

Attributes:

Name Type Description
storage StorageBackend

Storage backend that holds shots and task metadata.

shot_filter ShotFilter

Filter used when reading shots and deriving subtask scope. Defaults to the DETECTED frame type.

storage_filter property

storage_filter: StorageFilter

Return the subtask-level portion of shot_filter.

Returns:

Name Type Description
StorageFilter StorageFilter

Filter containing task IDs, subtask indices, and task-subtask pairs from shot_filter.

arguments

arguments(verify: bool = True) -> list[dict | None]

Return subtask arguments after merging selected task IDs.

Parameters:

Name Type Description Default
verify bool

Whether to validate that selected task IDs can be merged before reading arguments. Defaults to True.

True

Returns:

Type Description
list[dict | None]

list[dict | None]: One arguments entry per merged subtask, ordered by subtask index.

Raises:

Type Description
ValueError

If verify is True and selected task IDs cannot be merged.

Source code in src/bloqade/core/device/result.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
def arguments(self, verify: bool = True) -> list[dict | None]:
    """Return subtask arguments after merging selected task IDs.

    Args:
        verify (bool): Whether to validate that selected task IDs can be
            merged before reading arguments. Defaults to True.

    Returns:
        list[dict | None]: One arguments entry per merged subtask, ordered
            by subtask index.

    Raises:
        ValueError: If `verify` is True and selected task IDs cannot be
            merged.
    """
    subtasks = self.subtasks(verify=verify)
    return [subtask["arguments"] for subtask in subtasks]

full_arguments

full_arguments() -> list[dict | None]

Return all stored subtask arguments without merging task IDs.

Returns:

Type Description
list[dict | None]

list[dict | None]: Arguments for every selected stored subtask row, including None for rows without arguments.

Source code in src/bloqade/core/device/result.py
162
163
164
165
166
167
168
169
def full_arguments(self) -> list[dict | None]:
    """Return all stored subtask arguments without merging task IDs.

    Returns:
        list[dict | None]: Arguments for every selected stored subtask row,
            including `None` for rows without arguments.
    """
    return self.storage.get_arguments(storage_filter=self.storage_filter)

full_subtasks

full_subtasks() -> list[dict]

Return selected stored subtasks without merging task IDs.

If selected task IDs share the same subtask structure, this view contains one row per task and subtask.

Returns:

Type Description
list[dict]

list[dict]: Full subtask dictionaries selected by storage_filter.

Source code in src/bloqade/core/device/result.py
205
206
207
208
209
210
211
212
213
214
def full_subtasks(self) -> list[dict]:
    """Return selected stored subtasks without merging task IDs.

    If selected task IDs share the same subtask structure, this view
    contains one row per task and subtask.

    Returns:
        list[dict]: Full subtask dictionaries selected by `storage_filter`.
    """
    return self.storage.get_subtasks(storage_filter=self.storage_filter)

shot_results

shot_results(verify: bool = True) -> list[np.ndarray]

Return physical shot bitstrings grouped by merged subtask.

Parameters:

Name Type Description Default
verify bool

Whether to validate that selected task IDs can be merged before reading shots. Defaults to True.

True

Returns:

Type Description
list[ndarray]

list[np.ndarray]: One two-dimensional boolean array per merged subtask, ordered by subtask index.

Raises:

Type Description
ValueError

If verify is True and selected task IDs cannot be merged.

Source code in src/bloqade/core/device/result.py
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def shot_results(self, verify: bool = True) -> list[np.ndarray]:
    """Return physical shot bitstrings grouped by merged subtask.

    Args:
        verify (bool): Whether to validate that selected task IDs can be
            merged before reading shots. Defaults to True.

    Returns:
        list[np.ndarray]: One two-dimensional boolean array per merged
            subtask, ordered by subtask index.

    Raises:
        ValueError: If `verify` is True and selected task IDs cannot be
            merged.
    """
    subtasks = self.subtasks(verify=verify)
    return self._shot_results_for_subtasks(subtasks)

subtasks

subtasks(verify: bool = True) -> list[dict]

Return subtasks merged across selected task IDs.

The merged view is ordered by subtask_index, removes ambiguous per-task fields (task_id and metadata), and aggregates num_shots. Use full_subtasks when task IDs or metadata must be preserved.

Parameters:

Name Type Description Default
verify bool

Whether to validate that selected task IDs can be merged before returning subtasks. Defaults to True.

True

Returns:

Type Description
list[dict]

list[dict]: Merged subtask dictionaries ordered by subtask index.

Raises:

Type Description
ValueError

If verify is True and selected task IDs cannot be merged.

Source code in src/bloqade/core/device/result.py
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
def subtasks(self, verify: bool = True) -> list[dict]:
    """Return subtasks merged across selected task IDs.

    The merged view is ordered by `subtask_index`, removes ambiguous
    per-task fields (`task_id` and `metadata`), and aggregates `num_shots`.
    Use `full_subtasks` when task IDs or metadata must be preserved.

    Args:
        verify (bool): Whether to validate that selected task IDs can be
            merged before returning subtasks. Defaults to True.

    Returns:
        list[dict]: Merged subtask dictionaries ordered by subtask index.

    Raises:
        ValueError: If `verify` is True and selected task IDs cannot be
            merged.
    """
    if verify:
        self.validate()

    subtasks = self.storage.get_subtasks(storage_filter=self.storage_filter)
    subtasks_by_index: dict[int, dict] = {}
    for subtask in subtasks:
        # NOTE: remove task_id and metadata since we're merging multiple ones
        subtask.pop("task_id")
        subtask.pop("metadata")
        idx = subtask["subtask_index"]
        if idx in subtasks_by_index:
            subtasks_by_index[idx]["num_shots"] += subtask["num_shots"]
        else:
            subtasks_by_index[idx] = subtask
    return [subtasks_by_index[i] for i in sorted(subtasks_by_index)]

task_ids

task_ids() -> set[str]

Return task IDs selected by this result view.

Returns:

Type Description
set[str]

set[str]: Task IDs from shot_filter.task_ids when set; otherwise all task IDs known to storage.

Source code in src/bloqade/core/device/result.py
216
217
218
219
220
221
222
223
224
225
226
def task_ids(self) -> set[str]:
    """Return task IDs selected by this result view.

    Returns:
        set[str]: Task IDs from `shot_filter.task_ids` when set; otherwise
            all task IDs known to storage.
    """
    if self.shot_filter.task_ids is not None:
        return set(self.shot_filter.task_ids)

    return self.storage.task_ids()

validate

validate() -> None

Validate that selected task IDs can be merged by subtask index.

Compatible task IDs have the same program_index and equal arguments for each shared subtask_index. Different shot counts are allowed, and None and empty dictionaries are treated as equivalent arguments.

Raises:

Type Description
ValueError

If selected task IDs disagree on program_index or arguments for the same subtask_index.

Source code in src/bloqade/core/device/result.py
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
def validate(self) -> None:
    """Validate that selected task IDs can be merged by subtask index.

    Compatible task IDs have the same `program_index` and equal arguments
    for each shared `subtask_index`. Different shot counts are allowed, and
    None and empty dictionaries are treated as equivalent arguments.

    Raises:
        ValueError: If selected task IDs disagree on `program_index` or
            arguments for the same `subtask_index`.
    """

    if self._is_valid:
        return

    if self.shot_filter.task_ids is None:
        task_ids = self.storage.task_ids()
    else:
        task_ids = self.shot_filter.task_ids

    if len(task_ids) == 1:
        # Just a single task, we're safe
        self._is_valid = True
        return

    full_subtasks = self.full_subtasks()

    subtask_index_groups: dict[int, list[dict]] = {}
    for subtask in full_subtasks:
        subtask_index_groups.setdefault(subtask["subtask_index"], []).append(
            subtask
        )

    _VERIFY_HINT = "Pass verify=False to skip this check."

    for idx, group in subtask_index_groups.items():
        if len(group) <= 1:
            continue
        ref_subtask = group[0]
        for other_subtask in group[1:]:
            if other_subtask["program_index"] != ref_subtask["program_index"]:
                raise ValueError(
                    f"task_ids disagree on program_index for subtask_index={idx}: "
                    f"{ref_subtask['task_id']!r} -> {ref_subtask['program_index']}, "
                    f"{other_subtask['task_id']!r} -> {other_subtask['program_index']}. "
                    + _VERIFY_HINT
                )
            ref_arguments = ref_subtask["arguments"]
            other_arguments = other_subtask["arguments"]
            if not ref_arguments and not other_arguments:
                # NOTE: treat empty dict and None as equal
                continue
            if other_subtask["arguments"] != ref_subtask["arguments"]:
                raise ValueError(
                    f"task_ids disagree on arguments for subtask_index={idx}: "
                    f"{ref_subtask['task_id']!r} -> {ref_subtask['arguments']!r}, "
                    f"{other_subtask['task_id']!r} -> {other_subtask['arguments']!r}. "
                    + _VERIFY_HINT
                )

    self._is_valid = True

where_arguments

where_arguments(
    predicate: Callable[[dict | None], bool],
) -> Self

Return a result narrowed by subtask arguments.

The predicate sees only subtasks in the scope of self.shot_filter; the returned result inherits that scope intersected with the matches.

NOTE: the Subtask model coerces bool values in arguments to float (True -> 1.0, False -> 0.0). Predicates that rely on identity (is True) or strict types will silently match nothing for bool-valued arguments. Use == 1 or > 0 instead, or store non-bool discriminators.

Parameters:

Name Type Description Default
predicate Callable[[dict | None], bool]

Predicate applied to each selected subtask's arguments.

required

Returns:

Name Type Description
Self Self

A narrowed result view.

Source code in src/bloqade/core/device/result.py
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
def where_arguments(
    self,
    predicate: Callable[[dict | None], bool],
) -> Self:
    """Return a result narrowed by subtask arguments.

    The predicate sees only subtasks in the scope of `self.shot_filter`; the
    returned result inherits that scope intersected with the matches.

    NOTE: the Subtask model coerces bool values in `arguments` to float
    (True -> 1.0, False -> 0.0). Predicates that rely on identity
    (`is True`) or strict types will silently match nothing for bool-valued
    arguments. Use `== 1` or `> 0` instead, or store non-bool
    discriminators.

    Args:
        predicate (Callable[[dict | None], bool]): Predicate applied to each
            selected subtask's arguments.

    Returns:
        Self: A narrowed result view.
    """
    where_filter = self.storage.filter_by_arguments(
        predicate=predicate, storage_filter=self.storage_filter
    )
    return self._from_where_filters(
        where_filter=where_filter,
    )

where_metadata

where_metadata(
    predicate: Callable[[dict | None], bool],
) -> Self

Return a result narrowed by JSON-decoded user metadata.

Expects user_metadata to be a JSON-serialized dict; non-JSON values raise. To filter on raw strings instead, use where_subtasks and parse manually. The predicate sees only subtasks in the scope of self.shot_filter; the returned result inherits that scope intersected with the matches.

Parameters:

Name Type Description Default
predicate Callable[[dict | None], bool]

Predicate applied to each selected subtask's decoded user_metadata.

required

Returns:

Name Type Description
Self Self

A narrowed result view.

Source code in src/bloqade/core/device/result.py
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
def where_metadata(
    self,
    predicate: Callable[[dict | None], bool],
) -> Self:
    """Return a result narrowed by JSON-decoded user metadata.

    Expects user_metadata to be a JSON-serialized dict; non-JSON values raise. To
    filter on raw strings instead, use `where_subtasks` and parse manually. The
    predicate sees only subtasks in the scope of `self.shot_filter`; the returned
    result inherits that scope intersected with the matches.

    Args:
        predicate (Callable[[dict | None], bool]): Predicate applied to each
            selected subtask's decoded `user_metadata`.

    Returns:
        Self: A narrowed result view.
    """
    where_filter = self.storage.filter_by_metadata(
        predicate=predicate, storage_filter=self.storage_filter
    )
    return self._from_where_filters(
        where_filter=where_filter,
    )

where_shots

where_shots(
    predicate: Callable[[ShotResult], bool],
    predicate_filter: ShotFilter | None = None,
) -> Self

Return a result narrowed by shot-level predicate.

predicate_filter selects the shots the predicate evaluates against; defaults to self.shot_filter (predicate sees the same shots the current result fetches). The returned result inherits self.shot_filter's scope (notably frame_type) intersected with the matching shot pairs.

To precondition on one frame and return another, such as SORTED-was-all-1 -> DETECTED, pass predicate_filter=replace(self.shot_filter, frame_type='SORTED').

Parameters:

Name Type Description Default
predicate Callable[[ShotResult], bool]

Predicate applied to each shot selected by predicate_filter.

required
predicate_filter ShotFilter | None

Filter used only for predicate evaluation. When None, self.shot_filter is used. Defaults to None.

None

Returns:

Name Type Description
Self Self

A narrowed result view.

Source code in src/bloqade/core/device/result.py
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
def where_shots(
    self,
    predicate: Callable[[ShotResult], bool],
    predicate_filter: ShotFilter | None = None,
) -> Self:
    """Return a result narrowed by shot-level predicate.

    `predicate_filter` selects the shots the predicate evaluates against;
    defaults to `self.shot_filter` (predicate sees the same shots the
    current result fetches). The returned result inherits
    `self.shot_filter`'s scope (notably `frame_type`) intersected with the
    matching shot pairs.

    To precondition on one frame and return another, such as
    SORTED-was-all-1 -> DETECTED, pass
    `predicate_filter=replace(self.shot_filter, frame_type='SORTED')`.

    Args:
        predicate (Callable[[ShotResult], bool]): Predicate applied to each
            shot selected by `predicate_filter`.
        predicate_filter (ShotFilter | None): Filter used only for predicate
            evaluation. When None, `self.shot_filter` is used. Defaults to
            None.

    Returns:
        Self: A narrowed result view.
    """
    if predicate_filter is None:
        predicate_filter = self.shot_filter

    where_filter = self.storage.filter_by_shots(
        predicate, shot_filter=predicate_filter
    )
    shot_filter = replace(
        self.shot_filter,
        task_shot_pairs=where_filter.task_shot_pairs,
    )
    return type(self)(
        storage=self.storage,
        shot_filter=shot_filter,
    )

where_subtasks

where_subtasks(predicate: Callable[[dict], bool]) -> Self

Return a result narrowed to subtasks matching a predicate.

The predicate sees only subtasks in the scope of self.shot_filter; the returned result inherits that scope intersected with the matches.

Parameters:

Name Type Description Default
predicate Callable[[dict], bool]

Predicate applied to each selected subtask dictionary.

required

Returns:

Name Type Description
Self Self

A narrowed result view.

Source code in src/bloqade/core/device/result.py
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
def where_subtasks(
    self,
    predicate: Callable[[dict], bool],
) -> Self:
    """Return a result narrowed to subtasks matching a predicate.

    The predicate sees only subtasks in the scope of `self.shot_filter`; the
    returned result inherits that scope intersected with the matches.

    Args:
        predicate (Callable[[dict], bool]): Predicate applied to each
            selected subtask dictionary.

    Returns:
        Self: A narrowed result view.
    """
    where_filter = self.storage.filter_by_subtasks(
        predicate, storage_filter=self.storage_filter
    )
    return self._from_where_filters(
        where_filter=where_filter,
    )