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
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 module in modules_to_import:
00091 m = module + "_dataformats"
00092 try:
00093 sys.path.append(path+"/src/Documentation/DataFormats/python/")
00094
00095 globals()[m] = __import__(m)
00096 imported_modules.append(m)
00097 print "Searching in "+ module
00098 except ImportError:
00099 print "skipping", module
00100
00101
00102
00103
00104 def search(query):
00105 labels = ('Where(Package)', 'Instance', 'Container', 'Description')
00106 width = 20
00107 data = ""
00108
00109 for module in imported_modules:
00110 dict = vars(globals()[module])["json"]
00111 for type in ["full", "reco", "aod"]:
00112 for data_items in dict[type]['data']:
00113 if query.lower() in data_items.__str__().lower() and not (("No documentation".lower()) in data_items.__str__().lower()):
00114 data+= module.replace("_json", "")+" ("+ type.replace("full", "FEVT") + ")||" + "||".join(data_items.values())+"\n"
00115
00116 if (data != ""):
00117 rows = [row.strip().split('||') for row in data.splitlines()]
00118 print indent([labels]+rows, hasHeader=True, separateRows=True, prefix='| ', postfix=' |', wrapfunc=lambda x: wrap_always(x,width))
00119 else:
00120 print "No documentation found"
00121
00122 def help():
00123 print "usage: dataformats pattern_to_search"
00124 print "example: dataformats muon"
00125 print "Note! multiple patterns separated by space are not supported"
00126
00127 if __name__ == "__main__":
00128
00129 if ("help" in sys.argv):
00130 help()
00131 sys.exit(0)
00132
00133 if (len(sys.argv) > 2):
00134 importDF(sys.argv[1])
00135 print "\nSearching for: "+sys.argv[2]+"\n"
00136 search(sys.argv[2])
00137
00138 else:
00139 help()
00140
00141