lsst-pipe-base 30.0.0rc2__py3-none-any.whl → 30.0.0rc3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lsst/pipe/base/_instrument.py +6 -5
- lsst/pipe/base/log_capture.py +39 -79
- lsst/pipe/base/log_on_close.py +79 -0
- lsst/pipe/base/mp_graph_executor.py +51 -15
- lsst/pipe/base/quantum_graph/_common.py +4 -3
- lsst/pipe/base/quantum_graph/_multiblock.py +6 -16
- lsst/pipe/base/quantum_graph/_predicted.py +106 -12
- lsst/pipe/base/quantum_graph/_provenance.py +657 -6
- lsst/pipe/base/quantum_graph/aggregator/_communicators.py +18 -50
- lsst/pipe/base/quantum_graph/aggregator/_scanner.py +35 -229
- lsst/pipe/base/quantum_graph/aggregator/_structs.py +3 -113
- lsst/pipe/base/quantum_graph/aggregator/_supervisor.py +10 -5
- lsst/pipe/base/quantum_graph/aggregator/_writer.py +31 -348
- lsst/pipe/base/quantum_graph/formatter.py +101 -0
- lsst/pipe/base/quantum_graph_builder.py +12 -1
- lsst/pipe/base/quantum_graph_executor.py +116 -13
- lsst/pipe/base/quantum_graph_skeleton.py +1 -7
- lsst/pipe/base/separable_pipeline_executor.py +18 -2
- lsst/pipe/base/single_quantum_executor.py +53 -35
- lsst/pipe/base/version.py +1 -1
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/METADATA +1 -1
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/RECORD +30 -28
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/WHEEL +0 -0
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/entry_points.txt +0 -0
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/licenses/COPYRIGHT +0 -0
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/licenses/LICENSE +0 -0
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/licenses/bsd_license.txt +0 -0
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/licenses/gpl-v3.0.txt +0 -0
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/top_level.txt +0 -0
- {lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/zip-safe +0 -0
|
@@ -27,23 +27,113 @@
|
|
|
27
27
|
|
|
28
28
|
from __future__ import annotations
|
|
29
29
|
|
|
30
|
-
__all__ = ["QuantumExecutor", "QuantumGraphExecutor"]
|
|
30
|
+
__all__ = ["QuantumExecutionResult", "QuantumExecutor", "QuantumGraphExecutor"]
|
|
31
31
|
|
|
32
32
|
from abc import ABC, abstractmethod
|
|
33
|
-
from typing import TYPE_CHECKING
|
|
33
|
+
from typing import TYPE_CHECKING, Self
|
|
34
|
+
|
|
35
|
+
from lsst.daf.butler import Quantum
|
|
34
36
|
|
|
35
37
|
from .quantum_reports import QuantumReport, Report
|
|
36
38
|
|
|
37
39
|
if TYPE_CHECKING:
|
|
38
40
|
import uuid
|
|
39
41
|
|
|
40
|
-
from lsst.daf.butler import
|
|
42
|
+
from lsst.daf.butler.logging import ButlerLogRecords
|
|
41
43
|
|
|
44
|
+
from ._task_metadata import TaskMetadata
|
|
42
45
|
from .graph import QuantumGraph
|
|
43
46
|
from .pipeline_graph import TaskNode
|
|
44
47
|
from .quantum_graph import PredictedQuantumGraph
|
|
45
48
|
|
|
46
49
|
|
|
50
|
+
class QuantumExecutionResult(tuple[Quantum, QuantumReport | None]):
|
|
51
|
+
"""A result struct that captures information about a single quantum's
|
|
52
|
+
execution.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
quantum : `lsst.daf.butler.Quantum`
|
|
57
|
+
Quantum that was executed.
|
|
58
|
+
report : `.quantum_reports.QuantumReport`
|
|
59
|
+
Report with basic information about the execution.
|
|
60
|
+
task_metadata : `TaskMetadata`, optional
|
|
61
|
+
Metadata saved by the task and executor during execution.
|
|
62
|
+
skipped_existing : `bool`, optional
|
|
63
|
+
If `True`, this quantum was not executed because it appeared to have
|
|
64
|
+
already been executed successfully.
|
|
65
|
+
adjusted_no_work : `bool`, optional
|
|
66
|
+
If `True`, this quantum was not executed because the
|
|
67
|
+
`PipelineTaskConnections.adjustQuanta` hook raised `NoWorkFound`.
|
|
68
|
+
|
|
69
|
+
Notes
|
|
70
|
+
-----
|
|
71
|
+
For backwards compatibility, this class is a two-element tuple that allows
|
|
72
|
+
the ``quantum`` and ``report`` attributes to be unpacked. Additional
|
|
73
|
+
regular attributes may be added by executors (but the tuple must remain
|
|
74
|
+
only two elements to enable the current unpacking interface).
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
def __new__(
|
|
78
|
+
cls,
|
|
79
|
+
quantum: Quantum,
|
|
80
|
+
report: QuantumReport | None,
|
|
81
|
+
*,
|
|
82
|
+
task_metadata: TaskMetadata | None = None,
|
|
83
|
+
skipped_existing: bool | None = None,
|
|
84
|
+
adjusted_no_work: bool | None = None,
|
|
85
|
+
) -> Self:
|
|
86
|
+
return super().__new__(cls, (quantum, report))
|
|
87
|
+
|
|
88
|
+
# We need to define both __init__ and __new__ because tuple inheritance
|
|
89
|
+
# requires __new__ and numpydoc requires __init__.
|
|
90
|
+
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
quantum: Quantum,
|
|
94
|
+
report: QuantumReport | None,
|
|
95
|
+
*,
|
|
96
|
+
task_metadata: TaskMetadata | None = None,
|
|
97
|
+
skipped_existing: bool | None = None,
|
|
98
|
+
adjusted_no_work: bool | None = None,
|
|
99
|
+
):
|
|
100
|
+
self._task_metadata = task_metadata
|
|
101
|
+
self._skipped_existing = skipped_existing
|
|
102
|
+
self._adjusted_no_work = adjusted_no_work
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def quantum(self) -> Quantum:
|
|
106
|
+
"""The quantum actually executed."""
|
|
107
|
+
return self[0]
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def report(self) -> QuantumReport | None:
|
|
111
|
+
"""Structure describing the status of the execution of a quantum.
|
|
112
|
+
|
|
113
|
+
This is `None` if the implementation does not support this feature.
|
|
114
|
+
"""
|
|
115
|
+
return self[1]
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def task_metadata(self) -> TaskMetadata | None:
|
|
119
|
+
"""Metadata saved by the task and executor during execution."""
|
|
120
|
+
return self._task_metadata
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def skipped_existing(self) -> bool | None:
|
|
124
|
+
"""If `True`, this quantum was not executed because it appeared to have
|
|
125
|
+
already been executed successfully.
|
|
126
|
+
"""
|
|
127
|
+
return self._skipped_existing
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def adjusted_no_work(self) -> bool | None:
|
|
131
|
+
"""If `True`, this quantum was not executed because the
|
|
132
|
+
`PipelineTaskConnections.adjustQuanta` hook raised `NoWorkFound`.
|
|
133
|
+
"""
|
|
134
|
+
return self._adjusted_no_work
|
|
135
|
+
|
|
136
|
+
|
|
47
137
|
class QuantumExecutor(ABC):
|
|
48
138
|
"""Class which abstracts execution of a single Quantum.
|
|
49
139
|
|
|
@@ -55,8 +145,14 @@ class QuantumExecutor(ABC):
|
|
|
55
145
|
|
|
56
146
|
@abstractmethod
|
|
57
147
|
def execute(
|
|
58
|
-
self,
|
|
59
|
-
|
|
148
|
+
self,
|
|
149
|
+
task_node: TaskNode,
|
|
150
|
+
/,
|
|
151
|
+
quantum: Quantum,
|
|
152
|
+
quantum_id: uuid.UUID | None = None,
|
|
153
|
+
*,
|
|
154
|
+
log_records: ButlerLogRecords | None = None,
|
|
155
|
+
) -> QuantumExecutionResult:
|
|
60
156
|
"""Execute single quantum.
|
|
61
157
|
|
|
62
158
|
Parameters
|
|
@@ -67,15 +163,18 @@ class QuantumExecutor(ABC):
|
|
|
67
163
|
Quantum for this execution.
|
|
68
164
|
quantum_id : `uuid.UUID` or `None`, optional
|
|
69
165
|
The ID of the quantum to be executed.
|
|
166
|
+
log_records : `lsst.daf.butler.ButlerLogRecords`, optional
|
|
167
|
+
Container that should be used to store logs in memory before
|
|
168
|
+
writing them to the butler. This disables streaming log (since
|
|
169
|
+
we'd have to store them in memory anyway), but it permits the
|
|
170
|
+
caller to prepend logs to be stored in the butler and allows task
|
|
171
|
+
logs to be inspected by the caller after execution is complete.
|
|
70
172
|
|
|
71
173
|
Returns
|
|
72
174
|
-------
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
Structure describing the status of the execution of a quantum.
|
|
77
|
-
`None` is returned if implementation does not support this
|
|
78
|
-
feature.
|
|
175
|
+
result : `QuantumExecutionResult`
|
|
176
|
+
Result struct. May also be unpacked as a 2-tuple (see type
|
|
177
|
+
documentation).
|
|
79
178
|
|
|
80
179
|
Notes
|
|
81
180
|
-----
|
|
@@ -93,7 +192,9 @@ class QuantumGraphExecutor(ABC):
|
|
|
93
192
|
"""
|
|
94
193
|
|
|
95
194
|
@abstractmethod
|
|
96
|
-
def execute(
|
|
195
|
+
def execute(
|
|
196
|
+
self, graph: QuantumGraph | PredictedQuantumGraph, *, provenance_graph_file: str | None = None
|
|
197
|
+
) -> None:
|
|
97
198
|
"""Execute whole graph.
|
|
98
199
|
|
|
99
200
|
Implementation of this method depends on particular execution model
|
|
@@ -103,8 +204,10 @@ class QuantumGraphExecutor(ABC):
|
|
|
103
204
|
|
|
104
205
|
Parameters
|
|
105
206
|
----------
|
|
106
|
-
graph : `.QuantumGraph`
|
|
207
|
+
graph : `.QuantumGraph` or `.quantum_graph.PredictedQuantumGraph`
|
|
107
208
|
Execution graph.
|
|
209
|
+
provenance_graph_file : `str`, optional
|
|
210
|
+
A filename to write provenance to.
|
|
108
211
|
"""
|
|
109
212
|
raise NotImplementedError()
|
|
110
213
|
|
|
@@ -383,12 +383,6 @@ class QuantumGraphSkeleton:
|
|
|
383
383
|
The dataset ref of the prerequisite.
|
|
384
384
|
**attrs : `~typing.Any`
|
|
385
385
|
Additional attributes for the node.
|
|
386
|
-
|
|
387
|
-
Notes
|
|
388
|
-
-----
|
|
389
|
-
This automatically sets the 'existing_input' ref attribute (see
|
|
390
|
-
`set_existing_input_ref`), since prerequisites are always overall
|
|
391
|
-
inputs.
|
|
392
386
|
"""
|
|
393
387
|
key = PrerequisiteDatasetKey(ref.datasetType.name, ref.id.bytes)
|
|
394
388
|
self._xgraph.add_node(key, data_id=ref.dataId, ref=ref, **attrs)
|
|
@@ -606,7 +600,7 @@ class QuantumGraphSkeleton:
|
|
|
606
600
|
|
|
607
601
|
def set_output_in_the_way(self, ref: DatasetRef) -> None:
|
|
608
602
|
"""Associate a dataset node with a `DatasetRef` that represents an
|
|
609
|
-
existing output in the output RUN
|
|
603
|
+
existing output in the output RUN collection.
|
|
610
604
|
|
|
611
605
|
Parameters
|
|
612
606
|
----------
|
|
@@ -40,7 +40,8 @@ from collections.abc import Iterable
|
|
|
40
40
|
from typing import Any
|
|
41
41
|
|
|
42
42
|
import lsst.resources
|
|
43
|
-
from lsst.daf.butler import Butler
|
|
43
|
+
from lsst.daf.butler import Butler, DatasetRef
|
|
44
|
+
from lsst.daf.butler._rubin.temporary_for_ingest import TemporaryForIngest
|
|
44
45
|
|
|
45
46
|
from ._quantumContext import ExecutionResources
|
|
46
47
|
from .all_dimensions_quantum_graph_builder import AllDimensionsQuantumGraphBuilder
|
|
@@ -362,6 +363,8 @@ class SeparablePipelineExecutor:
|
|
|
362
363
|
fail_fast: bool = False,
|
|
363
364
|
graph_executor: QuantumGraphExecutor | None = None,
|
|
364
365
|
num_proc: int = 1,
|
|
366
|
+
*,
|
|
367
|
+
provenance_dataset_ref: DatasetRef | None = None,
|
|
365
368
|
) -> None:
|
|
366
369
|
"""Run a pipeline in the form of a prepared quantum graph.
|
|
367
370
|
|
|
@@ -384,6 +387,14 @@ class SeparablePipelineExecutor:
|
|
|
384
387
|
The number of processes that can be used to run the pipeline. The
|
|
385
388
|
default value ensures that no subprocess is created. Only used with
|
|
386
389
|
the default graph executor.
|
|
390
|
+
provenance_dataset_ref : `lsst.daf.butler.DatasetRef`, optional
|
|
391
|
+
Dataset that should be used to save provenance. Provenance is only
|
|
392
|
+
supported when running in a single process (at least for the
|
|
393
|
+
default quantum executor), and should not be used with
|
|
394
|
+
``skip_existing_in=[output_run]`` when retrying a previous
|
|
395
|
+
execution attempt. The caller is responsible for registering the
|
|
396
|
+
dataset type and for ensuring that the dimensions of this dataset
|
|
397
|
+
do not lead to uniqueness conflicts.
|
|
387
398
|
"""
|
|
388
399
|
if not graph_executor:
|
|
389
400
|
quantum_executor = SingleQuantumExecutor(
|
|
@@ -404,4 +415,9 @@ class SeparablePipelineExecutor:
|
|
|
404
415
|
# forked processes.
|
|
405
416
|
self._butler.registry.resetConnectionPool()
|
|
406
417
|
|
|
407
|
-
|
|
418
|
+
if provenance_dataset_ref is not None:
|
|
419
|
+
with TemporaryForIngest(self._butler, provenance_dataset_ref) as temporary:
|
|
420
|
+
graph_executor.execute(graph, provenance_graph_file=temporary.ospath)
|
|
421
|
+
temporary.ingest()
|
|
422
|
+
else:
|
|
423
|
+
graph_executor.execute(graph)
|
|
@@ -37,13 +37,13 @@ from typing import Any
|
|
|
37
37
|
|
|
38
38
|
from lsst.daf.butler import (
|
|
39
39
|
Butler,
|
|
40
|
-
ButlerMetrics,
|
|
41
40
|
DatasetRef,
|
|
42
41
|
DatasetType,
|
|
43
42
|
LimitedButler,
|
|
44
43
|
NamedKeyDict,
|
|
45
44
|
Quantum,
|
|
46
45
|
)
|
|
46
|
+
from lsst.daf.butler.logging import ButlerLogRecords
|
|
47
47
|
from lsst.utils.introspection import get_full_type_name
|
|
48
48
|
from lsst.utils.timer import logInfo
|
|
49
49
|
|
|
@@ -59,7 +59,7 @@ from .connections import AdjustQuantumHelper
|
|
|
59
59
|
from .log_capture import LogCapture, _ExecutionLogRecordsExtra
|
|
60
60
|
from .pipeline_graph import TaskNode
|
|
61
61
|
from .pipelineTask import PipelineTask
|
|
62
|
-
from .quantum_graph_executor import QuantumExecutor
|
|
62
|
+
from .quantum_graph_executor import QuantumExecutionResult, QuantumExecutor
|
|
63
63
|
from .quantum_reports import QuantumReport
|
|
64
64
|
from .task import _TASK_FULL_METADATA_TYPE, _TASK_METADATA_TYPE
|
|
65
65
|
from .taskFactory import TaskFactory
|
|
@@ -157,21 +157,28 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
157
157
|
self._previous_process_quanta: list[uuid.UUID] = []
|
|
158
158
|
|
|
159
159
|
def execute(
|
|
160
|
-
self,
|
|
161
|
-
|
|
160
|
+
self,
|
|
161
|
+
task_node: TaskNode,
|
|
162
|
+
/,
|
|
163
|
+
quantum: Quantum,
|
|
164
|
+
quantum_id: uuid.UUID | None = None,
|
|
165
|
+
*,
|
|
166
|
+
log_records: ButlerLogRecords | None = None,
|
|
167
|
+
) -> QuantumExecutionResult:
|
|
162
168
|
# Docstring inherited from QuantumExecutor.execute
|
|
163
|
-
assert quantum.dataId is not None, "Quantum DataId cannot be None"
|
|
164
|
-
|
|
165
169
|
if self._butler is not None:
|
|
166
170
|
self._butler.registry.refresh()
|
|
167
|
-
|
|
168
|
-
result = self._execute(task_node, quantum, quantum_id=quantum_id)
|
|
169
|
-
report = QuantumReport(quantumId=quantum_id, dataId=quantum.dataId, taskLabel=task_node.label)
|
|
170
|
-
return result, report
|
|
171
|
+
return self._execute(task_node, quantum, quantum_id=quantum_id, log_records=log_records)
|
|
171
172
|
|
|
172
173
|
def _execute(
|
|
173
|
-
self,
|
|
174
|
-
|
|
174
|
+
self,
|
|
175
|
+
task_node: TaskNode,
|
|
176
|
+
/,
|
|
177
|
+
quantum: Quantum,
|
|
178
|
+
quantum_id: uuid.UUID | None = None,
|
|
179
|
+
*,
|
|
180
|
+
log_records: ButlerLogRecords | None = None,
|
|
181
|
+
) -> QuantumExecutionResult:
|
|
175
182
|
"""Execute the quantum.
|
|
176
183
|
|
|
177
184
|
Internal implementation of `execute()`.
|
|
@@ -189,7 +196,7 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
189
196
|
|
|
190
197
|
try:
|
|
191
198
|
return self._execute_with_limited_butler(
|
|
192
|
-
task_node, limited_butler, quantum=quantum, quantum_id=quantum_id
|
|
199
|
+
task_node, limited_butler, quantum=quantum, quantum_id=quantum_id, log_records=log_records
|
|
193
200
|
)
|
|
194
201
|
finally:
|
|
195
202
|
if used_butler_factory:
|
|
@@ -202,14 +209,17 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
202
209
|
/,
|
|
203
210
|
quantum: Quantum,
|
|
204
211
|
quantum_id: uuid.UUID | None = None,
|
|
205
|
-
|
|
212
|
+
*,
|
|
213
|
+
log_records: ButlerLogRecords | None = None,
|
|
214
|
+
) -> QuantumExecutionResult:
|
|
206
215
|
startTime = time.time()
|
|
207
|
-
|
|
216
|
+
assert quantum.dataId is not None, "Quantum DataId cannot be None"
|
|
217
|
+
report = QuantumReport(quantumId=quantum_id, dataId=quantum.dataId, taskLabel=task_node.label)
|
|
208
218
|
if self._butler is not None:
|
|
209
219
|
log_capture = LogCapture.from_full(self._butler)
|
|
210
220
|
else:
|
|
211
221
|
log_capture = LogCapture.from_limited(limited_butler)
|
|
212
|
-
with log_capture.capture_logging(task_node, quantum) as captureLog:
|
|
222
|
+
with log_capture.capture_logging(task_node, quantum, records=log_records) as captureLog:
|
|
213
223
|
# Save detailed resource usage before task start to metadata.
|
|
214
224
|
quantumMetadata = _TASK_METADATA_TYPE()
|
|
215
225
|
logInfo(None, "prep", metadata=quantumMetadata) # type: ignore[arg-type]
|
|
@@ -228,7 +238,7 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
228
238
|
task_node.label,
|
|
229
239
|
quantum.dataId,
|
|
230
240
|
)
|
|
231
|
-
return quantum
|
|
241
|
+
return QuantumExecutionResult(quantum, report, skipped_existing=True, adjusted_no_work=False)
|
|
232
242
|
captureLog.store = True
|
|
233
243
|
|
|
234
244
|
captureLog.extra.previous_process_quanta.extend(self._previous_process_quanta)
|
|
@@ -256,7 +266,7 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
256
266
|
if self._job_metadata is not None:
|
|
257
267
|
fullMetadata["job"] = self._job_metadata
|
|
258
268
|
self._write_metadata(quantum, fullMetadata, task_node, limited_butler)
|
|
259
|
-
return quantum
|
|
269
|
+
return QuantumExecutionResult(quantum, report, skipped_existing=False, adjusted_no_work=True)
|
|
260
270
|
|
|
261
271
|
# enable lsstDebug debugging
|
|
262
272
|
if self._enable_lsst_debug:
|
|
@@ -278,10 +288,12 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
278
288
|
)
|
|
279
289
|
task = self._task_factory.makeTask(task_node, limited_butler, init_input_refs)
|
|
280
290
|
logInfo(None, "start", metadata=quantumMetadata) # type: ignore[arg-type]
|
|
291
|
+
outputs_put: list[uuid.UUID] = []
|
|
281
292
|
try:
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
293
|
+
with limited_butler.record_metrics() as butler_metrics:
|
|
294
|
+
caveats = self._run_quantum(
|
|
295
|
+
task, quantum, task_node, limited_butler, quantum_id=quantum_id, ids_put=outputs_put
|
|
296
|
+
)
|
|
285
297
|
except Exception as e:
|
|
286
298
|
_LOG.error(
|
|
287
299
|
"Execution of task '%s' on quantum %s failed. Exception %s: %s",
|
|
@@ -301,10 +313,10 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
301
313
|
quantumMetadata["caveats"] = caveats.value
|
|
302
314
|
# Stringify the UUID for easier compatibility with
|
|
303
315
|
# PropertyList.
|
|
304
|
-
quantumMetadata["outputs"] = [str(output) for output in outputsPut]
|
|
305
316
|
finally:
|
|
306
317
|
logInfo(None, "end", metadata=quantumMetadata) # type: ignore[arg-type]
|
|
307
318
|
fullMetadata = task.getFullMetadata()
|
|
319
|
+
quantumMetadata["outputs"] = [str(output) for output in outputs_put]
|
|
308
320
|
fullMetadata["quantum"] = quantumMetadata
|
|
309
321
|
if self._job_metadata is not None:
|
|
310
322
|
fullMetadata["job"] = self._job_metadata
|
|
@@ -317,7 +329,13 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
317
329
|
quantum.dataId,
|
|
318
330
|
stopTime - startTime,
|
|
319
331
|
)
|
|
320
|
-
return
|
|
332
|
+
return QuantumExecutionResult(
|
|
333
|
+
quantum,
|
|
334
|
+
report,
|
|
335
|
+
skipped_existing=False,
|
|
336
|
+
adjusted_no_work=False,
|
|
337
|
+
task_metadata=fullMetadata,
|
|
338
|
+
)
|
|
321
339
|
|
|
322
340
|
def _check_existing_outputs(
|
|
323
341
|
self,
|
|
@@ -519,8 +537,9 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
519
537
|
task_node: TaskNode,
|
|
520
538
|
/,
|
|
521
539
|
limited_butler: LimitedButler,
|
|
522
|
-
quantum_id: uuid.UUID | None
|
|
523
|
-
|
|
540
|
+
quantum_id: uuid.UUID | None,
|
|
541
|
+
ids_put: list[uuid.UUID],
|
|
542
|
+
) -> QuantumSuccessCaveats:
|
|
524
543
|
"""Execute task on a single quantum.
|
|
525
544
|
|
|
526
545
|
Parameters
|
|
@@ -533,18 +552,17 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
533
552
|
Task definition structure.
|
|
534
553
|
limited_butler : `~lsst.daf.butler.LimitedButler`
|
|
535
554
|
Butler to use for dataset I/O.
|
|
536
|
-
quantum_id : `uuid.UUID` or `None
|
|
555
|
+
quantum_id : `uuid.UUID` or `None`
|
|
537
556
|
ID of the quantum being executed.
|
|
557
|
+
ids_put : list[ `uuid.UUID` ]
|
|
558
|
+
List to be populated with the dataset IDs that were written by this
|
|
559
|
+
quantum. This is an output parameter in order to allow it to be
|
|
560
|
+
populated even when an exception is raised.
|
|
538
561
|
|
|
539
562
|
Returns
|
|
540
563
|
-------
|
|
541
564
|
flags : `QuantumSuccessCaveats`
|
|
542
565
|
Flags that describe qualified successes.
|
|
543
|
-
ids_put : list[ `uuid.UUID` ]
|
|
544
|
-
Record of all the dataset IDs that were written by this quantum
|
|
545
|
-
being executed.
|
|
546
|
-
metrics : `lsst.daf.butler.ButlerMetrics`
|
|
547
|
-
Butler metrics recorded for this quantum.
|
|
548
566
|
"""
|
|
549
567
|
flags = QuantumSuccessCaveats.NO_CAVEATS
|
|
550
568
|
|
|
@@ -556,8 +574,7 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
556
574
|
|
|
557
575
|
# Call task runQuantum() method.
|
|
558
576
|
try:
|
|
559
|
-
|
|
560
|
-
task.runQuantum(butlerQC, inputRefs, outputRefs)
|
|
577
|
+
task.runQuantum(butlerQC, inputRefs, outputRefs)
|
|
561
578
|
except NoWorkFound as err:
|
|
562
579
|
# Not an error, just an early exit.
|
|
563
580
|
_LOG.info(
|
|
@@ -595,12 +612,13 @@ class SingleQuantumExecutor(QuantumExecutor):
|
|
|
595
612
|
)
|
|
596
613
|
_LOG.error(error, exc_info=error)
|
|
597
614
|
flags |= caught.FLAGS
|
|
615
|
+
finally:
|
|
616
|
+
ids_put.extend(output[2] for output in butlerQC.outputsPut)
|
|
598
617
|
if not butlerQC.outputsPut:
|
|
599
618
|
flags |= QuantumSuccessCaveats.ALL_OUTPUTS_MISSING
|
|
600
619
|
if not butlerQC.outputsPut == butlerQC.allOutputs:
|
|
601
620
|
flags |= QuantumSuccessCaveats.ANY_OUTPUTS_MISSING
|
|
602
|
-
|
|
603
|
-
return flags, ids_put, butler_metrics
|
|
621
|
+
return flags
|
|
604
622
|
|
|
605
623
|
def _write_metadata(
|
|
606
624
|
self, quantum: Quantum, metadata: Any, task_node: TaskNode, /, limited_butler: LimitedButler
|
lsst/pipe/base/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "30.0.
|
|
2
|
+
__version__ = "30.0.0rc3"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-pipe-base
|
|
3
|
-
Version: 30.0.
|
|
3
|
+
Version: 30.0.0rc3
|
|
4
4
|
Summary: Pipeline infrastructure for the Rubin Science Pipelines.
|
|
5
5
|
Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
|
|
6
6
|
License-Expression: BSD-3-Clause OR GPL-3.0-or-later
|
|
@@ -3,7 +3,7 @@ lsst/pipe/__init__.py,sha256=_2bZAHuDVAx7MM7KA7pt3DYp641NY4RzSoRAwesWKfU,67
|
|
|
3
3
|
lsst/pipe/base/__init__.py,sha256=qBLN0yYQjIcLBLb4jFKM_ppopuqTnCehcUdFcEe69Js,970
|
|
4
4
|
lsst/pipe/base/_datasetQueryConstraints.py,sha256=bFH0_lVc49NS2_4v_i6r9POr500c0K-OHLMhMX5FjkQ,6373
|
|
5
5
|
lsst/pipe/base/_dataset_handle.py,sha256=ft_ke1LbhLLndDPARsHSQJUA05LgUFnfWOq2vbwH3wI,11353
|
|
6
|
-
lsst/pipe/base/_instrument.py,sha256=
|
|
6
|
+
lsst/pipe/base/_instrument.py,sha256=yZTTgEPmGcEKG4WnAkfWGM1K5f3PxALcQRFqrtVp57A,30215
|
|
7
7
|
lsst/pipe/base/_observation_dimension_packer.py,sha256=78Jg2OVFOdXIK62TS2Y3X4095xqCzmiIx9o4TXyADYA,8027
|
|
8
8
|
lsst/pipe/base/_quantumContext.py,sha256=gb60mTHbgOIEptYvJ64SaChvViXyeKJlG6kEHq4nYVw,19345
|
|
9
9
|
lsst/pipe/base/_status.py,sha256=7gJPrqt03t1fO5tREc_sfQaN7XmDBvruihORXPnRqUE,21216
|
|
@@ -20,29 +20,30 @@ lsst/pipe/base/exec_fixup_data_id.py,sha256=9OjOcH-6AHZ1JnD_CemieI0wWX90J_VdaY9v
|
|
|
20
20
|
lsst/pipe/base/execution_graph_fixup.py,sha256=ND0x4hlpeEW-gudo-i2K7HT7MoM5sp_mcoqRMCopSqQ,3815
|
|
21
21
|
lsst/pipe/base/execution_reports.py,sha256=jYtWCD4PkEAeVUpKIxuiJJVgsCm7qiwCorWVgNHkVgU,17270
|
|
22
22
|
lsst/pipe/base/graph_walker.py,sha256=Ij7JfYF0srA29VgM_DhbNBxUBeOHDOnujrTQPjVNha0,4694
|
|
23
|
-
lsst/pipe/base/log_capture.py,sha256=
|
|
23
|
+
lsst/pipe/base/log_capture.py,sha256=6fq1L53FUYsbILX-tQixXUhxQjvKxFGDjYELRDAXnsw,11072
|
|
24
|
+
lsst/pipe/base/log_on_close.py,sha256=rauQYvsWQF9GuxoaZRjPJJ7VjATGyRUo0RyHEoUVTnQ,2666
|
|
24
25
|
lsst/pipe/base/mermaid_tools.py,sha256=cdlDJQ1x8k7-VvCLEUqvSC3GR1zCsB-aUTxOjYejNWc,5216
|
|
25
|
-
lsst/pipe/base/mp_graph_executor.py,sha256=
|
|
26
|
+
lsst/pipe/base/mp_graph_executor.py,sha256=bbsJD0i-WpW1Qc6lAvagIIx__jZfeOqN8dyt3IsyEq0,37350
|
|
26
27
|
lsst/pipe/base/pipeline.py,sha256=FVaiLhgw9Pzo-nzXKS0dLNafegP0AMZKLtPlSvOSkRU,37563
|
|
27
28
|
lsst/pipe/base/pipelineIR.py,sha256=UuZ02NLhVmzzekbuWlyar7cPLCf_4yfzD5qFEmGHs_A,45821
|
|
28
29
|
lsst/pipe/base/pipelineTask.py,sha256=K3GdjJLvy8A7I-jzQiERQZaYF7mC1LM3iB5TmUtbOCI,8394
|
|
29
30
|
lsst/pipe/base/prerequisite_helpers.py,sha256=bmiebQ4veSrypZgAXjmCBFfj8fUtPW9eRQaVShhxdBQ,28446
|
|
30
31
|
lsst/pipe/base/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
-
lsst/pipe/base/quantum_graph_builder.py,sha256=
|
|
32
|
-
lsst/pipe/base/quantum_graph_executor.py,sha256
|
|
33
|
-
lsst/pipe/base/quantum_graph_skeleton.py,sha256=
|
|
32
|
+
lsst/pipe/base/quantum_graph_builder.py,sha256=YM3pvt4ignAZnpO9bpBc_Yl8V-y2r3SQmYJdWnyQQNI,68742
|
|
33
|
+
lsst/pipe/base/quantum_graph_executor.py,sha256=-bbeR9wZ5_Etcqpx6cDS_R-oEvfUVv9gmW0Wc4QuQNc,8127
|
|
34
|
+
lsst/pipe/base/quantum_graph_skeleton.py,sha256=hxSbeNhdCSBO2aqdIMRyQaejiUxKQfE6bSn0S0qWBNo,28395
|
|
34
35
|
lsst/pipe/base/quantum_provenance_graph.py,sha256=33S5iCVxD9Co4oJSU_N8AJXL14Nw0UwGzPEc3gpQiqk,91981
|
|
35
36
|
lsst/pipe/base/quantum_reports.py,sha256=ut235L88v7SXaeVUvMA9qFl7tpeMwGnzob3X0QoOI_s,14210
|
|
36
37
|
lsst/pipe/base/resource_usage.py,sha256=LfH7Qf6taI3lxw0aB90riRMn1UxUTMBSqtBjKPJ-XuY,6759
|
|
37
|
-
lsst/pipe/base/separable_pipeline_executor.py,sha256=
|
|
38
|
+
lsst/pipe/base/separable_pipeline_executor.py,sha256=y3ZnQJApocxusHGG1R5Rnpke3B0vren1h4dcuyZLivs,17717
|
|
38
39
|
lsst/pipe/base/simple_pipeline_executor.py,sha256=_HGeAOgHUiRdQwsmD_qira-vcHZXlLbf_LmhLJffh2U,29563
|
|
39
|
-
lsst/pipe/base/single_quantum_executor.py,sha256=
|
|
40
|
+
lsst/pipe/base/single_quantum_executor.py,sha256=BgmRtouSIKMeh44hbihdyWsYG4sH1fvoN1PoyVNjxUI,29283
|
|
40
41
|
lsst/pipe/base/struct.py,sha256=Fa-UkpuXOxdzKWbHrMUkJYOszZuBXCm2NesXNR0IOPQ,5048
|
|
41
42
|
lsst/pipe/base/task.py,sha256=XHBd-7m1a4-6LgobBYA1DgY4H7EV-_RWKfxbhZbMmD4,15145
|
|
42
43
|
lsst/pipe/base/taskFactory.py,sha256=MsDGECJqZLSZk8SGhpuVhNaP32UWuNvxZiDcZExPFG8,3412
|
|
43
44
|
lsst/pipe/base/testUtils.py,sha256=lSBKMhoKflbi8JkMNYfEqqHNl-rtFI8UYT3QneDYpLo,18477
|
|
44
45
|
lsst/pipe/base/utils.py,sha256=JmEt3l0xrh9uayKrSXuQEq12aXOhDr2YXmbYduaxCko,1940
|
|
45
|
-
lsst/pipe/base/version.py,sha256=
|
|
46
|
+
lsst/pipe/base/version.py,sha256=Tt7y1Knxuicvk026_H8m0GXmxEFM8XEWyfbDoHcAxbs,52
|
|
46
47
|
lsst/pipe/base/cli/__init__.py,sha256=861tXIAW7SqtqNUYkjbeEdfg8lDswXsjJQca0gVCFz4,54
|
|
47
48
|
lsst/pipe/base/cli/_get_cli_subcommands.py,sha256=g_af64klRybBGKAg7fmBSZBdw2LYBAsFON_yQIMZON0,1289
|
|
48
49
|
lsst/pipe/base/cli/cmd/__init__.py,sha256=3UF2IQEEBor4YMGRNPdcZAVCAI5yFyeHp5nGul4IoyM,1557
|
|
@@ -82,20 +83,21 @@ lsst/pipe/base/pipeline_graph/visualization/_printer.py,sha256=yJMRJ-aXd3nYDgs1F
|
|
|
82
83
|
lsst/pipe/base/pipeline_graph/visualization/_show.py,sha256=lPRjO1To2n5r3f_Wgcwy-7TmyJ7UszGGFXAlOtN1wDs,10510
|
|
83
84
|
lsst/pipe/base/pipeline_graph/visualization/_status_annotator.py,sha256=dp7PXl9Cu7GfWjBi5g8KjXZgnF1KGg_idKKxtICL53Q,8679
|
|
84
85
|
lsst/pipe/base/quantum_graph/__init__.py,sha256=-Gp3LihB0AXCvhG387wKAEpHRM-NrHGSXMti8cHee90,1437
|
|
85
|
-
lsst/pipe/base/quantum_graph/_common.py,sha256=
|
|
86
|
-
lsst/pipe/base/quantum_graph/_multiblock.py,sha256=
|
|
87
|
-
lsst/pipe/base/quantum_graph/_predicted.py,sha256=
|
|
88
|
-
lsst/pipe/base/quantum_graph/_provenance.py,sha256=
|
|
86
|
+
lsst/pipe/base/quantum_graph/_common.py,sha256=jBNmuVK0RaD6nFNk2cmRQY5ej0v_wADRREcAPlhneNs,22841
|
|
87
|
+
lsst/pipe/base/quantum_graph/_multiblock.py,sha256=lw--3Ol-nmQPkC5gzC95xUTkGXOVAfPoa1bb21cFHXE,27412
|
|
88
|
+
lsst/pipe/base/quantum_graph/_predicted.py,sha256=vUbKXfIPLtH4YZmgAlxJBwCqwMJ9X-2dSFh35vgvntg,91216
|
|
89
|
+
lsst/pipe/base/quantum_graph/_provenance.py,sha256=eGCs2K9UYg5bILEPY6x6xsoA1x-mTTgzn5opFq1bL6k,84207
|
|
90
|
+
lsst/pipe/base/quantum_graph/formatter.py,sha256=PZhn6I7HAdBjhm-_vcWoXdhwm9hDsK5QQ07GnIGJtPU,3948
|
|
89
91
|
lsst/pipe/base/quantum_graph/visualization.py,sha256=EbTWhk9aPq7sX6bcHmnEIsr2xuuR6d1SxspQbRe8D0Q,12235
|
|
90
92
|
lsst/pipe/base/quantum_graph/aggregator/__init__.py,sha256=4CK8sP_ZjUKmxKS3LnCH1zG7XSk9IEwijrluRBHhEMU,7436
|
|
91
|
-
lsst/pipe/base/quantum_graph/aggregator/_communicators.py,sha256=
|
|
93
|
+
lsst/pipe/base/quantum_graph/aggregator/_communicators.py,sha256=deLXCdKlSM2GXGW4LdtfzOS7aa3Yd9QVajtyjJE4u3s,35197
|
|
92
94
|
lsst/pipe/base/quantum_graph/aggregator/_config.py,sha256=iV1Ejfk-UnFoQ8TkpJE_jMZYHsmZcdLm5R-FnQEqO7s,5167
|
|
93
95
|
lsst/pipe/base/quantum_graph/aggregator/_ingester.py,sha256=lhu8I0R3IwoLkVcrqF1ypoHAFamNapSoMcG9aYFjbQ4,14158
|
|
94
96
|
lsst/pipe/base/quantum_graph/aggregator/_progress.py,sha256=jiz9Np73uUQ03CtH7pI6TXxXrwFUChh5hSj_gbMGHr0,7207
|
|
95
|
-
lsst/pipe/base/quantum_graph/aggregator/_scanner.py,sha256=
|
|
96
|
-
lsst/pipe/base/quantum_graph/aggregator/_structs.py,sha256=
|
|
97
|
-
lsst/pipe/base/quantum_graph/aggregator/_supervisor.py,sha256=
|
|
98
|
-
lsst/pipe/base/quantum_graph/aggregator/_writer.py,sha256=
|
|
97
|
+
lsst/pipe/base/quantum_graph/aggregator/_scanner.py,sha256=HxW8F4smuV3-0g4SFwlQ3SKrktpPDcRkvckz8oVV-s0,12872
|
|
98
|
+
lsst/pipe/base/quantum_graph/aggregator/_structs.py,sha256=tkFh6-XaEoXGqfMH9RQq8rZqXXco1jUtiYCJKPsGus8,2401
|
|
99
|
+
lsst/pipe/base/quantum_graph/aggregator/_supervisor.py,sha256=NuUQiC-ZtLQkK_sJ1bktRiRv4ObdwjeE6vOJLjDrepc,9559
|
|
100
|
+
lsst/pipe/base/quantum_graph/aggregator/_writer.py,sha256=hd3zALTm9uTicQyPukN34fjcUJ3TIogf_EONy5nsywU,7917
|
|
99
101
|
lsst/pipe/base/script/__init__.py,sha256=cLEXE7aq5UZ0juL_ScmRw0weFgp4tDgwEX_ts-NEYic,1522
|
|
100
102
|
lsst/pipe/base/script/register_instrument.py,sha256=neQ2MTPtAiV_Hl2yatQ8-vQC24xHjhpI7VJUHf5kPX4,2445
|
|
101
103
|
lsst/pipe/base/script/retrieve_artifacts_for_quanta.py,sha256=Cr0HpzXm_C3LnIOQg5tNJht02O6xoqtWWIphjugasMA,3957
|
|
@@ -113,13 +115,13 @@ lsst/pipe/base/tests/mocks/_data_id_match.py,sha256=jVekStcrItC0tqOCc01VjYaiE9ex
|
|
|
113
115
|
lsst/pipe/base/tests/mocks/_pipeline_task.py,sha256=N3fC4OMAMWWnYtyLkVdMfb9ZiFse39HniRDvlAOofOY,30691
|
|
114
116
|
lsst/pipe/base/tests/mocks/_repo.py,sha256=SH-jzynS-H2xc_3GLjF7ln-kHdRoSeVVaal5qLd2hXI,28359
|
|
115
117
|
lsst/pipe/base/tests/mocks/_storage_class.py,sha256=12IFfJMbZ5GkYlMX6ZMWiG8pMZc2Jlxke3qQW-bljdU,27434
|
|
116
|
-
lsst_pipe_base-30.0.
|
|
117
|
-
lsst_pipe_base-30.0.
|
|
118
|
-
lsst_pipe_base-30.0.
|
|
119
|
-
lsst_pipe_base-30.0.
|
|
120
|
-
lsst_pipe_base-30.0.
|
|
121
|
-
lsst_pipe_base-30.0.
|
|
122
|
-
lsst_pipe_base-30.0.
|
|
123
|
-
lsst_pipe_base-30.0.
|
|
124
|
-
lsst_pipe_base-30.0.
|
|
125
|
-
lsst_pipe_base-30.0.
|
|
118
|
+
lsst_pipe_base-30.0.0rc3.dist-info/licenses/COPYRIGHT,sha256=kB3Z9_f6a6uFLGpEmNJT_n186CE65H6wHu4F6BNt_zA,368
|
|
119
|
+
lsst_pipe_base-30.0.0rc3.dist-info/licenses/LICENSE,sha256=pRExkS03v0MQW-neNfIcaSL6aiAnoLxYgtZoFzQ6zkM,232
|
|
120
|
+
lsst_pipe_base-30.0.0rc3.dist-info/licenses/bsd_license.txt,sha256=7MIcv8QRX9guUtqPSBDMPz2SnZ5swI-xZMqm_VDSfxY,1606
|
|
121
|
+
lsst_pipe_base-30.0.0rc3.dist-info/licenses/gpl-v3.0.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
122
|
+
lsst_pipe_base-30.0.0rc3.dist-info/METADATA,sha256=v-PIw7-tNmgiZbq1LmCijq7c2EO70ugAcNVgBphTpdI,2254
|
|
123
|
+
lsst_pipe_base-30.0.0rc3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
124
|
+
lsst_pipe_base-30.0.0rc3.dist-info/entry_points.txt,sha256=bnmUhJBsChxMdqST9VmFBYYKxLQoToOfqW1wjW7khjk,64
|
|
125
|
+
lsst_pipe_base-30.0.0rc3.dist-info/top_level.txt,sha256=eUWiOuVVm9wwTrnAgiJT6tp6HQHXxIhj2QSZ7NYZH80,5
|
|
126
|
+
lsst_pipe_base-30.0.0rc3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
127
|
+
lsst_pipe_base-30.0.0rc3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/licenses/COPYRIGHT
RENAMED
|
File without changes
|
|
File without changes
|
{lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/licenses/bsd_license.txt
RENAMED
|
File without changes
|
{lsst_pipe_base-30.0.0rc2.dist-info → lsst_pipe_base-30.0.0rc3.dist-info}/licenses/gpl-v3.0.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|