lsst-ctrl-mpexec 29.2025.4100__tar.gz → 29.2025.4300__tar.gz

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 (70) hide show
  1. {lsst_ctrl_mpexec-29.2025.4100/python/lsst_ctrl_mpexec.egg-info → lsst_ctrl_mpexec-29.2025.4300}/PKG-INFO +1 -1
  2. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/qgraph.py +7 -7
  3. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/run_qbb.py +1 -1
  4. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/utils.py +14 -10
  5. lsst_ctrl_mpexec-29.2025.4300/python/lsst/ctrl/mpexec/version.py +2 -0
  6. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300/python/lsst_ctrl_mpexec.egg-info}/PKG-INFO +1 -1
  7. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_qgraph.py +35 -0
  8. lsst_ctrl_mpexec-29.2025.4100/python/lsst/ctrl/mpexec/version.py +0 -2
  9. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/COPYRIGHT +0 -0
  10. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/LICENSE +0 -0
  11. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/MANIFEST.in +0 -0
  12. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/README.rst +0 -0
  13. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/bsd_license.txt +0 -0
  14. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/doc/lsst.ctrl.mpexec/CHANGES.rst +0 -0
  15. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/doc/lsst.ctrl.mpexec/configuring-pipetask-tasks.rst +0 -0
  16. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/doc/lsst.ctrl.mpexec/index.rst +0 -0
  17. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/doc/lsst.ctrl.mpexec/pipetask.rst +0 -0
  18. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/gpl-v3.0.txt +0 -0
  19. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/pyproject.toml +0 -0
  20. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/__init__.py +0 -0
  21. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/__init__.py +0 -0
  22. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/__init__.py +0 -0
  23. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/_pipeline_graph_factory.py +0 -0
  24. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/__init__.py +0 -0
  25. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/butler_factory.py +0 -0
  26. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/cmd/__init__.py +0 -0
  27. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/cmd/commands.py +0 -0
  28. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/opt/__init__.py +0 -0
  29. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/opt/arguments.py +0 -0
  30. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/opt/optionGroups.py +0 -0
  31. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/opt/options.py +0 -0
  32. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/pipetask.py +0 -0
  33. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/__init__.py +0 -0
  34. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/build.py +0 -0
  35. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/cleanup.py +0 -0
  36. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/confirmable.py +0 -0
  37. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/pre_exec_init_qbb.py +0 -0
  38. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/purge.py +0 -0
  39. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/report.py +0 -0
  40. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/run.py +0 -0
  41. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/cli/script/update_graph_run.py +0 -0
  42. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/execFixupDataId.py +0 -0
  43. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/executionGraphFixup.py +0 -0
  44. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/log_capture.py +0 -0
  45. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/mpGraphExecutor.py +0 -0
  46. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/preExecInit.py +0 -0
  47. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/py.typed +0 -0
  48. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/quantumGraphExecutor.py +0 -0
  49. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/reports.py +0 -0
  50. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/separablePipelineExecutor.py +0 -0
  51. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/showInfo.py +0 -0
  52. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/simple_pipeline_executor.py +0 -0
  53. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/singleQuantumExecutor.py +0 -0
  54. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/taskFactory.py +0 -0
  55. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst/ctrl/mpexec/util.py +0 -0
  56. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst_ctrl_mpexec.egg-info/SOURCES.txt +0 -0
  57. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst_ctrl_mpexec.egg-info/dependency_links.txt +0 -0
  58. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst_ctrl_mpexec.egg-info/entry_points.txt +0 -0
  59. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst_ctrl_mpexec.egg-info/requires.txt +0 -0
  60. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst_ctrl_mpexec.egg-info/top_level.txt +0 -0
  61. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/python/lsst_ctrl_mpexec.egg-info/zip-safe +0 -0
  62. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/setup.cfg +0 -0
  63. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_build.py +0 -0
  64. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_cliCmdCleanup.py +0 -0
  65. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_cliCmdPurge.py +0 -0
  66. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_cliCmdReport.py +0 -0
  67. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_cliCmdUpdateGraphRun.py +0 -0
  68. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_cliUtils.py +0 -0
  69. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_preExecInit.py +0 -0
  70. {lsst_ctrl_mpexec-29.2025.4100 → lsst_ctrl_mpexec-29.2025.4300}/tests/test_run.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-ctrl-mpexec
3
- Version: 29.2025.4100
3
+ Version: 29.2025.4300
4
4
  Summary: Pipeline execution infrastructure for the Rubin Observatory LSST Science Pipelines.
5
5
  Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
6
6
  License: BSD 3-Clause License
@@ -251,7 +251,7 @@ def qgraph(
251
251
  else:
252
252
  import_mode = TaskImportMode.DO_NOT_IMPORT
253
253
  with PredictedQuantumGraph.open(qgraph, import_mode=import_mode) as reader:
254
- if for_execution or qgraph_dot or qgraph_mermaid or show.needs_full_qg:
254
+ if for_execution or qgraph_dot or qgraph_mermaid or show.needs_full_qg or qgraph_node_id:
255
255
  # This reads everything for the given quanta.
256
256
  reader.read_execution_quanta(quantum_ids)
257
257
  elif for_init_output_run:
@@ -316,24 +316,24 @@ def qgraph(
316
316
  output, metadata=metadata, attach_datastore_records=qgraph_datastore_records
317
317
  )
318
318
 
319
- if not summarize_quantum_graph(qgc.header):
320
- return None
321
-
322
319
  if save_qgraph:
323
320
  _LOG.verbose("Writing quantum graph to %r.", save_qgraph)
324
321
  qgc.write(save_qgraph)
325
322
 
326
323
  qg = qgc.assemble()
327
324
 
325
+ if not summarize_quantum_graph(qg):
326
+ return None
327
+
328
328
  if qgraph_dot:
329
329
  _LOG.verbose("Writing quantum graph DOT visualization to %r.", qgraph_dot)
330
- graph2dot(qg, qgraph_dot) # TODO[DM-51850]: make this work
330
+ graph2dot(qg, qgraph_dot)
331
331
 
332
332
  if qgraph_mermaid:
333
333
  _LOG.verbose("Writing quantum graph Mermaid visualization to %r.", qgraph_mermaid)
334
- graph2mermaid(qg, qgraph_mermaid) # TODO[DM-51850]: make this work
334
+ graph2mermaid(qg, qgraph_mermaid)
335
335
 
336
336
  # optionally dump some info.
337
- show.show_graph_info(qg, butler_config) # TODO[DM-51850]: make this work
337
+ show.show_graph_info(qg, butler_config)
338
338
 
339
339
  return qg
@@ -163,7 +163,7 @@ def run_qbb(
163
163
  qg = PredictedQuantumGraph.read_execution_quanta(qgraph, quantum_ids=quantum_ids)
164
164
  job_metadata = {"qg_read_time": qg_read_time.duration, "qg_size": len(qg)}
165
165
 
166
- summarize_quantum_graph(qg.header)
166
+ summarize_quantum_graph(qg)
167
167
 
168
168
  dataset_types = {dtn.name: dtn.dataset_type for dtn in qg.pipeline_graph.dataset_types.values()}
169
169
 
@@ -38,7 +38,7 @@ from astropy.table import Table
38
38
  from lsst.daf.butler.cli.opt import config_file_option, config_option
39
39
  from lsst.daf.butler.cli.utils import MWCommand, MWCtxObj, split_commas
40
40
  from lsst.pipe.base.cli.opt import instrument_option
41
- from lsst.pipe.base.quantum_graph import HeaderModel
41
+ from lsst.pipe.base.quantum_graph import BaseQuantumGraph
42
42
  from lsst.utils.logging import getLogger
43
43
 
44
44
  from .opt import delete_option, task_option
@@ -219,32 +219,36 @@ class PipetaskCommand(MWCommand):
219
219
  extra_epilog = "See 'pipetask --help' for more options."
220
220
 
221
221
 
222
- def summarize_quantum_graph(qg_header: HeaderModel) -> int:
222
+ def summarize_quantum_graph(qg: BaseQuantumGraph) -> int:
223
223
  """Report a summary of the quanta in the graph.
224
224
 
225
+ This only reports quanta that were actually loaded.
226
+
225
227
  Parameters
226
228
  ----------
227
- qg_header : `lsst.pipe.base.quantum_graph.HeaderModel`
228
- Header of the quantum graph.
229
+ qg : `lsst.pipe.base.quantum_graph.BaseQuantumGraph`
230
+ Quantum graph object
229
231
 
230
232
  Returns
231
233
  -------
232
234
  n_quanta : `int`
233
235
  The number of quanta in the graph.
234
236
  """
235
- n_quanta = qg_header.n_quanta
237
+ n_task_quanta = {
238
+ task_label: len(quanta_for_task)
239
+ for task_label, quanta_for_task in qg.quanta_by_task.items()
240
+ if quanta_for_task
241
+ }
242
+ n_quanta = sum(n_task_quanta.values())
236
243
  if n_quanta == 0:
237
244
  _LOG.info("QuantumGraph contains no quanta.")
238
245
  else:
239
246
  if _LOG.isEnabledFor(logging.INFO):
240
- qg_quanta, qg_tasks = [], []
241
- for task_label, n_quanta_for_task in qg_header.n_task_quanta.items():
242
- qg_tasks.append(task_label)
243
- qg_quanta.append(n_quanta_for_task)
247
+ qg_tasks, qg_quanta = zip(*n_task_quanta.items())
244
248
  qg_task_table = Table(dict(Quanta=qg_quanta, Tasks=qg_tasks))
245
249
  qg_task_table_formatted = "\n".join(qg_task_table.pformat())
246
250
  quanta_str = "quantum" if n_quanta == 1 else "quanta"
247
- n_tasks = len(qg_header.n_task_quanta)
251
+ n_tasks = len(n_task_quanta)
248
252
  n_tasks_plural = "" if n_tasks == 1 else "s"
249
253
  _LOG.info(
250
254
  "QuantumGraph contains %d %s for %d task%s\n%s",
@@ -0,0 +1,2 @@
1
+ __all__ = ["__version__"]
2
+ __version__ = "29.2025.4300"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-ctrl-mpexec
3
- Version: 29.2025.4100
3
+ Version: 29.2025.4300
4
4
  Summary: Pipeline execution infrastructure for the Rubin Observatory LSST Science Pipelines.
5
5
  Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
6
6
  License: BSD 3-Clause License
@@ -71,6 +71,41 @@ class QgraphTest(unittest.TestCase):
71
71
  self.assertEqual(summary.qgraphSummary.outputRun, "output_run")
72
72
  self.assertEqual(len(summary.qgraphSummary.qgraphTaskSummaries), 2)
73
73
 
74
+ def test_partial_read_counts(self):
75
+ """Test reading only one node from a saved graph and check that the
76
+ printed task/quantum counts reflect only that node.
77
+ """
78
+ with DirectButlerRepo.make_temporary() as (helper, root):
79
+ helper.add_task()
80
+ helper.add_task()
81
+ qgc = helper.make_quantum_graph_builder().finish(attach_datastore_records=False)
82
+ quantum_id = next(iter(qgc.quantum_datasets.keys()))
83
+ graph_uri = os.path.join(root, "graph.qg")
84
+ qgc.write(graph_uri)
85
+ log_filename = os.path.join(root, "qgraph.log")
86
+ runner = LogCliRunner()
87
+ result = runner.invoke(
88
+ pipetask_cli,
89
+ [
90
+ "--log-level",
91
+ "lsst.ctrl.mpexec.cli.utils=INFO",
92
+ "--log-file",
93
+ log_filename,
94
+ "qgraph",
95
+ "--butler-config",
96
+ root,
97
+ "--qgraph",
98
+ graph_uri,
99
+ "--qgraph-node-id",
100
+ str(quantum_id),
101
+ ],
102
+ input="no",
103
+ )
104
+ self.assertEqual(result.exit_code, 0, clickResultMsg(result))
105
+ with open(log_filename) as log_file:
106
+ log = log_file.read()
107
+ self.assertIn("1 quantum for 1 task", log)
108
+
74
109
  def test_qgraph_show(self):
75
110
  with DirectButlerRepo.make_temporary() as (helper, root):
76
111
  helper.add_task()
@@ -1,2 +0,0 @@
1
- __all__ = ["__version__"]
2
- __version__ = "29.2025.4100"