ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
DataQuality
DQDefects
share
defects_dump_graph.py
Go to the documentation of this file.
1
#!/usr/bin/env python
2
3
from
os
import
makedirs
4
from
os.path
import
isdir
5
from
argparse
import
ArgumentParser
6
from
typing
import
Mapping, Union, TextIO
7
8
from
DQDefects
import
DefectsDB
9
from
DQDefects.virtual_logic
import
DefectLogic
10
11
DEPENDSON_DIR =
"dependson"
12
13
class
Node
(object):
14
def
__init__
(self, name: str):
15
self.
name
= name
16
self.
children
=
set
()
17
self.
parents
=
set
()
18
19
def
get_name
(self) -> str:
20
return
self.
name
21
22
@property
23
def
virtual
(self) -> bool:
24
return
bool(self.
children
)
25
26
@property
27
def
primary
(self) -> bool:
28
return
not
self.
virtual
29
30
@property
31
def
has_primary_children
(self) -> bool:
32
return
any(c.primary
for
c
in
self.
children
)
33
34
@property
35
def
only_primary_children
(self) -> bool:
36
return
all(c.primary
for
c
in
self.
children
)
37
38
def
__repr__
(self):
39
return
(f
'<Node {self.name} parents="{[n.name for n in self.parents]}" '
40
f
'children="{[n.name for n in self.children]}">'
)
41
42
def
dot
(self, current_node=False, tooltip: str =
""
, viewing_dependents: bool =
False
) -> str:
43
import
html
44
color =
"grey"
if
self.
primary
else
"white"
45
if
current_node:
46
color =
"darkslategray2"
if
viewing_dependents
else
"gold"
47
48
tooltip = (
"[Virtual]"
if
self.
virtual
else
"[Primary]"
) +
" "
+ html.escape(tooltip,
True
)
49
label = self.
name
50
51
52
if
current_node:
53
# Clicking on the current node toggles between views
54
if
viewing_dependents:
55
url = f
"../{self.name}.svg"
56
label +=
r"\n[Deep dependants]"
57
else
:
58
url = f
"{DEPENDSON_DIR}/{self.name}.svg"
59
label +=
r"\n[Dependencies]"
60
else
:
61
url =
"%s.svg"
% self.
name
62
63
return
f
'{self.name} [fillcolor={color}, style=filled, URL="{url}", tooltip="{tooltip}", label="{label}"];'
64
65
def
build_tree
(all_logic: Mapping[str, DefectLogic]) -> dict[str, Node]:
66
67
all_nodes: dict[str, Node] = {}
68
69
def
make_primary(current_logic: str) -> Node:
70
if
current_logic
in
all_nodes:
71
return
all_nodes[current_logic]
72
all_nodes[current_logic] = node =
Node
(current_logic)
73
return
node
74
75
def
explore_virtual(current_logic: str) -> Node:
76
if
current_logic
in
all_nodes:
77
return
all_nodes[current_logic]
78
79
this_logic = all_logic[current_logic]
80
all_nodes[current_logic] = node =
Node
(current_logic)
81
82
for
name
in
this_logic.clauses:
83
if
name
in
all_logic:
84
child = explore_virtual(name)
85
else
:
86
child = make_primary(name)
87
88
child.parents.add(node)
89
node.children.add(child)
90
91
return
node
92
93
for
name
in
all_logic:
94
explore_virtual(name)
95
96
return
all_nodes
97
98
def
walk
(node: Node, visited: set[Node], visit_primary: bool, fd: TextIO):
99
visited.add(node)
100
101
for
subnode
in
sorted(node.children, key=Node.get_name):
102
if
subnode.virtual
or
(subnode.primary
and
visit_primary):
103
print
(f
"{node.name} -> {subnode.name}"
, file=fd)
104
walk
(subnode, visited, visit_primary, fd)
105
106
def
dump_visited
(fd: TextIO, current_node: Node, nodes: set[Node],
107
descs: Mapping[Union[str, int], str], parents: bool):
108
for
node
in
sorted(nodes, key=Node.get_name):
109
at_current_node = node.name == current_node.name
110
description = descs.get(node.name, node.name)
111
# Line breaks in defect descriptions mess up the svg generation
112
description = description.replace(
'\n'
,
' '
)
113
print
(node.dot(at_current_node, description, parents), file=fd)
114
115
def
build_dependency_graph
(output_dir: str, node: Node, descs: Mapping[Union[str, int], str]):
116
117
with
open(
"%s/%s.dot"
% (output_dir, node.name),
"w"
)
as
fd:
118
print
(f
"strict digraph {node.name} {{"
, file=fd)
119
print
(
"rankdir=LR;\n"
, file=fd)
120
121
visited =
set
()
122
123
for
parent
in
sorted(node.parents, key=Node.get_name):
124
print
(f
"{parent.name} -> {node.name}"
, file=fd)
125
visited.add(parent)
126
127
walk
(node, visited, node.has_primary_children, fd)
128
129
dump_visited
(fd, node, visited, descs, parents=
False
)
130
131
print
(
"}"
, file=fd)
132
133
def
build_parent_tree
(output_dir: str, node: Node, descs: Mapping[Union[str, int], str]):
134
135
visited =
set
([node])
136
137
with
open(f
"{output_dir}/{DEPENDSON_DIR}/{node.name}.dot"
,
"w"
)
as
fd:
138
def
walk_parents(node):
139
visited.add(node)
140
for
parent
in
node.parents:
141
print
(f
"{parent.name} -> {node.name}"
, file=fd)
142
walk_parents(parent)
143
144
print
(f
"strict digraph {node.name} {{"
, file=fd)
145
print
(
"rankdir=LR;\n"
, file=fd)
146
147
walk_parents(node)
148
149
dump_visited
(fd, node, visited, descs, parents=
True
)
150
151
print
(
"}"
, file=fd)
152
153
def
render_all_flags
(output_dir: str, all_nodes: dict[str, Node], descs: Mapping[Union[str, int], str]):
154
155
path =
"%s/%s"
% (output_dir, DEPENDSON_DIR)
156
if
not
isdir(path):
157
makedirs(path)
158
159
for
_, node
in
sorted(all_nodes.items()):
160
build_dependency_graph
(output_dir, node, descs)
161
build_parent_tree
(output_dir, node, descs)
162
163
def
main
():
164
165
parser = ArgumentParser(description=
"Dump defect viewer information"
)
166
167
parser.add_argument(
"-t"
,
"--tag"
, default=
"HEAD"
, help=
"Defect tag"
)
168
parser.add_argument(
"-o"
,
"--output"
, default=
"."
, help=
"Directory to dump files"
)
169
170
args = parser.parse_args()
171
172
# Instantiate the Defect DB
173
db = DefectsDB(tag=args.tag)
174
175
descs = db.all_defect_descriptions
176
177
# Build node objects
178
all_nodes =
build_tree
(db.virtual_defect_logics)
179
180
# Write outputs
181
output_dir =
"%s/%s"
% (args.output, args.tag)
182
render_all_flags
(output_dir, all_nodes, descs)
183
184
if
__name__ ==
"__main__"
:
185
main
()
print
void print(char *figname, TCanvas *c1)
Definition
TRTCalib_StrawStatusPlots.cxx:26
defects_dump_graph.Node
Definition
defects_dump_graph.py:13
defects_dump_graph.Node.parents
parents
Definition
defects_dump_graph.py:17
defects_dump_graph.Node.__repr__
__repr__(self)
Definition
defects_dump_graph.py:38
defects_dump_graph.Node.has_primary_children
bool has_primary_children(self)
Definition
defects_dump_graph.py:31
defects_dump_graph.Node.primary
bool primary(self)
Definition
defects_dump_graph.py:27
defects_dump_graph.Node.get_name
str get_name(self)
Definition
defects_dump_graph.py:19
defects_dump_graph.Node.__init__
__init__(self, str name)
Definition
defects_dump_graph.py:14
defects_dump_graph.Node.virtual
bool virtual(self)
Definition
defects_dump_graph.py:23
defects_dump_graph.Node.children
children
Definition
defects_dump_graph.py:16
defects_dump_graph.Node.name
name
Definition
defects_dump_graph.py:15
defects_dump_graph.Node.only_primary_children
bool only_primary_children(self)
Definition
defects_dump_graph.py:35
set
STL class.
defects_dump_graph.build_tree
dict[str, Node] build_tree(Mapping[str, DefectLogic] all_logic)
Definition
defects_dump_graph.py:65
defects_dump_graph.build_dependency_graph
build_dependency_graph(str output_dir, Node node, Mapping[Union[str, int], str] descs)
Definition
defects_dump_graph.py:115
defects_dump_graph.build_parent_tree
build_parent_tree(str output_dir, Node node, Mapping[Union[str, int], str] descs)
Definition
defects_dump_graph.py:133
defects_dump_graph.walk
walk(Node node, set[Node] visited, bool visit_primary, TextIO fd)
Definition
defects_dump_graph.py:98
defects_dump_graph.main
main()
Definition
defects_dump_graph.py:163
defects_dump_graph.dump_visited
dump_visited(TextIO fd, Node current_node, set[Node] nodes, Mapping[Union[str, int], str] descs, bool parents)
Definition
defects_dump_graph.py:107
defects_dump_graph.render_all_flags
render_all_flags(str output_dir, dict[str, Node] all_nodes, Mapping[Union[str, int], str] descs)
Definition
defects_dump_graph.py:153
dot
Definition
dot.py:1
Generated on
for ATLAS Offline Software by
1.17.0