lsst-pipe-base 29.2025.4600__tar.gz → 29.2025.4800__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.4600/python/lsst_pipe_base.egg-info → lsst_pipe_base-29.2025.4800}/PKG-INFO +1 -1
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/connections.py +11 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/_common.py +15 -1
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/_multiblock.py +14 -39
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/_predicted.py +77 -73
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/_provenance.py +73 -144
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/_communicators.py +10 -10
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/_scanner.py +88 -60
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/_structs.py +36 -19
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/_supervisor.py +7 -10
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/_writer.py +55 -144
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph_builder.py +0 -1
- lsst_pipe_base-29.2025.4800/python/lsst/pipe/base/version.py +2 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800/python/lsst_pipe_base.egg-info}/PKG-INFO +1 -1
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst_pipe_base.egg-info/SOURCES.txt +1 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_aggregator.py +27 -2
- lsst_pipe_base-29.2025.4800/tests/test_deferredDatasetRef.py +69 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_predicted_qg.py +2 -0
- lsst_pipe_base-29.2025.4600/python/lsst/pipe/base/version.py +0 -2
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/COPYRIGHT +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/LICENSE +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/MANIFEST.in +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/README.md +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/bsd_license.txt +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/CHANGES.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/creating-a-pipeline.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/creating-a-pipelinetask.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/creating-a-task.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/index.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/task-framework-overview.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/task-retargeting-howto.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/testing-a-pipeline-task.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/testing-pipelines-with-mocks.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/doc/lsst.pipe.base/working-with-pipeline-graphs.rst +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/gpl-v3.0.txt +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/pyproject.toml +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/_datasetQueryConstraints.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/_dataset_handle.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/_instrument.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/_observation_dimension_packer.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/_quantumContext.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/_status.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/_task_metadata.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/all_dimensions_quantum_graph_builder.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/automatic_connection_constants.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/caching_limited_butler.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/cli/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/cli/_get_cli_subcommands.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/cli/cmd/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/cli/cmd/commands.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/cli/opt/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/cli/opt/arguments.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/cli/opt/options.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/config.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/configOverrides.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/connectionTypes.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/dot_tools.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/exec_fixup_data_id.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/execution_graph_fixup.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/execution_reports.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/formatters/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/formatters/pexConfig.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/graph/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/graph/_implDetails.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/graph/_loadHelpers.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/graph/_versionDeserializers.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/graph/graph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/graph/graphSummary.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/graph/quantumNode.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/graph_walker.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/log_capture.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/mermaid_tools.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/mp_graph_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipelineIR.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipelineTask.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/__main__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/_dataset_types.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/_edges.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/_exceptions.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/_mapping_views.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/_nodes.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/_pipeline_graph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/_task_subsets.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/_tasks.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/expressions.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/io.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_dot.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_formatting.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_layout.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_merge.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_mermaid.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_options.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_printer.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_show.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/pipeline_graph/visualization/_status_annotator.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/prerequisite_helpers.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/py.typed +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/_config.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/_ingester.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/aggregator/_progress.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph/visualization.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_graph_skeleton.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_provenance_graph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/quantum_reports.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/resource_usage.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/script/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/script/register_instrument.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/script/retrieve_artifacts_for_quanta.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/script/transfer_from_graph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/script/utils.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/script/zip_from_graph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/separable_pipeline_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/simple_pipeline_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/single_quantum_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/struct.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/task.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/taskFactory.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/testUtils.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/in_memory_limited_butler.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/mocks/__init__.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/mocks/_data_id_match.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/mocks/_pipeline_task.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/mocks/_repo.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/mocks/_storage_class.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/no_dimensions.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/pipelineStepTester.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/simpleQGraph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/tests/util.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/utils.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst_pipe_base.egg-info/dependency_links.txt +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst_pipe_base.egg-info/entry_points.txt +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst_pipe_base.egg-info/requires.txt +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst_pipe_base.egg-info/top_level.txt +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst_pipe_base.egg-info/zip-safe +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/setup.cfg +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_adjust_all_quanta.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_caching_limited_butler.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_cliCmdRegisterInstrument.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_configOverrides.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_config_formatter.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_connections.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_dataid_match.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_dataset_handle.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_dot_tools.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_dynamic_connections.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_execution_reports.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_execution_storage_class_conversion.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_graphBuilder.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_graph_walker.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_init_output_run.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_instrument.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_mermaid.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_mp_graph_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_pipeline.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_pipelineIR.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_pipelineLoadSubset.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_pipelineTask.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_pipeline_graph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_pipeline_graph_expressions.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_qg_builder_dimensions.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_quantumGraph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_quantum_provenance_graph.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_quantum_reports.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_quantum_success_caveats.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_script_utils.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_separable_pipeline_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_simple_pipeline_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_single_quantum_executor.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_struct.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_task.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_task_factory.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_taskmetadata.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_testUtils.py +0 -0
- {lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/tests/test_utils.py +0 -0
{lsst_pipe_base-29.2025.4600/python/lsst_pipe_base.egg-info → lsst_pipe_base-29.2025.4800}/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.4800
|
|
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
|
{lsst_pipe_base-29.2025.4600 → lsst_pipe_base-29.2025.4800}/python/lsst/pipe/base/connections.py
RENAMED
|
@@ -506,8 +506,19 @@ class DeferredDatasetRef:
|
|
|
506
506
|
datasetRef: DatasetRef
|
|
507
507
|
|
|
508
508
|
def __getattr__(self, name: str) -> Any:
|
|
509
|
+
# make sure reduce is called on DeferredDatasetRef and not on
|
|
510
|
+
# the DatasetRef
|
|
511
|
+
if name in ("__reduce__", "datasetRef", "__deepcopy__"):
|
|
512
|
+
object.__getattribute__(self, name)
|
|
509
513
|
return getattr(self.datasetRef, name)
|
|
510
514
|
|
|
515
|
+
def __deepcopy__(self, memo: dict) -> DeferredDatasetRef:
|
|
516
|
+
# dataset refs should be immutable deferred version should be too
|
|
517
|
+
return self
|
|
518
|
+
|
|
519
|
+
def __reduce__(self) -> tuple:
|
|
520
|
+
return (self.__class__, (self.datasetRef,))
|
|
521
|
+
|
|
511
522
|
|
|
512
523
|
class PipelineTaskConnections(metaclass=PipelineTaskConnectionsMetaclass):
|
|
513
524
|
"""PipelineTaskConnections is a class used to declare desired IO when a
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
from __future__ import annotations
|
|
29
29
|
|
|
30
30
|
__all__ = (
|
|
31
|
+
"FORMAT_VERSION",
|
|
31
32
|
"BaseQuantumGraph",
|
|
32
33
|
"BaseQuantumGraphReader",
|
|
33
34
|
"BipartiteEdgeInfo",
|
|
@@ -92,6 +93,19 @@ DataCoordinateValues: TypeAlias = list[DataIdValue]
|
|
|
92
93
|
|
|
93
94
|
_T = TypeVar("_T", bound=pydantic.BaseModel)
|
|
94
95
|
|
|
96
|
+
FORMAT_VERSION: int = 1
|
|
97
|
+
"""
|
|
98
|
+
File format version number for new files.
|
|
99
|
+
|
|
100
|
+
This applies to both predicted and provenance QGs, since they usually change
|
|
101
|
+
in concert.
|
|
102
|
+
|
|
103
|
+
CHANGELOG:
|
|
104
|
+
|
|
105
|
+
- 0: Initial version.
|
|
106
|
+
- 1: Switched from internal integer IDs to UUIDs in all models.
|
|
107
|
+
"""
|
|
108
|
+
|
|
95
109
|
|
|
96
110
|
class IncompleteQuantumGraphError(RuntimeError):
|
|
97
111
|
pass
|
|
@@ -100,7 +114,7 @@ class IncompleteQuantumGraphError(RuntimeError):
|
|
|
100
114
|
class HeaderModel(pydantic.BaseModel):
|
|
101
115
|
"""Data model for the header of a quantum graph file."""
|
|
102
116
|
|
|
103
|
-
version: int =
|
|
117
|
+
version: int = FORMAT_VERSION
|
|
104
118
|
"""File format / data model version number."""
|
|
105
119
|
|
|
106
120
|
graph_type: str = ""
|
|
@@ -323,10 +323,11 @@ class AddressReader:
|
|
|
323
323
|
rows: dict[uuid.UUID, AddressRow] = dataclasses.field(default_factory=dict)
|
|
324
324
|
"""Rows that have already been read."""
|
|
325
325
|
|
|
326
|
-
rows_by_index: dict[int, AddressRow] = dataclasses.field(default_factory=dict)
|
|
327
|
-
"""Rows that have already been read, keyed by integer index."""
|
|
328
|
-
|
|
329
326
|
pages: list[AddressPage] = dataclasses.field(default_factory=list)
|
|
327
|
+
"""Descriptions of the file offsets and integer row indexes of pages and
|
|
328
|
+
flags for whether they have been read already.
|
|
329
|
+
"""
|
|
330
|
+
|
|
330
331
|
page_bounds: dict[int, PageBounds] = dataclasses.field(default_factory=dict)
|
|
331
332
|
"""Mapping from page index to page boundary information."""
|
|
332
333
|
|
|
@@ -502,32 +503,23 @@ class AddressReader:
|
|
|
502
503
|
self.pages.clear()
|
|
503
504
|
return self.rows
|
|
504
505
|
|
|
505
|
-
def find(self, key: uuid.UUID
|
|
506
|
+
def find(self, key: uuid.UUID) -> AddressRow:
|
|
506
507
|
"""Read the row for the given UUID or integer index.
|
|
507
508
|
|
|
508
509
|
Parameters
|
|
509
510
|
----------
|
|
510
|
-
key : `uuid.UUID`
|
|
511
|
-
UUID
|
|
511
|
+
key : `uuid.UUID`
|
|
512
|
+
UUID to find.
|
|
512
513
|
|
|
513
514
|
Returns
|
|
514
515
|
-------
|
|
515
516
|
row : `AddressRow`
|
|
516
517
|
Addresses for the given UUID.
|
|
517
518
|
"""
|
|
518
|
-
|
|
519
|
-
case uuid.UUID():
|
|
520
|
-
return self._find_uuid(key)
|
|
521
|
-
case int():
|
|
522
|
-
return self._find_index(key)
|
|
523
|
-
case _:
|
|
524
|
-
raise TypeError(f"Invalid argument: {key}.")
|
|
525
|
-
|
|
526
|
-
def _find_uuid(self, target: uuid.UUID) -> AddressRow:
|
|
527
|
-
if (row := self.rows.get(target)) is not None:
|
|
519
|
+
if (row := self.rows.get(key)) is not None:
|
|
528
520
|
return row
|
|
529
521
|
if self.n_rows == 0 or not self.pages:
|
|
530
|
-
raise LookupError(f"Address for {
|
|
522
|
+
raise LookupError(f"Address for {key} not found.")
|
|
531
523
|
|
|
532
524
|
# Use a binary search to find the page containing the target UUID.
|
|
533
525
|
left = 0
|
|
@@ -535,35 +527,19 @@ class AddressReader:
|
|
|
535
527
|
while left <= right:
|
|
536
528
|
mid = left + ((right - left) // 2)
|
|
537
529
|
self._read_page(mid)
|
|
538
|
-
if (row := self.rows.get(
|
|
530
|
+
if (row := self.rows.get(key)) is not None:
|
|
539
531
|
return row
|
|
540
532
|
bounds = self.page_bounds[mid]
|
|
541
|
-
if
|
|
533
|
+
if key.int < bounds.uuid_int_begin:
|
|
542
534
|
right = mid - 1
|
|
543
|
-
elif
|
|
535
|
+
elif key.int > bounds.uuid_int_end:
|
|
544
536
|
left = mid + 1
|
|
545
537
|
else:
|
|
546
538
|
# Should have been on this page, but it wasn't.
|
|
547
|
-
raise LookupError(f"Address for {
|
|
539
|
+
raise LookupError(f"Address for {key} not found.")
|
|
548
540
|
|
|
549
541
|
# Ran out of pages to search.
|
|
550
|
-
raise LookupError(f"Address for {
|
|
551
|
-
|
|
552
|
-
def _find_index(self, target: int) -> AddressRow:
|
|
553
|
-
# First shortcut if we've already loaded this row.
|
|
554
|
-
if (row := self.rows_by_index.get(target)) is not None:
|
|
555
|
-
return row
|
|
556
|
-
if target < 0 or target >= self.n_rows:
|
|
557
|
-
raise LookupError(f"Address for index {target} not found.")
|
|
558
|
-
# Since all indexes should be present, we can predict the right page
|
|
559
|
-
# exactly.
|
|
560
|
-
page_index = target // self.rows_per_page
|
|
561
|
-
self._read_page(page_index)
|
|
562
|
-
try:
|
|
563
|
-
return self.rows_by_index[target]
|
|
564
|
-
except KeyError:
|
|
565
|
-
_LOG.debug("Index find failed: %s should have been in page %s.", target, page_index)
|
|
566
|
-
raise LookupError(f"Address for {target} not found.") from None
|
|
542
|
+
raise LookupError(f"Address for {key} not found.")
|
|
567
543
|
|
|
568
544
|
def _read_page(self, page_index: int, page_stream: BytesIO | None = None) -> bool:
|
|
569
545
|
page = self.pages[page_index]
|
|
@@ -586,7 +562,6 @@ class AddressReader:
|
|
|
586
562
|
def _read_row(self, page_stream: BytesIO) -> AddressRow:
|
|
587
563
|
row = AddressRow.read(page_stream, self.n_addresses, self.int_size)
|
|
588
564
|
self.rows[row.key] = row
|
|
589
|
-
self.rows_by_index[row.index] = row
|
|
590
565
|
_LOG.debug("Read address row %s.", row)
|
|
591
566
|
return row
|
|
592
567
|
|
|
@@ -43,7 +43,6 @@ __all__ = (
|
|
|
43
43
|
import dataclasses
|
|
44
44
|
import itertools
|
|
45
45
|
import logging
|
|
46
|
-
import operator
|
|
47
46
|
import sys
|
|
48
47
|
import uuid
|
|
49
48
|
import warnings
|
|
@@ -89,6 +88,7 @@ from ..pipeline_graph import (
|
|
|
89
88
|
log_config_mismatch,
|
|
90
89
|
)
|
|
91
90
|
from ._common import (
|
|
91
|
+
FORMAT_VERSION,
|
|
92
92
|
BaseQuantumGraph,
|
|
93
93
|
BaseQuantumGraphReader,
|
|
94
94
|
BaseQuantumGraphWriter,
|
|
@@ -103,7 +103,7 @@ from ._common import (
|
|
|
103
103
|
QuantumInfo,
|
|
104
104
|
TaskLabel,
|
|
105
105
|
)
|
|
106
|
-
from ._multiblock import DEFAULT_PAGE_SIZE, MultiblockReader, MultiblockWriter
|
|
106
|
+
from ._multiblock import DEFAULT_PAGE_SIZE, AddressRow, MultiblockReader, MultiblockWriter
|
|
107
107
|
|
|
108
108
|
if TYPE_CHECKING:
|
|
109
109
|
from ..config import PipelineTaskConfig
|
|
@@ -115,7 +115,7 @@ _LOG = logging.getLogger(__name__)
|
|
|
115
115
|
_T = TypeVar("_T", bound=pydantic.BaseModel)
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
class
|
|
118
|
+
class _PredictedThinQuantumModelV0(pydantic.BaseModel):
|
|
119
119
|
"""Data model for a quantum data ID and internal integer ID in a predicted
|
|
120
120
|
quantum graph.
|
|
121
121
|
"""
|
|
@@ -126,6 +126,18 @@ class PredictedThinQuantumModel(pydantic.BaseModel):
|
|
|
126
126
|
data_coordinate: DataCoordinateValues = pydantic.Field(default_factory=list)
|
|
127
127
|
"""Full (required and implied) data coordinate values for this quantum."""
|
|
128
128
|
|
|
129
|
+
|
|
130
|
+
class PredictedThinQuantumModel(pydantic.BaseModel):
|
|
131
|
+
"""Data model for a quantum data ID and UUID in a predicted
|
|
132
|
+
quantum graph.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
quantum_id: uuid.UUID
|
|
136
|
+
"""Universally unique ID for this quantum."""
|
|
137
|
+
|
|
138
|
+
data_coordinate: DataCoordinateValues = pydantic.Field(default_factory=list)
|
|
139
|
+
"""Full (required and implied) data coordinate values for this quantum."""
|
|
140
|
+
|
|
129
141
|
# Work around the fact that Sphinx chokes on Pydantic docstring formatting,
|
|
130
142
|
# when we inherit those docstrings in our public classes.
|
|
131
143
|
if "sphinx" in sys.modules and not TYPE_CHECKING:
|
|
@@ -172,17 +184,45 @@ class PredictedThinQuantumModel(pydantic.BaseModel):
|
|
|
172
184
|
return super().model_validate_strings(*args, **kwargs)
|
|
173
185
|
|
|
174
186
|
|
|
175
|
-
class
|
|
187
|
+
class _PredictedThinGraphModelV0(pydantic.BaseModel):
|
|
176
188
|
"""Data model for the predicted quantum graph component that maps each
|
|
177
189
|
task label to the data IDs and internal integer IDs of its quanta.
|
|
178
190
|
"""
|
|
179
191
|
|
|
180
|
-
quanta: dict[TaskLabel, list[
|
|
192
|
+
quanta: dict[TaskLabel, list[_PredictedThinQuantumModelV0]] = pydantic.Field(default_factory=dict)
|
|
181
193
|
"""Minimal descriptions of all quanta, grouped by task label."""
|
|
182
194
|
|
|
183
195
|
edges: list[tuple[QuantumIndex, QuantumIndex]] = pydantic.Field(default_factory=list)
|
|
184
196
|
"""Pairs of (predecessor, successor) internal integer quantum IDs."""
|
|
185
197
|
|
|
198
|
+
def _upgraded(self, address_rows: Mapping[uuid.UUID, AddressRow]) -> PredictedThinGraphModel:
|
|
199
|
+
"""Convert to the v1+ model."""
|
|
200
|
+
uuid_by_index = {v.index: k for k, v in address_rows.items()}
|
|
201
|
+
return PredictedThinGraphModel(
|
|
202
|
+
quanta={
|
|
203
|
+
task_label: [
|
|
204
|
+
PredictedThinQuantumModel(
|
|
205
|
+
quantum_id=uuid_by_index[q.quantum_index], data_coordinate=q.data_coordinate
|
|
206
|
+
)
|
|
207
|
+
for q in quanta
|
|
208
|
+
]
|
|
209
|
+
for task_label, quanta in self.quanta.items()
|
|
210
|
+
},
|
|
211
|
+
edges=[(uuid_by_index[index1], uuid_by_index[index2]) for index1, index2 in self.edges],
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class PredictedThinGraphModel(pydantic.BaseModel):
|
|
216
|
+
"""Data model for the predicted quantum graph component that maps each
|
|
217
|
+
task label to the data IDs and UUIDs of its quanta.
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
quanta: dict[TaskLabel, list[PredictedThinQuantumModel]] = pydantic.Field(default_factory=dict)
|
|
221
|
+
"""Minimal descriptions of all quanta, grouped by task label."""
|
|
222
|
+
|
|
223
|
+
edges: list[tuple[uuid.UUID, uuid.UUID]] = pydantic.Field(default_factory=list)
|
|
224
|
+
"""Pairs of (predecessor, successor) quantum IDs."""
|
|
225
|
+
|
|
186
226
|
# Work around the fact that Sphinx chokes on Pydantic docstring formatting,
|
|
187
227
|
# when we inherit those docstrings in our public classes.
|
|
188
228
|
if "sphinx" in sys.modules and not TYPE_CHECKING:
|
|
@@ -673,7 +713,7 @@ class PredictedQuantumGraph(BaseQuantumGraph):
|
|
|
673
713
|
self._add_init_quanta(components.init_quanta)
|
|
674
714
|
self._quantum_datasets: dict[uuid.UUID, PredictedQuantumDatasetsModel] = {}
|
|
675
715
|
self._expanded_data_ids: dict[DataCoordinate, DataCoordinate] = {}
|
|
676
|
-
self._add_thin_graph(components.thin_graph
|
|
716
|
+
self._add_thin_graph(components.thin_graph)
|
|
677
717
|
for quantum_datasets in components.quantum_datasets.values():
|
|
678
718
|
self._add_quantum_datasets(quantum_datasets)
|
|
679
719
|
if not components.thin_graph.edges:
|
|
@@ -710,19 +750,11 @@ class PredictedQuantumGraph(BaseQuantumGraph):
|
|
|
710
750
|
quantum_datasets.task_label,
|
|
711
751
|
)
|
|
712
752
|
|
|
713
|
-
def _add_thin_graph(
|
|
714
|
-
self
|
|
715
|
-
) -> None:
|
|
716
|
-
uuid_by_index = {v: k for k, v in indices.items()}
|
|
717
|
-
for index1, index2 in component.edges:
|
|
718
|
-
self._quantum_only_xgraph.add_edge(uuid_by_index[index1], uuid_by_index[index2])
|
|
753
|
+
def _add_thin_graph(self, component: PredictedThinGraphModel) -> None:
|
|
754
|
+
self._quantum_only_xgraph.add_edges_from(component.edges)
|
|
719
755
|
for task_label, thin_quanta_for_task in component.quanta.items():
|
|
720
756
|
for thin_quantum in thin_quanta_for_task:
|
|
721
|
-
self._add_quantum(
|
|
722
|
-
uuid_by_index[thin_quantum.quantum_index],
|
|
723
|
-
task_label,
|
|
724
|
-
thin_quantum.data_coordinate,
|
|
725
|
-
)
|
|
757
|
+
self._add_quantum(thin_quantum.quantum_id, task_label, thin_quantum.data_coordinate)
|
|
726
758
|
|
|
727
759
|
def _add_quantum_datasets(self, quantum_datasets: PredictedQuantumDatasetsModel) -> None:
|
|
728
760
|
self._quantum_datasets[quantum_datasets.quantum_id] = quantum_datasets
|
|
@@ -1496,8 +1528,6 @@ class PredictedQuantumGraphComponents:
|
|
|
1496
1528
|
thin_graph: PredictedThinGraphModel = dataclasses.field(default_factory=PredictedThinGraphModel)
|
|
1497
1529
|
"""A lightweight quantum-quantum DAG with task labels and data IDs only.
|
|
1498
1530
|
|
|
1499
|
-
This uses internal integer IDs ("indexes") for node IDs.
|
|
1500
|
-
|
|
1501
1531
|
This does not include the special "init" quanta.
|
|
1502
1532
|
"""
|
|
1503
1533
|
|
|
@@ -1511,18 +1541,6 @@ class PredictedQuantumGraphComponents:
|
|
|
1511
1541
|
This does not include special "init" quanta.
|
|
1512
1542
|
"""
|
|
1513
1543
|
|
|
1514
|
-
quantum_indices: dict[uuid.UUID, QuantumIndex] = dataclasses.field(default_factory=dict)
|
|
1515
|
-
"""A mapping from external universal quantum ID to internal integer ID.
|
|
1516
|
-
|
|
1517
|
-
While this `dict` does not need to be sorted, the internal integer IDs do
|
|
1518
|
-
need to correspond exactly to ``enumerate(sorted(uuids))``.
|
|
1519
|
-
|
|
1520
|
-
When used to construct a `PredictedQuantumGraph`, this must be fully
|
|
1521
|
-
populated if `thin_graph` is. It can be empty otherwise.
|
|
1522
|
-
|
|
1523
|
-
This does include special "init" quanta.
|
|
1524
|
-
"""
|
|
1525
|
-
|
|
1526
1544
|
def make_dataset_ref(self, predicted: PredictedDatasetModel) -> DatasetRef:
|
|
1527
1545
|
"""Make a `lsst.daf.butler.DatasetRef` from information in the
|
|
1528
1546
|
predicted quantum graph.
|
|
@@ -1555,48 +1573,35 @@ class PredictedQuantumGraphComponents:
|
|
|
1555
1573
|
id=predicted.dataset_id,
|
|
1556
1574
|
)
|
|
1557
1575
|
|
|
1558
|
-
def set_quantum_indices(self) -> None:
|
|
1559
|
-
"""Populate the `quantum_indices` component by sorting the UUIDs in the
|
|
1560
|
-
`init_quanta` and `quantum_datasets` components (which must both be
|
|
1561
|
-
complete).
|
|
1562
|
-
"""
|
|
1563
|
-
all_quantum_ids = [q.quantum_id for q in self.init_quanta.root]
|
|
1564
|
-
all_quantum_ids.extend(self.quantum_datasets.keys())
|
|
1565
|
-
all_quantum_ids.sort(key=operator.attrgetter("int"))
|
|
1566
|
-
self.quantum_indices = {quantum_id: index for index, quantum_id in enumerate(all_quantum_ids)}
|
|
1567
|
-
|
|
1568
1576
|
def set_thin_graph(self) -> None:
|
|
1569
1577
|
"""Populate the `thin_graph` component from the `pipeline_graph`,
|
|
1570
|
-
`quantum_datasets`
|
|
1571
|
-
complete).
|
|
1578
|
+
`quantum_datasets` components (which must be complete).
|
|
1572
1579
|
"""
|
|
1573
1580
|
bipartite_xgraph = networkx.DiGraph()
|
|
1574
1581
|
self.thin_graph.quanta = {task_label: [] for task_label in self.pipeline_graph.tasks}
|
|
1575
|
-
|
|
1582
|
+
graph_quantum_ids: list[uuid.UUID] = []
|
|
1576
1583
|
for quantum_datasets in self.quantum_datasets.values():
|
|
1577
|
-
quantum_index = self.quantum_indices[quantum_datasets.quantum_id]
|
|
1578
1584
|
self.thin_graph.quanta[quantum_datasets.task_label].append(
|
|
1579
1585
|
PredictedThinQuantumModel.model_construct(
|
|
1580
|
-
|
|
1586
|
+
quantum_id=quantum_datasets.quantum_id,
|
|
1581
1587
|
data_coordinate=quantum_datasets.data_coordinate,
|
|
1582
1588
|
)
|
|
1583
1589
|
)
|
|
1584
1590
|
for dataset in itertools.chain.from_iterable(quantum_datasets.inputs.values()):
|
|
1585
|
-
bipartite_xgraph.add_edge(dataset.dataset_id,
|
|
1591
|
+
bipartite_xgraph.add_edge(dataset.dataset_id, quantum_datasets.quantum_id)
|
|
1586
1592
|
for dataset in itertools.chain.from_iterable(quantum_datasets.outputs.values()):
|
|
1587
|
-
bipartite_xgraph.add_edge(
|
|
1588
|
-
|
|
1593
|
+
bipartite_xgraph.add_edge(quantum_datasets.quantum_id, dataset.dataset_id)
|
|
1594
|
+
graph_quantum_ids.append(quantum_datasets.quantum_id)
|
|
1589
1595
|
quantum_only_xgraph: networkx.DiGraph = networkx.bipartite.projected_graph(
|
|
1590
|
-
bipartite_xgraph,
|
|
1596
|
+
bipartite_xgraph, graph_quantum_ids
|
|
1591
1597
|
)
|
|
1592
1598
|
self.thin_graph.edges = list(quantum_only_xgraph.edges)
|
|
1593
1599
|
|
|
1594
1600
|
def set_header_counts(self) -> None:
|
|
1595
1601
|
"""Populate the quantum and dataset counts in the header from the
|
|
1596
|
-
`
|
|
1597
|
-
components.
|
|
1602
|
+
`thin_graph`, `init_quanta`, and `quantum_datasets` components.
|
|
1598
1603
|
"""
|
|
1599
|
-
self.header.n_quanta = len(self.
|
|
1604
|
+
self.header.n_quanta = len(self.quantum_datasets)
|
|
1600
1605
|
self.header.n_task_quanta = {
|
|
1601
1606
|
task_label: len(thin_quanta) for task_label, thin_quanta in self.thin_graph.quanta.items()
|
|
1602
1607
|
}
|
|
@@ -1642,8 +1647,7 @@ class PredictedQuantumGraphComponents:
|
|
|
1642
1647
|
)
|
|
1643
1648
|
# Update the keys of the quantum_datasets dict.
|
|
1644
1649
|
self.quantum_datasets = {qd.quantum_id: qd for qd in self.quantum_datasets.values()}
|
|
1645
|
-
# Since the UUIDs have changed, the
|
|
1646
|
-
self.set_quantum_indices()
|
|
1650
|
+
# Since the UUIDs have changed, the thin graph needs to be rewritten.
|
|
1647
1651
|
self.set_thin_graph()
|
|
1648
1652
|
# Update the header last, since we use it above to get the old run.
|
|
1649
1653
|
self.header.output_run = output_run
|
|
@@ -1728,7 +1732,6 @@ class PredictedQuantumGraphComponents:
|
|
|
1728
1732
|
records=dimension_data_extractor.records.values(),
|
|
1729
1733
|
dimensions=result.pipeline_graph.get_all_dimensions(),
|
|
1730
1734
|
)
|
|
1731
|
-
result.set_quantum_indices()
|
|
1732
1735
|
result.set_thin_graph()
|
|
1733
1736
|
result.set_header_counts()
|
|
1734
1737
|
return result
|
|
@@ -1764,11 +1767,15 @@ class PredictedQuantumGraphComponents:
|
|
|
1764
1767
|
Only a complete predicted quantum graph with all components fully
|
|
1765
1768
|
populated should be written.
|
|
1766
1769
|
"""
|
|
1767
|
-
if self.header.
|
|
1770
|
+
if self.header.n_task_quanta != {
|
|
1771
|
+
task_label: len(quanta) for task_label, quanta in self.thin_graph.quanta.items()
|
|
1772
|
+
}:
|
|
1768
1773
|
raise RuntimeError(
|
|
1769
|
-
|
|
1770
|
-
f"got {len(self.quantum_indices)}."
|
|
1774
|
+
"Cannot save graph after partial read of quanta: thin graph is inconsistent with header."
|
|
1771
1775
|
)
|
|
1776
|
+
# Ensure we record the actual version we're about to write, in case
|
|
1777
|
+
# we're rewriting an old graph in a new format.
|
|
1778
|
+
self.header.version = FORMAT_VERSION
|
|
1772
1779
|
uri = ResourcePath(uri)
|
|
1773
1780
|
match uri.getExtension():
|
|
1774
1781
|
case ".qg":
|
|
@@ -1811,11 +1818,12 @@ class PredictedQuantumGraphComponents:
|
|
|
1811
1818
|
else:
|
|
1812
1819
|
cdict_data = cdict.as_bytes()
|
|
1813
1820
|
compressor = zstandard.ZstdCompressor(level=zstd_level, dict_data=cdict)
|
|
1821
|
+
indices = {quantum_id: n for n, quantum_id in enumerate(sorted(self.quantum_datasets.keys()))}
|
|
1814
1822
|
with BaseQuantumGraphWriter.open(
|
|
1815
1823
|
uri,
|
|
1816
1824
|
header=self.header,
|
|
1817
1825
|
pipeline_graph=self.pipeline_graph,
|
|
1818
|
-
indices=
|
|
1826
|
+
indices=indices,
|
|
1819
1827
|
address_filename="quanta",
|
|
1820
1828
|
compressor=compressor,
|
|
1821
1829
|
cdict_data=cdict_data,
|
|
@@ -1907,18 +1915,17 @@ class PredictedQuantumGraphReader(BaseQuantumGraphReader):
|
|
|
1907
1915
|
def read_thin_graph(self) -> None:
|
|
1908
1916
|
"""Read the thin graph.
|
|
1909
1917
|
|
|
1910
|
-
The thin graph is a quantum-quantum DAG with
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
init-output information.
|
|
1918
|
+
The thin graph is a quantum-quantum DAG with just task labels and data
|
|
1919
|
+
IDs as node attributes. It always includes all regular quanta, and
|
|
1920
|
+
does not include init-input or init-output information.
|
|
1914
1921
|
"""
|
|
1915
1922
|
if not self.components.thin_graph.quanta:
|
|
1916
|
-
self.
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1923
|
+
if self.header.version > 0:
|
|
1924
|
+
self.components.thin_graph = self._read_single_block("thin_graph", PredictedThinGraphModel)
|
|
1925
|
+
else:
|
|
1926
|
+
self.address_reader.read_all()
|
|
1927
|
+
thin_graph_v0 = self._read_single_block("thin_graph", _PredictedThinGraphModelV0)
|
|
1928
|
+
self.components.thin_graph = thin_graph_v0._upgraded(self.address_reader.rows)
|
|
1922
1929
|
|
|
1923
1930
|
def read_init_quanta(self) -> None:
|
|
1924
1931
|
"""Read the list of special quanta that represent init-inputs and
|
|
@@ -1971,8 +1978,6 @@ class PredictedQuantumGraphReader(BaseQuantumGraphReader):
|
|
|
1971
1978
|
):
|
|
1972
1979
|
self.components.quantum_datasets.setdefault(quantum_datasets.quantum_id, quantum_datasets)
|
|
1973
1980
|
self.address_reader.read_all()
|
|
1974
|
-
for address_row in self.address_reader.rows.values():
|
|
1975
|
-
self.components.quantum_indices[address_row.key] = address_row.index
|
|
1976
1981
|
return
|
|
1977
1982
|
with MultiblockReader.open_in_zip(
|
|
1978
1983
|
self.zf, "quantum_datasets", int_size=self.components.header.int_size
|
|
@@ -1981,7 +1986,6 @@ class PredictedQuantumGraphReader(BaseQuantumGraphReader):
|
|
|
1981
1986
|
if quantum_id in self.components.quantum_datasets:
|
|
1982
1987
|
continue
|
|
1983
1988
|
address_row = self.address_reader.find(quantum_id)
|
|
1984
|
-
self.components.quantum_indices[address_row.key] = address_row.index
|
|
1985
1989
|
quantum_datasets = mb_reader.read_model(
|
|
1986
1990
|
address_row.addresses[0], PredictedQuantumDatasetsModel, self.decompressor
|
|
1987
1991
|
)
|