CMS 3D CMS Logo

Public Member Functions | Public Attributes

DOTExport::DotProducer Class Reference

List of all members.

Public Member Functions

def __call__
def __init__
def connectPaths
def connectTags
def getTopLevel
def makePath
def nodeLabel
def nodeURL
def produceLegend
def produceNodes
def producePaths
def produceServices
def produceSource
def recurseChildren
def seqRecurseChildren

Public Attributes

 data
 endstarts
 nodes
 options
 pathends
 pathstarts
 shapes
 toplevel

Detailed Description

Definition at line 18 of file DOTExport.py.


Constructor & Destructor Documentation

def DOTExport::DotProducer::__init__ (   self,
  data,
  options,
  shapes 
)

Definition at line 19 of file DOTExport.py.

00020                                         :
00021     self.data = data
00022     self.options = options
00023     self.shapes = shapes
00024     self.nodes={}
00025     #lists of starts, ends of paths for path-endpath and source-path connections
00026     self.pathstarts=[]
00027     self.pathends=[]
00028     self.endstarts=[]
00029     self.toplevel = self.getTopLevel()
    

Member Function Documentation

def DOTExport::DotProducer::__call__ (   self)

Definition at line 240 of file DOTExport.py.

00241                     :
00242     blocks=[]
00243     if self.options['legend']:
00244       blocks += [self.produceLegend()]
00245     blocks += [self.producePaths()]
00246     if self.options['seqconnect']:
00247       blocks += [self.connectPaths()]
00248     if self.options['tagconnect']:
00249       blocks += [self.connectTags()]
00250     if self.options['source']:
00251       blocks += [self.produceSource()]
00252     if self.options['es'] or self.options['services']:
00253       blocks += [self.produceServices()]
00254     blocks += [self.produceNodes()]
00255     if self.data.process():
00256       return 'digraph configbrowse {\nsubgraph clusterProcess {\nlabel="%s\\n%s"\nfontsize=%s\nfontname="%s"\n%s\n}\n}\n' % (self.data.process().name_(),self.data._filename,self.options['font_size'],self.options['font_name'],'\n'.join(blocks))
00257     else:
00258       return 'digraph configbrowse {\nsubgraph clusterCFF {\nlabel="%s"\nfontsize=%s\nfontname="%s"\n%s\n}\n}\n' % (self.data._filename,self.options['font_size'],self.options['font_name'],'\n'.join(blocks))
00259   
00260   

def DOTExport::DotProducer::connectPaths (   self)

Definition at line 159 of file DOTExport.py.

00160                         :
00161     result=''
00162     for p in self.pathends:
00163       for p2 in self.endstarts:
00164         result+="%s->%s\n" % (p,p2)
00165     return result
  
def DOTExport::DotProducer::connectTags (   self)

Definition at line 166 of file DOTExport.py.

00167                        :
00168     #if we are connecting by tag, add labelled tag joining lines
00169     #this doesn't have to be exclusive with sequence connection, by stylistically probably should be
00170     result=''
00171     allobjects = [self.nodes[n]['obj'] for n in self.nodes if self.nodes[n]['inpath']]
00172     self.data.readConnections(allobjects)
00173     connections = self.data.connections()
00174     for objects,names in connections.items():
00175       if self.options['taglabel']:
00176         result += '%s->%s[label="%s",color="%s",fontcolor="%s",fontsize=%s,fontname="%s"]\n' % (objects[0],objects[1],names[1],self.options['color_inputtag'],self.options['color_inputtag'],self.options['font_size'],self.options['font_name'])
00177       else:
00178         result += '%s->%s[color="%s"]\n' % (objects[0],objects[1],self.options['color_inputtag'])
00179     return result
00180   
  
def DOTExport::DotProducer::getTopLevel (   self)

Definition at line 30 of file DOTExport.py.

00031                        :
00032       
00033     #build a dictionary of available top-level objects
00034     all_toplevel={}
00035     if self.data.process():
00036       for tlo in self.data.children(self.data.topLevelObjects()[0]):
00037         children = self.data.children(tlo)
00038         if children:
00039           all_toplevel[tlo._label]=children
00040     else:
00041       #case if we have only an anonymous (non-process) file
00042       #pick up (modules, sequences, paths)
00043       for tlo in self.data.topLevelObjects():
00044         if self.data.type(tlo)=='Sequence':
00045           if 'sequences' in all_toplevel:
00046             all_toplevel['sequences']+=[tlo]
00047           else:
00048             all_toplevel['sequences']=[tlo]
00049         if self.data.type(tlo)=='Path':
00050           if 'paths' in all_toplevel:
00051             all_toplevel['paths']+=[tlo]
00052           else:
00053             all_toplevel['paths']=[tlo]
00054         if self.data.type(tlo) in ('EDAnalyzer','EDFilter','EDProducer','OutputModule'):
00055           self.nodes[self.data.label(tlo)]={'obj':tlo,'n_label':self.nodeLabel(tlo),'n_shape':self.shapes.get(self.data.type(tlo),'plaintext'),'inpath':True} 
00056         if self.options['services'] and self.data.type(tlo)=='Service':
00057           self.nodes[self.data.label(tlo)]={'obj':tlo,'n_label':self.nodeLabel(tlo),'n_shape':self.shapes.get(self.data.type(tlo),'plaintext'),'inpath':False}
00058         if self.options['es'] and self.data.type(tlo) in ('ESSource','ESProducer'):
00059           self.nodes[self.data.label(tlo)]={'obj':tlo,'n_label':self.nodeLabel(tlo),'n_shape':self.shapes.get(self.data.type(tlo),'plaintext'),'inpath':False}
00060     return all_toplevel      

def DOTExport::DotProducer::makePath (   self,
  path,
  endpath = False 
)

Definition at line 103 of file DOTExport.py.

00104                                        :
00105     children = self.recurseChildren(path)
00106     pathlabel = self.data.label(path)
00107     if self.options['file']:
00108       pathlabel += '\\n%s:%s'%(self.data.pypackage(path),self.data.lineNumber(path))
00109     if endpath:
00110       pathresult = 'subgraph cluster%s {\nlabel="%s"\ncolor="%s"\nfontcolor="%s"\nfontname="%s"\nfontsize=%s\n' % (self.data.label(path),pathlabel,self.options['color_endpath'],self.options['color_endpath'],self.options['font_name'],self.options['font_size'])
00111     else:
00112       pathresult = 'subgraph cluster%s {\nlabel="%s"\ncolor="%s"\nfontcolor="%s"\nfontname="%s"\nfontsize=%s\n' % (self.data.label(path),pathlabel,self.options['color_path'],self.options['color_path'],self.options['font_name'],self.options['font_size'])
00113     if self.options['seqconnect']:
00114       if endpath:
00115         self.endstarts.append('endstart_%s'%self.data.label(path))
00116         self.nodes['endstart_%s'%self.data.label(path)]={'obj':path,'n_label':'Start %s'%self.data.label(path),'n_color':'grey','n_shape':'plaintext','inpath':False}
00117       else:
00118         self.pathstarts.append('start_%s'%self.data.label(path))
00119         self.pathends.append('end_%s'%self.data.label(path))
00120         self.nodes['start_%s'%self.data.label(path)]={'obj':path,'n_label':'Start %s'%self.data.label(path),'n_color':'grey','n_shape':'plaintext','inpath':False}
00121         self.nodes['end_%s'%self.data.label(path)]={'obj':path,'n_label':'End %s'%self.data.label(path),'n_color':'grey','n_shape':'plaintext','inpath':False}
00122     labels=[]
00123     for c in children:
00124       #this is also done in seqRecurseChildren, so will be duplicated
00125       #unncessary, but relatively cheap and saves more cff/cfg conditionals
00126       self.nodes[self.data.label(c)]={'obj':c,'n_label':self.nodeLabel(c),'n_shape':self.shapes.get(self.data.type(c),'plaintext'),'inpath':True}
00127       labels.append(self.data.label(c))
00128     if self.options['seqconnect']:
00129       pathresult += '->'.join(labels)+'\n'
00130     else:
00131       if not self.options['seq']:
00132         pathresult += '\n'.join(labels)+'\n'
00133     if self.options['seq']:
00134       if self.data.children(path):
00135         for path_child in self.data.children(path):
00136           pathresult += self.seqRecurseChildren(path_child)
00137     pathresult += '}\n'
00138     if len(labels)>0 and self.options['seqconnect']:
00139       if endpath:
00140         pathresult += 'endstart_%s->%s\n' % (self.data.label(path),labels[0])
00141       else:
00142         pathresult += 'start_%s->%s\n%s->end_%s\n' % (self.data.label(path),labels[0],labels[-1],self.data.label(path))
00143     
00144     return pathresult

def DOTExport::DotProducer::nodeLabel (   self,
  obj 
)

Definition at line 87 of file DOTExport.py.

00088                          :
00089     result = self.data.label(obj)
00090     if self.options['class']:
00091       result += '\\n%s'%self.data.classname(obj)
00092     if self.options['file']:
00093       result += '\\n%s:%s'%(self.data.pypackage(obj),self.data.lineNumber(obj))
00094     return result
00095     
    #generate an appropriate URL by replacing placeholders in baseurl
def DOTExport::DotProducer::nodeURL (   self,
  obj 
)

Definition at line 96 of file DOTExport.py.

00097                        :
00098     classname = self.data.classname(obj)
00099     pypath = self.data.pypath(obj)
00100     pyline = self.data.lineNumber(obj)
00101     url = self.options['urlbase'].replace('$classname',classname).replace('$pypath',pypath).replace('$pyline',pyline)
00102     return url
    
def DOTExport::DotProducer::produceLegend (   self)
Return a legend subgraph using current shape and colour preferences.

Definition at line 234 of file DOTExport.py.

00235                          :
00236     """
00237     Return a legend subgraph using current shape and colour preferences.
00238     """
00239     return 'subgraph clusterLegend {\nlabel="legend"\ncolor=red\nSource->Producer->Filter->Analyzer\nService->ESSource[style=invis]\nESSource->ESProducer[style=invis]\nProducer->Filter[color="%s",label="InputTag",fontcolor="%s"]\nProducer[shape=%s]\nFilter[shape=%s]\nAnalyzer[shape=%s]\nESSource[shape=%s]\nESProducer[shape=%s]\nSource[shape=%s]\nService[shape=%s]\nsubgraph clusterLegendSequence {\nlabel="Sequence"\ncolor="%s"\nfontcolor="%s"\nProducer\nFilter\n}\n}\n' % (self.options['color_inputtag'],self.options['color_inputtag'],self.shapes['EDProducer'],self.shapes['EDFilter'],self.shapes['EDAnalyzer'],self.shapes['ESSource'],self.shapes['ESProducer'],self.shapes['Source'],self.shapes['Service'],self.options['color_sequence'],self.options['color_sequence'])
    
def DOTExport::DotProducer::produceNodes (   self)

Definition at line 224 of file DOTExport.py.

00225                         :
00226     result=''
00227     for n in self.nodes:
00228       self.nodes[n]['n_fontname']=self.options['font_name']
00229       self.nodes[n]['n_fontsize']=self.options['font_size']
00230       if self.options['url']:
00231         self.nodes[n]['n_URL']=self.nodeURL(self.nodes[n]['obj'])
00232       result += "%s[%s]\n" % (n,','.join(['%s="%s"' % (k[2:],v) for k,v in self.nodes[n].items() if k[0:2]=='n_']))
00233     return result
    
def DOTExport::DotProducer::producePaths (   self)

Definition at line 145 of file DOTExport.py.

00146                         :
00147     result=''
00148     if 'paths' in self.toplevel:
00149       for path in self.toplevel['paths']:
00150         result += self.makePath(path)
00151     if self.options['endpath']:
00152       if 'endpaths' in self.toplevel:
00153         for path in self.toplevel['endpaths']:
00154           result += self.makePath(path,True)
00155     if 'sequences' in self.toplevel:
00156       for seq in self.toplevel['sequences']:
00157         result += self.seqRecurseChildren(seq)
00158     return result
    
def DOTExport::DotProducer::produceServices (   self)

Definition at line 194 of file DOTExport.py.

00195                            :
00196     # add service, eventsetup nodes
00197     # this will usually result in thousands and isn't that interesting
00198     servicenodes=[]
00199     result=''
00200     if self.options['es']:
00201       if 'essources' in self.toplevel:
00202         for e in self.toplevel['essources']:
00203           servicenodes.append(self.data.label(e))
00204           self.nodes[self.data.label(e)]={'obj':e,'n_label':self.nodeLabel(e), 'n_shape':self.shapes['ESSource'],'inpath':False}
00205       if 'esproducers' in self.toplevel:
00206         for e in self.toplevel['esproducers']:
00207           servicenodes.append(self.data.label(e))
00208           self.nodes[self.data.label(e)]={'obj':e,'n_label':self.nodeLabel(e), 'n_shape':self.shapes['ESProducer'],'inpath':False}
00209     if self.options['services']:
00210       if 'services' in self.toplevel:
00211         for s in self.toplevel['services']:
00212           self.servicenodes.append(self.data.label(s))
00213           self.nodes[self.data.label(s)]={'obj':s,'n_label':self.nodeLabel(e), 'n_shape':self.shapes['Service'],'inpath':False}
00214     #find the maximum path and endpath lengths for servicenode layout
00215     maxpath=max([len(recurseChildren(path) for path in self.toplevel.get('paths',(0,)))])
00216     maxendpath=max([len(recurseChildren(path) for path in self.toplevel.get('endpaths',(0,)))])
00217     
00218     #add invisible links between service nodes where necessary to ensure they only fill to the same height as the longest path+endpath
00219     #this constraint should only apply for link view
00220     for i,s in enumerate(servicenodes[:-1]):
00221       if not i%(maxpath+maxendpath)==(maxpath+maxendpath)-1:
00222         result+='%s->%s[style=invis]\n' % (s,servicenodes[i+1])
00223     return result
    
def DOTExport::DotProducer::produceSource (   self)

Definition at line 181 of file DOTExport.py.

00182                          :
00183     #add the source
00184     #if we are connecting sequences, connect it to all the path starts
00185     #if we are connecting sequences and have a schedule, connect it to path #0
00186     result=''
00187     if 'source' in self.toplevel:
00188       for s in self.toplevel['source']:
00189         self.nodes['source']={'obj':s,'n_label':self.data.classname(s),'n_shape':self.shapes['Source']}
00190         if self.options['seqconnect']:
00191             for p in self.pathstarts:
00192               result += 'source->%s\n' % (p)   
00193     return result
    
def DOTExport::DotProducer::recurseChildren (   self,
  obj 
)

Definition at line 76 of file DOTExport.py.

00077                                :
00078     result=[]
00079     children=self.data.children(obj)
00080     if children:
00081       for c in children:
00082         result += self.recurseChildren(c)
00083     else:
00084       result.append(obj)
00085     return result
    
def DOTExport::DotProducer::seqRecurseChildren (   self,
  obj 
)

Definition at line 61 of file DOTExport.py.

00062                                   :
00063     children = self.data.children(obj)
00064     if children:
00065       seqlabel = self.data.label(obj)
00066       if self.options['file']:
00067         seqlabel += '\\n%s:%s' % (self.data.pypackage(obj),self.data.lineNumber(obj))
00068       result='subgraph clusterSeq%s {\nlabel="Sequence %s"\ncolor="%s"\nfontcolor="%s"\nfontname="%s"\nfontsize=%s\n' % (self.data.label(obj),seqlabel,self.options['color_sequence'],self.options['color_sequence'],self.options['font_name'],self.options['font_size'])
00069       for c in children:
00070         result += self.seqRecurseChildren(c)
00071       result+='}\n'
00072       return result
00073     else:
00074       self.nodes[self.data.label(obj)]={'obj':obj,'n_label':self.nodeLabel(obj),'n_shape':self.shapes.get(self.data.type(obj),'plaintext'),'inpath':True}
00075       return '%s\n'%self.data.label(obj)   
      

Member Data Documentation

Definition at line 19 of file DOTExport.py.

Definition at line 19 of file DOTExport.py.

Definition at line 19 of file DOTExport.py.

Definition at line 19 of file DOTExport.py.

Definition at line 19 of file DOTExport.py.

Definition at line 19 of file DOTExport.py.

Definition at line 19 of file DOTExport.py.

Definition at line 19 of file DOTExport.py.