=== Specific TELEMAC Toolbox === Global dictionnaries to avoid having to read these more than once. The keys are the full path to the dictionnaries and therefore allows for //root// and //version// to change \\ def getDICO(cfg,code): dicoFile = path.join(cfg['MODULES'][code]['path'],code+'.dico') if dicoFile not in DICOS.keys(): print ' +> register this DICO file: ' + dicoFile frgb,dico = scanDICO(dicoFile) idico,odico = getIOFilesSubmit(frgb,dico) globals()['DICOS'].update({dicoFile:{ 'frgb':frgb, 'dico':dico, 'input':idico, 'output':odico }}) return dicoFile # _____ _______________________________________ # ____/ General XML Toolbox /______________________________________/ # """ Will read the xml's XML keys based on the template do. +: those with None are must have +: those without None are optional and reset if there """ def getXMLKeys(xml,do): xcpt = [] # try all keys for full report done = do.copy() # shallow copy is here sufficient for key in done.keys(): if not key in xml.keys(): if done[key] == None: xcpt.append({'name':'getXMLKeys','msg':'cannot find the key: '+key}) else: done[key] = xml.attrib[key] if xcpt != []: raise Exception(xcpt) # raise full report return done def setSafe(casFile,cas,idico,odico,safe): copyFile(casFile,safe) # TODO: look at relative paths wDir = path.dirname(casFile) # ~~> process sortie files if any sacFile = path.join(safe,casFile) sortieFiles = getLatestSortieFiles(sacFile) # ~~> process input / output iFS = []; oFS = [] for k,v in zip(*cas): if idico.has_key(k): copyFile(path.join(wDir,eval(v[0])),safe) ifile = path.join(safe,eval(v[0])) iFS.append([k,[ifile],idico[k]]) #if not path.isfile(ifile): # print '... file does not exist ',ifile # sys.exit() if odico.has_key(k): ofile = path.join(safe,eval(v[0])) oFS.append([k,[ofile],odico[k]]) return sortieFiles,iFS,oFS def findTargets(dido,src): layers = {} oneFound = False for cfg in dido.keys(): cfgFound = False if dido[cfg].has_key(src): layers.update({ cfg:[dido[cfg][src],'',src] }) cfgFound = True if not cfgFound and dido[cfg].has_key('input'): for i,j,k in dido[cfg]['input']: k = k.split(';') if src in k[1]: # filename, fileForm, fileType # /!\ Temporary fix because TOMAWAC's IOs names are not yet standard TELEMAC if k[5] =='SCAL': k[5] = k[1] # \!/ layers.update({ cfg:[j,k[3],k[5]] }) cfgFound = True if not cfgFound and dido[cfg].has_key('output'): if dido[cfg]['code'] == 'postel3d': for file in dido[cfg]['output']: if src == path.basename(file) : layers.update({ cfg:[[file],'','SELAFIN'] }) cfgFound = True else : for i,j,k in dido[cfg]['output']: k = k.split(';') if src in k[1]: # filename, fileForm, fileType # /!\ Temporary fix because TOMAWAC's IOs names are not yet standard TELEMAC if k[5] =='SCAL': k[5] = k[1] # \!/ layers.update({ cfg:[j,k[3],k[5]] }) cfgFound = True if not cfgFound and dido[cfg].has_key('type'): if dido[cfg]['type'] == src: layers.update({ cfg:[[dido[cfg]['target']],'',src] }) cfgFound = True oneFound = oneFound or cfgFound if not oneFound: raise Exception([{'name':'findTargets','msg':'did not find the file to group: '+src}]) return layers def findDecos(): pass # _____ _____________________________________ # ____/ Primary Class: ACTION /____________________________________/ # """ In the classes below, the double quoted keys refer to the keys of the XML file. Contrarily, the single quoted keys in because they are internal to the python scripts. In the XML file, you can have multiple actions and each action will be associated with multiple configurations: did.keys() => array [xref] for each action did[xref].keys() => array [cfgname] for each possible configuration did[xref][cfgname].keys() => - 'target', basename of the CAS file - 'cas', scanned CAS file - 'code', name of the module - 'title', title of the action (xref) - 'cmaps', refer to the directory 'ColourMaps' for colour plotting - 'deprefs', refer to the files that need copying from path to safe - 'outrefs', refer to the files that need copying from safe to path - 'where' will not default to xref anymore, allowing files to be shared and located at the same place between actions """ class ACTION: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # General Methods # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ availacts = '' availkeys = { 'path':'','safe':'','cfg':'', "target": '', "xref": '', "do": '', "rank":'', "title": '', "deprefs":'', "outrefs":'', "where":'' } def __init__(self,title='',bypass=True): self.active = {} if title != '': self.active["title"] = title self.bypass = bypass self.dids = {} def addAction(self,actions,rank=''): self.active.update(deepcopy(self.availkeys)) try: self.active = getXMLKeys(actions,self.active) except Exception as e: raise Exception([filterMessage({'name':'ACTION::addACTION'},e,self.bypass)]) # only one item here if self.dids.has_key(self.active["xref"]): raise Exception([{'name':'ACTION::addACTION','msg':'you are getting me confused, this xref already exists: '+self.active["xref"]}]) self.dids.update({ self.active["xref"]:{} }) if self.active["rank"] == '': self.active["rank"] = rank if self.active["rank"] == '': self.active["rank"] = '953' self.active["rank"] = int(self.active["rank"]) if isinstance(self.active["deprefs"], StringTypes): deprefs = {} if self.active["deprefs"] != '': for depref in self.active["deprefs"].split(';'): if ':' in depref: ref,dep = depref.split(':') else: # ref becomes the name itself if no dependencies to other actions ref = depref dep = depref deprefs.update({ref:dep}) self.active["deprefs"] = deprefs if isinstance(self.active["outrefs"], StringTypes): outrefs = {} if self.active["outrefs"] != '': for outref in self.active["outrefs"].split(';'): ref,out = outref.split(':') outrefs.update({ref:out}) self.active["outrefs"] = outrefs return self.active["target"] def addCFG(self,cfgname,cfg): self.active['cfg'] = cfgname if self.active["where"] != '': self.active['safe'] = path.join( path.join(self.active['path'],self.active["where"]),cfgname ) else: self.active['safe'] = path.join( path.join(self.active['path'],self.active["xref"]),cfgname ) self.dids[self.active["xref"]].update( { cfgname: { 'target': self.active["target"], 'safe': self.active['safe'], 'path': self.active['path'], 'title': self.active["title"], 'cmaps': path.join(cfg['PWD'],'ColourMaps') } } ) def updateCFG(self,d): self.dids[self.active["xref"]][self.active['cfg']].update( d ) # _____ _____________________________________ # ____/ Primary Class: GROUPS /____________________________________/ # """ In the classes below, the double quoted keys refer to the keys of the XML file. Contrarily, the single quoted keys in because they are internal to the python scripts. In the XML file, you can have multiple actions and each action will be associated with multiple configurations: did.keys() => array [xref] for each action did[xref].keys() => array [cfgname] for each possible configuration did[xref][cfgname].keys() => - 'target', basename of the CAS file - 'cas', scanned CAS file - 'code', name of the module - 'title', title of the action (xref) - 'cmaps', refer to the directory 'ColourMaps' for colour plotting - 'deprefs', refer to the files that need copying from path to safe - 'outrefs', refer to the files that need copying from safe to path - 'where' will not default to xref anymore, allowing files to be shared and located at the same place between groups """ class GROUPS: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # General Methods # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ availacts = '' availkeys = { "xref": None, "deco": '' } groupkeys = { } avaylkeys = { } def __init__(self,title='',bypass=True): self.active = deepcopy(self.availkeys) if title != '': self.active["title"] = title self.bypass = bypass self.dids = {} # those you need to see in the XML file self.active["target"] = None self.active["code"] = None self.active["do"] = None self.active["type"] = None # additional entities self.tasks = {} def addGroupType(self,group): self.dids.update({group:{}}) self.active['type'] = group def addGroup(self,group): tasks = deepcopy(self.availkeys) try: self.tasks = getXMLKeys(group,tasks) except Exception as e: raise Exception([filterMessage({'name':'GROUP::addGroup'},e,self.bypass)]) self.active['xref'] = self.tasks["xref"] if self.dids[self.active['type']].has_key(self.tasks["xref"]): raise Exception([{'name':'GROUP::addGroup','msg':'you are getting me confused, this xref already exists: '+self.tasks["xref"]}]) self.dids[self.active['type']].update({self.tasks["xref"]:self.tasks}) def update(self,d): self.dids[self.active['type']][self.active['xref']].update( d ) def addSubTask(self,layer,nametask='layers'): # ~~> set default from the upper grouper subtasks = {} for k in self.groupkeys: subtasks.update({k:self.tasks[k]}) for k in self.avaylkeys: subtasks.update({k:self.avaylkeys[k]}) # ~~> reset from layer try: subtasks = getXMLKeys(layer,subtasks) except Exception as e: raise Exception([filterMessage({'name':'GROUP::addSubTask'},e,self.bypass)]) # ~~> filling-in remaining gaps subtasks = self.distributeMeta(subtasks) # ~~> adding subtask to the list of tasks if self.tasks.has_key(nametask): self.tasks[nametask].append(subtasks) else: self.tasks.update({nametask:[subtasks]}) return len(self.tasks[nametask])-1,nametask def targetSubTask(self,target,index=0,nametask='layers'): self.tasks[nametask][index].update({ 'fileName': target }) if not self.dids[self.active['type']][self.active['xref']].has_key(nametask): self.dids[self.active['type']][self.active['xref']].update({nametask:[]}) self.dids[self.active['type']][self.active['xref']][nametask].append(self.tasks[nametask][index]) def distributeMeta(self,subtask): return subtask def decotasks(self,deco={},index=0,nametask='layers'): # ~~> set default self.tasks[nametask][index]['deco'] = deco # _____ _____________________________________ # ____/ Secondary Class: META /____________________________________/ # class groupMETA(GROUPS): availkeys = deepcopy(GROUPS.availkeys) availkeys.update({ "roi":'', "deco": 'line', "size":'[15;10]', 'outFormat': 'png', 'grid': True }) groupkeys = deepcopy(GROUPS.groupkeys) def __init__(self,xmlFile,title='',bypass=True): GROUPS.__init__(self,title,bypass) # those you reset self.active['path'] = path.dirname(xmlFile) # those you need to see in the XML file self.active["deco"] = {} def addDraw(self,meta): GROUPS.addGroup(self,meta) def addLookTask(self,layer,nametask='look'): #self.avaylkeys = deepcopy(GROUPS.avaylkeys) self.avaylkeys = {} for key in layer.attrib.keys(): self.avaylkeys.update({key:layer.attrib[key]}) if key == 'grid': if layer.attrib['grid'] == 'no': layer.attrib['grid'] = False else: layer.attrib['grid'] = True return GROUPS.addSubTask(self,layer,'look') def addDataTask(self,layer,nametask='data'): self.avaylkeys = deepcopy(GROUPS.avaylkeys) self.avaylkeys.update({ "title":'', "contact":'', "author":'' }) return GROUPS.addSubTask(self,layer,'data') # _____ __________________________________ # ____/ Secondary Class actionRUN /_________________________________/ # # actionRUN is to do with the modules of the TELEMAC system and # other execution (pre- and post-processes). # . It understands what a PRINCI and what a CAS file and will do # the necessary steps to run modules accordingly. # . It includes specific methods to do with CAS and PRINCI # . It will organise the tranfer of files (inputs and outputs) # class actionRUN(ACTION): availkeys = deepcopy(ACTION.availkeys) availkeys.update({ 'dico':'', "ncsize":'', "code": '' }) def __init__(self,xmlFile,title='',bypass=True): ACTION.__init__(self,title,bypass) # those you reset self.active['path'] = path.dirname(xmlFile) # those you need to see in the XML file self.active["target"] = None self.active["code"] = None self.active["xref"] = None self.active["do"] = None def addAction(self,actions,rank=''): target = ACTION.addAction(self,actions,rank) self.code = self.active["code"] return target def addCFG(self,cfgname,cfg): if not ( self.active["code"] == 'exec' or self.active["code"] in cfg['MODULES'].keys() ): print '... do not know about: ' + self.active["code"] + ' in configuration: ' + cfgname sys.exit() ACTION.addCFG(self,cfgname,cfg) ACTION.updateCFG(self,{ "links": {}, 'code': self.active["code"], 'deprefs': self.active['deprefs'], 'outrefs': self.active['outrefs'] }) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # CAS related Methods # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~ todo: difference of CAS file with default keys ~~~~~~~~~~~~~ def diffCAS(self): return # ~~ Translate the CAS file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def translateCAS(self,rebuild): if not "translate" in self.availacts.split(';'): return xref = self.active["xref"]; cfgname = self.active['cfg'] active = self.dids[xref][cfgname] # ~~> principal CAS file casFile = path.join(active['path'],active["target"]) sacFile = path.join(active['safe'],active["target"]) oneup = path.dirname(active['safe']) # copied one level up if matchSafe(casFile,active["target"]+'.??',oneup,rebuild): print ' ~> translate cas file: ' + active["target"] casfr,casgb = translateCAS(sacFile,DICOS[active['dico']]['frgb']) #/!\ removes comments at end of lines moveFile(casfr,oneup) moveFile(casgb,oneup) # ~~> associated CAS files for mod in active["links"]: link = active["links"][mod] casFile = path.join(active['path'],link['target']) sacFile = path.join(active['safe'],link['target']) if matchSafe(casFile,link['target']+'.??',oneup,rebuild): print ' ~> translate cas file: ' + link['target'] casfr,casgb = translateCAS(sacFile,DICOS[link['dico']]['frgb']) #/!\ removes comments at end of lines moveFile(casfr,oneup) moveFile(casgb,oneup) # ~~ Run the CAS file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def runCAS(self,options,cfg,rebuild): if not "run" in self.availacts.split(';'): return # ~~> prepare options as if run from command line specs = Values() setattr(specs,'configName',options.configName) setattr(specs,'configFile', options.configFile) setattr(specs,'sortieFile',True) setattr(specs,'tmpdirectory',True) setattr(specs,'rootDir', options.rootDir) setattr(specs,'version', options.version) setattr(specs,'wDir', options.wDir) setattr(specs,'compileonly', False) if options.hosts != '': setattr(specs,'hosts', options.hosts) else: setattr(specs,'hosts', gethostname().split('.')[0]) setattr(specs,'split', options.split) setattr(specs,'run', options.run) setattr(specs,'merge', options.merge) if options.ncsize != '' and self.active["ncsize"] != '': self.active["ncsize"] = options.ncsize setattr(specs,'ncsize', self.active["ncsize"]) setattr(specs,'nctile', '1') # default but should not be used for validation setattr(specs,'bypass',self.bypass) # ~~> check on sorties and run casFile = path.join(self.active['path'],self.active["target"]) sacFile = path.join(self.active['safe'],self.active["target"]) sortieFiles = getLatestSortieFiles(sacFile) outputs = self.dids[self.active["xref"]][self.active['cfg']]['output'] if matchSafe(casFile,self.active["target"]+'_*??h??min??s*.sortie',self.active['safe'],rebuild): print ' +> running cas file: ' + self.active["target"] for k in outputs: matchSafe('',path.basename(k[1][0]),self.active['safe'],2) try: sortieFiles = runCAS(self.active['cfg'],cfg,self.active["code"],sacFile,specs) except Exception as e: raise Exception([filterMessage({'name':'ACTION::runCAS'},e,self.bypass)]) # only one item here if sortieFiles != []: self.updateCFG({ 'sortie': sortieFiles }) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # PRINCI related Methods # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~ Highligh user PRINCI differences ~~~~~~~~~~~~~~~~~~~~~~~~~~~ def diffPRINCI(self,options,cfg,rebuild): if not "princi" in self.availacts.split(';'): return xref = self.active["xref"]; cfgname = self.active['cfg'] active = self.dids[xref][cfgname] oneup = path.dirname(active['safe']) # copied one level up # ~~> principal PRINCI file value,default = getKeyWord('FICHIER FORTRAN',active['cas'],DICOS[active['dico']]['dico'],DICOS[active['dico']]['frgb']) princiFile = '' if value != []: princiFile = path.join(active['path'],eval(value[0])) if path.exists(princiFile): htmlFile = path.join(oneup,path.splitext(path.basename(princiFile))[0]+'.html') if matchSafe(htmlFile,path.basename(htmlFile),oneup,rebuild): # ~~> Scans the principal user PRINCI file print ' ~> scanning your PRINCI file: ',path.basename(princiFile) pFiles = getPrincipalWrapNames(princiFile) if pFiles == []: raise Exception([{'name':'ACTION::diffPRINCI','msg':'I could not recognised entities in your PRINCI: '+princiFile}]) else: print ' +> found:' for pFile in pFiles: print ' - ',pFile # ~~> Scans the entire system oFiles = {} for mod in cfg['MODULES']: for dirpath,dirnames,filenames in walk(cfg['MODULES'][mod]['path']) : break for file in filenames: n,e = path.splitext(file) # Only looking for fortran files if e.lower() not in ['.f','.f90']: continue for pFile in pFiles: if pFile.lower() == n: oFiles.update( filterPrincipalWrapNames( [pFile],[path.join(dirpath,file)] ) ) if oFiles == {}: raise Exception([{'name':'ACTION::diffPRINCI','msg':'I could not relate your PRINCI with the system: '+princiFile}]) else: print ' +> found:' for oFile in oFiles: print ' - ',oFile # ~~> Save temporarily for subsequent difference oriFile = path.splitext(princiFile)[0]+'.original'+path.splitext(princiFile)[1] putFileContent(oriFile,[]) for p in pFiles: if p in oFiles.keys(): addFileContent(oriFile,getFileContent(oFiles[p])) # ~~> Process difference and write output into an HTML file diff = diffTextFiles(oriFile,princiFile,options) remove(oriFile) of = open(htmlFile,'wb') of.writelines( diff ) of.close() print ' ~> comparison successful ! created: ' + path.basename(htmlFile) else: raise Exception([{'name':'ACTION::diffPRINCI','msg':'I could not find your PRINCI file: '+princiFile}]) # ~~> associated PRINCI file # TODO: case of coupling with multiple PRINCI files # ~~ Compile the PRINCI file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def compilePRINCI(self,cfg,rebuild): if not "compile" in self.availacts.split(';'): return xref = self.active["xref"]; cfgname = self.active['cfg'] active = self.dids[xref][cfgname] confirmed = False # ~~> principal PRINCI file value,default = getKeyWord('FICHIER FORTRAN',active['cas'],DICOS[active['dico']]['dico'],DICOS[active['dico']]['frgb']) princiFile = ''; princiSafe = '' if value != []: # you do not need to compile the default executable princiFile = path.join(active['path'],eval(value[0])) if path.exists(princiFile): exeFile = path.join(active['safe'],path.splitext(eval(value[0]))[0] + cfg['SYSTEM']['sfx_exe']) if not path.exists(exeFile) or cfg['REBUILD'] == 0: print ' +> compiling princi file: ' + path.basename(princiFile) copyFile(princiFile,active['safe']) print '*********copying '+princiFile+' '+active['safe'] princiSafe = path.join(active['safe'],path.basename(princiFile)) confirmed = True else: raise Exception([{'name':'ACTION::compilePRINCI','msg':'I could not find your PRINCI file: '+princiFile}]) # ~~> associated PRINCI file for mod in active["links"]: link = active["links"][mod] value,default = getKeyWord('FICHIER FORTRAN',link['cas'],DICOS[link['dico']]['dico'],DICOS[link['dico']]['frgb']) princiFilePlage = '' if value != []: # you do not need to compile the default executable princiFilePlage = path.join(active['path'],eval(value[0])) if path.exists(princiFilePlage): if princiSafe != '': print '*********adding content of '+path.basename(princiFilePlage)+' to '+princiSafe putFileContent(princiSafe,getFileContent(princiSafe)+['']+getFileContent(princiFilePlage)) else: print ' +> compiling princi file: ' + path.basename(princiFilePlage) exeFile = path.join(active['safe'],path.splitext(eval(value[0]))[0] + cfg['SYSTEM']['sfx_exe']) princiSafe = path.join(active['safe'],path.basename(princiFilePlage)) print '*********copying '+path.basename(princiFilePlage)+ ' ' + active['safe'] copyFile(princiFilePlage,active['safe']) confirmed = True else: raise Exception([{'name':'ACTION::compilePRINCI','msg':'I could not find your PRINCI file: '+princiFilePlage}]) if confirmed: try: compilePRINCI(princiSafe,active["code"],self.active['cfg'],cfg,self.bypass) except Exception as e: raise Exception([filterMessage({'name':'ACTION::compilePRINCI'},e,self.bypass)]) # only one item here #moveFile(exeFile,active['safe']) print ' ~> compilation successful ! created: ' + path.basename(exeFile) #else: you may wish to retrieve the executable for later analysis # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Direct Executions # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def runCommand(self,rebuild): print ' +> executing your command:\n ', self.active["do"] mes = MESSAGES(size=10) # ~~> copy of inputs copyFile(path.join(self.active['path'],self.active["target"]),self.active['safe']) for iFile in self.active["deprefs"]: copyFile(path.join(self.active['path'],iFile),self.active['safe']) # ~~> execute command locally os.chdir(self.active['safe']) try: tail,code = mes.runCmd(self.active["do"],True) #self.bypass) except Exception as e: raise Exception([filterMessage({'name':'runCommand','msg':'something went wrong when executing you command.'},e,True)]) if code != 0: raise Exception([{'name':'runCommand','msg':'Could run your command ('+self.active["do"]+').\n '+tail}]) # ~~> copy of outputs /!\ you are replacing one config by another for oFile in self.active["outrefs"]: if path.exists(path.join(self.active['safe'],self.active["outrefs"][oFile])): try: copyFile(path.join(self.active['safe'],self.active["outrefs"][oFile]),self.active['path']) except Exception as e: raise Exception([filterMessage({'name':'runCommand','msg':'I can see your file '+oFile+': '+self.active["outrefs"][oFile]+'but cannot copy it'},e,True)]) else: raise Exception([{'name':'runCommand','msg':'I cannot see your output file '+oFile+': '+self.active["outrefs"][oFile]}]) # _____ __________________________________ # ____/ Secondary Class actionGET /_________________________________/ # # actionGET is to do with loading data in memory for future use. # class actionGET(ACTION): availkeys = deepcopy(ACTION.availkeys) availkeys.update({ 'type':'' }) def __init__(self,xmlFile,title='',bypass=True): ACTION.__init__(self,title,bypass) # those you reset self.active['path'] = path.dirname(xmlFile) # those you need to see in the XML file self.active["target"] = None self.active["xref"] = None self.active["type"] = None def addCFG(self,cfgname,cfg): ACTION.addCFG(self,cfgname,cfg) ACTION.updateCFG(self,{ "type": self.active["type"], "target":path.join(self.active['path'],self.active["target"]) }) # _____ __________________________________ # ____/ Secondary Class groupPLOT /_________________________________/ # # groupPLOT is to do with plotting and producing PNG (mainly) # class groupPLOT(GROUPS): availkeys = deepcopy(GROUPS.availkeys) availkeys.update({ 'path':'','safe':'','cfg':'', "size":'[15;10]', "time": '[-1]', "extract": '', "vars": '', 'outFormat': 'png', "target": '', "do": '', "rank":'', "title": '', "deprefs":'', "outrefs":'', "where":'', "type":'', "config": 'distinct' }) groupkeys = deepcopy(GROUPS.groupkeys) groupkeys.update({ "vars":'', "time":'', "extract":'', "config":'' }) avaylkeys = deepcopy(GROUPS.avaylkeys) avaylkeys.update({ "title":'', "target":'', "deco":'' }) def __init__(self,xmlFile,title='',bypass=True): GROUPS.__init__(self,title,bypass) # those you reset self.active['path'] = path.dirname(xmlFile) def addDraw(self,draw,rank=''): GROUPS.addGroup(self,draw) if self.dids[self.active['type']][self.tasks["xref"]]['rank'] == '': self.dids[self.active['type']][self.tasks["xref"]]['rank'] = rank if self.dids[self.active['type']][self.tasks["xref"]]['rank'] == '': self.dids[self.active['type']][self.tasks["xref"]]['rank'] = '953' self.dids[self.active['type']][self.tasks["xref"]]['rank'] = int(self.dids[self.active['type']][self.tasks["xref"]]['rank']) #self.active['deco'] = self.tasks["deco"] def distributeMeta(self,subtask): # ~~> distribute decoration vars = subtask["vars"].split(';') for i in range(len(vars)): if ':' not in vars[i]: vars[i] = vars[i] + ':' + self.tasks["deco"] subtask["vars"] = ';'.join(vars) return subtask def decolooks(self,deco={},index=0,nametask='layers'): # ~~> set default GROUPS.decotasks(self,deco,index,nametask) # ~~> set the look if deco.has_key('look'): for key in deco['look'][0].keys(): self.tasks[nametask][index]['deco'].update({key:deco['look'][0][key]}) # _____ ___________________________________ # ____/ Secondary Class groupGET /__________________________________/ # class groupGET(GROUPS): availkeys = deepcopy(GROUPS.availkeys) availkeys.update({ 'path':'','safe':'','cfg':'', "time": '[-1]', "extract": '', "vars": '', 'outFormat': 'csv', "target": '', "do": '', "rank":'', "title": '', "deprefs":'', "outrefs":'', "where":'', "type":'', "config": 'distinct' }) groupkeys = deepcopy(GROUPS.groupkeys) groupkeys.update({ "vars":'', "time":'', "extract":'', "config":'' }) avaylkeys = deepcopy(GROUPS.avaylkeys) avaylkeys.update({ "title":'', "target":'', "deco":'' }) def __init__(self,xmlFile,title='',bypass=True): GROUPS.__init__(self,title,bypass) # those you reset self.active['path'] = path.dirname(xmlFile) def distributeMeta(self,subtask): # ~~> distribute decoration vars = subtask["vars"].split(';') for i in range(len(vars)): if ':' not in vars[i]: vars[i] = vars[i] + ':xyz' # :xyz is not used subtask["vars"] = ';'.join(vars) return subtask # _____ ___________________________________ # ____/ Secondary Class CRITERIA /__________________________________/ # class CRITERIA(GROUPS): availkeys = deepcopy(GROUPS.availkeys) availkeys.update({ 'path':'','safe':'','cfg':'', "target": '', "do": '', "rank":'', "title": '', "deprefs":'', "outrefs":'', "where":'', "type":'', "config": 'distinct' }) groupkeys = deepcopy(GROUPS.groupkeys) groupkeys.update({ "vars":'', "time":'', "extract":'', "config":'' }) avaylkeys = deepcopy(GROUPS.avaylkeys) #avaylkeys.update({ "title":'', "target":'' }) def __init__(self,xmlFile,title='',bypass=True): GROUPS.__init__(self,title,bypass) # those you reset self.active['path'] = path.dirname(xmlFile) # ~~~~~~~~~~~~~ self.variabling = {}; self.conditionning = {} def addCriteria(self,criteria): try: i = getXMLKeys(criteria,self.active) except Exception as e: raise Exception([filterMessage({'name':'ACTION::addCriteria'},e,self.bypass)]) # only one item here else: self.active = i if self.dids.has_key(self.active["xref"]): raise Exception([{'name':'CRITERIA::addCriteria','msg':'you are getting me confused, this xref already exists: '+self.active["xref"]}]) self.dids.update({ self.active["xref"]:{} }) print '\n +> Validation Criteria :', self.active["xref"] return def addCFG(self,cfgname,cfg): self.active['cfg'] = cfgname self.dids[self.active["xref"]].update( { cfgname: {'variables':{},'condition':{} } } ) def addvariable(self,variable): variabling = {"vars": None, "target":None, "path":''} cfgname = self.active['cfg'] try: self.variabling = getXMLKeys(variable,variabling) except Exception as e: raise Exception([filterMessage({'name':'CRITERIA::addvariable'},e,self.bypass)]) # only one item here self.dids[self.active["xref"]][self.active['cfg']]['variables'].update({self.variabling["vars"]:{}}) active = self.dids[self.active["xref"]][self.active['cfg']]['variables'] folder,file = self.variabling["target"].split(':') pathfolder = path.join(os.getcwd(),folder) pathcfg = path.join(pathfolder,cfgname) pathfile = path.join(pathcfg,file) active[self.variabling["vars"]]['path'] = [pathfile] self.variabling['path'] = [pathfile] return def addcondition(self,condition,NBR): conditionning = {"do": None, "success":None, "failure":None, "warning":'', "result":[]} cfgname = self.active['cfg'] try: self.conditionning = getXMLKeys(condition,conditionning) except Exception as e: raise Exception([filterMessage({'name':'CRITERIA::addcondition'},e,self.bypass)]) # only one item here self.dids[self.active["xref"]][self.active['cfg']]['condition'][NBR] = self.conditionning return self.conditionning def updateCFG(self,d): self.dids[self.active["xref"]][self.active['cfg']].update( d ) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Available Operations for criteria # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def compare(self,condition): variables = self.dids[self.active["xref"]][self.active['cfg']]['variables'] ######### Success condition ################################ NameVar1,operator,NameVar2 = condition["success"].split(':') print ' +> comparing :', NameVar1, '&', NameVar2 if NameVar1.isalpha() == False : var1 = float(NameVar1) else : PathVar1 = variables[NameVar1]['path'][0] var1 = [] #getVariableCSV(PathVar1,NameVar1) if NameVar2.isalpha() == False : var2 = float(NameVar2) else : PathVar2 = variables[NameVar2]['path'][0] var2 = [] #getVariableCSV(PathVar2,NameVar2) if operator == 'LE' : if var1 <= var2 : condition["result"].append('success') elif operator == 'LT' : if var1 < var2 : condition["result"].append('success') elif operator == 'GE' : if var1 >= var2 : condition["result"].append('success') elif operator == 'GT' : if var1 > var2 : condition["result"].append('success') ######### Failure condition ################################ NameVar1,operator,NameVar2 = condition["failure"].split(':') if NameVar1.isalpha() == False : var1 = float(NameVar1) else : PathVar1 = variables[NameVar1]['path'][0] var1 = [] #getVariableCSV(PathVar1,NameVar1) if NameVar2.isalpha() == False : var2 = float(NameVar2) else : PathVar2 = variables[NameVar2]['path'][0] var2 = [] #getVariableCSV(PathVar2,NameVar2) if operator == 'LE' : if var1 <= var2 : condition["result"].append('failed') elif operator == 'LT' : if var1 < var2 : condition["result"].append('failed') elif operator == 'GE' : if var1 >= var2 : condition["result"].append('failed') elif operator == 'GT' : if var1 > var2 : condition["result"].append('failed') ######### Warning condition ################################ if condition["result"] == [] : condition["result"].append('warning') return def CalcL2error(self,task): xref = self.active["xref"]; cfgname = self.active['cfg'] active = self.dids[xref][cfgname] file = self.tasking["target"] print ' +> Calculating L2 error :', self.tasking["title"],'\n' if self.tasking["reference"] != '': file = path.join(self.dids[self.tasking["reference"]][cfgname]['tasks']['safe'],file) var1 = self.tasking["ModelData"].lower() var2 = self.tasking["ExactData"].lower() VarModel,VarExperiment = get2VariablesCSV(file,var1,var2) L2error = (la.norm(VarModel-VarExperiment))/(la.norm(VarExperiment)) columns = [[self.tasking["title"],'None',L2error]] file2 = path.join(self.active['safe'], xref +'.csv') if path.exists(file2): columns = [[self.tasking["title"],'None',L2error]] #addColumnCSV(file2,columns[0]) else : pass #putDataCSV(file2,columns) return \\ === XML Parser Toolbox === \\ def runXML(xmlFile,xmlConfig,bypass): xcpt = [] # try all keys for full report # ~~ Parse xmlFile ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ import xml.etree.ElementTree as XML print '... reading XML test specification file: ' + path.basename(xmlFile) f = open(xmlFile,'r') xmlTree = XML.parse(f) # may need to try first and report error xmlRoot = xmlTree.getroot() f.close() # ~~ Default Ranking ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rank = '' if "rank" in xmlRoot.keys(): rank = xmlRoot.attrib["rank"] # ~~ Meta data process ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # This needs to be developed further # title = "" dc = groupMETA(xmlFile,title,bypass) dc.addGroupType("meta") for metaing in xmlRoot.findall("meta"): # ~~ Step 1. Common check for keys ~~~~~~~~~~~~~~~~~~~~~~~~ try: dc.addGroup(metaing) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add meta object to the list'},e,bypass)) continue # bypass the rest of the for loop # ~~ Step 2. Cumul looks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if len(metaing.findall("look")) > 1: xcpt.append({'name':'runXML','msg':'you can only have one look in meta referenced: '+dc.tasks["xref"]}) if len(metaing.findall("look")) > 0: look = metaing.findall("look")[0] try: dc.addLookTask(look) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add look to the list'},e,bypass)) continue # bypass the rest of the for loop # ~~ Step 2. Cumul metas ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if len(metaing.findall("data")) > 1: xcpt.append({'name':'runXML','msg':'you can only have one data in meta referenced: '+dc.tasks["xref"]}) if len(metaing.findall("data")) > 0: data = metaing.findall("data")[0] try: dc.addDataTask(data) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add meta to the list'},e,bypass)) continue # bypass the rest of the for loop dc.update(dc.tasks) if xcpt != []: raise Exception({'name':'runXML','msg':'looking at meta in xmlFile: '+xmlFile,'tree':xcpt}) display = False # ~~ Main action process ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Whether an action is carried out or not, it is known through: # xmlConfig[cfgname]['options'].todos['act']['todo'] # PRINCAS(ACTION) will still be loaded to register various files # for possible subsequent extraction, plotting or analysis # TODO: limit the number of path / safe duplication # do = actionRUN(xmlFile,title,bypass) for action in xmlRoot.findall("action"): # ~~ Step 1. Common check for keys and driving file ~~~~~~~~~~ try: targetFile = do.addAction(action,rank) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add todo to the list'},e,bypass)) continue # bypass rest of the loop else: if not path.isfile(path.join(do.active['path'],targetFile)): xcpt.append({'name':'runXML','msg':'could not find your target file'+targetFile}) continue # bypass rest of the loop # ~~ Step 2. Loop over configurations ~~~~~~~~~~~~~~~~~~~~~~~~ for cfgname in xmlConfig.keys(): cfg = xmlConfig[cfgname]['cfg'] do.addCFG(cfgname,cfg) #if not : continue # ~~> Temper with rank but still gather intelligence dodo = True rankdo = do.active['rank'] print '>>',rankdo rankdont = xmlConfig[cfgname]['options'].todos['act']['rank'] if rankdont != rankdo*int( rankdont / rankdo ): dodo = False do.updateCFG({'dodo':dodo}) # ~~> Create the safe createDirectories(do.active['safe']) # ~~ Step 3a. Deals with TELEMAC launchers ~~~~~~~~~~~~~~~~ if do.active["code"] in cfg['MODULES'].keys(): do.availacts = "translate;run;compile;princi" # ~~> Manage targetFile and other inputs casFile = path.join(do.active['path'],targetFile) # ~~> Parse DICO File and its IO Files default (only once) dicoFile = getDICO(cfg,do.active["code"]) do.updateCFG({'dico':dicoFile}) dico = DICOS[dicoFile]['dico'] frgb = DICOS[dicoFile]['frgb'] cas = readCAS(scanCAS(casFile),dico,frgb) if do.active["ncsize"] != '': cas = setKeyValue('PROCESSEURS PARALLELES',cas,frgb,int(do.active["ncsize"])) do.updateCFG({'cas':cas}) if not checkConsistency(cas,dico,frgb,cfg): continue idico = DICOS[dicoFile]['input'] odico = DICOS[dicoFile]['output'] # ~~> Define config-split storage sortieFiles,iFS,oFS = setSafe(casFile,cas,idico,odico,do.active['safe']) # TODO: look at relative paths if sortieFiles != []: do.updateCFG({ 'sortie': sortieFiles }) do.updateCFG({ 'input':iFS }) do.updateCFG({ 'output':oFS }) # ~~> Case of coupling cplages,defaut = getKeyWord('COUPLING WITH',cas,dico,frgb) links = {} for cplage in cplages: for mod in cfg['MODULES'].keys(): if mod in cplage.lower(): # ~~> Extract the CAS File name casFilePlage,defaut = getKeyWord(mod.upper()+' STEERING FILE',cas,dico,frgb) if casFilePlage == []: casFilePlage = defaut[0] else: casFilePlage = eval(casFilePlage[0]) casFilePlage = path.join(path.dirname(casFile),casFilePlage) if not path.isfile(casFilePlage): raise Exception([{'name':'runCAS','msg':'missing coupling CAS file for '+mod+': '+casFilePlage}]) # ~~> Read the DICO File dicoFilePlage = getDICO(cfg,mod) dicoPlage = DICOS[dicoFilePlage]['dico'] frgbPlage = DICOS[dicoFilePlage]['frgb'] # ~~> Read the coupled CAS File casPlage = readCAS(scanCAS(casFilePlage),dicoPlage,frgbPlage) # ~~> Fill-in the safe idicoPlage = DICOS[dicoFilePlage]['input'] odicoPlage = DICOS[dicoFilePlage]['output'] sortiePlage,iFSPlage,oFSPlage = setSafe(casFilePlage,casPlage,idicoPlage,odicoPlage,do.active['safe']) # TODO: look at relative paths links.update({mod:{}}) links[mod].update({ 'code':mod, 'target':path.basename(casFilePlage), 'cas':casPlage, 'frgb':frgbPlage, 'dico':dicoFilePlage, 'iFS':iFSPlage, 'oFS':oFSPlage, 'sortie':sortiePlage }) if sortiePlage != []: links[mod].update({ 'sortie':sortiePlage }) if links != {}: do.updateCFG({ "links":links }) # ~~> Complete all actions # options.todos['act']['todo'] takes: translate;run;compile and none doable = xmlConfig[cfgname]['options'].todos['act']['todo'] if doable == '': doable = do.active["do"] if doable == '' or doable == 'all': doable = do.availacts display = display or xmlConfig[cfgname]['options'].display # ~~> Action type A. Translate the CAS file if "translate" in doable.split(';') and dodo: try: # - exchange keywords between dictionaries do.translateCAS(cfg['REBUILD']) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':' +> translate'},e,bypass)) # ~~> Action type B. Analysis of the CAS file # TODO: # - comparison with DEFAULT values of the DICTIONARY #if "cas" in doable.split(';') and dodo: # - comparison of dictionnaries betwen configurations #if "dico" in doable.split(';') and dodo: # ~~> Action type C. Analysis of the PRINCI file if "princi" in doable.split(';') and dodo: #try: # - comparison with standard source files specs = Values() setattr(specs,'unified',False) setattr(specs,'ndiff',False) setattr(specs,'html',True) setattr(specs,'ablines',3) setattr(specs,'context',False) do.diffPRINCI(specs,cfg,cfg['REBUILD']) #except Exception as e: # xcpt.append(filterMessage({'name':'runXML','msg':' +> diff(princi)'},e,bypass)) # TODO: - comparison of subroutines between action items # ~~> Action type E. Running CAS files if "run" in doable.split(';') and dodo: try: do.runCAS(xmlConfig[cfgname]['options'],cfg,cfg['REBUILD']) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':' +> run'},e,bypass)) # ~~ Step 3b. Deals with execute launchers ~~~~~~~~~~~~~~~~ elif do.active["code"] == 'exec': do.availacts = "exec" # ~~> Complete all actions # options.todos['act']['todo'] takes: exec and none doable = xmlConfig[cfgname]['options'].todos['act']['todo'] if doable == '': doable = do.active["code"] if doable == '' or doable == 'all': doable = do.availacts # ~~> Action type E. Running exec if "exec" in doable.split(';') and dodo: try: # - simply run the exec as stated do.runCommand(cfg['REBUILD']) except Exception as e: xcpt.append(filterMessage({'name':'runXML::runCommand','msg':' +> '+do.active["do"]},e,bypass)) if xcpt != []: raise Exception({'name':'runXML','msg':'looking at actions in xmlFile: '+xmlFile,'tree':xcpt}) # ~~ Load targets ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # gt = actionGET(xmlFile,title,bypass) for load in xmlRoot.findall("load"): # ~~ Step 1. Common check for keys and driving file ~~~~~~~~~~ try: targetFile = gt.addAction(load,rank) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add load to the list'},e,bypass)) continue # bypass rest of the loop else: if not path.isfile(path.join(gt.active['path'],targetFile)): xcpt.append({'name':'runXML','msg':'could not find your target file'+targetFile}) continue # bypass rest of the loop # ~~ Step 2. Loop over configurations ~~~~~~~~~~~~~~~~~~~~~~~~ for cfgname in xmlConfig.keys(): cfg = xmlConfig[cfgname]['cfg'] gt.addCFG(cfgname,cfg) if xcpt != []: raise Exception({'name':'runXML','msg':'looking at loads in xmlFile: '+xmlFile,'tree':xcpt}) # ~~ Extraction targets ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # did has all the IO references and the latest sortie files ex = groupGET(xmlFile,title,bypass) for typeSave in ["save1d","save2d","save3d"]: ex.addGroupType(typeSave) for extracting in xmlRoot.findall(typeSave): # ~~ Step 1. Common check for keys ~~~~~~~~~~~~~~~~~~~~~~~~ try: ex.addGroup(extracting) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add extract object to the list'},e,bypass)) continue # bypass the rest of the for loop # ~~> Temper with rank but still gather intelligence doex = True rankdo = ex.dids[typeSave][ex.active['xref']]['rank'] rankdont = xmlConfig[cfgname]['options'].todos['get']['rank'] if rankdont != rankdo*int( rankdont / rankdo ): doex = False if not doex: continue # ~~ Step 2. Cumul layers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for layer in extracting.findall("layer"): try: index,namex = ex.addSubTask(layer) target = ex.tasks[namex][index]["target"] except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add layer to the list'},e,bypass)) continue # bypass the rest of the for loop # ~~> round up targets and their configurations looking in exes and does xref,src = target.split(':') if gt.dids.has_key(xref): try: findlayer = findTargets(gt.dids[xref],src) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'could not find reference to extract within loads: '+xref},e)) ex.targetSubTask({},index,namex) continue # bypass the rest of the for loop else : ex.targetSubTask(findlayer,index,namex) elif do.dids.has_key(xref): try: findlayer = findTargets(do.dids[xref],src) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'could not find reference to extract within actions: '+xref},e)) ex.targetSubTask({},index,namex) continue # bypass the rest of the for loop else: ex.targetSubTask(findlayer,index,namex) else : xcpt.append({'name':'runXML','msg':'could not find reference to extract the action: '+xref}) ex.update(ex.tasks) if xcpt != []: raise Exception({'name':'runXML','msg':'looking at extractions in xmlFile: '+xmlFile,'tree':xcpt}) # ~~ Matrix distribution by extraction types ~~~~~~~~~~~~~~~~~~~~ for typeSave in ex.dids.keys(): for xref in ex.dids[typeSave]: task = ex.dids[typeSave][xref] if not task.has_key("layers"): continue print ' +> reference: ',xref,' of type ',typeSave xlayers = '' # now done with strings as arrays proved to be too challenging for layer in task["layers"]: if layer['config'] == 'together': xys = [] for x in xlayers.split('|'): xys.append( (x+';'+':'.join( layer['fileName'].keys() )).strip(';') ) xlayers = '|'.join(xys) elif layer['config'] == 'distinct': ylayers = layer['fileName'].keys() xys = [] for i in range(len(ylayers)): for x in xlayers.split('|'): xys.append( (x+';'+ylayers[i]).strip(';') ) xlayers = '|'.join(xys) elif layer['config'] == 'oneofall': xys = []; cfg = layer['fileName'].keys()[0] #/!\ you are sure to have at least one (?) for x in xlayers.split('|'): xys.append( (x+';'+cfg).strip(';') ) xlayers = '|'.join(xys) else: if layer['config'] in layer['fileName'].keys(): xys = [] for x in xlayers.split('|'): xys.append( (x+';'+layer['config']).strip(';') ) xlayers = '|'.join(xys) nbFile = 0; alayers = xlayers.split('|') for cfglist in alayers: # ~~> Figure name if len(alayers) == 1: extractName = '.'.join([xref.replace(' ','_'),task['outFormat']]) else: nbFile += 1 extractName = '.'.join([xref.replace(' ','_'),str(nbFile),task['outFormat']]) print ' ~> saved as: ',extractName extractName = path.join(path.dirname(xmlFile),extractName) # ~~> Create Figure if typeSave == "save1d": figure = Figure1D(typeSave,task,extractName) if typeSave == "save2d": figure = Figure2D(typeSave,task,extractName) for layer,cfgs in zip(task["layers"],cfglist.split(';')): for cfg in cfgs.split(':'): for file in layer['fileName'][cfg][0]: figure.draw( layer['fileName'][cfg][2], { 'file': file, 'deco': {}, 'vars': layer["vars"], 'extract':parseArrayPaires(layer["extract"]), 'type': task['type'], 'time':parseArrayPaires(layer["time"])[0] } ) figure.dump() if xcpt != []: raise Exception({'name':'runXML','msg':'looking at savings in xmlFile: '+xmlFile,'tree':xcpt}) """ if "L2error" in doaddtask["do"]: os.chdir(racine) try: ex.CalcL2error(doaddtask) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':' +> CalcL2error'},e,bypass))""" # ~~ Gathering targets ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ plot = groupPLOT(xmlFile,title,bypass) for typePlot in ["plot1d","plot2d","plot3d","plotpv"]: plot.addGroupType(typePlot) for ploting in xmlRoot.findall(typePlot): # ~~ Step 1. Common check for keys ~~~~~~~~~~~~~~~~~~~~~~~~ try: plot.addDraw(ploting,rank) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add plot to the list'},e,bypass)) continue # bypass the rest of the for loop # ~~> Temper with rank but still gather intelligence doplt = True rankdo = plot.dids[typePlot][plot.active['xref']]['rank'] rankdont = xmlConfig[cfgname]['options'].todos['draw']['rank'] if rankdont != rankdo*int( rankdont / rankdo ): doplt = False if not doplt: continue # ~~ Step 2. Cumul layers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for layer in ploting.findall("layer"): try: index,namex = plot.addSubTask(layer) target = plot.tasks[namex][index]["target"] except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add layer to the list'},e,bypass)) continue # bypass the rest of the for loop # ~~> round up targets and their configurations looking in exes and does xref,src = target.split(':') if gt.dids.has_key(xref): try: findlayer = findTargets(gt.dids[xref],src) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'could not find reference to draw the load: '+xref},e)) plot.targetSubTask({}) continue # bypass the rest of the for loop else : plot.targetSubTask(findlayer) elif ex.dids.has_key(xref): try: findlayer = findTargets(ex.dids[xref],src) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'could not find reference to draw the extract: '+xref},e)) plot.targetSubTask({}) continue # bypass the rest of the for loop else : plot.targetSubTask(findlayer) elif do.dids.has_key(xref): try: findlayer = findTargets(do.dids[xref],src) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'could not find reference to draw the action: '+xref},e)) plot.targetSubTask({}) continue # bypass the rest of the for loop else: plot.targetSubTask(findlayer) else : xcpt.append({'name':'runXML','msg':'could not find reference to draw the action: '+xref}) # ~~> round up decos if dc.dids['meta'].has_key(plot.tasks[namex][index]['deco']): plot.decolooks(dc.dids['meta'][plot.tasks[namex][index]['deco']],index,namex) else: plot.decolooks({},index,namex) plot.update(plot.tasks) if xcpt != []: raise Exception({'name':'runXML','msg':'looking at targets in xmlFile: '+xmlFile,'tree':xcpt}) # ~~ Matrix distribution by plot types ~~~~~~~~~~~~~~~~~~~~~~~~~~ # /!\ configurations cannot be called "together" or "distinct" or "oneofall" for typePlot in plot.dids.keys(): for xref in plot.dids[typePlot]: draw = plot.dids[typePlot][xref] if not draw.has_key("layers"): continue print ' +> reference: ',xref,' of type ',typePlot xlayers = '' # now done with strings as arrays proved to be too challenging for layer in draw["layers"]: if layer['config'] == 'together': xys = [] for x in xlayers.split('|'): xys.append( (x+';'+':'.join( layer['fileName'].keys() )).strip(';') ) xlayers = '|'.join(xys) elif layer['config'] == 'distinct': ylayers = layer['fileName'].keys() xys = [] for i in range(len(ylayers)): for x in xlayers.split('|'): xys.append( (x+';'+ylayers[i]).strip(';') ) xlayers = '|'.join(xys) elif layer['config'] == 'oneofall': xys = []; cfg = layer['fileName'].keys()[0] #/!\ you are sure to have at least one (?) for x in xlayers.split('|'): xys.append( (x+';'+cfg).strip(';') ) xlayers = '|'.join(xys) else: if layer['config'] in layer['fileName'].keys(): xys = [] for x in xlayers.split('|'): xys.append( (x+';'+layer['config']).strip(';') ) xlayers = '|'.join(xys) if xlayers == '': xcpt.append(filterMessage({'name':'runXML','msg':'could not find reference to draw the action: '+xref},e)) continue nbFile = 0; alayers = xlayers.split('|') for cfglist in alayers: # ~~> Figure name if len(alayers) == 1: figureName = '.'.join([xref.replace(' ','_'),draw['outFormat']]) else: nbFile += 1 figureName = '.'.join([xref.replace(' ','_'),str(nbFile),draw['outFormat']]) print ' ~> saved as: ',figureName figureName = path.join(path.dirname(xmlFile),figureName) # ~~> Figure size draw["size"] = parseArrayPaires(draw["size"]) # ~~> Create Figure if typePlot == "plot1d": figure = Figure1D(typePlot,draw,figureName,display) if typePlot == "plot2d": figure = Figure2D(typePlot,draw,figureName,display) # ~~> User Deco taken from 'look' if layer['deco'].has_key('look'): for key in layer['deco']['look'][0]: layer['deco'].update({key:layer['deco']['look'][0][key]}) for layer,cfgs in zip(draw["layers"],cfglist.split(';')): for cfg in cfgs.split(':'): for file in layer['fileName'][cfg][0]: figure.draw( layer['fileName'][cfg][2], { 'file': file, 'deco': layer["deco"], 'vars': layer["vars"], 'extract':parseArrayPaires(layer["extract"]), 'type': draw['type'], 'time':parseArrayPaires(layer["time"])[0] } ) figure.show() if xcpt != []: raise Exception({'name':'runXML','msg':'looking at plotting in xmlFile: '+xmlFile,'tree':xcpt}) # ~~ Validation Criteria ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # racine = path.split(xmlFile)[0] os.chdir(racine) docriteria = CRITERIA(xmlFile,title,bypass) for criteria in xmlRoot.findall("criteria"): # ~~ Step 1. Common check for keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~ try: doadd = docriteria.addCriteria(criteria) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add todo to the list'},e,bypass)) continue # ~~> Temper with rank but still gather intelligence docrt = True rankdo = docriteria.dids['?'][docriteria.active['xref']]['rank'] rankdont = xmlConfig[cfgname]['options'].todos['test']['rank'] if rankdont != rankdo*int( rankdont / rankdo ): docrt = False if not docrt: continue for cfgname in xmlConfig.keys(): criteriacfg = xmlConfig[cfgname]['cfg'] docriteria.addCFG(cfgname,criteriacfg) #if not : continue for vars in criteria.findall("variable"): try: doaddvariable = docriteria.addvariable(vars) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add todo to the list'},e,bypass)) continue conditionNBR = 1 for condition in criteria.findall("condition"): try: doaddcondition = docriteria.addcondition(condition,conditionNBR) conditionNBR += 1 except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':'add todo to the list'},e,bypass)) continue if "compare" in doaddcondition["do"]: try: docriteria.compare(doaddcondition) except Exception as e: xcpt.append(filterMessage({'name':'runXML','msg':' +> compare'},e,bypass)) for criteria in docriteria.dids.keys() : for cfg in docriteria.dids[criteria]: for NBR in docriteria.dids[criteria][cfg]['condition']: if docriteria.dids[criteria][cfg]['condition'][NBR]['result'][0] == 'success' : continue else : if docriteria.dids[criteria][cfg]['condition'][NBR]['result'][0] == 'warning' : print '\n!!!!! Warning about the follwing condition %s !!!!!!!!\n' % docriteria.dids[criteria][cfg]['condition'][NBR]['success'] else : #raise Exception([{'name':'CRITERIA','msg':'the following criteria failed: '+criteria}]) raise Exception([{'name':'CRITERIA','msg':'the following condition failed: '+docriteria.dids[criteria][cfg]['condition'][NBR]['success']}]) # ~~ Error management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if xcpt != []: # raise full report raise Exception({'name':'runXML','msg':'in xmlFile: '+xmlFile,'tree':xcpt}) return