CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ConfigDataAccessor.py
Go to the documentation of this file.
1 import sys
2 import os.path
3 import logging
4 import re
5 
6 from Vispa.Share.BasicDataAccessor import BasicDataAccessor
7 from Vispa.Share.RelativeDataAccessor import RelativeDataAccessor
8 from Vispa.Main.Exceptions import PluginIgnoredException,exception_traceback
9 
11 import FWCore.ParameterSet.Config as cms
12 import FWCore.ParameterSet.Modules as mod
13 import FWCore.ParameterSet.Types as typ
14 
15 imported_configs = {}
16 file_dict = {}
17 
19  def __init__(self, label, parent=None, parameters=None):
20  self._label = label
21  self._configChildren = []
22  self._parameters = {}
23  if parent != None:
24  parent._configChildren += [self]
25  if parameters != None:
26  self._parameters = parameters
27  def label_(self):
28  return self._label
29  def parameters_(self):
30  return self._parameters
31  def _configChildren(self):
32  return self._configChildren
33 
35  def __init__(self):
36  logging.debug(__name__ + ": __init__")
37 
38  self._file = None
39  self._filename=""
40  self._isReplaceConfig = False
41  self._history=None
42  self._cancelOperationsFlag = False
43  self._initLists()
44 
45  def _initLists(self):
46  self._allObjects = []
48  self._connections = {}
49  self._topLevelObjects = []
50  self._inputTagsDict = {}
51  self._foundInDict = {}
52  self._usesDict = {}
53  self._usedByDict = {}
56 
57  def cancelOperations(self):
58  self._cancelOperationsFlag = True
59 
60  def isReplaceConfig(self):
61  return self._isReplaceConfig
62 
63  def setIsReplaceConfig(self):
64  self._isReplaceConfig = True
65 
66  def topLevelObjects(self):
67  return self._topLevelObjects
68 
69  def _readRecursive(self, mother, pth):
70  """ Read cms objects recursively from path """
71  entry = None
72  if isinstance(pth, (cms.Path, cms.EndPath, cms.Sequence, cms.SequencePlaceholder, cms.Source, mod._Module, cms.Service, cms.ESSource, cms.ESProducer, cms.ESPrefer, cms.PSet, cms.VPSet)):
73  entry = pth
74  entry._configChildren=[]
75  self._allObjects += [pth]
76  if mother != None:
77  if not pth in mother._configChildren:
78  mother._configChildren += [pth]
79  else:
80  self._topLevelObjects += [pth]
81  next_mother = entry
82  if entry == None:
83  next_mother = mother
84  if isinstance(pth, list):
85  for i in pth:
86  self._readRecursive(next_mother, i)
87  if hasattr(sqt,"_SequenceCollection"):
88  # since CMSSW_3_11_X
89  if isinstance(pth, (sqt._ModuleSequenceType)):
90  if isinstance(pth._seq, (sqt._SequenceCollection)):
91  for o in pth._seq._collection:
92  self._readRecursive(next_mother, o)
93  else:
94  self._readRecursive(next_mother, pth._seq)
95  elif isinstance(pth, sqt._UnarySequenceOperator):
96  self._readRecursive(next_mother, pth._operand)
97  else:
98  # for backwards-compatibility with CMSSW_3_10_X
99  for i in dir(pth):
100  o = getattr(pth, i)
101  if isinstance(o, sqt._Sequenceable):
102  self._readRecursive(next_mother, o)
103 
104  def readConnections(self, objects,toNeighbors=False):
105  """ Read connection between objects """
106  connections={}
107  self._motherRelationsDict={}
108  self._daughterRelationsDict={}
109  if toNeighbors:
110  compareObjectList=[]
111  for obj in objects:
112  compareObjectList+=[(obj,o) for o in self._allObjects]
113  compareObjectList+=[(o,obj) for o in self._allObjects]
114  else:
115  compareObjectList=[(o1,o2) for o1 in objects for o2 in objects]
116  for connection in compareObjectList:
117  if self._cancelOperationsFlag:
118  break
119  if not connection in self._connections.keys():
120  for key, value in self.inputTags(connection[1]):
121  module = str(value).split(":")[0]
122  if module == self.label(connection[0]):
123  product = ".".join(str(value).split(":")[1:])
124  try:
125  self._connections[connection]=(product, key)
126  except TypeError:
127  return []
128  if connection in self._connections.keys():
129  connections[connection]=self._connections[connection]
130  if not connection[1] in self._motherRelationsDict.keys():
131  self._motherRelationsDict[connection[1]]=[]
132  self._motherRelationsDict[connection[1]]+=[connection[0]]
133  if not connection[0] in self._daughterRelationsDict.keys():
134  self._daughterRelationsDict[connection[0]]=[]
135  self._daughterRelationsDict[connection[0]]+=[connection[1]]
136  return connections
137 
138  def connections(self):
139  return self._connections
140 
141  def _sort_list(self, l):
142  result = l[:]
143  result.sort(lambda x, y: cmp(self.label(x).lower(), self.label(y).lower()))
144  return result
145 
146  def open(self, filename=None):
147  """ Open config file and read it.
148  """
149  logging.debug(__name__ + ": open")
150  if filename != None:
151  self._filename = str(filename)
152  global imported_configs
153  self._isReplaceConfig = False
154  self._history=None
155 
156 # import input-config and make list of all imported configs
157  for i in imported_configs.iterkeys():
158  if i in sys.modules.keys():
159  del sys.modules[i]
160  sys.path.insert(0, os.path.dirname(self._filename))
161  common_imports = sys.modules.copy()
162 
163  import imp
164  theFile = open(self._filename)
165  self._file = imp.load_module(os.path.splitext(os.path.basename(self._filename))[0].replace(".", "_"), theFile, self._filename, ("py", "r", 1))
166  theFile.close()
167 
168  imported_configs = sys.modules.copy()
169  for i in common_imports.iterkeys():
170  del imported_configs[i]
171 
172 # make dictionary that connects every cms-object with the file in which it is defined
173  for j in imported_configs.itervalues():
174  setj = set(dir(j))
175  for entry in setj:
176  if entry[0] != "_" and entry != "cms":
177  source = 1
178  for k in imported_configs.itervalues():
179  if hasattr(k, entry):
180  setk = set(dir(k))
181  if len(setk) < len(setj) and setk < setj:
182  source = 0
183  if source == 1:
184  filen = self._filename
185  if hasattr(j, "__file__"):
186  filen = j.__file__
187  file_dict[entry] = filen
188 
189 # collect all path/sequences/modules of the input-config in a list
190  if self.process():
191  self.setProcess(self.process())
192  self._readHeaderInfo()
193  self._history=self.process().dumpHistory()
194  if not self._isReplaceConfig and hasattr(self.process(),"resetHistory"):
195  self.process().resetHistory()
196  else:
197  self._initLists()
198  for entry in dir(self._file):
199  o=getattr(self._file, entry)
200  if entry[0] != "_" and entry != "cms" and hasattr(o, "label_"):
201  getattr(self._file, entry).setLabel(entry)
202  text = os.path.splitext(os.path.basename(file_dict[o.label_()]))[0]
203  if text == os.path.splitext(os.path.basename(self._filename))[0] and not o in self._allObjects:
204  self._readRecursive(None, o)
205  return True
206 
207  def _scheduleRecursive(self,object):
208  if object in self._scheduledObjects:
209  return
210  if self.isContainer(object):
211  for obj in reversed(self.children(object)):
212  self._scheduleRecursive(obj)
213  else:
214  self._scheduledObjects+=[object]
215  for used in self.motherRelations(object):
216  self._scheduleRecursive(used)
217 
218  def setProcess(self,process):
219  self._file.process=process
220  self._initLists()
221  parameters = {"name": self.process().process}
222  process_folder = ConfigFolder("process", None, parameters)
223 
224  self._allObjects += [process_folder]
225  self._topLevelObjects += [process_folder]
226 
227  folder_list = []
228  folder_list += [("source", [self.process().source])]
229  if self.process().schedule != None:
230  folder_list += [("paths", self.process().schedule)]
231  else:
232  folder_list += [("paths", self.process().paths.itervalues())]
233  folder_list += [("endpaths", self.process().endpaths.itervalues())]
234  if hasattr(self.process(),"options") and hasattr(self.process().options,"allowUnscheduled") and self.process().options.allowUnscheduled:
235  print "Running in Unscheduled mode"
236  folder_list += [("modules", self._sort_list(self.process().producers.values()+self.process().filters.values()+self.process().analyzers.values()))]
237  folder_list += [("services", self._sort_list(self.process().services.values()))]
238  folder_list += [("psets", self._sort_list(self.process().psets.values()))]
239  folder_list += [("vpsets", self._sort_list(self.process().vpsets.values()))]
240  folder_list += [("essources", self._sort_list(self.process().es_sources.values()))]
241  folder_list += [("esproducers", self._sort_list(self.process().es_producers.values()))]
242  folder_list += [("esprefers", self._sort_list(self.process().es_prefers.values()))]
243  folders={}
244  for foldername, entry in folder_list:
245  folder = ConfigFolder(foldername, process_folder)
246  self._allObjects += [folder]
247  folders[foldername]=folder
248  for path in entry:
249  self._readRecursive(folder, path)
250  if hasattr(self.process(),"options") and hasattr(self.process().options,"allowUnscheduled") and self.process().options.allowUnscheduled:
251  print "Creating schedule...",
252  self.readConnections(self.allChildren(folders["modules"]))
253  self._scheduleRecursive(folders["paths"])
254  self._scheduledObjects.reverse()
255  scheduled_folder = ConfigFolder("scheduled", folders["paths"])
256  self._allObjects += [scheduled_folder]
257  folders["paths"]._configChildren.remove(scheduled_folder)
258  folders["paths"]._configChildren.insert(0,scheduled_folder)
259  scheduled_folder._configChildren=self._scheduledObjects
260  print "done"
261  else:
263 
264  def process(self):
265  if hasattr(self._file, "process"):
266  return self._file.process
267  return None
268 
269  def _readHeaderInfo(self):
270  theFile = open(self._filename)
271  foundHeaderPart1 = False
272  foundHeaderPart2 = False
273  lines = 10
274  search_paths=[os.path.abspath(os.path.dirname(self._filename))]
275  while theFile and not (foundHeaderPart1 and foundHeaderPart2) and lines > 0:
276  line = theFile.readline()
277  lines -= 1
278  if "Generated by ConfigEditor" in line:
279  foundHeaderPart1 = True
280  splitline = line.split("'")
281  if foundHeaderPart1 and len(splitline) == 5 and splitline[0] == "sys.path.append(os.path.abspath(os.path.expandvars(os.path.join(" and splitline[4] == "))))\n":
282  search_paths+=[os.path.abspath(os.path.expandvars(os.path.join(splitline[1],splitline[3])))]
283  splitline = line.split()
284  if foundHeaderPart1 and len(splitline) == 4 and splitline[0] == "from" and splitline[2] == "import":
285  for search_path in search_paths:
286  if os.path.exists(os.path.join(search_path,splitline[1]+".py")):
287  self._filename = os.path.join(search_path,splitline[1]+".py")
288  break
289  self._isReplaceConfig = True
290  foundHeaderPart2 = True
291  theFile.close()
292 
293  def dumpPython(self):
294  """ dump python configuration """
295  logging.debug(__name__ + ": dumpPython")
296  text = None
297  if self.process():
298  text = self.process().dumpPython()
299  return text
300 
301  def history(self):
302  """ configuration history """
303  logging.debug(__name__ + ": history")
304  return self._history
305 
306  def configFile(self):
307  return self._filename
308 
309  def label(self, object):
310  """ Get label of an object """
311  text = ""
312  if hasattr(object, "label_") and (not hasattr(object,"hasLabel_") or object.hasLabel_()):
313  text = str(object.label_())
314  if text == "":
315  if hasattr(object, "_name"):
316  text = str(object._name)
317  if text == "":
318  if hasattr(object, "type_"):
319  text = str(object.type_())
320  if text == "":
321  text = "NoLabel"
322  return text
323 
324  def children(self, object):
325  """ Get children of an object """
326  if hasattr(object, "_configChildren"):
327  return tuple(object._configChildren)
328  else:
329  return ()
330 
331  def isContainer(self, object):
332  return isinstance(object, (ConfigFolder, list, cms.Path, cms.EndPath, cms.Sequence)) # cms.SequencePlaceholder assumed to be a module
333 
334  def nonSequenceChildren(self, object):
335  objects=[]
336  if self.isContainer(object):
337  for o in self.allChildren(object):
338  if not self.isContainer(o) and len(self.children(o)) == 0 and not o in objects:
339  objects += [o]
340  else:
341  for o in self.motherRelations(object)+[object]+self.daughterRelations(object):
342  if not o in objects:
343  objects += [o]
344  return objects
345 
346  def motherRelations(self, object):
347  """ Get motherRelations of an object """
348  if object in self._motherRelationsDict.keys():
349  try:
350  return self._motherRelationsDict[object]
351  except TypeError:
352  return []
353  else:
354  return []
355 
356  def daughterRelations(self, object):
357  """ Get daughterRelations of an object """
358  if object in self._daughterRelationsDict.keys():
359  try:
360  return self._daughterRelationsDict[object]
361  except TypeError:
362  return []
363  else:
364  return []
365 
366  def type(self, object):
367  """ Get type of an object """
368  return object.__class__.__name__
369 
370  def classname(self, object):
371  """ Get classname of an object """
372  text = ""
373  if hasattr(object, "type_"):
374  text = object.type_()
375  return text
376 
377  def fullFilename(self, object):
378  """ Get full filename """
379  text = ""
380 # if hasattr(object,"_filename"):
381 # text=object._filename
382  if text == "" or text.find("FWCore/ParameterSet") >= 0 or text.find("/build/") >= 0:
383  if self.label(object) in file_dict:
384  text = file_dict[self.label(object)]
385  else:
386  text = self._filename
387  root = os.path.splitext(text)[0]
388  if root != "":
389  text = root + ".py"
390  return text
391 
392  def lineNumber(self, object):
393  """ Get linenumber """
394  text = ""
395  if hasattr(object, "_filename"):
396  if object._filename.find("FWCore/ParameterSet") < 0 and object._filename.find("ConfigEditor") < 0:
397  if hasattr(object, "_lineNumber"):
398  text = str(object._lineNumber)
399  return text
400 
401  def filename(self, object):
402  """ Get filename """
403  text = os.path.splitext(os.path.basename(self.fullFilename(object)))[0]
404  return text
405 
406  def pypackage(self,object):
407  match_compiled = re.match(r'(?:^|.*?/)CMSSW[0-9_]*/python/((?:\w*/)*\w*)\.py$',self.fullFilename(object))
408  if match_compiled:
409  return match_compiled.group(1).replace('/','.')
410 
411  match_norm = re.match(r'(?:^|.*?/)(\w*)/(\w*)/(?:test|python)/((?:\w*/)*)(\w*)\.py$',self.fullFilename(object))
412  if match_norm:
413  return '%s.%s.%s%s' % (match_norm.group(1),match_norm.group(2),match_norm.group(3).replace('/','.'),match_norm.group(4))
414  return ''
415 
416  def pypath(self,object):
417  match_compiled = re.match(r'(?:^|.*?/)CMSSW[0-9_]*/python/((?:\w*/){2})((?:\w*/)*)(\w*\.py)$',self.fullFilename(object))
418  if match_compiled:
419  return '%spython/%s%s' % (match_compiled.group(1),match_compiled.group(2),match_compiled.group(3))
420  match_norm = re.match(r'(?:^|.*?/)(\w*/\w*/(?:test|python)/(?:\w*/)*\w*\.py)$',self.fullFilename(object))
421  if match_norm:
422  return match_norm.group(1)
423  return ''
424 
425  def package(self, object):
426  """ Get Package of an object file """
427  shortdirname = os.path.dirname(self.fullFilename(object)).split('python/')
428  text = ""
429  if len(shortdirname) > 1:
430  text = shortdirname[1]
431  return text
432 
433  def parameters(self, object):
434  """ Get parameters of an object """
435  this_parameters = []
436  if hasattr(object, "parameters_"):
437  this_parameters = object.parameters_().items()
438  elif hasattr(object, "_seq"):
439  if hasattr(object._seq,"dumpSequencePython"):
440  this_parameters = [('sequence', object._seq.dumpSequencePython())]
441  else:
442  this_parameters = [('sequence', 'WARNING: object was removed from a sequence.')]
443  if hasattr(object, "tarlabel_"):
444  this_parameters += [('tarlabel', object.tarlabel_())]
445  return this_parameters
446 
447  def _addInputTag(self, value, this_key, this_inputtags):
448  """ Add alls inputtags of value to a list """
449  if isinstance(value, cms.VInputTag):
450  for i in range(len(value)):
451  if type(value[i])==str:
452  self._addInputTag(cms.InputTag(value[i]), this_key+"["+str(i)+"]", this_inputtags)
453  else:
454  self._addInputTag(value[i], this_key+"["+str(i)+"]", this_inputtags)
455  elif isinstance(value, list):
456  for i in value:
457  self._addInputTag(i, this_key, this_inputtags)
458  if hasattr(value, "parameters_"):
459  this_inputtags += self._readInputTagsRecursive(value.parameters_().items(), this_key)
460  if isinstance(value, cms.InputTag):
461  pythonValue = value.value()
462  this_inputtags += [(str(this_key), value.value())]
463 
464  def _readInputTagsRecursive(self, this_parameters, start_key=""):
465  """ Make list of inputtags from parameter dict """
466  this_inputtags = []
467  for key, value in this_parameters:
468  this_key = start_key
469  if this_key != "":
470  this_key += "."
471  this_key += key
472  self._addInputTag(value, this_key, this_inputtags)
473  return this_inputtags
474 
475  def inputTags(self, object):
476  """ Make list of inputtags from parameter dict """
477  if not object in self._inputTagsDict.keys():
478  try:
479  self._inputTagsDict[object]=self._readInputTagsRecursive(self.parameters(object))
480  except TypeError:
481  return []
482  return self._inputTagsDict[object]
483 
484  def uses(self, object):
485  """ Get list of all config objects that are used as input """
486  if not object in self._usesDict.keys():
487  uses = []
488  for key, value in self.inputTags(object):
489  module = str(value).split(":")[0]
490  product = ".".join(str(value).split(":")[1:])
491  if module not in uses:
492  uses += [module]
493  try:
494  self._usesDict[object]=uses
495  except TypeError:
496  return []
497  return self._usesDict[object]
498 
499  def foundIn(self, object):
500  """ Make list of all mother sequences """
501  if not object in self._foundInDict.keys():
502  foundin = []
503  for entry in self._allObjects:
504  for daughter in self.children(entry):
505  if self.label(object) == self.label(daughter) and len(self.children(entry)) > 0 and not self.label(entry) in foundin:
506  foundin += [self.label(entry)]
507  try:
508  self._foundInDict[object]=foundin
509  except TypeError:
510  return []
511  return self._foundInDict[object]
512 
513  def usedBy(self, object):
514  """ Find config objects that use this as input """
515  if not object in self._usedByDict.keys():
516  usedby = []
517  for entry in self._allObjects:
518  for uses in self.uses(entry):
519  if self.label(object) == uses and not self.label(entry) in usedby:
520  usedby += [self.label(entry)]
521  try:
522  self._usedByDict[object]=usedby
523  except TypeError:
524  return []
525  return self._usedByDict[object]
526 
527  def recursePSetProperties(self, name, object, readonly=None):
528  #logging.debug(__name__ + ": recursePSetProperties: " + name)
529  properties = []
530  if name != "" and not isinstance(object, typ.PSet):
531  try:
532  partyp=str(type(object)).split("'")[1].replace("FWCore.ParameterSet.Types","cms")
533  if isinstance(object, cms.InputTag):
534  inputtagValue=object.pythonValue()
535  for i in range(3-len(inputtagValue.split(","))):
536  inputtagValue+=', ""'
537  properties += [("String", name, "cms.InputTag("+inputtagValue+")", partyp, readonly)]
538  elif isinstance(object, cms.bool):
539  properties += [("Boolean", name, object.value(), partyp, readonly)]
540  elif isinstance(object, (cms.int32, cms.uint32, cms.int64, cms.uint64)):
541  properties += [("Integer", name, object.value(), partyp, readonly)]
542  elif isinstance(object, cms.double):
543  properties += [("Double", name, object.value(), partyp, readonly)]
544  elif hasattr(object, "pythonValue"):
545  properties += [("String", name, str(object.pythonValue()).strip("\"'"), partyp, readonly)]
546  elif hasattr(object, "value"):
547  properties += [("MultilineString", name, str(object.value()), partyp, readonly)]
548  else:
549  properties += [("MultilineString", name, str(object), partyp, readonly)]
550  except Exception:
551  logging.error(__name__ + ": " + exception_traceback())
552 
553  if isinstance(object, ConfigFolder):
554  readonly = True
555 
556  params = self.parameters(object)[:]
557  params.sort(lambda x, y: cmp(x[0].lower(), y[0].lower()))
558  for key, value in params:
559  keyname = name
560  if name != "":
561  keyname += "."
562  keyname += key
563  properties += self.recursePSetProperties(keyname, value, readonly)
564  return properties
565 
566  def properties(self, object):
567  """ Make list of all properties """
568  #logging.debug(__name__ + ": properties")
569  properties = []
570  properties += [("Category", "Object info", "")]
571  if self.label(object) != "":
572  properties += [("String", "label", self.label(object), None, True)]
573  if self.type(object) != "":
574  text = self.type(object)
575  if self.classname(object) != "":
576  text += " <" + self.classname(object) + ">"
577  properties += [("String", "type", text, None, True)]
578  if self.filename(object) != "":
579  text = self.filename(object)
580  if self.lineNumber(object) != "":
581  text += " : " + self.lineNumber(object)
582  properties += [("String", "file", text, None, True)]
583  if self.package(object) != "":
584  properties += [("String", "package", self.package(object), None, True)]
585  if self.fullFilename(object) != "":
586  properties += [("String", "full filename", self.fullFilename(object), None, True)]
587  foundIn=self.foundIn(object)
588  if len(foundIn) > 0:
589  text = ""
590  for entry in foundIn:
591  if text != "":
592  text += ", "
593  text += entry
594  properties += [("String", "in sequence", text, "This module/sequence is used the listed sequences", True)]
595  uses=self.uses(object)
596  usedBy=self.usedBy(object)
597  if len(uses) + len(usedBy) > 0:
598  properties += [("Category", "Connections", "")]
599  if len(uses) > 0:
600  text = ""
601  for label in uses:
602  if text != "":
603  text += ", "
604  text += label
605  properties += [("MultilineString", "uses", text, "This module/sequence depends on the output of the listes modules/seuquences", True)]
606  if len(usedBy) > 0:
607  text = ""
608  usedby = []
609  for entry in usedBy:
610  if text != "":
611  text += ", "
612  text += entry
613  properties += [("MultilineString", "used by", text, "The listed modules/sequences depend on the output of this module/sequence", True)]
614  if len(self.parameters(object)) > 0:
615  properties += [("Category", "Parameters", "")]
616  properties += self.recursePSetProperties("", object)
617  return tuple(properties)
618 
619  def setProperty(self, object, name, value, categoryName):
620  """ Sets a property with given name to value.
621  """
622  if hasattr(object, "_seq") and name=="sequence":
623  return "Modification of sequences not supported yet."
624  else:
625  process=self.process()
626  try:
627  if isinstance(value,str) and\
628  not value[0]=="[" and\
629  not value[0:4]=="cms.":
630  exec "object." + name + "='''" + value + "'''"
631  else:
632  exec "object." + name + "=" + str(value)
633  except Exception,e:
634  error="Cannot set parameter "+name+" (see logfile for details):\n"+str(e)
635  logging.warning(__name__ + ": setProperty: Cannot set parameter "+name+": "+exception_traceback())
636  return error
637  return True
638 
639  def inputEventContent(self):
640  content = []
641  allLabels = [self.label(object) for object in self._scheduledObjects]
642  content_objects = {}
643  for object in self._scheduledObjects:
644  for key, value in self.inputTags(object):
645  elements=str(value).split(":")
646  module = elements[0]
647  if len(elements)>1:
648  product = elements[1]
649  else:
650  product = ""
651  if len(elements)>2:
652  process = elements[2]
653  else:
654  process = "*"
655  if not module in allLabels:
656  if not ("*",module,product,process) in content:
657  content += [("*",module,product,process)]
658  if "*_"+module+"_"+product+"_"+process in content_objects.keys():
659  content_objects["*_"+module+"_"+product+"_"+process]+=","+self.label(object)
660  else:
661  content_objects["*_"+module+"_"+product+"_"+process]=self.label(object)
662  return (content,content_objects)
663 
665  content = [("*",self.label(object),"*",self.process().process) for object in self._allObjects\
666  if self.type(object) in ["EDProducer", "EDFilter", "EDAnalyzer"]]
667  return content
668 
669  def inputCommands(self):
670  inputModules = [object for object in self._allObjects\
671  if self.type(object) == "Source"]
672  if len(inputModules) > 0 and hasattr(inputModules[0], "inputCommands"):
673  return inputModules[0].inputCommands
674  else:
675  return []
676 
677  def outputCommands(self):
678  outputModules = [object for object in self._allObjects\
679  if self.type(object) == "OutputModule"]
680  if len(outputModules) > 0 and hasattr(outputModules[0], "outputCommands"):
681  return outputModules[0].outputCommands
682  else:
683  return []
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
list object
Definition: dbtoconf.py:77
dbl *** dir
Definition: mlp_gen.cc:35
double split
Definition: MVATrainer.cc:139