00001
00002 import cStringIO,operator
00003
00004 def indent(rows, hasHeader=False, headerChar='-', delim=' | ', justify='left',
00005 separateRows=False, prefix='', postfix='', wrapfunc=lambda x:x):
00006 """Indents a table by column.
00007 - rows: A sequence of sequences of items, one sequence per row.
00008 - hasHeader: True if the first row consists of the columns' names.
00009 - headerChar: Character to be used for the row separator line
00010 (if hasHeader==True or separateRows==True).
00011 - delim: The column delimiter.
00012 - justify: Determines how are data justified in their column.
00013 Valid values are 'left','right' and 'center'.
00014 - separateRows: True if rows are to be separated by a line
00015 of 'headerChar's.
00016 - prefix: A string prepended to each printed row.
00017 - postfix: A string appended to each printed row.
00018 - wrapfunc: A function f(text) for wrapping text; each element in
00019 the table is first wrapped by this function."""
00020
00021 def rowWrapper(row):
00022 newRows = [wrapfunc(item).split('\n') for item in row]
00023 return [[substr or '' for substr in item] for item in map(None,*newRows)]
00024
00025 logicalRows = [rowWrapper(row) for row in rows]
00026
00027 columns = map(None,*reduce(operator.add,logicalRows))
00028
00029 maxWidths = [max([len(str(item)) for item in column]) for column in columns]
00030 rowSeparator = headerChar * (len(prefix) + len(postfix) + sum(maxWidths) + \
00031 len(delim)*(len(maxWidths)-1))
00032
00033 justify = {'center':str.center, 'right':str.rjust, 'left':str.ljust}[justify.lower()]
00034 output=cStringIO.StringIO()
00035 if separateRows: print >> output, rowSeparator
00036 for physicalRows in logicalRows:
00037 for row in physicalRows:
00038 print >> output, \
00039 prefix \
00040 + delim.join([justify(str(item),width) for (item,width) in zip(row,maxWidths)]) \
00041 + postfix
00042 if separateRows or hasHeader: print >> output, rowSeparator; hasHeader=False
00043 return output.getvalue()
00044
00045
00046
00047 def wrap_onspace(text, width):
00048 """
00049 A word-wrap function that preserves existing line breaks
00050 and most spaces in the text. Expects that existing line
00051 breaks are posix newlines (\n).
00052 """
00053 return reduce(lambda line, word, width=width: '%s%s%s' %
00054 (line,
00055 ' \n'[(len(line[line.rfind('\n')+1:])
00056 + len(word.split('\n',1)[0]
00057 ) >= width)],
00058 word),
00059 text.split(' ')
00060 )
00061
00062 import re
00063 def wrap_onspace_strict(text, width):
00064 """Similar to wrap_onspace, but enforces the width constraint:
00065 words longer than width are split."""
00066 wordRegex = re.compile(r'\S{'+str(width)+r',}')
00067 return wrap_onspace(wordRegex.sub(lambda m: wrap_always(m.group(),width),text),width)
00068
00069 import math
00070 def wrap_always(text, width):
00071 """A simple word-wrap function that wraps text on exactly width characters.
00072 It doesn't split the text in words."""
00073 return '\n'.join([ text[width*i:width*(i+1)] \
00074 for i in xrange(int(math.ceil(1.*len(text)/width))) ])
00075
00076
00077
00078
00079
00080
00081 import sys, pprint
00082 imported_modules = []
00083
00084 def importDF(path):
00085
00086 modules_to_import = "RecoTracker RecoLocalTracker RecoLocalCalo RecoEcal RecoEgamma RecoLocalMuon RecoMuon RecoJets RecoMET RecoBTag RecoTauTag RecoVertex RecoPixelVertexing HLTrigger RecoParticleFlow".split()
00087 modules_to_import = "RecoLocalTracker RecoLocalMuon RecoLocalCalo RecoEcal TrackingTools RecoTracker RecoJets RecoMET RecoMuon RecoBTau RecoBTag RecoTauTag RecoVertex RecoPixelVertexing RecoEgamma RecoParticleFlow L1Trigger".split()
00088
00089
00090 for m in modules_to_import:
00091 m = m + "_dataformats"
00092 try:
00093 sys.path.append(path+"/src/Documentation/DataFormats/python/")
00094 globals()[m] = __import__(m)
00095 imported_modules.append(m)
00096 print m
00097 except ImportError:
00098 print "skipping", m
00099
00100
00101
00102 def search(query):
00103 labels = ('Where(Package)', 'Instance', 'Container', 'Description')
00104 width = 20
00105
00106 data = ""
00107 for module in imported_modules:
00108 for dict_name in ["full", "reco", "aod"]:
00109
00110 dict = vars(globals()[module])[dict_name]
00111
00112 for key in sorted(dict.keys()):
00113
00114 element = dict[key]
00115 if query.lower() in element.__str__().lower():
00116 if not (("No documentation".lower()) in element.__str__().lower()):
00117 data+= module.replace("_dataformats", "")+" ("+ dict_name.replace("full", "FEVT") + ")||" + "||".join(element)+"\n"
00118
00119 if (data != ""):
00120 rows = [row.strip().split('||') for row in data.splitlines()]
00121 print indent([labels]+rows, hasHeader=True, separateRows=True, prefix='| ', postfix=' |', wrapfunc=lambda x: wrap_always(x,width))
00122 else:
00123 print "No documentation found"
00124
00125 def help():
00126 print "usage: dataformats pattern_to_search"
00127 print "example: dataformats muon"
00128 print "Note! multiple patterns separated by space are not supported"
00129
00130 if __name__ == "__main__":
00131
00132 if ("help" in sys.argv):
00133 help()
00134 sys.exit(0)
00135
00136 print sys.argv[1]
00137 print sys.argv[2]
00138
00139 if (len(sys.argv) > 2):
00140 importDF(sys.argv[1])
00141 print "\nSearching for: "+sys.argv[2]+"\n"
00142 search(sys.argv[2])
00143 else:
00144 help()
00145
00146