ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
DataQuality
DataQualityInterfaces
scripts
han_lark_tester.py
Go to the documentation of this file.
1
#!/usr/bin/env python
2
# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3
4
# More detailed syntax checking for han files
5
6
7
import
lark, sys
8
from
AthenaCommon.Utils.unixtools
import
find_datafile
9
10
class
T
(lark.Transformer):
11
def
__init__
(self):
12
super().
__init__
()
13
self.
library_set
=
set
()
14
15
def
__default_token__
(self,tok):
16
print
(tok)
17
return
tok
18
def
referenceblock
(self, tok):
19
locations = [_
for
_
in
tok
if
isinstance(_, lark.Tree)
and
_.data ==
'location'
]
20
if
len(locations) > 1:
21
raise
ValueError(f
'More than one location given for reference {tok[0].children[0]}'
)
22
if
len(locations) > 0:
23
locs = locations[0].children[0].
split
(
','
)
24
else
:
25
locs = [_.children[0]
for
_
in
tok
if
isinstance(_, lark.Tree)
and
_.data ==
'file'
]
26
afspaths = [_
for
_
in
locs
if
_.startswith(
'/afs'
)]
27
if
any(afspaths):
28
raise
ValueError(
'A reference location for a production han configuration is given with an AFS path\n'
29
f
'Offending path is {",".join(afspaths)} of reference {tok[0].children[0]}'
)
30
eospaths = [_
for
_
in
locs
if
_.startswith(
'/eos'
)]
31
xrootdpaths = [_
for
_
in
locs
if
_.startswith(
'root://'
)]
32
if
len(eospaths) != len(xrootdpaths):
33
raise
ValueError(f
'Backup xrootd locations must be given for references with EOS paths for reference {tok[0].children[0]}\n'
34
f
'Given EOS paths are {",".join(eospaths)}\n'
35
f
'Given xrootd paths are {",".join(xrootdpaths)}'
)
36
return
tok
37
38
39
class
AlgorithmNameInterpreter
(lark.visitors.Interpreter):
40
def
__init__
(self):
41
super().
__init__
()
42
43
def
algorithmblock
(self, tree: lark.Tree):
44
thisalgname = [_.children[0].value
for
_
in
tree.children
if
isinstance(_, lark.Tree)
and
_.data ==
"algorithmname"
][0]
45
thisalgrealname = [_
for
_
in
tree.children
if
isinstance(_, lark.Tree)
and
_.data ==
"realname"
]
46
if
not
thisalgrealname:
47
raise
ValueError(f
"no underlying algorithm specified for {thisalgname}"
)
48
for
node
in
tree.children:
49
if
node.data ==
'algorithmblock'
:
50
for
subnode
in
node.children:
51
if
subnode.data ==
'algorithmname'
:
52
subnode.children[0].value = thisalgname +
'/'
+ subnode.children[0].value
53
if
not
[_
for
_
in
node.children
if
isinstance(_, lark.Tree)
and
_.data ==
"realname"
]:
54
node.children.append(thisalgrealname[0])
55
self.visit(node)
56
57
def
dirblock
(self, tree: lark.Tree):
58
thisdirname = [_.children[0].value
for
_
in
tree.children
if
isinstance(_, lark.Tree)
and
_.data ==
"dirname"
][0]
59
for
node
in
tree.children:
60
if
node.data ==
'dirblock'
:
61
for
subnode
in
node.children:
62
if
subnode.data ==
'dirname'
:
63
subnode.children[0].value = thisdirname +
'/'
+ subnode.children[0].value
64
self.visit(node)
65
elif
node.data ==
'histblock'
:
66
for
subnode
in
node.children:
67
if
subnode.data ==
'histname'
:
68
subnode.children[0].value = thisdirname +
'/'
+ subnode.children[0].value
69
70
71
grammarfile = find_datafile(
'DataQualityInterfaces/han_def.lark'
)
72
if
grammarfile
is
None
:
73
raise
OSError(
'Unable to find file parser configuration file'
)
74
grammar = open(grammarfile).
read
()
75
transformer =
T
()
76
parser = lark.Lark(grammar, parser=
'lalr'
, lexer=
'contextual'
, transformer=transformer)
77
78
79
def
algorithm_check
(tree):
80
import
ROOT
81
import
cppyy
82
83
ROOT.gSystem.Load(
'libdqm_core.so'
)
84
cppyy.include(
"dqm_core/AlgorithmManager.h"
)
85
86
cppyy.cppdef(
r"""
87
#include <dqm_core/AlgorithmManager.h>
88
std::pair<std::vector<std::string>, std::vector<std::string>> get_lib_algs() {
89
std::vector<std::string> rv1;
90
std::vector<std::string> rv2;
91
for (const auto& p : dqm_core::AlgorithmManager::instance().getAlgorithmMap()) {
92
rv1.push_back(p.first);
93
}
94
for (const auto& p : dqm_core::AlgorithmManager::instance().getSummaryMakerMap()) {
95
rv2.push_back(p.first);
96
}
97
return std::move(std::make_pair(rv1, rv2));
98
}
99
"""
100
)
101
102
rv =
True
103
try
:
104
AlgorithmNameInterpreter
().visit(tree)
105
except
ValueError
as
e:
106
print
(f
'ERROR: {e}'
)
107
return
False
108
libs = {_.children[0].value
for
_
in
tree.find_data(
'libname'
)}
# Defined libraries
109
compalgs = {_.children[0].value
for
_
in
tree.find_data(
'compalgname'
)}
# Defined composite algorithms
110
111
# Check if the referenced libraries exist
112
for
lib
in
libs:
113
if
ROOT.gSystem.Load(lib) < 0:
114
rv =
False
115
print
(f
'ERROR: Library {lib} defined by a libname clause cannot be found. Referenced by:'
)
116
for
alg
in
tree.find_data(
'algorithmblock'
):
117
alibname = alg.find_data(
'libname'
)
118
if
alibname
and
lib
in
{_.children[0].value
for
_
in
alibname}:
119
print
(list(alg.find_data(
'algorithmname'
))[0].children[0].value)
120
121
# Extract the list of "base" algorithms and summaries
122
libalgos, libsummaries = ROOT.get_lib_algs()
123
124
# Check that the composite algorithms reference existing base algorithms (and not summaries!)
125
for
alg
in
tree.find_data(
'compalgblock'
):
126
subalglist = [_
for
_
in
alg.children
if
_.data ==
'subalglist'
]
127
for
tok
in
subalglist[0].children:
128
if
tok.value
not
in
libalgos:
129
algname = list(alg.find_data(
'compalgname'
))[0].children[0].value
130
print
(f
'ERROR: composite algorithm {algname} references {tok.value} which is not a known algorithm'
)
131
rv =
False
132
133
# Check that all the instantiated algorithms and summaries refer to existing base algorithms and summaries
134
instalgos =
set
()
135
instsummaries =
set
()
136
for
alg
in
tree.find_data(
'algorithmblock'
):
137
try
:
138
algname = [_.children[0].value
for
_
in
alg.children
if
isinstance(_, lark.Tree)
and
_.data ==
"algorithmname"
][0]
139
algrealname = [_.children[0].value
for
_
in
alg.children
if
isinstance(_, lark.Tree)
and
_.data ==
"realname"
][0]
140
if
algrealname
in
libalgos:
141
instalgos.add(algname)
142
elif
algrealname
in
libsummaries:
143
instsummaries.add(algname)
144
elif
algrealname
in
compalgs:
145
instalgos.add(algname)
146
else
:
147
print
(f
'ERROR: undefined base algorithm {algrealname} for {algname}'
)
148
rv =
False
149
except
Exception
as
e:
150
print
(
'??? problem processing'
, alg, e)
151
152
# These SHOULD just be summaries
153
for
ref
in
tree.find_data(
'algorefstatement'
):
154
nodealg = ref.children[0].children[0].value
155
if
nodealg
not
in
instsummaries:
156
print
(f
'ERROR: an output is specifying algorithm = {nodealg} which is not a known summary algorithm'
)
157
rv =
False
158
159
# These SHOULD just be non-summary algos
160
for
ref
in
list(tree.find_data(
'dirblock'
)) + list(tree.find_data(
'histblock'
)):
161
nodealg = [_
for
_
in
ref.children
if
_.data ==
'algorithmreference'
]
162
if
nodealg:
163
nodealgname = nodealg[0].children[0].value
164
if
nodealgname
not
in
instalgos:
165
refname = [_
for
_
in
ref.children
if
_.data
in
(
'histname'
,
'dirname'
)][0].children[0].value
166
print
(f
'ERROR: a dir/hist is specifying algorthm = {nodealgname} which is not a known histogram algorithm. Referenced by {refname}'
)
167
rv =
False
168
169
return
rv
170
171
172
infile = open(sys.argv[1]).
read
()
173
try
:
174
tree = parser.parse(infile)
175
print
(
'Tree done'
)
176
print
(
'Checking algorithms'
)
177
if
algorithm_check
(tree):
178
print
(tree.pretty())
179
print
(
'All ok'
)
180
else
:
181
sys.exit(1)
182
183
except
Exception
as
e:
184
print
(
'ERROR:'
)
185
print
(e)
186
raise
e
187
sys.exit(1)
print
void print(char *figname, TCanvas *c1)
Definition
TRTCalib_StrawStatusPlots.cxx:26
han_lark_tester.AlgorithmNameInterpreter
Definition
han_lark_tester.py:39
han_lark_tester.AlgorithmNameInterpreter.algorithmblock
algorithmblock(self, lark.Tree tree)
Definition
han_lark_tester.py:43
han_lark_tester.AlgorithmNameInterpreter.dirblock
dirblock(self, lark.Tree tree)
Definition
han_lark_tester.py:57
han_lark_tester.AlgorithmNameInterpreter.__init__
__init__(self)
Definition
han_lark_tester.py:40
han_lark_tester.T
Definition
han_lark_tester.py:10
han_lark_tester.T.__default_token__
__default_token__(self, tok)
Definition
han_lark_tester.py:15
han_lark_tester.T.library_set
library_set
Definition
han_lark_tester.py:13
han_lark_tester.T.referenceblock
referenceblock(self, tok)
Definition
han_lark_tester.py:18
han_lark_tester.T.__init__
__init__(self)
Definition
han_lark_tester.py:11
set
STL class.
split
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition
hcg.cxx:179
han_lark_tester.algorithm_check
algorithm_check(tree)
Definition
han_lark_tester.py:79
read
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)
Definition
openCoraCool.cxx:569
Generated on
for ATLAS Offline Software by
1.17.0