ATLAS Offline Software
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 """
10 This module contains tools to write a DQConfiguration in han format
11 """
12 
13 import DQHanConfMaker
14 from DQConfMakerBase.Helpers import BaseException, toList
15 from DQConfMakerBase.DQElements import DQBase
16 from functools import reduce
17 
18 # Writing exception
19 # Han exception
20 
21 
22 class 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  BaseException.__init__(
29  self, "Cannot create the han file ("+str(reason)+")")
30 
31 # Generic exception
32 # Han exception
33 
34 
35 class 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  BaseException.__init__(
42  self, "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 
48 class 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:
136  raise HanCannotCreateConf(
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 
327 class HanLimit(Node):
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):
373  raise HanCannotCreateConf(
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 
382 class HanDir(Node):
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)
526  self.appendChild(self.root_output_level)
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
565 def _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
572  raise HanCannotCreateConf(
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:
629  raise HanCannotCreateConf(
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:
663  raise HanCannotCreateConf(
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 
673 def _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:
684  raise HanCannotCreateConf(
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 
694 def _findAllDQBaseObjects(rootlist):
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 
722 def 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)
python.hanwriter.HanOutput
Definition: hanwriter.py:437
python.hanwriter.HanOutput.getAlgorithm
def getAlgorithm(self)
Definition: hanwriter.py:468
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
python.hanwriter.Node.toprettyhan
def toprettyhan(self, indent="\t", newl="\n", encoding=None)
Definition: hanwriter.py:86
python.hanwriter.HanDir.addHistogram
def addHistogram(self, histogram, algorithm, annotations={}, output=DQHanConfMaker._default_output, attributes={})
Definition: hanwriter.py:416
python.hanwriter.HanOutput.getOutputPath
def getOutputPath(self, append=None, delimiter="/")
Definition: hanwriter.py:493
python.hanwriter.HanHistogram.getAlgorithm
def getAlgorithm(self)
Definition: hanwriter.py:235
python.hanwriter.HanDir.getSubDir
def getSubDir(self, name)
Definition: hanwriter.py:427
python.hanwriter.Node.setAttribute
def setAttribute(self, key, attribute)
Definition: hanwriter.py:145
python.hanwriter.Node.getAttribute
def getAttribute(self, key)
Definition: hanwriter.py:168
python.hanwriter.HanThreshold.addLimit
def addLimit(self, name, warning, error)
Definition: hanwriter.py:365
python.hanwriter.HanReference.__init__
def __init__(self, name, histogramname, file, info=None)
Definition: hanwriter.py:311
python.hanwriter.Node.getSubNode
def getSubNode(self, name, nodetype)
Definition: hanwriter.py:180
python.hanwriter.HanHistogram.__init__
def __init__(self, histogram, algorithm, annotations={}, output=DQHanConfMaker._default_output, attributes={})
Definition: hanwriter.py:211
python.hanwriter.HanOutput.addOutput
def addOutput(self, name, algorithm, annotations, attributes)
Definition: hanwriter.py:481
python.hanwriter.HanWritingError.__init__
def __init__(self, reason)
Definition: hanwriter.py:27
python.hanwriter.HanCannotCreateConf.__init__
def __init__(self, reason)
Definition: hanwriter.py:40
python.hanwriter.Document.__init__
def __init__(self, top_level_algorithm='WorstCaseSummary')
Definition: hanwriter.py:516
python.hanwriter.Node.removeAttribute
def removeAttribute(self, key)
Definition: hanwriter.py:156
python.hanwriter.Node.tohan
def tohan(self, encoding=None)
Definition: hanwriter.py:75
python.hanwriter.Node.appendChild
def appendChild(self, child)
Definition: hanwriter.py:126
python.hanwriter._findRoots
def _findRoots(input=[], objecttype="DQRegion")
Definition: hanwriter.py:673
dq_make_web_display.recurse
def recurse(rdir, dqregion, ignorepath, reffile=None)
Definition: dq_make_web_display.py:22
reduce
void reduce(HepMC::GenEvent *ge, std::vector< HepMC::GenParticlePtr > toremove)
Remove unwanted particles from the event, collapsing the graph structure consistently.
Definition: FixHepMC.cxx:84
python.hanwriter.HanLimit
Definition: hanwriter.py:327
python.hanwriter._hanAddDQParameter
def _hanAddDQParameter(handocument, dqparameter, output=DQHanConfMaker._default_output)
Definition: hanwriter.py:565
python.hanwriter.Node.name
name
Definition: hanwriter.py:70
python.hanwriter.HanHistogram
Definition: hanwriter.py:196
python.hanwriter.HanThreshold
Definition: hanwriter.py:350
python.hanwriter.HanAlgorithm.__init__
def __init__(self, name, algoname, libname='libdqm_algorithms.so', reference=None, thresholds=None, parameters={})
Definition: hanwriter.py:257
python.hanwriter.HanCannotCreateConf
Definition: hanwriter.py:35
python.hanwriter.HanLimit.__init__
def __init__(self, name, warning, error)
Definition: hanwriter.py:336
python.hanwriter.Node.nodeType
nodeType
Definition: hanwriter.py:69
python.hanwriter.Document
Definition: hanwriter.py:509
python.hanwriter.HanAlgorithm
Definition: hanwriter.py:245
python.hanwriter.HanHistogram.getOutput
def getOutput(self)
Definition: hanwriter.py:227
python.hanwriter.Document.root_output_level
root_output_level
Definition: hanwriter.py:525
python.hanwriter.Node.__str__
def __str__(self)
Definition: hanwriter.py:190
python.hanwriter._findAllDQBaseObjects
def _findAllDQBaseObjects(rootlist)
Definition: hanwriter.py:694
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.hanwriter.Document.addOutput
def addOutput(self, name, algorithm, annotations={}, attributes={})
Definition: hanwriter.py:534
python.hanwriter.HanDir
Definition: hanwriter.py:382
python.hanwriter.HanOutput.father
father
Definition: hanwriter.py:460
python.hanwriter.HanWritingError
Definition: hanwriter.py:22
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.hanwriter.HanOutput.__init__
def __init__(self, name, algorithm=None, father=None, annotations={}, attributes={})
Definition: hanwriter.py:451
python.hanwriter.Node
Definition: hanwriter.py:48
python.hanwriter.HanDir.__init__
def __init__(self, name)
Definition: hanwriter.py:390
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:71
python.hanwriter.HanCompositeAlgorithm
Definition: hanwriter.py:279
python.hanwriter.Node.writehan
def writehan(self, writer, indent="", addindent="", newl="")
Definition: hanwriter.py:105
Trk::open
@ open
Definition: BinningType.h:40
python.hanwriter.Node.acceptChild
acceptChild
Definition: hanwriter.py:67
python.hanwriter.Document.getAlgorithm
def getAlgorithm(self, name)
Definition: hanwriter.py:544
python.hanwriter.Node.subnodes
subnodes
Definition: hanwriter.py:65
python.hanwriter.Node.attributes
attributes
Definition: hanwriter.py:66
python.hanwriter.HanReference
Definition: hanwriter.py:302
python.hanwriter.HanCompositeAlgorithm.__init__
def __init__(self, name, subalgnames=[], libnames=[])
Definition: hanwriter.py:288
python.hanwriter.HanDir.addSubDir
def addSubDir(self, name)
Definition: hanwriter.py:401
str
Definition: BTagTrackIpAccessor.cxx:11
python.hanwriter.Document.getReference
def getReference(self, name)
Definition: hanwriter.py:553
python.hanwriter.HanThreshold.__init__
def __init__(self, name)
Definition: hanwriter.py:357
python.hanwriter.Node.__init__
def __init__(self, name='')
Definition: hanwriter.py:61
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
python.hanwriter.writeHanConfiguration
def writeHanConfiguration(filename='dq.han.config', roots=[])
Definition: hanwriter.py:722