Coverage for python / lsst / pipe / base / dot_tools.py: 15%
32 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-24 08:19 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-24 08:19 +0000
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/>.
28"""Module defining few methods to generate GraphViz diagrams from pipelines
29or quantum graphs.
30"""
32from __future__ import annotations
34__all__ = ["graph2dot", "pipeline2dot"]
36from collections.abc import Iterable
37from typing import TYPE_CHECKING, Any
39from .pipeline import Pipeline
41if TYPE_CHECKING:
42 from .graph import QuantumGraph
43 from .pipeline import TaskDef
44 from .quantum_graph import PredictedQuantumGraph
47def graph2dot(qgraph: QuantumGraph | PredictedQuantumGraph, file: Any) -> None:
48 """Convert QuantumGraph into GraphViz digraph.
50 This method is mostly for documentation/presentation purposes.
52 Parameters
53 ----------
54 qgraph : `lsst.pipe.base.QuantumGraph` or \
55 `lsst.pipe.base.quantum_graph.PredictedQuantumGraph`
56 Quantum graph object.
57 file : `str` or file object
58 File where GraphViz graph (DOT language) is written, can be a file name
59 or file object.
61 Raises
62 ------
63 OSError
64 Raised if the output file cannot be opened.
65 ImportError
66 Raised if the task class cannot be imported.
67 """
68 from .quantum_graph import PredictedQuantumGraph, visualization
70 if not isinstance(qgraph, PredictedQuantumGraph):
71 qgraph = PredictedQuantumGraph.from_old_quantum_graph(qgraph)
73 # open a file if needed
74 close = False
75 if not hasattr(file, "write"):
76 file = open(file, "w")
77 close = True
79 v = visualization.QuantumGraphDotVisualizer()
80 v.write_bipartite(qgraph, file)
82 if close:
83 file.close()
86def pipeline2dot(pipeline: Pipeline | Iterable[TaskDef], file: Any) -> None:
87 """Convert `~lsst.pipe.base.Pipeline` into GraphViz digraph.
89 This method is mostly for documentation/presentation purposes.
90 Unlike other methods this method does not validate graph consistency.
92 Parameters
93 ----------
94 pipeline : `.Pipeline` or `~collections.abc.Iterable` [ `.TaskDef` ]
95 Pipeline description.
96 file : `str` or file object
97 File where GraphViz graph (DOT language) is written, can be a file name
98 or file object.
100 Raises
101 ------
102 OSError
103 Raised if the output file cannot be opened.
104 ImportError
105 Raised if the task class cannot be imported.
106 """
107 from .pipeline_graph import PipelineGraph, visualization
109 # open a file if needed
110 close = False
111 if not hasattr(file, "write"):
112 file = open(file, "w")
113 close = True
115 if isinstance(pipeline, Pipeline):
116 pg = pipeline.to_graph(visualization_only=True)
117 else:
118 pg = PipelineGraph()
119 for task_def in pipeline:
120 pg.add_task(
121 task_def.label,
122 task_class=task_def.taskClass,
123 config=task_def.config,
124 connections=task_def.connections,
125 )
126 pg.resolve(visualization_only=True)
127 visualization.show_dot(pg, stream=file, dataset_types=True)
129 if close:
130 file.close()