00001
00002
00003 '''
00004 usage example:
00005
00006 nuwa.py -A -n 0 -m "StatisticSvc.MergeStats -i input1.root -i input2.root -o output.root -d name1,name2,name3"
00007
00008 -i : input statistics file (as many as you want)
00009 -o : output statistics file (1)
00010 -d : Comma-separated list of names of objects that should not be added
00011 (First occurance is copied, the remaining are ignored)
00012 '''
00013
00014
00015 from GaudiPython.GaudiAlgs import GaudiAlgo
00016 from GaudiPython import SUCCESS, FAILURE
00017 from GaudiPython import gbl
00018
00019 from GaudiKernel.Constants import *
00020
00021
00022 class MergeAlg(GaudiAlgo):
00023 "Statistics Merging Algorithm"
00024 def __init__(self,name):
00025 GaudiAlgo.__init__(self,name)
00026 self.Input = ['file1', 'file2']
00027 self.Output = 'file0'
00028 self.DontAdd = []
00029 return
00030
00031 def initialize(self):
00032 status = GaudiAlgo.initialize(self)
00033 print "Init MergeAlg",self.name()
00034 if status.isFailure(): return status
00035
00036
00037 self.msgSvc = self.svc('IMessageSvc','MessageSvc')
00038 self.statsSvc = self.svc('IStatisticsSvc','StatisticsSvc')
00039
00040
00041 for path in self.Input:
00042 status = self.mergePaths('/'+path, '/'+self.Output )
00043 if status.isFailure(): break
00044
00045 return status
00046
00047 def execute(self):
00048 return SUCCESS
00049
00050 def finalize(self):
00051 print "Finalizing MergeAlg",self.name()
00052 status = GaudiAlgo.finalize(self)
00053 return status
00054
00055 def mergePaths(self, inputPath, outputPath):
00056 hasInPath = self.statsSvc.exists(inputPath)
00057 if( not hasInPath ):
00058 self.error("Input path doesn't exist: "+inputPath)
00059 return FAILURE
00060 contents = self.statsSvc.getContents(inputPath)
00061 for name in contents:
00062 status = self.mergeObjects(inputPath + "/" + name,
00063 outputPath + "/" + name)
00064 if status.isFailure(): return status
00065 subfolders = self.statsSvc.getSubFolders(inputPath)
00066 for folder in subfolders:
00067 status = self.mergePaths(inputPath+'/'+folder,
00068 outputPath+'/'+folder)
00069 if status.isFailure(): return status
00070 return SUCCESS
00071
00072 def mergeObjects(self, inputPath, outputPath):
00073 inputObject = self.statsSvc.get(inputPath)
00074 if( inputObject == None ):
00075 self.error("No item at "+inputPath)
00076 return FAILURE
00077 hasOutput = self.statsSvc.exists(outputPath)
00078 if( not hasOutput ):
00079
00080 status = self.statsSvc.put(outputPath, inputObject)
00081 if status.isFailure(): return status
00082 else:
00083
00084 for name in self.DontAdd:
00085 if inputObject.GetName().find(name) > -1:
00086 return SUCCESS
00087 outputObject = self.statsSvc.get(outputPath)
00088 if( outputObject == None ):
00089 self.error("No item at "+outputPath)
00090 return FAILURE
00091 if outputObject.IsA().InheritsFrom("TH1"):
00092
00093 if( outputObject.TestBit( gbl.TH1.kIsAverage ) ):
00094
00095 outputObject.Add( inputObject )
00096 else:
00097
00098 ilist = gbl.TList();
00099 ilist.Add(inputObject)
00100 outputObject.Merge(ilist)
00101 elif outputObject.ClassName().startswith("TParameter"):
00102
00103 outputObject.SetVal( outputObject.GetVal()
00104 + inputObject.GetVal() )
00105 else:
00106 self.error("Can't add "+inputPath)
00107
00108 return SUCCESS
00109
00110 def error(self, message):
00111 self.msgSvc.reportMessage(self.name(), ERROR, message)
00112
00113 inputMap = {}
00114 output = 'file0'
00115 dontAdd = []
00116
00117 def configure(argv = []):
00118 global inputMap, output, dontAdd
00119 import sys,getopt
00120
00121 inFiles = []
00122 outFile = "merge.root"
00123
00124 opts, args = getopt.getopt(argv,"i:o:d:")
00125 print "opts = ",opts
00126 for opt, arg in opts:
00127 if opt == "-i":
00128 inFiles.append(arg)
00129 if opt == "-o":
00130 outFile = arg
00131 if opt == "-d":
00132 print arg.split(",")
00133 dontAdd = [name.strip() for name in arg.split(",")]
00134
00135 print "inFiles: ",inFiles
00136 print "outFile: ",outFile
00137 print "dontAdd: ",dontAdd
00138
00139 nPath = 1
00140 for filename in inFiles:
00141 inputMap["file%d" % nPath] = filename
00142 nPath += 1
00143
00144 print "inputMap = ", inputMap
00145 from StatisticsSvc.StatisticsSvcConf import StatisticsSvc
00146 statssvc = StatisticsSvc()
00147 statssvc.Input = inputMap
00148 statssvc.Output = { output : outFile }
00149
00150 return
00151
00152 def run(app):
00153 '''
00154 Configure and add an algorithm to job
00155 '''
00156 global inputMap, output, dontAdd
00157 app.ExtSvc += ["StatisticsSvc"]
00158 mergeAlg = MergeAlg("MyMerge")
00159 mergeAlg.Input = inputMap.keys()
00160 mergeAlg.Output = output
00161 mergeAlg.DontAdd = dontAdd
00162
00163 app.addAlgorithm(mergeAlg)
00164 pass