11 piecesRE = re.compile (
r'(.+?)\s+"(\S+)"\s+"(\S*)"\s+"(\S+)"')
13 nonAlphaRE = re.compile (
r'\W')
14 commaRE = re.compile (
r',')
15 queueCommand =
'/uscms/home/cplager/bin/clpQueue.pl addjob %s' 17 compRootDir =
'compRoot' 20 doubleRE = re.compile (
r'^(double|int)')
21 vectorRE = re.compile (
r'^vector<([^<>]+)>')
22 detSetVecRE = re.compile (
r'^edm::DetSetVector<([^<>]+)>')
23 edColRE = re.compile (
r'^edm::EDCollection<([^<>]+)>')
24 sortedColRE = re.compile (
r'^edm::SortedCollection<([^<>]+),\S+?> >')
25 singletonRE = re.compile (
r'^([\w:]+)$')
26 containerList = [vectorRE, detSetVecRE, edColRE, sortedColRE, doubleRE]
31 self.container, self.one, self.two, self.
three = tup
33 for regex
in containerList:
34 match = regex.search( self.container)
41 return pprint.pformat (self.__dict__)
47 return "%s,%s,%s" % (self.one, self.two, self.
three)
50 if __name__ ==
"__main__":
55 parser = optparse.OptionParser (
"%prog [options] file1.root [file2.root]"\
56 "\nFor more details, see\nhttps://twiki.cern.ch/twiki/bin/view/CMS/SWGuidePhysicsToolsEdmOneToOneComparison")
57 describeGroup = optparse.OptionGroup (parser,
"Description Options")
58 precisionGroup = optparse.OptionGroup (parser,
"Precision Options")
59 summaryGroup = optparse.OptionGroup (parser,
"Summary Options")
60 queueGroup = optparse.OptionGroup (parser,
"Queue Options")
61 verboseGroup = optparse.OptionGroup (parser,
"Verbose Options")
63 parser.add_option (
"--compRoot", dest=
"compRoot",
64 action=
"store_true", default=
False,
65 help=
"Make compRoot files.")
66 parser.add_option (
'--strictPairing', dest=
'strictPairing',
68 help=
"Objects are paired uniquely by order in collection")
69 parser.add_option (
"--prefix", dest=
"prefix", type=
"string",
70 help=
"Prefix to prepend to logfile name")
71 parser.add_option (
"--regex", dest=
'regex', action=
"append",
72 type=
"string", default=[],
73 help=
"Only run on branches containing regex")
75 describeGroup.add_option (
"--describeOnly", dest=
"describeOnly",
76 action=
"store_true", default=
False,
77 help=
"Run description step only and stop.")
78 describeGroup.add_option (
"--forceDescribe", dest=
"forceDescribe",
79 action=
"store_true", default=
False,
80 help=
"Run description step even if "\
81 "file already exists.")
82 describeGroup.add_option (
"--singletons", dest=
"singletons",
83 action=
"store_true", default=
False,
84 help=
"Describe singleton objects (" \
85 "used only with --describeOnly option).")
86 describeGroup.add_option (
"--privateMemberData", dest=
"privateMemberData",
87 action=
"store_true", default=
False,
88 help=
"include private member data "\
89 "(NOT for comparisons)")
91 precisionGroup.add_option (
"--precision", dest=
"precision", type=
"string",
92 help=
"Change precision use for floating "\
94 precisionGroup.add_option (
'--absolute', dest=
'absolute',
95 action=
'store_true', default=
False,
96 help=
'Precision is checked against '\
97 'absolute difference')
98 precisionGroup.add_option (
'--relative', dest=
'relative',
99 action=
'store_true', default=
False,
100 help=
'Precision is checked against '\
101 'relative difference')
103 summaryGroup.add_option (
"--summary", dest=
"summary",
104 action=
"store_true", default=
False,
105 help=
"Print out summary counts at end")
106 summaryGroup.add_option (
"--summaryFull", dest=
"summaryFull",
107 action=
"store_true", default=
False,
108 help=
"Print out full summary at end (VERY LONG)")
110 queueGroup.add_option (
"--noQueue", dest=
"noQueue",
111 action=
"store_true", default=
True,
112 help=
"Do not use queue, but run "\
113 "jobs serially (default).")
114 queueGroup.add_option (
"--queue", dest=
"noQueue",
115 action=
"store_false",
116 help=
"Use defaultqueueing system.")
117 queueGroup.add_option (
"--queueCommand", dest=
"queueCommand", type=
"string",
118 help=
"Use QUEUECOMMAND TO queue jobs")
120 verboseGroup.add_option (
"--verbose", dest=
"verbose",
121 action=
"store_true", default=
False,
122 help=
"Verbose output")
123 verboseGroup.add_option (
"--verboseDebug", dest=
"verboseDebug",
124 action=
"store_true", default=
False,
125 help=
"Verbose output for debugging")
126 parser.add_option_group (describeGroup)
127 parser.add_option_group (precisionGroup)
128 parser.add_option_group (summaryGroup)
129 parser.add_option_group (queueGroup)
130 parser.add_option_group (verboseGroup)
131 options, args = parser.parse_args()
135 if len (args) < 1
or len (args) > 2:
136 raise RuntimeError(
"You must provide 1 or 2 root files")
141 if options.queueCommand:
142 queueCommand = options.queueCommand
143 options.noQueue =
False 144 if not re.match (
r'%%s', queueCommand):
145 queueCommand +=
' %s' 147 command =
'src/Validation/Tools/scripts/runCommand.bash' 149 command =
'src/Validation/Tools/scripts/runCMScommand.bash' 152 if options.compRoot
or options.summary
or options.summaryFull:
153 raise RuntimeError(
"You can not use --compRoot or --summary "\
159 base = os.environ.get (
'CMSSW_BASE')
160 release_base = os.environ.get (
'CMSSW_RELEASE_BASE')
161 if not base
or not release_base:
162 raise RuntimeError(
"You must have already setup a CMSSW environment.")
165 for directory
in [base, release_base]:
166 fullCommand = directory +
'/' + command
167 if os.path.exists (fullCommand):
171 raise RuntimeError(
"Can not find %s" % command)
172 if not options.noQueue:
173 fullCommand = queueCommand % fullCommand
174 if not os.path.isdir (logDir):
176 if not os.path.isdir (logDir):
177 raise RuntimeError(
"Can't create %s directory" % logDir)
178 if options.compRoot
and not os.path.isdir (compRootDir):
179 os.mkdir (compRootDir)
180 if not os.path.isdir (compRootDir):
181 raise RuntimeError(
"Can't create %s directory" % compRootDir)
182 logPrefix = logDir +
'/' 183 compRootPrefix = compRootDir +
'/' 185 logPrefix += options.prefix +
'_' 186 currentDir = os.getcwd()
191 filename2 = filename1
192 if not os.path.exists (filename1)
or not os.path.exists (filename2):
193 raise RuntimeError(
"Can not find '%s' or '%s'" % (filename1, filename2))
195 if options.verboseDebug:
196 options.verbose =
True 198 print "files", filename1, filename2
199 if options.singletons
and not options.describeOnly:
200 raise RuntimeError(
"--singletons can only be used with "\
201 "--describeOnly option")
202 if options.privateMemberData
and not options.describeOnly:
203 raise RuntimeError(
"--privateMemberData can only be used with "\
204 "--describeOnly option")
205 if options.singletons:
206 containerList.append (singletonRE)
211 print "Getting edmDumpEventContent output" 213 for regex
in options.regex:
214 regexLine +=
' "--regex=%s"' % regex
215 dumpCommand =
'edmDumpEventContent %s %s' % (regexLine, filename1)
216 if options.verboseDebug:
217 print dumpCommand,
'\n' 218 output = commands.getoutput (dumpCommand).
split(
"\n")
220 raise RuntimeError(
"No output from edmDumpEventContent.")
221 if options.verboseDebug:
222 print "output:\n",
"\n".
join(output)
224 total = failed = skipped = useless = 0
227 match = piecesRE.search(line)
231 collection.setdefault( obj.container, [] ).
append(obj)
240 for key, value
in sorted (six.iteritems(collection)):
242 prettyName = nonAlphaRE.sub(
'', name)
243 descriptionName = prettyName +
'.txt' 244 if os.path.exists (descriptionName) \
245 and os.path.getsize (descriptionName) \
246 and not options.forceDescribe:
248 print '%s exists. Skipping' % descriptionName
251 describeCmd =
"%s %s %s useReflexToDescribeForGenObject.py %s '--type=%s'" \
252 % (fullCommand, currentDir, logPrefix + prettyName,
253 GenObject.encodeNonAlphanumerics (name),
255 GenObject.encodeNonAlphanumerics (key))
256 if options.precision:
257 describeCmd +=
" --precision=" + options.precision
259 print "describing %s" % name
260 if options.verboseDebug:
261 print describeCmd,
'\n' 262 returnCode = os.system (describeCmd)
265 if returnCode == GenObject.uselessReturnCode << 8:
268 print "Error trying to describe '%s'. Continuing.\n" % \
271 if options.describeOnly:
272 print "Total: %3d Skipped: %3d Failed: %3d Useless: %3d" % \
273 (total, skipped, failed, useless)
274 if not options.noQueue:
275 print "Note: Failed not recorded when using queuing system." 281 for key, value
in sorted (six.iteritems(collection)):
286 prettyName = nonAlphaRE.sub(
'', name)
287 scriptName =
'edmOneToOneComparison.py' 288 if prettyName
in [
'int',
'double']:
289 scriptName =
'simpleEdmComparison.py' 290 prettyLabel = commaRE.sub (
'_', obj.label())
291 compareCmd =
'%s %s %s %s --compare --label=reco^%s^%s' \
298 fullCompareCmd =
'%s %s %s %s' \
299 % (fullCommand, currentDir,
300 logPrefix + prettyName +
'_' + prettyLabel,
303 fullCompareCmd +=
' --relative' 304 elif options.absolute:
305 fullCompareCmd +=
' --absolute' 307 compRootName = compRootPrefix + prettyName \
308 +
'_' + prettyLabel +
'.root' 309 fullCompareCmd +=
' --compRoot=%s' % compRootName
310 if options.strictPairing:
311 fullCompareCmd +=
' --strictPairing' 313 print "comparing branch %s %s" % (name, obj.label())
314 if options.verboseDebug:
315 print fullCompareCmd,
'\n' 316 os.system (fullCompareCmd)
321 if options.summary
or options.summaryFull:
323 summaryMask = options.prefix +
'_%_' 326 if options.summaryFull:
327 summaryOptions =
'--diffTree' 329 summaryOptions =
'--counts' 330 summaryCmd =
'summarizeEdmComparisonLogfiles.py %s %s logfiles' \
331 % (summaryOptions, summaryMask)
333 print commands.getoutput (summaryCmd)
static std::string join(char **cmd)