ATLAS Offline Software
Loading...
Searching...
No Matches
hanwriter.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3# @package DQHanConfMaker.hanwriter
4# Module containing the tools to write a DQConfiguration in han format.
5# @author: andrea.dotti@pi.infn.it
6# @author: ponyisi@hep.uchicago.edu
7# 15 August 2008
8# @note: The content of this module is inspired by the xml.dom.minidom module
9"""
10This module contains tools to write a DQConfiguration in han format
11"""
12
13import DQHanConfMaker
14from DQConfMakerBase.Helpers import BaseException, toList
15from DQConfMakerBase.DQElements import DQBase
16from functools import reduce
17
18# Writing exception
19# Han exception
20
21
22class HanWritingError(BaseException):
23 """
24 This exception is thrown when an error writing the han configuration is encountered
25 """
26
27 def __init__(self, reason):
28 super().__init__(
29 "Cannot create the han file ("+str(reason)+")")
30
31# Generic exception
32# Han exception
33
34
35class HanCannotCreateConf(BaseException):
36 """
37 This exception is thrown when an error creating the han configuration is encountered
38 """
39
40 def __init__(self, reason):
41 super().__init__(
42 "Cannot create configuration ("+str(reason)+")")
43
44# Han writer base class
45# Each valid element that can be written in a han file must inherit from this class
46
47
48class Node(DQHanConfMaker.Node):
49 """
50 This is the base class for each element that can be written in a valid han configuration file.
51 Attributes:
52 - subnodes : a list of Node instances
53 - attributes : a list of attributes associated with the node
54 - acceptChild : a list of Node types that can be accepted as sub nodes
55 - nodeType : the type of the node
56 - name : the name of the node
57 """
58 # Default constructor
59 # @param name: the name of the element @c name: string
60
61 def __init__(self, name=''):
62 """
63 Create a han node
64 """
65 self.subnodes = None
66 self.attributes = None
67 self.acceptChild = [Node.ALGORITHM, Node.DIR, Node.DOCUMENT, Node.HIST, Node.OUTPUT,
68 Node.REFERENCE, Node.THRESHOLD, Node.LIMIT, Node.COMPALG]
69 self.nodeType = Node.UNKNOWN
70 self.name = name
71
72 # Creates a valid han block
73 # @param encoding: a valid encoding identifier. @see: module codecs
74 # @return: the han string
75 def tohan(self, encoding=None):
76 """
77 convert the object in a valid han script block
78 """
79 return self.toprettyhan("", "", encoding)
80
81 # Creates a valid han block
82 # @param indent: used as indentation @c indent: string
83 # @param newl: used as new line character @c newl: string
84 # @param encoding: a valid encoding identifier @see: module codecs
85 # @return: the string representing the han configuration
86 def toprettyhan(self, indent="\t", newl="\n", encoding=None):
87 """
88 convert the object in a formatted han string
89 """
90 # restore the following in a future tdaq release
91 # writer = DQHanConfMaker._get_StringIO()
92 import io
93 writer = io.StringIO()
94 if encoding is not None:
95 import codecs
96 writer = codecs.lookup(encoding)[3](writer)
97 self.writehan(writer, "", indent, newl)
98 return writer.getvalue()
99
100 # Writes a han block
101 # @param writer: the writer helper @c writer: an object supporting the write method
102 # @param indent: used as indentation @c indent: string
103 # @param addindent: used as additional indentation for each sub node @c addindent: string
104 # @param newl: used as newline at the end of the element @c newl: string
105 def writehan(self, writer, indent="", addindent="", newl=""):
106 """
107 Converts the object in a han string and writes it in the writer object
108 """
109 writer.write(
110 indent+DQHanConfMaker._get_NodeType(self.nodeType)+" "+self.name)
111 # if it is a document do not need to add { }
112 if self.nodeType != Node.DOCUMENT:
113 writer.write(" { %s" % (newl))
114 if self.attributes:
115 for key, attribute in self.attributes.items():
116 writer.write("%s %s = %s%s" % (indent, key, attribute, newl))
117 if self.subnodes:
118 for node in self.subnodes:
119 node.writehan(writer, indent+addindent, addindent, newl)
120 if self.nodeType != Node.DOCUMENT:
121 writer.write("%s}%s" % (indent, newl))
122
123 # Adds a sub node
124 # @param child: the node to add @c child: a Node object instance
125 # @raise HanCannotCreaqteConf: in case of errors
126 def appendChild(self, child):
127 """
128 Add a sub node to this node
129 """
130 try:
131 if child.nodeType not in self.acceptChild:
132 msg = " Node: "+DQHanConfMaker._get_NodeType(self.nodeType)
133 msg += " Cannot have a child of type:", child.nodeType
134 raise HanCannotCreateConf(msg)
135 except Exception:
137 "Object:"+str(child)+" is not a valid Node")
138 if not self.subnodes:
139 self.subnodes = []
140 self.subnodes += [child]
141
142 # Adds an attribute to the node
143 # @param key: the attribute identifier @c key: a string
144 # @param attribute: the value for the attribute @c attribute: a string
145 def setAttribute(self, key, attribute):
146 """
147 The attribute identified by key is added to this node
148 """
149 if not self.attributes:
150 self.attributes = {}
151 self.attributes[key] = attribute
152 # Removes an attribute
153 # @param key: the attribute key @c key: a string
154 # @return: True on success
155
156 def removeAttribute(self, key):
157 """
158 Removes attribute identified by key
159 """
160 if self.attributes and key in self.attributes:
161 del self.attributes[key]
162 return True
163 return False
164 # Gets the attribute identified by key
165 # @param key: an attribute identifier @c key: string
166 # @return: the corresponding attribute or None if not found
167
168 def getAttribute(self, key):
169 """
170 Gets the attribute identified by the key, None if not found
171 """
172 if self.attributes and key in self.attributes:
173 return self.attributes[key]
174 return None
175 # Gets a sub-node by name and type
176 # @param name: the sub-node name
177 # @param nodetype: the sub-node type
178 # @return: the found Node or None if not found
179
180 def getSubNode(self, name, nodetype):
181 """
182 Returns the sub-node identified by name and nodetype
183 """
184 if self.subnodes:
185 for sn in self.subnodes:
186 if sn.nodeType == nodetype and sn.name == name:
187 return sn
188 return None
189
190 def __str__(self):
191 return "HanNode: "+self.name+" ("+DQHanConfMaker._get_NodeType(self.nodeType)+") Attributes:"+str(self.attributes)+" SubNodes: "+str(self.subnodes)
192
193
194# HanHistogram class
195# This class represents the configuration for a histogram
197 """
198 A han histogram element is a Node with attributes:
199 - the histogram name
200 - the algorithm to be used
201 - the output where to store the dq result
202 """
203 # Default constructor
204 # @param histogram: the histogram name @c histogram: a string
205 # @param algorithm: the algorithm element name @c algorithm: a string
206 # @param output: the output key @c output: a string
207 # @param annotations: annotations for the DQRegion @c : a dict
208 # @param attributes: attributes for the DQRegion @c : a dict
209 # @note: the histogram name is the histogram name without the directory structure. Thus a HanHistogram is usually nested in a directory tree (@see: HanDir)
210
211 def __init__(self, histogram, algorithm, annotations={}, output=DQHanConfMaker._default_output, attributes={}):
212 """
213 Creates a han histogram configuration element
214 """
215 Node.__init__(self, histogram)
216 self.acceptChild = []
217 self.nodeType = Node.HIST
218 self.setAttribute('algorithm', algorithm)
219 self.setAttribute('output', output)
220 if 'Weight' in attributes:
221 self.setAttribute('weight', attributes['Weight'][1])
222 for annotation in annotations:
223 self.setAttribute(annotation, annotations[annotation])
224
225 # Gets the output attribute
226 # @return: the output attribute string
227 def getOutput(self):
228 """
229 Retrieves the output attribute
230 """
231 return self.getAttribute('output')
232
233 # Gets the algorithm attribute
234 # @return: the algorithm attribute string
235 def getAlgorithm(self):
236 """
237 Retrieves the algorithm attribute
238 """
239 return self.getAttribute('algorithm')
240
241# Class algorithm
242# This class implements the han representation of a DQAlgorithm element
243
244
246 """
247 The han representation of a DQAlgorithm
248 """
249 # Default constructor
250 # @param name: the identifier for the han algorithm @c name: a string
251 # @param algoname: the dqm_algorithm name @c algoname: a string
252 # @param libname: the library containing the algorithm @c libname: a string
253 # @param reference: the reference object, can be None
254 # @param thresholds: the thresholds objects, can be None
255 # @param parameters: additional parameters, can be empty. @c parameters: a list
256
257 def __init__(self, name, algoname, libname='libdqm_algorithms.so', reference=None, thresholds=None,
258 parameters={}):
259 """
260 Creates a han algorithm configuration element
261 """
262 Node.__init__(self, name)
263 self.acceptChild = [Node.THRESHOLD, Node.REFERENCE]
264 self.nodeType = Node.ALGORITHM
265 self.setAttribute('name', algoname)
266 if libname:
267 self.setAttribute('libname', libname)
268 if reference:
269 self.setAttribute('reference', reference)
270 if thresholds:
271 self.setAttribute('thresholds', thresholds)
272 for parameter in parameters:
273 self.setAttribute(parameter, parameters[parameter])
274
275# Class for composite algorithm
276# This class implements the han representation of a DQCompositeAlgorithm
277
278
280 """
281 The han representation of a CompositeAlgorithm
282 """
283 # Default constructor
284 # @param name: the identifier for the han algorithm @c name: a string
285 # @param algoname: the dqm_algorithm name @c algoname: a string
286 # @param libname: the library containing the algorithm @c libname: a string
287
288 def __init__(self, name, subalgnames=[], libnames=[]):
289 """
290 Creates a han composite algorithm configuration element
291 """
292 Node.__init__(self, name)
293 self.acceptChild = []
294 self.nodeType = Node.COMPALG
295 self.setAttribute('subalgs', ','.join(subalgnames))
296 self.setAttribute('libnames', ','.join(libnames))
297
298# Class for reference
299# This class implements the han representation of a DQReference
300
301
303 """
304 The han representation of a DQReference
305 """
306 # Default constructor
307 # @param name: the identifier for the han reference @c name: a string
308 # @param histogramname: the histogram name @c histogramname: a string
309 # @param file: the filename for the reference histogram @c file: a string
310
311 def __init__(self, name, histogramname, file, info=None):
312 """
313 Creates a han reference configuration element
314 """
315 Node.__init__(self, name)
316 self.setAttribute('name', histogramname)
317 self.setAttribute('file', file)
318 if info is not None:
319 self.setAttribute('info', info)
320 self.nodeType = Node.REFERENCE
321 self.acceptChild = []
322
323# Class for limit
324# This class implements the han representation of a DQLimit
325
326
328 """
329 The han representation of a limit for a HanThreshold
330 """
331 # Default constructor
332 # @param name: the name of the limit @c name: a string
333 # @param warning: the value for the warning level
334 # @param error: the value for the error level
335
336 def __init__(self, name, warning, error):
337 """
338 Creates a han limit object
339 """
340 Node.__init__(self, name)
341 self.nodeType = Node.LIMIT
342 self.acceptChild = []
343 self.setAttribute('warning', warning)
344 self.setAttribute('error', error)
345
346# Class for threshold
347# This class implements the han representation of a DQThreshold
348
349
351 """
352 The han representation of a DQThreshold
353 """
354 # Default constructor
355 # @param name: the threshold identifier @c name: a string
356
357 def __init__(self, name):
358 """
359 Creates a han threshold configuration element
360 """
361 Node.__init__(self, name)
362 self.acceptChild = [Node.LIMIT]
363 self.nodeType = Node.THRESHOLD
364
365 def addLimit(self, name, warning, error):
366 """
367 Adds a limit to the threshold
368 @param name: the limits name
369 @param warning: the limit value for the warning level
370 @param error: the limit value for the error level
371 """
372 if self.getSubNode(name, Node.LIMIT):
374 "The limit: "+name+" already exists for threshold: "+self.name)
375 limit = HanLimit(name, warning, error)
376 self.appendChild(limit)
377
378# Class for han directory
379# This class implements the han directory
380
381
383 """
384 Class representing a dir element
385 A han dir element is a Node with sub nodes of type HanDir or HanHisto
386 """
387 # Default constructor
388 # @param namne: the name of the directory @c name: a string
389
390 def __init__(self, name):
391 """
392 Creates a han directory element
393 """
394 Node.__init__(self, name)
395 self.acceptChild = [Node.DIR, Node.HIST]
396 self.nodeType = Node.DIR
397
398 # Adds a sub directory
399 # @param name: the name of the subdirectory @c name: a string
400 # @return: the created HanDir object
401 def addSubDir(self, name):
402 """
403 Adds a subdirectory called name to the current directory and returns the newly created sub directory
404 """
405 subdir = HanDir(name)
406 self.appendChild(subdir)
407 return subdir
408 # Adds a histogram to the current directory
409 # @param histogram: the name of the histogram @c histogram: a string
410 # @param algorithm: the algorithm name to be used for this check @c algorithm: a string
411 # @param annotations: annotations for the DQRegion @c : a dict
412 # @param attributes: attributes for the DQRegion @c : a dict
413 # @param output: the output path for the result @c output: a string
414 # @return: the created HanHistogram object
415
416 def addHistogram(self, histogram, algorithm, annotations={}, output=DQHanConfMaker._default_output, attributes={}):
417 """
418 Adds to the directory a histogram specifying the histogram name, the algorithm and the output path.
419 """
420 histo = HanHistogram(histogram, algorithm,
421 annotations, output, attributes)
422 self.appendChild(histo)
423 return histo
424 # Gets a sub-directory name
425 # @param name: the subdirectory name @c name: a string
426
427 def getSubDir(self, name):
428 """
429 returns the sub-directory called name
430 """
431 return self.getSubNode(name, Node.DIR)
432
433# Class for han output
434# This class implements the han output
435
436
438 """
439 Class representing a output element
440 A han output element is a Node with sub nodes of type output and with the optional attribute algorithm
441 attribute:
442 - father: the HanOutput that contains this HanOutput
443 """
444 # Default constructor
445 # @param name: the output name @c name: a string
446 # @param algorithm: the optional algorithm name for this summary @c algorithm: summary
447 # @param father: the HanOutput containing this node
448 # @param annotations: annotations for the DQRegion @c : a dict
449 # @param attributes: attributes for the DQRegion @c : a dict
450
451 def __init__(self, name, algorithm=None, father=None, annotations={}, attributes={}):
452 """
453 Creates an output han element
454 """
455 Node.__init__(self, name)
456 self.acceptChild = [Node.OUTPUT]
457 self.nodeType = Node.OUTPUT
458 if algorithm:
459 self.setAttribute('algorithm', algorithm)
460 self.father = father
461 if 'Weight' in attributes:
462 self.setAttribute('weight', attributes['Weight'][1])
463 for annotation in annotations:
464 self.setAttribute(annotation, annotations[annotation])
465
466 # Gets the algorithm
467 # @return: the associated algorithm name
468 def getAlgorithm(self):
469 """
470 Gets the algorithm attribute
471 """
472 if 'algorithm' in self.attributes:
473 return self.getAttribute('algorithm')
474 # Adds a sub-output
475 # @param name: the sub output name @c name: a string
476 # @param algorithm: the algorithm for the sub output @c : a string
477 # @param annotations: annotations for the DQRegion @c : a dict
478 # @param attributes: attributes for the DQRegion @c : a dict
479 # @return: the created HanOutput object
480
481 def addOutput(self, name, algorithm, annotations, attributes):
482 """
483 Adds a sub output element with name and algorithm
484 """
485 subnode = HanOutput(name, algorithm, self, annotations, attributes)
486 self.appendChild(subnode)
487 return subnode
488 # Creates the complete output string
489 # @param append: string to be appended to the name @c append: a string
490 # @param delimter: the delimiting characters for the string concatenation @c delimiter: a string
491 # @return: the complete path output string
492
493 def getOutputPath(self, append=None, delimiter="/"):
494 """
495 Creates the complete path of this output directory
496 """
497 name = self.name
498 if append:
499 name = name + append
500 if self.father:
501 name = self.father.getOutputPath(delimiter+name, delimiter)
502 return name
503
504# Class document
505# This class represents the han document.
506# This class is a set of nodes
507
508
510 """
511 Class representing a han document
512 """
513 # Default constructor
514 # @param top_level_algorithm: the algorithm name for the top level output
515
516 def __init__(self, top_level_algorithm='WorstCaseSummary'):
517 """
518 Creates an empty han document with a top level output
519 """
520 HanDir.__init__(self, '')
521 HanOutput.__init__(self, '')
522 self.nodeType = Node.DOCUMENT
523 self.acceptChild = [Node.ALGORITHM, Node.DIR, Node.HIST, Node.OUTPUT, Node.REFERENCE, Node.THRESHOLD,
524 Node.COMPALG]
525 self.root_output_level = HanOutput('top_level', top_level_algorithm)
527 # Adds an output subdirectory
528 # @param name: the sub output name @c name: a string
529 # @param algorithm: the algorithm for the sub output @c algorithm : a string
530 # @param annotations: annotations for the DQRegion @c annotations : a dict
531 # @param attributes: attributes for the DQRegion @c attributes : a dict
532 # @return: the created HanOutput object
533
534 def addOutput(self, name, algorithm, annotations={}, attributes={}):
535 """
536 Adds a sub output element with name and algorithm
537 """
538 # forward to root region
539 return HanOutput.addOutput(self.root_output_level, name, algorithm, annotations, attributes)
540 # Gets the algorithm object
541 # @param name: the name of the algorithm
542 # @return: the algorithm associated to name
543
544 def getAlgorithm(self, name):
545 """
546 retrieves the algorithm han object associated with name
547 """
548 return self.getSubNode(name, Node.ALGORITHM)
549 # Gets the reference object
550 # @param name: the reference name
551 # @return: the HanReference object
552
553 def getReference(self, name):
554 """
555 retrieves the han reference associated with name
556 """
557 return self.getSubNode(name, Node.REFERENCE)
558
559
560# Add a DQParameter object to the HanDocument
561# @param handocument: the document containing the configuration @c handocument: a HanDocument object
562# @param dqparameter: the DQParameter object @c dqparameter: a DQParameter object
563# @param output: the output element for the result
564# @note: This function is used internally and should not be used by users of this module
565def _hanAddDQParameter(handocument, dqparameter, output=DQHanConfMaker._default_output):
566 """
567 Add a DQParameter object to a HanDocument, Doing this it creates the tree of
568 dir and output.
569 """
570 try:
571 if dqparameter.type != "DQParameter": # This is not valid
573 "Object: "+str(dqparameter)+" type does not match 'DQParameter'")
574 # gets the directory structure of the histogram and add it, if needed to the document
575 histoname = dqparameter.getInput().split('/')
576 theDir = handocument
577 # add directories to han document if needed
578 for directory in histoname[0:len(histoname)-1]:
579 subdir = theDir.getSubDir(directory)
580 if subdir is None:
581 subdir = theDir.addSubDir(directory)
582 theDir = subdir
583 # prepare to build the han algorithm element
584 algo = dqparameter.getAlgorithm()
585 if algo is None:
586 raise Exception('DQParameter without DQAlgorithm')
587 dqalgoname, dqalgolibrary = algo.id, algo.getLibraryName()
588 # Build the han reference, if any, associated to this DQParameter
589 dqrefname, dqreference, refs = "", dqparameter.getReference(), []
590 if dqreference != [None]: # References are defined
591 refs = '[%s]' % (','.join(_.id for _ in dqreference))
592 for iref in dqreference:
593 ref = iref.id
594 # search if reference is already in the han document
595 if handocument.getReference(ref) is None:
596 # it's not found, let's create it
597 refcompletename = iref.getReference()
598 filename = refcompletename.rpartition(':')[0]
599 refhistoname = refcompletename.rpartition(':')[
600 2].lstrip('/')
601 hanref = HanReference(
602 ref, histogramname=refhistoname, file=filename,
603 info=iref.getAnnotation('info'))
604 handocument.appendChild(hanref)
605 dqrefname = '_'+ref
606 # build the han thresholds
607 # here it's quite tricky: we have to get two sets of DQThresholds and combine them in a single
608 # han thresholds element
609 warnings = toList(dqparameter.getWarnings())
610 errors = toList(dqparameter.getErrors())
611 thresholds, hanthreshold, thresholdsname = '', None, ''
612 if (warnings != [None]) and (errors != [None]):
613 # Found errors and warnings limits
614 thresholds = dqparameter.id.replace(
615 '_', '__').replace('/', '_')+'_thr'
616 hanthreshold = HanThreshold(thresholds)
617 thresholdsname = thresholds
618 thresholds = '_'+thresholds
619
620 def getCorrespondingRed(warningname):
621 for e in errors:
622 if e.getAttribute('Name')[1] == warningname:
623 return e
624 return None
625 for warning in warnings:
626 warningname = warning.getAttribute('Name')[1]
627 error = getCorrespondingRed(warningname)
628 if error is None:
630 'Cannot find corresponding error for warning names: '+warning.id)
631 hanthreshold.addLimit(warningname, warning.getAttribute(
632 'Value')[1], error.getAttribute('Value')[1])
633 #print DQHanConfMaker._get_NodeType(hanthreshold.nodeType),hanthreshold.name
634 handocument.appendChild(hanthreshold)
635
636 # build the parameter id string and key, value pairs
637 parameterstr = '_'.join([x.id for x in toList(
638 dqparameter.getAlgorithmParameters()) if x is not None])
639 parameters = {}
640 for x in toList(dqparameter.getAlgorithmParameters()):
641 if x is None:
642 continue
643 parameters[x.getName()[1]] = x.getValue()[1][0]
644 # create a unique string identifying this han algorithm element so far
645 hanalgoname = ("%s_%s%s%s%s" % (dqalgolibrary, dqalgoname,
646 dqrefname, thresholds.replace('/', '_'), parameterstr))
647 # Finally add the histogram han element
648 theDir.addHistogram(histogram=histoname[len(histoname)-1], algorithm=hanalgoname,
649 annotations=dqparameter.getAllAnnotations(), output=output, attributes=dqparameter.getAllAttributes())
650 # search the han algorithm in the document
651 if handocument.getAlgorithm(hanalgoname) is None:
652 # This algorithm has never been added before in the document
653 node = HanAlgorithm(name=hanalgoname, algoname=dqalgoname, libname=dqalgolibrary,
654 reference=refs, thresholds=thresholdsname, parameters=parameters)
655 handocument.appendChild(node)
656 # check for possible composite algorithms
657 compalg = algo.getCompositeAlgorithm()
658 if compalg is not None:
659 node = HanCompositeAlgorithm(name=compalg.id, subalgnames=compalg.getSubAlgNames(),
660 libnames=compalg.getLibNames())
661 handocument.appendChild(node)
662 except Exception as msg:
664 "Object: "+str(dqparameter)+" is not a valid DQParameter. Reason: "+str(msg))
665
666# Finds the root han objects of the input collection
667# @param input: the list of objects @c input: a list of DQBase objects
668# @raise HanCannotCreateConf: in case of errors
669# @return: the list of roots
670# @note: This function is used internally and should not be used by users of this module
671
672
673def _findRoots(input=[], objecttype="DQRegion"):
674 """
675 This helper return the list of objects that are the roots in the tree represented by input.
676 """
677 result = []
678 for o in input:
679 try:
680 if o.type == objecttype:
681 if len(o.isReferencedBy) == 0:
682 result += [o]
683 except Exception:
685 "object %s is not a valid DQBase object" % o)
686 return result
687
688# Gets all DQBase objects that corresponds to the input han objects
689# @param rootlist: a list of han object trees
690# @return: the list of all DQBaseObjects associated to each node of the input tree
691# @note: This function is used internally and should not be used by users of this module
692
693
695 """
696 This returns all DQBase objects reachable from the rootlist as a set.
697 """
698 import operator
699
700 def recurse(dqbase):
701 if dqbase is None:
702 return set()
703 if isinstance(dqbase, list):
704 return reduce(operator.ior, [recurse(x) for x in dqbase])
705 if not isinstance(dqbase, DQBase):
706 raise ValueError(
707 '%s is not a valid DQBase object; this should never happen' % dqbase)
708 retset = {dqbase}
709 for rel in dqbase.getAllRelatedObjects():
710 retset |= recurse(rel)
711 return retset
712
713 topset = set()
714 for dqbase in toList(rootlist):
715 topset |= recurse(dqbase)
716 return list(topset)
717
718# Writes the han configuration to a file
719# @param roots: the list of all roots of han trees
720
721
722def writeHanConfiguration(filename='dq.han.config', roots=[]):
723 """
724 Writes the configuration to a han file.
725 The configuration has to be passed as a list of roots in han configuration.
726 """
727 configList = _findAllDQBaseObjects(roots)
728 # First remove the configuration elements that cannot be saved as han
729 for element in configList:
730 try:
731 if not DQHanConfMaker._isAceptedHanElement(element):
732 print("==========WARNING===========")
733 print("Object: " + \
734 str(element) + \
735 " does not have a valid han representation, cannot save")
736 print("The object is referenced by:", element.isReferencedBy)
737 print("You may need to manually edit the configuration")
738 print("============================")
739 configList.remove(element)
740 except Exception:
741 print(element.isReferencedBy)
742 raise HanCannotCreateConf("Not valid object:" + str(element))
743 # Let's create the han document
744 doc = Document()
745 # Find all root regions
746 rootregions = _findRoots(configList)
747
748 # Navigate through DQRegions tree and add it to the han document
749 def _addchild(hanfather, dqregion, handocument):
750 outputalgo = dqregion.getAlgorithm()
751 if handocument.getAlgorithm(outputalgo.id) is None:
752 # Add to the document the summary maker algorithm
753 # summary makers do not have thresholds or parameters
754 # @todo: in the future extend this to make in enough general to support parameter
755 handocument.appendChild(HanAlgorithm(
756 outputalgo.id, outputalgo.id, outputalgo.getLibraryName())) # , reference, thresholds)
757 output = hanfather.addOutput(dqregion.id, outputalgo.id, annotations=dqregion.getAllAnnotations(
758 ), attributes=dqregion.getAllAttributes())
759 # recursively add subregions
760 for subregion in dqregion.getSubRegions():
761 if subregion is not None:
762 _addchild(output, subregion, doc)
763 # Add each DQParameter to the han document with the helper
764 for parameter in dqregion.getDQParameters():
765 if parameter is not None:
766 _hanAddDQParameter(handocument, parameter,
767 output=output.getOutputPath())
768
769 for region in rootregions:
770 _addchild(doc, region, doc)
771
772 fileout = open(filename, 'w')
773 print(doc.toprettyhan(" "), file=fileout)
static void reduce(HepMC::GenEvent *ge, HepMC::GenParticle *gp)
Remove an unwanted particle from the event, collapsing the graph structure consistently.
Definition FixHepMC.cxx:39
void print(char *figname, TCanvas *c1)
addOutput(self, name, algorithm, annotations={}, attributes={})
Definition hanwriter.py:534
__init__(self, top_level_algorithm='WorstCaseSummary')
Definition hanwriter.py:516
__init__(self, name, algoname, libname='libdqm_algorithms.so', reference=None, thresholds=None, parameters={})
Definition hanwriter.py:258
__init__(self, name, subalgnames=[], libnames=[])
Definition hanwriter.py:288
addHistogram(self, histogram, algorithm, annotations={}, output=DQHanConfMaker._default_output, attributes={})
Definition hanwriter.py:416
__init__(self, histogram, algorithm, annotations={}, output=DQHanConfMaker._default_output, attributes={})
Definition hanwriter.py:211
__init__(self, name, warning, error)
Definition hanwriter.py:336
addOutput(self, name, algorithm, annotations, attributes)
Definition hanwriter.py:481
getOutputPath(self, append=None, delimiter="/")
Definition hanwriter.py:493
__init__(self, name, algorithm=None, father=None, annotations={}, attributes={})
Definition hanwriter.py:451
__init__(self, name, histogramname, file, info=None)
Definition hanwriter.py:311
addLimit(self, name, warning, error)
Definition hanwriter.py:365
appendChild(self, child)
Definition hanwriter.py:126
removeAttribute(self, key)
Definition hanwriter.py:156
setAttribute(self, key, attribute)
Definition hanwriter.py:145
getSubNode(self, name, nodetype)
Definition hanwriter.py:180
toprettyhan(self, indent="\t", newl="\n", encoding=None)
Definition hanwriter.py:86
tohan(self, encoding=None)
Definition hanwriter.py:75
getAttribute(self, key)
Definition hanwriter.py:168
writehan(self, writer, indent="", addindent="", newl="")
Definition hanwriter.py:105
__init__(self, name='')
Definition hanwriter.py:61
STL class.
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
_findAllDQBaseObjects(rootlist)
Definition hanwriter.py:694
_findRoots(input=[], objecttype="DQRegion")
Definition hanwriter.py:673
writeHanConfiguration(filename='dq.han.config', roots=[])
Definition hanwriter.py:722
_hanAddDQParameter(handocument, dqparameter, output=DQHanConfMaker._default_output)
Definition hanwriter.py:565