CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
validateAlignments.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #test execute: export CMSSW_BASE=/tmp/CMSSW && ./validateAlignments.py -c defaultCRAFTValidation.ini,test.ini -n -N test
3 import os
4 import sys
5 import optparse
6 import datetime
7 import shutil
8 import fnmatch
9 
10 import Alignment.OfflineValidation.TkAlAllInOneTool.configTemplates \
11  as configTemplates
12 import Alignment.OfflineValidation.TkAlAllInOneTool.crabWrapper as crabWrapper
13 from Alignment.OfflineValidation.TkAlAllInOneTool.TkAlExceptions \
14  import AllInOneError
15 from Alignment.OfflineValidation.TkAlAllInOneTool.helperFunctions \
16  import replaceByMap, getCommandOutput2, addIndex
17 from Alignment.OfflineValidation.TkAlAllInOneTool.betterConfigParser \
18  import BetterConfigParser
19 from Alignment.OfflineValidation.TkAlAllInOneTool.alignment import Alignment
20 
21 from Alignment.OfflineValidation.TkAlAllInOneTool.genericValidation \
22  import GenericValidation
23 from Alignment.OfflineValidation.TkAlAllInOneTool.geometryComparison \
24  import GeometryComparison
25 from Alignment.OfflineValidation.TkAlAllInOneTool.offlineValidation \
26  import OfflineValidation, OfflineValidationDQM
27 from Alignment.OfflineValidation.TkAlAllInOneTool.monteCarloValidation \
28  import MonteCarloValidation
29 from Alignment.OfflineValidation.TkAlAllInOneTool.trackSplittingValidation \
30  import TrackSplittingValidation
31 from Alignment.OfflineValidation.TkAlAllInOneTool.zMuMuValidation \
32  import ZMuMuValidation
33 import Alignment.OfflineValidation.TkAlAllInOneTool.globalDictionaries \
34  as globalDictionaries
35 
36 
37 ####################--- Classes ---############################
39 
40  # these count the jobs of different varieties that are being run
41  crabCount = 0
42  interactCount = 0
43  batchCount = 0
44  batchJobIds = []
45  jobCount = 0
46 
47  def __init__( self, validation, config, options ):
48  if validation[1] == "":
49  # intermediate syntax
50  valString = validation[0].split( "->" )[0]
51  alignments = validation[0].split( "->" )[1]
52  # force user to use the normal syntax
53  if "->" in validation[0]:
54  msg = ("Instead of using the intermediate syntax\n'"
55  +valString.strip()+"-> "+alignments.strip()
56  +":'\nyou have to use the now fully supported syntax \n'"
57  +valString.strip()+": "
58  +alignments.strip()+"'.")
59  raise AllInOneError(msg)
60  else:
61  valString = validation[0]
62  alignments = validation[1]
63  valString = valString.split()
64  self.__valType = valString[0]
65  self.__valName = valString[1]
66  self.__commandLineOptions = options
67  self.__config = config
68  # workaround for intermediate parallel version
69  if self.__valType == "offlineParallel":
70  print ("offlineParallel and offline are now the same. To run an offline parallel validation,\n"
71  "just set parallelJobs to something > 1. There is no reason to call it offlineParallel anymore.")
72  self.__valType = "offline"
73  section = self.__valType + ":" + self.__valName
74  if not self.__config.has_section( section ):
75  raise AllInOneError, ("Validation '%s' of type '%s' is requested in"
76  " '[validation]' section, but is not defined."
77  "\nYou have to add a '[%s]' section."
78  %( self.__valName, self.__valType, section ))
79  self.validation = self.__getValidation( self.__valType, self.__valName,
80  alignments, self.__config,
81  options )
82 
83  def __getValidation( self, valType, name, alignments, config, options ):
84  if valType == "compare":
85  alignmentsList = alignments.split( "," )
86  firstAlignList = alignmentsList[0].split()
87  firstAlignName = firstAlignList[0].strip()
88  if firstAlignName == "IDEAL":
89  raise AllInOneError, ("'IDEAL' has to be the second (reference)"
90  " alignment in 'compare <val_name>: "
91  "<alignment> <reference>'.")
92  if len( firstAlignList ) > 1:
93  firstRun = firstAlignList[1]
94  else:
95  firstRun = "1"
96  firstAlign = Alignment( firstAlignName, self.__config, firstRun )
97  secondAlignList = alignmentsList[1].split()
98  secondAlignName = secondAlignList[0].strip()
99  if len( secondAlignList ) > 1:
100  secondRun = secondAlignList[1]
101  else:
102  secondRun = "1"
103  if secondAlignName == "IDEAL":
104  secondAlign = secondAlignName
105  else:
106  secondAlign = Alignment( secondAlignName, self.__config,
107  secondRun )
108  # check if alignment was already compared previously
109  try:
110  randomWorkdirPart = \
111  globalDictionaries.alignRandDict[firstAlignName]
112  except KeyError:
113  randomWorkdirPart = None
114 
115  validation = GeometryComparison( name, firstAlign, secondAlign,
116  self.__config,
117  self.__commandLineOptions.getImages,
118  randomWorkdirPart )
119  globalDictionaries.alignRandDict[firstAlignName] = \
120  validation.randomWorkdirPart
121  if not secondAlignName == "IDEAL":
122  globalDictionaries.alignRandDict[secondAlignName] = \
123  validation.randomWorkdirPart
124  elif valType == "offline":
125  validation = OfflineValidation( name,
126  Alignment( alignments.strip(), self.__config ), self.__config )
127  elif valType == "offlineDQM":
128  validation = OfflineValidationDQM( name,
129  Alignment( alignments.strip(), self.__config ), self.__config )
130  elif valType == "mcValidate":
131  validation = MonteCarloValidation( name,
132  Alignment( alignments.strip(), self.__config ), self.__config )
133  elif valType == "split":
134  validation = TrackSplittingValidation( name,
135  Alignment( alignments.strip(), self.__config ), self.__config )
136  elif valType == "zmumu":
137  validation = ZMuMuValidation( name,
138  Alignment( alignments.strip(), self.__config ), self.__config )
139  else:
140  raise AllInOneError, "Unknown validation mode '%s'"%valType
141  return validation
142 
143  def __createJob( self, jobMode, outpath ):
144  """This private method creates the needed files for the validation job.
145  """
146  self.validation.createConfiguration( outpath )
147  self.__scripts = sum([addIndex(script, self.validation.NJobs) for script in self.validation.createScript( outpath )], [])
148  if jobMode.split( ',' )[0] == "crab":
149  self.validation.createCrabCfg( outpath )
150  return None
151 
152  def createJob(self):
153  """This is the method called to create the job files."""
154  self.__createJob( self.validation.jobmode,
155  os.path.abspath( self.__commandLineOptions.Name) )
156 
157  def runJob( self ):
158  general = self.__config.getGeneral()
159  log = ""
160  for script in self.__scripts:
161  name = os.path.splitext( os.path.basename( script) )[0]
162  ValidationJob.jobCount += 1
163  if self.__commandLineOptions.dryRun:
164  print "%s would run: %s"%( name, os.path.basename( script) )
165  continue
166  log = "> Validating "+name
167  print "> Validating "+name
168  if self.validation.jobmode == "interactive":
169  log += getCommandOutput2( script )
170  ValidationJob.interactCount += 1
171  elif self.validation.jobmode.split(",")[0] == "lxBatch":
172  repMap = {
173  "commands": self.validation.jobmode.split(",")[1],
174  "logDir": general["logdir"],
175  "jobName": name,
176  "script": script,
177  "bsub": "/afs/cern.ch/cms/caf/scripts/cmsbsub"
178  }
179  bsubOut=getCommandOutput2("%(bsub)s %(commands)s "
180  "-J %(jobName)s "
181  "-o %(logDir)s/%(jobName)s.stdout "
182  "-e %(logDir)s/%(jobName)s.stderr "
183  "%(script)s"%repMap)
184  #Attention: here it is assumed that bsub returns a string
185  #containing a job id like <123456789>
186  ValidationJob.batchJobIds.append(bsubOut.split("<")[1].split(">")[0])
187  log+=bsubOut
188  ValidationJob.batchCount += 1
189  elif self.validation.jobmode.split( "," )[0] == "crab":
190  os.chdir( general["logdir"] )
191  crabName = "crab." + os.path.basename( script )[:-3]
192  theCrab = crabWrapper.CrabWrapper()
193  options = { "-create": "",
194  "-cfg": crabName + ".cfg",
195  "-submit": "" }
196  try:
197  theCrab.run( options )
198  except AllInOneError, e:
199  print "crab:", str(e).split("\n")[0]
200  exit(1)
201  ValidationJob.crabCount += 1
202 
203  else:
204  raise AllInOneError, ("Unknown 'jobmode'!\n"
205  "Please change this parameter either in "
206  "the [general] or in the ["
207  + self.__valType + ":" + self.__valName
208  + "] section to one of the following "
209  "values:\n"
210  "\tinteractive\n\tlxBatch, -q <queue>\n"
211  "\tcrab, -q <queue>")
212 
213  return log
214 
215  def getValidation( self ):
216  return self.validation
217 
218 
219 ####################--- Functions ---############################
220 def createOfflineParJobsMergeScript(offlineValidationList, outFilePath):
221  repMap = offlineValidationList[0].getRepMap() # bit ugly since some special features are filled
222 
223  theFile = open( outFilePath, "w" )
224  theFile.write( replaceByMap( configTemplates.mergeOfflineParJobsTemplate ,repMap ) )
225  theFile.close()
226 
227 def createExtendedValidationScript(offlineValidationList, outFilePath, resultPlotFile):
228  repMap = offlineValidationList[0].getRepMap() # bit ugly since some special features are filled
229  repMap[ "CMSSW_BASE" ] = os.environ['CMSSW_BASE']
230  repMap[ "resultPlotFile" ] = resultPlotFile
231  repMap[ "extendedInstantiation" ] = "" #give it a "" at first in order to get the initialisation back
232 
233  for validation in offlineValidationList:
234  repMap[ "extendedInstantiation" ] = validation.appendToExtendedValidation( repMap[ "extendedInstantiation" ] )
235 
236  theFile = open( outFilePath, "w" )
237  # theFile.write( replaceByMap( configTemplates.extendedValidationTemplate ,repMap ) )
238  theFile.write( replaceByMap( configTemplates.extendedValidationTemplate ,repMap ) )
239  theFile.close()
240 
241 def createTrackSplitPlotScript(trackSplittingValidationList, outFilePath):
242  repMap = trackSplittingValidationList[0].getRepMap() # bit ugly since some special features are filled
243  repMap[ "CMSSW_BASE" ] = os.environ['CMSSW_BASE']
244  repMap[ "trackSplitPlotInstantiation" ] = "" #give it a "" at first in order to get the initialisation back
245 
246  for validation in trackSplittingValidationList:
247  repMap[ "trackSplitPlotInstantiation" ] = validation.appendToExtendedValidation( repMap[ "trackSplitPlotInstantiation" ] )
248 
249  theFile = open( outFilePath, "w" )
250  # theFile.write( replaceByMap( configTemplates.trackSplitPlotTemplate ,repMap ) )
251  theFile.write( replaceByMap( configTemplates.trackSplitPlotTemplate ,repMap ) )
252  theFile.close()
253 
254 def createMergeScript( path, validations ):
255  if(len(validations) == 0):
256  raise AllInOneError("Cowardly refusing to merge nothing!")
257 
258  repMap = validations[0].getRepMap() #FIXME - not nice this way
259  repMap.update({
260  "DownloadData":"",
261  "CompareAlignments":"",
262  "RunExtendedOfflineValidation":"",
263  "RunTrackSplitPlot":""
264  })
265 
266  comparisonLists = {} # directory of lists containing the validations that are comparable
267  for validation in validations:
268  for referenceName in validation.filesToCompare:
269  validationName = "%s.%s"%(validation.__class__.__name__, referenceName)
270  validationName = validationName.split(".%s"%GenericValidation.defaultReferenceName )[0]
271  if validationName in comparisonLists:
272  comparisonLists[ validationName ].append( validation )
273  else:
274  comparisonLists[ validationName ] = [ validation ]
275 
276  # introduced to merge individual validation outputs separately
277  # -> avoids problems with merge script
278  repMap["haddLoop"] = "mergeRetCode=0\n"
279  repMap["rmUnmerged"] = ("if [[ mergeRetCode -eq 0 ]]; then\n"
280  " echo -e \\n\"Merging succeeded, removing original files.\"\n")
281  repMap["copyMergeScripts"] = ""
282  repMap["mergeParallelFilePrefixes"] = ""
283 
284  anythingToMerge = []
285  for validationType in comparisonLists:
286  for validation in comparisonLists[validationType]:
287  if validation.NJobs == 1:
288  continue
289  if validationType not in anythingToMerge:
290  anythingToMerge += [validationType]
291  repMap["haddLoop"] += '\n\n\n\necho -e "\n\nMerging results from %s jobs"\n\n' % validationType
292  repMap["haddLoop"] = validation.appendToMerge(repMap["haddLoop"])
293  repMap["haddLoop"] += "tmpMergeRetCode=${?}\n"
294  repMap["haddLoop"] += ("if [[ tmpMergeRetCode -eq 0 ]]; then "
295  "cmsStage -f "
296  +validation.getRepMap()["finalOutputFile"]
297  +" "
298  +validation.getRepMap()["finalResultFile"]
299  +"; fi\n")
300  repMap["haddLoop"] += ("if [[ ${tmpMergeRetCode} -gt ${mergeRetCode} ]]; then "
301  "mergeRetCode=${tmpMergeRetCode}; fi\n")
302  for f in validation.getRepMap()["outputFiles"]:
303  longName = os.path.join("/store/caf/user/$USER/",
304  validation.getRepMap()["eosdir"], f)
305  repMap["rmUnmerged"] += " cmsRm "+longName+"\n"
306  repMap["rmUnmerged"] += ("else\n"
307  " echo -e \\n\"WARNING: Merging failed, unmerged"
308  " files won't be deleted.\\n"
309  "(Ignore this warning if merging was done earlier)\"\n"
310  "fi\n")
311 
312  if "OfflineValidation" in anythingToMerge:
313  repMap["mergeOfflineParJobsScriptPath"] = os.path.join(path, "TkAlOfflineJobsMerge.C")
314  createOfflineParJobsMergeScript( comparisonLists["OfflineValidation"],
315  repMap["mergeOfflineParJobsScriptPath"] )
316  repMap["copyMergeScripts"] += ("cp .oO[CMSSW_BASE]Oo./src/Alignment/OfflineValidation/scripts/merge_TrackerOfflineValidation.C .\n"
317  "rfcp %s .\n" % repMap["mergeOfflineParJobsScriptPath"])
318 
319  if anythingToMerge:
320  # DownloadData is the section which merges output files from parallel jobs
321  # it uses the file TkAlOfflineJobsMerge.C
322  repMap["DownloadData"] += replaceByMap( configTemplates.mergeParallelResults, repMap )
323  else:
324  repMap["DownloadData"] = ""
325 
326 
327  if "OfflineValidation" in comparisonLists:
328  repMap["extendedValScriptPath"] = os.path.join(path, "TkAlExtendedOfflineValidation.C")
329  createExtendedValidationScript(comparisonLists["OfflineValidation"],
330  repMap["extendedValScriptPath"],
331  "OfflineValidation")
332  repMap["RunExtendedOfflineValidation"] = \
333  replaceByMap(configTemplates.extendedValidationExecution, repMap)
334 
335  if "TrackSplittingValidation" in comparisonLists:
336  repMap["trackSplitPlotScriptPath"] = \
337  os.path.join(path, "TkAlTrackSplitPlot.C")
338  createTrackSplitPlotScript(comparisonLists["TrackSplittingValidation"],
339  repMap["trackSplitPlotScriptPath"] )
340  repMap["RunTrackSplitPlot"] = \
341  replaceByMap(configTemplates.trackSplitPlotExecution, repMap)
342 
343  repMap["CompareAlignments"] = "#run comparisons"
344  for validationId in comparisonLists:
345  compareStrings = [ val.getCompareStrings(validationId) for val in comparisonLists[validationId] ]
346  compareStringsPlain = [ val.getCompareStrings(validationId, plain=True) for val in comparisonLists[validationId] ]
347 
348  repMap.update({"validationId": validationId,
349  "compareStrings": " , ".join(compareStrings),
350  "compareStringsPlain": " ".join(compareStringsPlain) })
351 
352  repMap["CompareAlignments"] += \
353  replaceByMap(configTemplates.compareAlignmentsExecution, repMap)
354 
355  filePath = os.path.join(path, "TkAlMerge.sh")
356  theFile = open( filePath, "w" )
357  theFile.write( replaceByMap( configTemplates.mergeTemplate, repMap ) )
358  theFile.close()
359  os.chmod(filePath,0755)
360 
361  return filePath
362 
363 def loadTemplates( config ):
364  if config.has_section("alternateTemplates"):
365  for templateName in config.options("alternateTemplates"):
366  if templateName == "AutoAlternates":
367  continue
368  newTemplateName = config.get("alternateTemplates", templateName )
369  #print "replacing default %s template by %s"%( templateName, newTemplateName)
370  configTemplates.alternateTemplate(templateName, newTemplateName)
371 
372 
373 ####################--- Main ---############################
374 def main(argv = None):
375  if argv == None:
376  argv = sys.argv[1:]
377  optParser = optparse.OptionParser()
378  optParser.description = """All-in-one Alignment Validation.
379 This will run various validation procedures either on batch queues or interactviely.
380 If no name is given (-N parameter) a name containing time and date is created automatically.
381 To merge the outcome of all validation procedures run TkAlMerge.sh in your validation's directory.
382 """
383  optParser.add_option("-n", "--dryRun", dest="dryRun", action="store_true", default=False,
384  help="create all scripts and cfg File but do not start jobs (default=False)")
385  optParser.add_option( "--getImages", dest="getImages", action="store_true", default=False,
386  help="get all Images created during the process (default= False)")
387  defaultConfig = "TkAlConfig.ini"
388  optParser.add_option("-c", "--config", dest="config", default = defaultConfig,
389  help="configuration to use (default TkAlConfig.ini) this can be a comma-seperated list of all .ini file you want to merge", metavar="CONFIG")
390  optParser.add_option("-N", "--Name", dest="Name",
391  help="Name of this validation (default: alignmentValidation_DATE_TIME)", metavar="NAME")
392  optParser.add_option("-r", "--restrictTo", dest="restrictTo",
393  help="restrict validations to given modes (comma seperated) (default: no restriction)", metavar="RESTRICTTO")
394  optParser.add_option("-s", "--status", dest="crabStatus", action="store_true", default = False,
395  help="get the status of the crab jobs", metavar="STATUS")
396  optParser.add_option("-d", "--debug", dest="debugMode", action="store_true",
397  default = False,
398  help="run the tool to get full traceback of errors",
399  metavar="DEBUG")
400  optParser.add_option("-m", "--autoMerge", dest="autoMerge", action="store_true", default = False,
401  help="submit TkAlMerge.sh to run automatically when all jobs have finished (default=False)."
402  " Works only for batch jobs")
403 
404  (options, args) = optParser.parse_args(argv)
405 
406  if not options.restrictTo == None:
407  options.restrictTo = options.restrictTo.split(",")
408 
409  options.config = [ os.path.abspath( iniFile ) for iniFile in \
410  options.config.split( "," ) ]
411  config = BetterConfigParser()
412  outputIniFileSet = set( config.read( options.config ) )
413  failedIniFiles = [ iniFile for iniFile in options.config if iniFile not in outputIniFileSet ]
414 
415  # Check for missing ini file
416  if options.config == [ os.path.abspath( defaultConfig ) ]:
417  if ( not options.crabStatus ) and \
418  ( not os.path.exists( defaultConfig ) ):
419  raise AllInOneError, ( "Default 'ini' file '%s' not found!\n"
420  "You can specify another name with the "
421  "command line option '-c'/'--config'."
422  %( defaultConfig ))
423  else:
424  for iniFile in failedIniFiles:
425  if not os.path.exists( iniFile ):
426  raise AllInOneError, ( "'%s' does not exist. Please check for "
427  "typos in the filename passed to the "
428  "'-c'/'--config' option!"
429  %( iniFile ) )
430  else:
431  raise AllInOneError, ( "'%s' does exist, but parsing of the "
432  "content failed!" )
433 
434  # get the job name
435  if options.Name == None:
436  if not options.crabStatus:
437  options.Name = "alignmentValidation_%s"%(datetime.datetime.now().strftime("%y%m%d_%H%M%S"))
438  else:
439  existingValDirs = fnmatch.filter( os.walk( '.' ).next()[1],
440  "alignmentValidation_*" )
441  if len( existingValDirs ) > 0:
442  options.Name = existingValDirs[-1]
443  else:
444  print "Cannot guess last working directory!"
445  print ( "Please use the parameter '-N' or '--Name' to specify "
446  "the task for which you want a status report." )
447  return 1
448 
449  # set output path
450  outPath = os.path.abspath( options.Name )
451 
452  # Check status of submitted jobs and return
453  if options.crabStatus:
454  os.chdir( outPath )
455  crabLogDirs = fnmatch.filter( os.walk('.').next()[1], "crab.*" )
456  if len( crabLogDirs ) == 0:
457  print "Found no crab tasks for job name '%s'"%( options.Name )
458  return 1
459  theCrab = crabWrapper.CrabWrapper()
460  for crabLogDir in crabLogDirs:
461  print
462  print "*" + "=" * 78 + "*"
463  print ( "| Status report and output retrieval for:"
464  + " " * (77 - len( "Status report and output retrieval for:" ) )
465  + "|" )
466  taskName = crabLogDir.replace( "crab.", "" )
467  print "| " + taskName + " " * (77 - len( taskName ) ) + "|"
468  print "*" + "=" * 78 + "*"
469  print
470  crabOptions = { "-getoutput":"",
471  "-c": crabLogDir }
472  try:
473  theCrab.run( crabOptions )
474  except AllInOneError, e:
475  print "crab: No output retrieved for this task."
476  crabOptions = { "-status": "",
477  "-c": crabLogDir }
478  theCrab.run( crabOptions )
479  return
480 
481  general = config.getGeneral()
482  config.set("internals","workdir",os.path.join(general["workdir"],options.Name) )
483  config.set("general","datadir",os.path.join(general["datadir"],options.Name) )
484  config.set("general","logdir",os.path.join(general["logdir"],options.Name) )
485  config.set("general","eosdir",os.path.join("AlignmentValidation", general["eosdir"], options.Name) )
486 
487  # clean up of log directory to avoid cluttering with files with different
488  # random numbers for geometry comparison
489  if os.path.isdir( outPath ):
490  shutil.rmtree( outPath )
491 
492  if not os.path.exists( outPath ):
493  os.makedirs( outPath )
494  elif not os.path.isdir( outPath ):
495  raise AllInOneError,"the file %s is in the way rename the Job or move it away"%outPath
496 
497  # replace default templates by the ones specified in the "alternateTemplates" section
498  loadTemplates( config )
499 
500  #save backup configuration file
501  backupConfigFile = open( os.path.join( outPath, "usedConfiguration.ini" ) , "w" )
502  config.write( backupConfigFile )
503 
504  validations = []
505  for validation in config.items("validation"):
506  alignmentList = validation[1].split(config.getSep())
507  validationsToAdd = [(validation[0],alignment) \
508  for alignment in alignmentList]
509  validations.extend(validationsToAdd)
510  jobs = [ ValidationJob( validation, config, options) \
511  for validation in validations ]
512  map( lambda job: job.createJob(), jobs )
513  validations = [ job.getValidation() for job in jobs ]
514 
515  createMergeScript(outPath, validations)
516 
517  print
518  map( lambda job: job.runJob(), jobs )
519 
520  if options.autoMerge:
521  # if everything is done as batch job, also submit TkAlMerge.sh to be run
522  # after the jobs have finished
523  if ValidationJob.jobCount == ValidationJob.batchCount and config.getGeneral()["jobmode"].split(",")[0] == "lxBatch":
524  print "> Automatically merging jobs when they have ended"
525  repMap = {
526  "commands": config.getGeneral()["jobmode"].split(",")[1],
527  "jobName": "TkAlMerge",
528  "logDir": config.getGeneral()["logdir"],
529  "script": "TkAlMerge.sh",
530  "bsub": "/afs/cern.ch/cms/caf/scripts/cmsbsub",
531  "conditions": '"' + " && ".join(["ended(" + jobId + ")" for jobId in ValidationJob.batchJobIds]) + '"'
532  }
533  getCommandOutput2("%(bsub)s %(commands)s "
534  "-o %(logDir)s/%(jobName)s.stdout "
535  "-e %(logDir)s/%(jobName)s.stderr "
536  "-w %(conditions)s "
537  "%(logDir)s/%(script)s"%repMap)
538 
539 if __name__ == "__main__":
540  # main(["-n","-N","test","-c","defaultCRAFTValidation.ini,latestObjects.ini","--getImages"])
541  if "-d" in sys.argv[1:] or "--debug" in sys.argv[1:]:
542  main()
543  else:
544  try:
545  main()
546  except AllInOneError, e:
547  print "\nAll-In-One Tool:", str(e)
548  exit(1)
— Classes —############################
def main
— Main —############################
def alternateTemplate
### Alternate Templates ###
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def replaceByMap
— Helpers —############################
Definition: main.py:1
if(conf.exists("allCellsPositionCalc"))
double split
Definition: MVATrainer.cc:139