lsst-pipe-base 30.0.0rc3__py3-none-any.whl → 30.2025.5100__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.
Files changed (28) hide show
  1. lsst/pipe/base/_instrument.py +5 -6
  2. lsst/pipe/base/log_capture.py +79 -39
  3. lsst/pipe/base/mp_graph_executor.py +15 -51
  4. lsst/pipe/base/quantum_graph/_common.py +3 -4
  5. lsst/pipe/base/quantum_graph/_multiblock.py +16 -6
  6. lsst/pipe/base/quantum_graph/_predicted.py +10 -104
  7. lsst/pipe/base/quantum_graph/_provenance.py +6 -657
  8. lsst/pipe/base/quantum_graph/aggregator/_communicators.py +50 -18
  9. lsst/pipe/base/quantum_graph/aggregator/_scanner.py +229 -35
  10. lsst/pipe/base/quantum_graph/aggregator/_structs.py +113 -3
  11. lsst/pipe/base/quantum_graph/aggregator/_supervisor.py +5 -10
  12. lsst/pipe/base/quantum_graph/aggregator/_writer.py +348 -31
  13. lsst/pipe/base/quantum_graph_executor.py +13 -116
  14. lsst/pipe/base/separable_pipeline_executor.py +2 -18
  15. lsst/pipe/base/single_quantum_executor.py +35 -53
  16. lsst/pipe/base/version.py +1 -1
  17. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/METADATA +1 -1
  18. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/RECORD +26 -28
  19. lsst/pipe/base/log_on_close.py +0 -79
  20. lsst/pipe/base/quantum_graph/formatter.py +0 -101
  21. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/WHEEL +0 -0
  22. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/entry_points.txt +0 -0
  23. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/licenses/COPYRIGHT +0 -0
  24. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/licenses/LICENSE +0 -0
  25. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/licenses/bsd_license.txt +0 -0
  26. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/licenses/gpl-v3.0.txt +0 -0
  27. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/top_level.txt +0 -0
  28. {lsst_pipe_base-30.0.0rc3.dist-info → lsst_pipe_base-30.2025.5100.dist-info}/zip-safe +0 -0
@@ -40,8 +40,7 @@ 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, DatasetRef
44
- from lsst.daf.butler._rubin.temporary_for_ingest import TemporaryForIngest
43
+ from lsst.daf.butler import Butler
45
44
 
46
45
  from ._quantumContext import ExecutionResources
47
46
  from .all_dimensions_quantum_graph_builder import AllDimensionsQuantumGraphBuilder
@@ -363,8 +362,6 @@ class SeparablePipelineExecutor:
363
362
  fail_fast: bool = False,
364
363
  graph_executor: QuantumGraphExecutor | None = None,
365
364
  num_proc: int = 1,
366
- *,
367
- provenance_dataset_ref: DatasetRef | None = None,
368
365
  ) -> None:
369
366
  """Run a pipeline in the form of a prepared quantum graph.
370
367
 
@@ -387,14 +384,6 @@ class SeparablePipelineExecutor:
387
384
  The number of processes that can be used to run the pipeline. The
388
385
  default value ensures that no subprocess is created. Only used with
389
386
  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.
398
387
  """
399
388
  if not graph_executor:
400
389
  quantum_executor = SingleQuantumExecutor(
@@ -415,9 +404,4 @@ class SeparablePipelineExecutor:
415
404
  # forked processes.
416
405
  self._butler.registry.resetConnectionPool()
417
406
 
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)
407
+ 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,
40
41
  DatasetRef,
41
42
  DatasetType,
42
43
  LimitedButler,
43
44
  NamedKeyDict,
44
45
  Quantum,
45
46
  )
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 QuantumExecutionResult, QuantumExecutor
62
+ from .quantum_graph_executor import 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,28 +157,21 @@ class SingleQuantumExecutor(QuantumExecutor):
157
157
  self._previous_process_quanta: list[uuid.UUID] = []
158
158
 
159
159
  def execute(
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:
160
+ self, task_node: TaskNode, /, quantum: Quantum, quantum_id: uuid.UUID | None = None
161
+ ) -> tuple[Quantum, QuantumReport | None]:
168
162
  # Docstring inherited from QuantumExecutor.execute
163
+ assert quantum.dataId is not None, "Quantum DataId cannot be None"
164
+
169
165
  if self._butler is not None:
170
166
  self._butler.registry.refresh()
171
- return self._execute(task_node, quantum, quantum_id=quantum_id, log_records=log_records)
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
172
171
 
173
172
  def _execute(
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:
173
+ self, task_node: TaskNode, /, quantum: Quantum, quantum_id: uuid.UUID | None = None
174
+ ) -> Quantum:
182
175
  """Execute the quantum.
183
176
 
184
177
  Internal implementation of `execute()`.
@@ -196,7 +189,7 @@ class SingleQuantumExecutor(QuantumExecutor):
196
189
 
197
190
  try:
198
191
  return self._execute_with_limited_butler(
199
- task_node, limited_butler, quantum=quantum, quantum_id=quantum_id, log_records=log_records
192
+ task_node, limited_butler, quantum=quantum, quantum_id=quantum_id
200
193
  )
201
194
  finally:
202
195
  if used_butler_factory:
@@ -209,17 +202,14 @@ class SingleQuantumExecutor(QuantumExecutor):
209
202
  /,
210
203
  quantum: Quantum,
211
204
  quantum_id: uuid.UUID | None = None,
212
- *,
213
- log_records: ButlerLogRecords | None = None,
214
- ) -> QuantumExecutionResult:
205
+ ) -> Quantum:
215
206
  startTime = time.time()
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)
207
+
218
208
  if self._butler is not None:
219
209
  log_capture = LogCapture.from_full(self._butler)
220
210
  else:
221
211
  log_capture = LogCapture.from_limited(limited_butler)
222
- with log_capture.capture_logging(task_node, quantum, records=log_records) as captureLog:
212
+ with log_capture.capture_logging(task_node, quantum) as captureLog:
223
213
  # Save detailed resource usage before task start to metadata.
224
214
  quantumMetadata = _TASK_METADATA_TYPE()
225
215
  logInfo(None, "prep", metadata=quantumMetadata) # type: ignore[arg-type]
@@ -238,7 +228,7 @@ class SingleQuantumExecutor(QuantumExecutor):
238
228
  task_node.label,
239
229
  quantum.dataId,
240
230
  )
241
- return QuantumExecutionResult(quantum, report, skipped_existing=True, adjusted_no_work=False)
231
+ return quantum
242
232
  captureLog.store = True
243
233
 
244
234
  captureLog.extra.previous_process_quanta.extend(self._previous_process_quanta)
@@ -266,7 +256,7 @@ class SingleQuantumExecutor(QuantumExecutor):
266
256
  if self._job_metadata is not None:
267
257
  fullMetadata["job"] = self._job_metadata
268
258
  self._write_metadata(quantum, fullMetadata, task_node, limited_butler)
269
- return QuantumExecutionResult(quantum, report, skipped_existing=False, adjusted_no_work=True)
259
+ return quantum
270
260
 
271
261
  # enable lsstDebug debugging
272
262
  if self._enable_lsst_debug:
@@ -288,12 +278,10 @@ class SingleQuantumExecutor(QuantumExecutor):
288
278
  )
289
279
  task = self._task_factory.makeTask(task_node, limited_butler, init_input_refs)
290
280
  logInfo(None, "start", metadata=quantumMetadata) # type: ignore[arg-type]
291
- outputs_put: list[uuid.UUID] = []
292
281
  try:
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
- )
282
+ caveats, outputsPut, butler_metrics = self._run_quantum(
283
+ task, quantum, task_node, limited_butler, quantum_id=quantum_id
284
+ )
297
285
  except Exception as e:
298
286
  _LOG.error(
299
287
  "Execution of task '%s' on quantum %s failed. Exception %s: %s",
@@ -313,10 +301,10 @@ class SingleQuantumExecutor(QuantumExecutor):
313
301
  quantumMetadata["caveats"] = caveats.value
314
302
  # Stringify the UUID for easier compatibility with
315
303
  # PropertyList.
304
+ quantumMetadata["outputs"] = [str(output) for output in outputsPut]
316
305
  finally:
317
306
  logInfo(None, "end", metadata=quantumMetadata) # type: ignore[arg-type]
318
307
  fullMetadata = task.getFullMetadata()
319
- quantumMetadata["outputs"] = [str(output) for output in outputs_put]
320
308
  fullMetadata["quantum"] = quantumMetadata
321
309
  if self._job_metadata is not None:
322
310
  fullMetadata["job"] = self._job_metadata
@@ -329,13 +317,7 @@ class SingleQuantumExecutor(QuantumExecutor):
329
317
  quantum.dataId,
330
318
  stopTime - startTime,
331
319
  )
332
- return QuantumExecutionResult(
333
- quantum,
334
- report,
335
- skipped_existing=False,
336
- adjusted_no_work=False,
337
- task_metadata=fullMetadata,
338
- )
320
+ return quantum
339
321
 
340
322
  def _check_existing_outputs(
341
323
  self,
@@ -537,9 +519,8 @@ class SingleQuantumExecutor(QuantumExecutor):
537
519
  task_node: TaskNode,
538
520
  /,
539
521
  limited_butler: LimitedButler,
540
- quantum_id: uuid.UUID | None,
541
- ids_put: list[uuid.UUID],
542
- ) -> QuantumSuccessCaveats:
522
+ quantum_id: uuid.UUID | None = None,
523
+ ) -> tuple[QuantumSuccessCaveats, list[uuid.UUID], ButlerMetrics]:
543
524
  """Execute task on a single quantum.
544
525
 
545
526
  Parameters
@@ -552,17 +533,18 @@ class SingleQuantumExecutor(QuantumExecutor):
552
533
  Task definition structure.
553
534
  limited_butler : `~lsst.daf.butler.LimitedButler`
554
535
  Butler to use for dataset I/O.
555
- quantum_id : `uuid.UUID` or `None`
536
+ quantum_id : `uuid.UUID` or `None`, optional
556
537
  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.
561
538
 
562
539
  Returns
563
540
  -------
564
541
  flags : `QuantumSuccessCaveats`
565
542
  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.
566
548
  """
567
549
  flags = QuantumSuccessCaveats.NO_CAVEATS
568
550
 
@@ -574,7 +556,8 @@ class SingleQuantumExecutor(QuantumExecutor):
574
556
 
575
557
  # Call task runQuantum() method.
576
558
  try:
577
- task.runQuantum(butlerQC, inputRefs, outputRefs)
559
+ with limited_butler.record_metrics() as butler_metrics:
560
+ task.runQuantum(butlerQC, inputRefs, outputRefs)
578
561
  except NoWorkFound as err:
579
562
  # Not an error, just an early exit.
580
563
  _LOG.info(
@@ -612,13 +595,12 @@ class SingleQuantumExecutor(QuantumExecutor):
612
595
  )
613
596
  _LOG.error(error, exc_info=error)
614
597
  flags |= caught.FLAGS
615
- finally:
616
- ids_put.extend(output[2] for output in butlerQC.outputsPut)
617
598
  if not butlerQC.outputsPut:
618
599
  flags |= QuantumSuccessCaveats.ALL_OUTPUTS_MISSING
619
600
  if not butlerQC.outputsPut == butlerQC.allOutputs:
620
601
  flags |= QuantumSuccessCaveats.ANY_OUTPUTS_MISSING
621
- return flags
602
+ ids_put = [output[2] for output in butlerQC.outputsPut]
603
+ return flags, ids_put, butler_metrics
622
604
 
623
605
  def _write_metadata(
624
606
  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.0rc3"
2
+ __version__ = "30.2025.5100"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-pipe-base
3
- Version: 30.0.0rc3
3
+ Version: 30.2025.5100
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=yZTTgEPmGcEKG4WnAkfWGM1K5f3PxALcQRFqrtVp57A,30215
6
+ lsst/pipe/base/_instrument.py,sha256=I9UTaj81krR1zkTZ1owfOPBzHN29PY3Egg7fIE5obxQ,30057
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,30 +20,29 @@ 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=6fq1L53FUYsbILX-tQixXUhxQjvKxFGDjYELRDAXnsw,11072
24
- lsst/pipe/base/log_on_close.py,sha256=rauQYvsWQF9GuxoaZRjPJJ7VjATGyRUo0RyHEoUVTnQ,2666
23
+ lsst/pipe/base/log_capture.py,sha256=5r99_Ek2A75vYOMo-z52ltWLdfYfWExm55UU9a4nqmM,12909
25
24
  lsst/pipe/base/mermaid_tools.py,sha256=cdlDJQ1x8k7-VvCLEUqvSC3GR1zCsB-aUTxOjYejNWc,5216
26
- lsst/pipe/base/mp_graph_executor.py,sha256=bbsJD0i-WpW1Qc6lAvagIIx__jZfeOqN8dyt3IsyEq0,37350
25
+ lsst/pipe/base/mp_graph_executor.py,sha256=FKlFxjtU2-6SFzX_wsdtMMAj5P09ZE8V65-Sg585g2Y,35501
27
26
  lsst/pipe/base/pipeline.py,sha256=FVaiLhgw9Pzo-nzXKS0dLNafegP0AMZKLtPlSvOSkRU,37563
28
27
  lsst/pipe/base/pipelineIR.py,sha256=UuZ02NLhVmzzekbuWlyar7cPLCf_4yfzD5qFEmGHs_A,45821
29
28
  lsst/pipe/base/pipelineTask.py,sha256=K3GdjJLvy8A7I-jzQiERQZaYF7mC1LM3iB5TmUtbOCI,8394
30
29
  lsst/pipe/base/prerequisite_helpers.py,sha256=bmiebQ4veSrypZgAXjmCBFfj8fUtPW9eRQaVShhxdBQ,28446
31
30
  lsst/pipe/base/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
31
  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
32
+ lsst/pipe/base/quantum_graph_executor.py,sha256=WP41iQmihy1jfgaHV6eu2aSrqQx_Fydq3mbEF6CLQ-s,4419
34
33
  lsst/pipe/base/quantum_graph_skeleton.py,sha256=hxSbeNhdCSBO2aqdIMRyQaejiUxKQfE6bSn0S0qWBNo,28395
35
34
  lsst/pipe/base/quantum_provenance_graph.py,sha256=33S5iCVxD9Co4oJSU_N8AJXL14Nw0UwGzPEc3gpQiqk,91981
36
35
  lsst/pipe/base/quantum_reports.py,sha256=ut235L88v7SXaeVUvMA9qFl7tpeMwGnzob3X0QoOI_s,14210
37
36
  lsst/pipe/base/resource_usage.py,sha256=LfH7Qf6taI3lxw0aB90riRMn1UxUTMBSqtBjKPJ-XuY,6759
38
- lsst/pipe/base/separable_pipeline_executor.py,sha256=y3ZnQJApocxusHGG1R5Rnpke3B0vren1h4dcuyZLivs,17717
37
+ lsst/pipe/base/separable_pipeline_executor.py,sha256=vXqJrRI5GNezzGV9QsiaRHEhioDF2Y_W7JQYQCzHR7A,16720
39
38
  lsst/pipe/base/simple_pipeline_executor.py,sha256=_HGeAOgHUiRdQwsmD_qira-vcHZXlLbf_LmhLJffh2U,29563
40
- lsst/pipe/base/single_quantum_executor.py,sha256=BgmRtouSIKMeh44hbihdyWsYG4sH1fvoN1PoyVNjxUI,29283
39
+ lsst/pipe/base/single_quantum_executor.py,sha256=yCpDS_eHsJTOu34mHYv8DJjj8UG0GjPdCuXdb74A2p8,28543
41
40
  lsst/pipe/base/struct.py,sha256=Fa-UkpuXOxdzKWbHrMUkJYOszZuBXCm2NesXNR0IOPQ,5048
42
41
  lsst/pipe/base/task.py,sha256=XHBd-7m1a4-6LgobBYA1DgY4H7EV-_RWKfxbhZbMmD4,15145
43
42
  lsst/pipe/base/taskFactory.py,sha256=MsDGECJqZLSZk8SGhpuVhNaP32UWuNvxZiDcZExPFG8,3412
44
43
  lsst/pipe/base/testUtils.py,sha256=lSBKMhoKflbi8JkMNYfEqqHNl-rtFI8UYT3QneDYpLo,18477
45
44
  lsst/pipe/base/utils.py,sha256=JmEt3l0xrh9uayKrSXuQEq12aXOhDr2YXmbYduaxCko,1940
46
- lsst/pipe/base/version.py,sha256=Tt7y1Knxuicvk026_H8m0GXmxEFM8XEWyfbDoHcAxbs,52
45
+ lsst/pipe/base/version.py,sha256=T_ii-AmyfLEzX_XiWTNw5GEFMy94NcXrbg2rkzKZg7g,55
47
46
  lsst/pipe/base/cli/__init__.py,sha256=861tXIAW7SqtqNUYkjbeEdfg8lDswXsjJQca0gVCFz4,54
48
47
  lsst/pipe/base/cli/_get_cli_subcommands.py,sha256=g_af64klRybBGKAg7fmBSZBdw2LYBAsFON_yQIMZON0,1289
49
48
  lsst/pipe/base/cli/cmd/__init__.py,sha256=3UF2IQEEBor4YMGRNPdcZAVCAI5yFyeHp5nGul4IoyM,1557
@@ -83,21 +82,20 @@ lsst/pipe/base/pipeline_graph/visualization/_printer.py,sha256=yJMRJ-aXd3nYDgs1F
83
82
  lsst/pipe/base/pipeline_graph/visualization/_show.py,sha256=lPRjO1To2n5r3f_Wgcwy-7TmyJ7UszGGFXAlOtN1wDs,10510
84
83
  lsst/pipe/base/pipeline_graph/visualization/_status_annotator.py,sha256=dp7PXl9Cu7GfWjBi5g8KjXZgnF1KGg_idKKxtICL53Q,8679
85
84
  lsst/pipe/base/quantum_graph/__init__.py,sha256=-Gp3LihB0AXCvhG387wKAEpHRM-NrHGSXMti8cHee90,1437
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
85
+ lsst/pipe/base/quantum_graph/_common.py,sha256=tgQsIylvs5wSAKs3SVp5_XJ7XEBJwBcRUbBGR2EFuwU,22714
86
+ lsst/pipe/base/quantum_graph/_multiblock.py,sha256=kc2pqezfU7xOAxYZa41mz3G4X5w4GVfovw3ZcjNgK2Y,27950
87
+ lsst/pipe/base/quantum_graph/_predicted.py,sha256=ImcH5nYvbUD7bfEnm5sp9wTcEn01ZwseqK1UkQeZ1Sc,87933
88
+ lsst/pipe/base/quantum_graph/_provenance.py,sha256=R1SoRxyi6cNi9fXSc7ybrbri9anuYnliJ6SBmVUrh40,55102
91
89
  lsst/pipe/base/quantum_graph/visualization.py,sha256=EbTWhk9aPq7sX6bcHmnEIsr2xuuR6d1SxspQbRe8D0Q,12235
92
90
  lsst/pipe/base/quantum_graph/aggregator/__init__.py,sha256=4CK8sP_ZjUKmxKS3LnCH1zG7XSk9IEwijrluRBHhEMU,7436
93
- lsst/pipe/base/quantum_graph/aggregator/_communicators.py,sha256=deLXCdKlSM2GXGW4LdtfzOS7aa3Yd9QVajtyjJE4u3s,35197
91
+ lsst/pipe/base/quantum_graph/aggregator/_communicators.py,sha256=w7hNEQjE1Qjhi6u4Tx4wS_1RrV3-WQRCz1FACd-vmro,36396
94
92
  lsst/pipe/base/quantum_graph/aggregator/_config.py,sha256=iV1Ejfk-UnFoQ8TkpJE_jMZYHsmZcdLm5R-FnQEqO7s,5167
95
93
  lsst/pipe/base/quantum_graph/aggregator/_ingester.py,sha256=lhu8I0R3IwoLkVcrqF1ypoHAFamNapSoMcG9aYFjbQ4,14158
96
94
  lsst/pipe/base/quantum_graph/aggregator/_progress.py,sha256=jiz9Np73uUQ03CtH7pI6TXxXrwFUChh5hSj_gbMGHr0,7207
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
95
+ lsst/pipe/base/quantum_graph/aggregator/_scanner.py,sha256=4wg2cgVcAoqyuZZUBogHXWkSr9X6sVwnJLu_o96D204,22758
96
+ lsst/pipe/base/quantum_graph/aggregator/_structs.py,sha256=bM-MejZz5DFUFQCH8kZDykuMBmBJYbQMl15nBm-3dtc,5499
97
+ lsst/pipe/base/quantum_graph/aggregator/_supervisor.py,sha256=5-6CshU9RFyVEgYI3qJwuVEGw8YtT9Ei7cNkcghXzMk,9290
98
+ lsst/pipe/base/quantum_graph/aggregator/_writer.py,sha256=fYQrJGCg3MQQQF1feWXCLyG6m5ucnzFrIINawWgnF8g,21504
101
99
  lsst/pipe/base/script/__init__.py,sha256=cLEXE7aq5UZ0juL_ScmRw0weFgp4tDgwEX_ts-NEYic,1522
102
100
  lsst/pipe/base/script/register_instrument.py,sha256=neQ2MTPtAiV_Hl2yatQ8-vQC24xHjhpI7VJUHf5kPX4,2445
103
101
  lsst/pipe/base/script/retrieve_artifacts_for_quanta.py,sha256=Cr0HpzXm_C3LnIOQg5tNJht02O6xoqtWWIphjugasMA,3957
@@ -115,13 +113,13 @@ lsst/pipe/base/tests/mocks/_data_id_match.py,sha256=jVekStcrItC0tqOCc01VjYaiE9ex
115
113
  lsst/pipe/base/tests/mocks/_pipeline_task.py,sha256=N3fC4OMAMWWnYtyLkVdMfb9ZiFse39HniRDvlAOofOY,30691
116
114
  lsst/pipe/base/tests/mocks/_repo.py,sha256=SH-jzynS-H2xc_3GLjF7ln-kHdRoSeVVaal5qLd2hXI,28359
117
115
  lsst/pipe/base/tests/mocks/_storage_class.py,sha256=12IFfJMbZ5GkYlMX6ZMWiG8pMZc2Jlxke3qQW-bljdU,27434
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,,
116
+ lsst_pipe_base-30.2025.5100.dist-info/licenses/COPYRIGHT,sha256=kB3Z9_f6a6uFLGpEmNJT_n186CE65H6wHu4F6BNt_zA,368
117
+ lsst_pipe_base-30.2025.5100.dist-info/licenses/LICENSE,sha256=pRExkS03v0MQW-neNfIcaSL6aiAnoLxYgtZoFzQ6zkM,232
118
+ lsst_pipe_base-30.2025.5100.dist-info/licenses/bsd_license.txt,sha256=7MIcv8QRX9guUtqPSBDMPz2SnZ5swI-xZMqm_VDSfxY,1606
119
+ lsst_pipe_base-30.2025.5100.dist-info/licenses/gpl-v3.0.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
120
+ lsst_pipe_base-30.2025.5100.dist-info/METADATA,sha256=AZu2-D91gCmfRmP0m2ETbsiRKZwX8DXqBiO-rvyDzFo,2257
121
+ lsst_pipe_base-30.2025.5100.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
122
+ lsst_pipe_base-30.2025.5100.dist-info/entry_points.txt,sha256=bnmUhJBsChxMdqST9VmFBYYKxLQoToOfqW1wjW7khjk,64
123
+ lsst_pipe_base-30.2025.5100.dist-info/top_level.txt,sha256=eUWiOuVVm9wwTrnAgiJT6tp6HQHXxIhj2QSZ7NYZH80,5
124
+ lsst_pipe_base-30.2025.5100.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
125
+ lsst_pipe_base-30.2025.5100.dist-info/RECORD,,
@@ -1,79 +0,0 @@
1
- # This file is part of pipe_base.
2
- #
3
- # Developed for the LSST Data Management System.
4
- # This product includes software developed by the LSST Project
5
- # (http://www.lsst.org).
6
- # See the COPYRIGHT file at the top-level directory of this distribution
7
- # for details of code ownership.
8
- #
9
- # This software is dual licensed under the GNU General Public License and also
10
- # under a 3-clause BSD license. Recipients may choose which of these licenses
11
- # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12
- # respectively. If you choose the GPL option then the following text applies
13
- # (but note that there is still no warranty even if you opt for BSD instead):
14
- #
15
- # This program is free software: you can redistribute it and/or modify
16
- # it under the terms of the GNU General Public License as published by
17
- # the Free Software Foundation, either version 3 of the License, or
18
- # (at your option) any later version.
19
- #
20
- # This program is distributed in the hope that it will be useful,
21
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- # GNU General Public License for more details.
24
- #
25
- # You should have received a copy of the GNU General Public License
26
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
27
-
28
- from __future__ import annotations
29
-
30
- __all__ = ("LogOnClose",)
31
-
32
- from collections.abc import Callable, Iterator
33
- from contextlib import AbstractContextManager, contextmanager
34
- from typing import TypeVar
35
-
36
- from lsst.utils.logging import VERBOSE
37
-
38
- _T = TypeVar("_T")
39
-
40
-
41
- class LogOnClose:
42
- """A factory for context manager wrappers that emit a log message when
43
- they are closed.
44
-
45
- Parameters
46
- ----------
47
- log_func : `~collections.abc.Callable` [ `int`, `str` ]
48
- Callable that takes an integer log level and a string message and emits
49
- a log message. Note that placeholder formatting is not supported.
50
- """
51
-
52
- def __init__(self, log_func: Callable[[int, str], None]):
53
- self.log_func = log_func
54
-
55
- def wrap(
56
- self,
57
- cm: AbstractContextManager[_T],
58
- msg: str,
59
- level: int = VERBOSE,
60
- ) -> AbstractContextManager[_T]:
61
- """Wrap a context manager to log when it is exited.
62
-
63
- Parameters
64
- ----------
65
- cm : `contextlib.AbstractContextManager`
66
- Context manager to wrap.
67
- msg : `str`
68
- Log message.
69
- level : `int`, optional
70
- Log level.
71
- """
72
-
73
- @contextmanager
74
- def wrapper() -> Iterator[_T]:
75
- with cm as result:
76
- yield result
77
- self.log_func(level, msg)
78
-
79
- return wrapper()
@@ -1,101 +0,0 @@
1
- # This file is part of pipe_base.
2
- #
3
- # Developed for the LSST Data Management System.
4
- # This product includes software developed by the LSST Project
5
- # (http://www.lsst.org).
6
- # See the COPYRIGHT file at the top-level directory of this distribution
7
- # for details of code ownership.
8
- #
9
- # This software is dual licensed under the GNU General Public License and also
10
- # under a 3-clause BSD license. Recipients may choose which of these licenses
11
- # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12
- # respectively. If you choose the GPL option then the following text applies
13
- # (but note that there is still no warranty even if you opt for BSD instead):
14
- #
15
- # This program is free software: you can redistribute it and/or modify
16
- # it under the terms of the GNU General Public License as published by
17
- # the Free Software Foundation, either version 3 of the License, or
18
- # (at your option) any later version.
19
- #
20
- # This program is distributed in the hope that it will be useful,
21
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- # GNU General Public License for more details.
24
- #
25
- # You should have received a copy of the GNU General Public License
26
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
27
-
28
- from __future__ import annotations
29
-
30
- __all__ = ("ProvenanceFormatter",)
31
-
32
- import uuid
33
- from typing import Any, ClassVar
34
-
35
- import pydantic
36
-
37
- from lsst.daf.butler import FormatterV2
38
- from lsst.resources import ResourcePath
39
- from lsst.utils.logging import getLogger
40
-
41
- from ..pipeline_graph import TaskImportMode
42
- from ._provenance import ProvenanceQuantumGraphReader
43
-
44
- _LOG = getLogger(__file__)
45
-
46
-
47
- class _ProvenanceFormatterParameters(pydantic.BaseModel):
48
- """A Pydantic model for validating and applying defaults to the
49
- read parameters of `ProvenanceFormatter`.
50
- """
51
-
52
- import_mode: TaskImportMode = TaskImportMode.DO_NOT_IMPORT
53
- quanta: list[uuid.UUID] | None = None
54
- datasets: list[uuid.UUID] | None = None
55
- read_init_quanta: bool = True
56
-
57
- @pydantic.field_validator("quanta", mode="before")
58
- @classmethod
59
- def quanta_to_list(cls, v: Any) -> list[uuid.UUID]:
60
- return list(v)
61
-
62
- @pydantic.field_validator("datasets", mode="before")
63
- @classmethod
64
- def datasets_to_list(cls, v: Any) -> list[uuid.UUID]:
65
- return list(v)
66
-
67
- @property
68
- def nodes(self) -> list[uuid.UUID]:
69
- if self.quanta is not None:
70
- if self.datasets is not None:
71
- return self.quanta + self.datasets
72
- else:
73
- return self.quanta
74
- elif self.datasets is not None:
75
- return self.datasets
76
- raise ValueError("'datasets' and/or 'quanta' parameters are required for this component")
77
-
78
-
79
- class ProvenanceFormatter(FormatterV2):
80
- """Butler interface for reading `ProvenanceQuantumGraph` objects."""
81
-
82
- default_extension: ClassVar[str] = ".qg"
83
- can_read_from_uri: ClassVar[bool] = True
84
-
85
- def read_from_uri(self, uri: ResourcePath, component: str | None = None, expected_size: int = -1) -> Any:
86
- parameters = _ProvenanceFormatterParameters.model_validate(self.file_descriptor.parameters or {})
87
- with ProvenanceQuantumGraphReader.open(uri, import_mode=parameters.import_mode) as reader:
88
- match component:
89
- case None:
90
- if parameters.read_init_quanta:
91
- reader.read_init_quanta()
92
- reader.read_quanta(parameters.quanta)
93
- reader.read_datasets(parameters.datasets)
94
- return reader.graph
95
- case "metadata":
96
- return reader.fetch_metadata(parameters.nodes)
97
- case "logs":
98
- return reader.fetch_logs(parameters.nodes)
99
- case "packages":
100
- return reader.fetch_packages()
101
- raise AssertionError(f"Unexpected component {component!r}.")