lsst-pipe-base 29.2025.1400__tar.gz → 29.2025.1600__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.
- {lsst_pipe_base-29.2025.1400/python/lsst_pipe_base.egg-info → lsst_pipe_base-29.2025.1600}/PKG-INFO +2 -1
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/working-with-pipeline-graphs.rst +99 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/pyproject.toml +3 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/all_dimensions_quantum_graph_builder.py +17 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/graph/_loadHelpers.py +4 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/graph/graph.py +2 -2
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline.py +1 -1
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipelineIR.py +10 -1
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/__main__.py +1 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/_exceptions.py +7 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/_pipeline_graph.py +360 -11
- lsst_pipe_base-29.2025.1600/python/lsst/pipe/base/pipeline_graph/expressions.py +271 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/visualization/__init__.py +1 -0
- lsst_pipe_base-29.2025.1600/python/lsst/pipe/base/pipeline_graph/visualization/_formatting.py +529 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/visualization/_mermaid.py +17 -25
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/visualization/_options.py +11 -3
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/visualization/_show.py +23 -3
- lsst_pipe_base-29.2025.1600/python/lsst/pipe/base/pipeline_graph/visualization/_status_annotator.py +250 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/quantum_provenance_graph.py +28 -0
- lsst_pipe_base-29.2025.1600/python/lsst/pipe/base/version.py +2 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600/python/lsst_pipe_base.egg-info}/PKG-INFO +2 -1
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst_pipe_base.egg-info/SOURCES.txt +3 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst_pipe_base.egg-info/requires.txt +1 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_pipeline.py +22 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_pipelineIR.py +32 -32
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_pipeline_graph.py +119 -0
- lsst_pipe_base-29.2025.1600/tests/test_pipeline_graph_expressions.py +127 -0
- lsst_pipe_base-29.2025.1400/python/lsst/pipe/base/pipeline_graph/visualization/_formatting.py +0 -234
- lsst_pipe_base-29.2025.1400/python/lsst/pipe/base/version.py +0 -2
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/COPYRIGHT +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/LICENSE +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/MANIFEST.in +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/README.md +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/bsd_license.txt +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/CHANGES.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/creating-a-pipeline.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/creating-a-pipelinetask.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/creating-a-task.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/index.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/task-framework-overview.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/task-retargeting-howto.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/testing-a-pipeline-task.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/doc/lsst.pipe.base/testing-pipelines-with-mocks.rst +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/gpl-v3.0.txt +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/_datasetQueryConstraints.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/_dataset_handle.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/_instrument.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/_observation_dimension_packer.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/_quantumContext.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/_status.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/_task_metadata.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/automatic_connection_constants.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/caching_limited_butler.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/cli/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/cli/_get_cli_subcommands.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/cli/cmd/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/cli/cmd/commands.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/cli/opt/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/cli/opt/arguments.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/cli/opt/options.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/config.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/configOverrides.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/connectionTypes.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/connections.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/dot_tools.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/executionButlerBuilder.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/execution_reports.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/formatters/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/formatters/pexConfig.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/graph/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/graph/_implDetails.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/graph/_versionDeserializers.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/graph/graphSummary.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/graph/quantumNode.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/mermaid_tools.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipelineTask.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/_dataset_types.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/_edges.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/_mapping_views.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/_nodes.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/_task_subsets.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/_tasks.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/io.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/visualization/_dot.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/visualization/_layout.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/visualization/_merge.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline_graph/visualization/_printer.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/prerequisite_helpers.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/py.typed +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/quantum_graph_builder.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/quantum_graph_skeleton.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/script/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/script/register_instrument.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/script/retrieve_artifacts_for_quanta.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/script/transfer_from_graph.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/script/zip_from_graph.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/struct.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/task.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/taskFactory.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/testUtils.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/mocks/__init__.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/mocks/_data_id_match.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/mocks/_pipeline_task.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/mocks/_storage_class.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/no_dimensions.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/pipelineStepTester.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/simpleQGraph.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/tests/util.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/utils.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst_pipe_base.egg-info/dependency_links.txt +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst_pipe_base.egg-info/entry_points.txt +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst_pipe_base.egg-info/top_level.txt +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst_pipe_base.egg-info/zip-safe +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/setup.cfg +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_adjust_all_quanta.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_caching_limited_butler.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_cliCmdRegisterInstrument.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_configOverrides.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_config_formatter.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_connections.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_dataid_match.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_dataset_handle.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_dot_tools.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_dynamic_connections.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_executionButler.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_execution_reports.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_graphBuilder.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_init_output_run.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_instrument.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_mermaid.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_pipelineLoadSubset.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_pipelineTask.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_quantumGraph.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_quantum_provenance_graph.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_quantum_success_caveats.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_struct.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_task.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_taskmetadata.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_testUtils.py +0 -0
- {lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/tests/test_utils.py +0 -0
{lsst_pipe_base-29.2025.1400/python/lsst_pipe_base.egg-info → lsst_pipe_base-29.2025.1600}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-pipe-base
|
|
3
|
-
Version: 29.2025.
|
|
3
|
+
Version: 29.2025.1600
|
|
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: BSD 3-Clause License
|
|
@@ -27,6 +27,7 @@ Requires-Dist: lsst-pex-config
|
|
|
27
27
|
Requires-Dist: astropy
|
|
28
28
|
Requires-Dist: pydantic<3.0,>=2
|
|
29
29
|
Requires-Dist: networkx
|
|
30
|
+
Requires-Dist: wcwidth
|
|
30
31
|
Requires-Dist: pyyaml>=5.1
|
|
31
32
|
Requires-Dist: numpy>=1.17
|
|
32
33
|
Requires-Dist: frozendict
|
|
@@ -86,3 +86,102 @@ The export methods include:
|
|
|
86
86
|
This is a `networkx.DiGraph`, because all dataset types that connect a pair of tasks are rolled into one edge, and edges have no state.
|
|
87
87
|
- `~PipelineGraph.make_dataset_type_graph` exports just dataset type nodes; it is one "bipartite projection" of the full graph.
|
|
88
88
|
This is a `networkx.DiGraph`, because all tasks that connect a pair of dataset types are rolled into one edge, and edges have no state.
|
|
89
|
+
|
|
90
|
+
.. _pipeline-graph-subset-expressions:
|
|
91
|
+
|
|
92
|
+
Pipeline graph subset expressions
|
|
93
|
+
---------------------------------
|
|
94
|
+
|
|
95
|
+
The `PipelineGraph.select` and `PipelineGraph.select_tasks` methods utilize a boolean expression language to select a subset of the tasks in a `PipelineGraph`.
|
|
96
|
+
The language uses familiar set operators for union (``|``), intersection (``&``), and set-inversion (``~``), with the operands any of the following:
|
|
97
|
+
|
|
98
|
+
- a task label
|
|
99
|
+
- a task subset label
|
|
100
|
+
- a dataset type name (resolves to the label of the producing task, or an empty set for overall inputs; may not be an init-output)
|
|
101
|
+
- an ancestor or descendant search, starting from a task label or dataset type name (see below)
|
|
102
|
+
- a nested expression.
|
|
103
|
+
|
|
104
|
+
Parentheses may be used for grouping.
|
|
105
|
+
|
|
106
|
+
Task labels, task subset labels, and dataset type names all appear as regular unquoted strings.
|
|
107
|
+
In cases where dataset type name is the same as a task or task subset label, a prefix can be added to disambiguate: ``T:`` for task, ``D:`` for dataset type, and ``S:`` for task subset.
|
|
108
|
+
|
|
109
|
+
An ancestor or descendant search uses ``<``, ``<=``, ``>``, and ``>=`` as *unary* operators, with the operands being task labels or dataset type names (which may be qualified with ``T:`` or ``D:``, respectively, as described above).
|
|
110
|
+
For tasks these searches are straightforward:
|
|
111
|
+
|
|
112
|
+
- ``<`` and ``<=`` select all tasks whose outputs are consumed by the operand task, recursively, with the operand task itself included only for ``<=``.
|
|
113
|
+
|
|
114
|
+
- ``>`` and ``>=`` select all tasks that consume the outputs of the operand task, rescursively, with the operand task itself included only for ``>=``.
|
|
115
|
+
|
|
116
|
+
Because the expressions are logically set operations on tasks, ancestor and descendant searches on dataset types work differently and are not quite symmetric:
|
|
117
|
+
|
|
118
|
+
- ``<`` and ``<=`` act like an ancestor search on the task that produces the operand dataset type.
|
|
119
|
+
For overall inputs they yield empty sets.
|
|
120
|
+
Init-outputs are not permitted.
|
|
121
|
+
|
|
122
|
+
- ``>`` and ``>=`` act like a union of descendant searches on all tasks that consume the operand dataset type.
|
|
123
|
+
This includes tasks that consume the operand dataset type as an init-input (this is the only context in which init-output dataset types can appear in expressions).
|
|
124
|
+
For ``>=`` only, the task that produces the operand dataset type is also included, but in this case it is an error for the operand to be an init-output.
|
|
125
|
+
|
|
126
|
+
Note that these ancestor and descendant searches are not the only useful way to define the subset of a pipeline that is "before" or "after" a task; the ancestors ``<a`` of a task ``a`` are those that *must* be run before ``a``, while the inverse of the descendants ``~>=a`` are the tasks that *can* be run before ``a``.
|
|
127
|
+
Similarly, the descendants ``>a`` of ``a`` are the tasks that can only be run after ``a``, while the inverse of the ancestors ``~<=a`` are all tasks that can be run after ``a``.
|
|
128
|
+
|
|
129
|
+
Examples
|
|
130
|
+
^^^^^^^^
|
|
131
|
+
|
|
132
|
+
All tasks in subset ``s`` except task ``b``:
|
|
133
|
+
|
|
134
|
+
.. code-block:: text
|
|
135
|
+
|
|
136
|
+
s & ~b
|
|
137
|
+
|
|
138
|
+
All tasks in either subset ``r`` or subset ``s`` that would need to be re-run to pick up a change in the behavior of task ``a``:
|
|
139
|
+
|
|
140
|
+
.. code-block:: text
|
|
141
|
+
|
|
142
|
+
(r | s) & >=a
|
|
143
|
+
|
|
144
|
+
All tasks in subset ``s`` that need to be run to accept failures in task ``c`` as unrecoverable, after a previous run left some quanta of those tasks blocked:
|
|
145
|
+
|
|
146
|
+
.. code-block:: text
|
|
147
|
+
|
|
148
|
+
s & >a
|
|
149
|
+
|
|
150
|
+
All tasks needed to produce dataset type ``d`` or dataset type ``e``:
|
|
151
|
+
|
|
152
|
+
.. code-block:: text
|
|
153
|
+
|
|
154
|
+
<d | <e
|
|
155
|
+
|
|
156
|
+
All tasks except task ``a`` that can be run without producing dataset type ``f``:
|
|
157
|
+
|
|
158
|
+
.. code-block:: text
|
|
159
|
+
|
|
160
|
+
~a & ~>=f
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
Formal grammar
|
|
164
|
+
^^^^^^^^^^^^^^
|
|
165
|
+
|
|
166
|
+
.. code-block:: bnf
|
|
167
|
+
|
|
168
|
+
<expression> ::= ~ <expression>
|
|
169
|
+
| <expression> | <expression>
|
|
170
|
+
| <expression> & <expression>
|
|
171
|
+
| (<expression>)
|
|
172
|
+
| S:<subset-label>
|
|
173
|
+
| <subset-label>
|
|
174
|
+
| < <node>
|
|
175
|
+
| <= <node>
|
|
176
|
+
| > <node>
|
|
177
|
+
| <= <node>
|
|
178
|
+
| <node>
|
|
179
|
+
|
|
180
|
+
<node> ::= T:<task-label>
|
|
181
|
+
| <task-label>
|
|
182
|
+
| D:<dataset-type-name>
|
|
183
|
+
| <dataset-type-name>
|
|
184
|
+
|
|
185
|
+
Whitespace is ignored, but is not permitted before or after the ``:`` in qualified identifiers.
|
|
186
|
+
|
|
187
|
+
The operator precedence in the absence of parenthesis is ``~``, ``&``, ``|`` ( highest to lowest).
|
|
@@ -30,6 +30,7 @@ dependencies = [
|
|
|
30
30
|
"astropy",
|
|
31
31
|
"pydantic >=2,<3.0",
|
|
32
32
|
"networkx",
|
|
33
|
+
"wcwidth",
|
|
33
34
|
"pyyaml >= 5.1",
|
|
34
35
|
"numpy >= 1.17",
|
|
35
36
|
"frozendict",
|
|
@@ -205,4 +206,6 @@ exclude = [
|
|
|
205
206
|
"^test_.*", # Do not test docstrings in test code.
|
|
206
207
|
'^commands\.', # Click docstrings, not numpydoc
|
|
207
208
|
'\._[a-zA-Z_]+$', # Private methods.
|
|
209
|
+
'_ParserLex\.', # Docstrings are not numpydoc
|
|
210
|
+
'_ParserYacc\.', # Docstrings are not numpydoc
|
|
208
211
|
]
|
|
@@ -39,6 +39,8 @@ from collections import defaultdict
|
|
|
39
39
|
from collections.abc import Iterable, Mapping
|
|
40
40
|
from typing import TYPE_CHECKING, Any, TypeAlias, final
|
|
41
41
|
|
|
42
|
+
import astropy.table
|
|
43
|
+
|
|
42
44
|
from lsst.daf.butler import (
|
|
43
45
|
Butler,
|
|
44
46
|
DataCoordinate,
|
|
@@ -85,6 +87,11 @@ class AllDimensionsQuantumGraphBuilder(QuantumGraphBuilder):
|
|
|
85
87
|
(sometimes catastrophically bad) query plan.
|
|
86
88
|
bind : `~collections.abc.Mapping`, optional
|
|
87
89
|
Variable substitutions for the ``where`` expression.
|
|
90
|
+
data_id_tables : `~collections.abc.Iterable` [ `astropy.table.Table` ],\
|
|
91
|
+
optional
|
|
92
|
+
Tables of data IDs to join in as constraints. Missing dimensions that
|
|
93
|
+
are constrained by the ``where`` argument or pipeline data ID will be
|
|
94
|
+
filled in automatically.
|
|
88
95
|
**kwargs
|
|
89
96
|
Additional keyword arguments forwarded to `QuantumGraphBuilder`.
|
|
90
97
|
|
|
@@ -113,6 +120,7 @@ class AllDimensionsQuantumGraphBuilder(QuantumGraphBuilder):
|
|
|
113
120
|
where: str = "",
|
|
114
121
|
dataset_query_constraint: DatasetQueryConstraintVariant = DatasetQueryConstraintVariant.ALL,
|
|
115
122
|
bind: Mapping[str, Any] | None = None,
|
|
123
|
+
data_id_tables: Iterable[astropy.table.Table] = (),
|
|
116
124
|
**kwargs: Any,
|
|
117
125
|
):
|
|
118
126
|
super().__init__(pipeline_graph, butler, **kwargs)
|
|
@@ -120,6 +128,7 @@ class AllDimensionsQuantumGraphBuilder(QuantumGraphBuilder):
|
|
|
120
128
|
self.where = where
|
|
121
129
|
self.dataset_query_constraint = dataset_query_constraint
|
|
122
130
|
self.bind = bind
|
|
131
|
+
self.data_id_tables = list(data_id_tables)
|
|
123
132
|
|
|
124
133
|
@timeMethod
|
|
125
134
|
def process_subgraph(self, subgraph: PipelineGraph) -> QuantumGraphSkeleton:
|
|
@@ -194,6 +203,14 @@ class AllDimensionsQuantumGraphBuilder(QuantumGraphBuilder):
|
|
|
194
203
|
f"{self.where!r}, bind={self.bind!r})"
|
|
195
204
|
)
|
|
196
205
|
query = query.where(tree.subgraph.data_id, self.where, bind=self.bind)
|
|
206
|
+
# It's important for tables to be joined in last, so data IDs from
|
|
207
|
+
# pipeline and where can be used to fill in missing columns.
|
|
208
|
+
for table in self.data_id_tables:
|
|
209
|
+
# If this is from ctrl_mpexec's pipetask, it'll have added
|
|
210
|
+
# a filename to the metadata for us.
|
|
211
|
+
table_name = table.meta.get("filename", "unknown")
|
|
212
|
+
query_cmd.append(f" query = query.join_data_coordinate_table(<{table_name}>)")
|
|
213
|
+
query = query.join_data_coordinate_table(table)
|
|
197
214
|
self.log.verbose("Querying for data IDs via: %s", "\n".join(query_cmd))
|
|
198
215
|
# Allow duplicates from common skypix overlaps to make some queries
|
|
199
216
|
# run faster.
|
|
@@ -65,6 +65,7 @@ class LoadHelper(AbstractContextManager["LoadHelper"]):
|
|
|
65
65
|
to upgrade them to the latest format before they can be used in
|
|
66
66
|
production.
|
|
67
67
|
"""
|
|
68
|
+
fullRead: bool = False
|
|
68
69
|
|
|
69
70
|
def __post_init__(self) -> None:
|
|
70
71
|
self._resourceHandle: ResourceHandleProtocol | None = None
|
|
@@ -261,6 +262,9 @@ class LoadHelper(AbstractContextManager["LoadHelper"]):
|
|
|
261
262
|
def __enter__(self) -> LoadHelper:
|
|
262
263
|
if isinstance(self.uri, BinaryIO | BytesIO | BufferedRandom):
|
|
263
264
|
self._resourceHandle = self.uri
|
|
265
|
+
elif self.fullRead:
|
|
266
|
+
local = self._exitStack.enter_context(self.uri.as_local())
|
|
267
|
+
self._resourceHandle = self._exitStack.enter_context(local.open("rb"))
|
|
264
268
|
else:
|
|
265
269
|
self._resourceHandle = self._exitStack.enter_context(self.uri.open("rb"))
|
|
266
270
|
self._initialize()
|
{lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/graph/graph.py
RENAMED
|
@@ -963,7 +963,7 @@ class QuantumGraph:
|
|
|
963
963
|
"""
|
|
964
964
|
uri = ResourcePath(uri)
|
|
965
965
|
if uri.getExtension() in {".qgraph"}:
|
|
966
|
-
with LoadHelper(uri, minimumVersion) as loader:
|
|
966
|
+
with LoadHelper(uri, minimumVersion, fullRead=(nodes is None)) as loader:
|
|
967
967
|
qgraph = loader.load(universe, nodes, graphID)
|
|
968
968
|
else:
|
|
969
969
|
raise ValueError(f"Only know how to handle files saved as `.qgraph`, not {uri}")
|
|
@@ -1230,7 +1230,7 @@ class QuantumGraph:
|
|
|
1230
1230
|
being loaded or if the supplied uri does not point at a valid
|
|
1231
1231
|
`QuantumGraph` save file.
|
|
1232
1232
|
"""
|
|
1233
|
-
with LoadHelper(file, minimumVersion) as loader:
|
|
1233
|
+
with LoadHelper(file, minimumVersion, fullRead=(nodes is None)) as loader:
|
|
1234
1234
|
qgraph = loader.load(universe, nodes, graphID)
|
|
1235
1235
|
if not isinstance(qgraph, QuantumGraph):
|
|
1236
1236
|
raise TypeError(f"QuantumGraph file contains unexpected object type: {type(qgraph)}")
|
{lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipeline.py
RENAMED
|
@@ -427,7 +427,7 @@ class Pipeline:
|
|
|
427
427
|
if "," in label_subset:
|
|
428
428
|
if ".." in label_subset:
|
|
429
429
|
raise ValueError(
|
|
430
|
-
"Can only specify a list of labels or a
|
|
430
|
+
"Can only specify a list of labels or a range when loading a Pipeline, not both."
|
|
431
431
|
)
|
|
432
432
|
args = {"labels": set(label_subset.split(","))}
|
|
433
433
|
# labels supplied as a range
|
{lsst_pipe_base-29.2025.1400 → lsst_pipe_base-29.2025.1600}/python/lsst/pipe/base/pipelineIR.py
RENAMED
|
@@ -980,10 +980,19 @@ class PipelineIR:
|
|
|
980
980
|
if extraTaskLabels := (labeled_subset.subset - pipeline.tasks.keys()):
|
|
981
981
|
match subsetCtrl:
|
|
982
982
|
case PipelineSubsetCtrl.DROP:
|
|
983
|
-
pipeline.labeled_subsets
|
|
983
|
+
del pipeline.labeled_subsets[label]
|
|
984
984
|
case PipelineSubsetCtrl.EDIT:
|
|
985
985
|
for extra in extraTaskLabels:
|
|
986
986
|
labeled_subset.subset.discard(extra)
|
|
987
|
+
elif subsetCtrl is PipelineSubsetCtrl.DROP and not labeled_subset.subset:
|
|
988
|
+
# When mode is DROP, also drop any subsets that were already
|
|
989
|
+
# empty. This ensures we drop steps that were emptied-out by
|
|
990
|
+
# (earlier) imports with exclude in EDIT mode. Note that we
|
|
991
|
+
# don't want to drop those steps when they're first excluded
|
|
992
|
+
# down to nothing, because the pipeline might be about to add
|
|
993
|
+
# new tasks back into them, and then we'd want to preserve the
|
|
994
|
+
# step definitions.
|
|
995
|
+
del pipeline.labeled_subsets[label]
|
|
987
996
|
|
|
988
997
|
# remove any steps that correspond to removed subsets
|
|
989
998
|
new_steps = []
|
|
@@ -31,6 +31,7 @@ __all__ = (
|
|
|
31
31
|
"DuplicateOutputError",
|
|
32
32
|
"EdgesChangedError",
|
|
33
33
|
"IncompatibleDatasetTypeError",
|
|
34
|
+
"InvalidExpressionError",
|
|
34
35
|
"InvalidStepsError",
|
|
35
36
|
"PipelineDataCycleError",
|
|
36
37
|
"PipelineGraphError",
|
|
@@ -102,5 +103,11 @@ class PipelineGraphExceptionSafetyError(PipelineGraphError):
|
|
|
102
103
|
"""
|
|
103
104
|
|
|
104
105
|
|
|
106
|
+
class InvalidExpressionError(PipelineGraphError):
|
|
107
|
+
"""Exception raised when a pipeline subset expression could not be parsed
|
|
108
|
+
or applied.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
|
|
105
112
|
class InvalidStepsError(PipelineGraphError):
|
|
106
113
|
"""Exception raised when the step definitions are invalid."""
|