<Group name="b">b1, b2, b3</Group> <Group name="c">c1, c2, c3</Group> <Group name="d">a1, b1</Group> <Group name="e">e1, e2 ,e3</Group> <Group name="f">f1, f2, f3</Group> <Group name="ce">c, e</Group> <Group name="ab">a,b</Group> <Group name="abd">a,b,d</Group> <Group name="plus">a,c</Group> <Group name="minus">a,-d</Group> <Group name="intersect">a,^d</Group> <Group name="symmdiff">a,%d</Group> <Group name="symmrev">d,%a</Group> </VariableGroups>""" node = ET.fromstring(example) groups = xmlUtils.readVariableGroups(node, mh, None) # test contents def testVarGroup(groups, g, right): got = groups[g].getVarsString() if got == right: results['pass'] += 1 else: print( 'ERROR: Vargroups group "{}" should be "{}" but got "{}"!'.format( g, right, got)) results['fail'] += 1 # note that order matters for these solutions!
def XMLread(self,xmlNode,runInfoSkip = set(),xmlFilename=None): """ parses the xml input file, instances the classes need to represent all objects in the simulation @ In, xmlNode, ElementTree.Element, xml node to read in @ In, runInfoSkip, set, optional, nodes to skip @ In, xmlFilename, string, optional, xml filename for relative directory @ Out, None """ #TODO update syntax to note that we read InputTrees not XmlTrees unknownAttribs = utils.checkIfUnknowElementsinList(['printTimeStamps','verbosity','color','profile'],list(xmlNode.attrib.keys())) if len(unknownAttribs) > 0: errorMsg = 'The following attributes are unknown:' for element in unknownAttribs: errorMsg += ' ' + element self.raiseAnError(IOError,errorMsg) self.verbosity = xmlNode.attrib.get('verbosity','all').lower() if 'printTimeStamps' in xmlNode.attrib.keys(): self.raiseADebug('Setting "printTimeStamps" to',xmlNode.attrib['printTimeStamps']) self.messageHandler.setTimePrint(xmlNode.attrib['printTimeStamps']) if 'color' in xmlNode.attrib.keys(): self.raiseADebug('Setting color output mode to',xmlNode.attrib['color']) self.messageHandler.setColor(xmlNode.attrib['color']) if 'profile' in xmlNode.attrib.keys(): thingsToProfile = list(p.strip().lower() for p in xmlNode.attrib['profile'].split(',')) if 'jobs' in thingsToProfile: self.jobHandler.setProfileJobs(True) self.messageHandler.verbosity = self.verbosity runInfoNode = xmlNode.find('RunInfo') if runInfoNode is None: self.raiseAnError(IOError,'The RunInfo node is missing!') self.__readRunInfo(runInfoNode,runInfoSkip,xmlFilename) ### expand variable groups before continuing ### ## build variable groups ## varGroupNode = xmlNode.find('VariableGroups') # init, read XML for variable groups if varGroupNode is not None: varGroups = xmlUtils.readVariableGroups(varGroupNode,self.messageHandler,self) else: varGroups={} # read other nodes for child in xmlNode: if child.tag=='VariableGroups': continue #we did these before the for loop if child.tag in list(self.whichDict.keys()): self.raiseADebug('-'*2+' Reading the block: {0:15}'.format(str(child.tag))+2*'-') Class = child.tag if len(child.attrib.keys()) == 0: globalAttributes = {} else: globalAttributes = child.attrib #if 'verbosity' in globalAttributes.keys(): self.verbosity = globalAttributes['verbosity'] if Class not in ['RunInfo','OutStreams'] and "returnInputParameter" in self.addWhatDict[Class].__dict__: paramInput = self.addWhatDict[Class].returnInputParameter() paramInput.parseNode(child) for childChild in paramInput.subparts: childName = childChild.getName() if "name" not in childChild.parameterValues: self.raiseAnError(IOError,'not found name attribute for '+childName +' in '+Class) name = childChild.parameterValues["name"] if "needsRunInfo" in self.addWhatDict[Class].__dict__: self.whichDict[Class][name] = self.addWhatDict[Class].returnInstance(childName,self.runInfoDict,self) else: self.whichDict[Class][name] = self.addWhatDict[Class].returnInstance(childName,self) self.whichDict[Class][name].handleInput(childChild, self.messageHandler, varGroups, globalAttributes=globalAttributes) elif Class != 'RunInfo': for childChild in child: subType = childChild.tag if 'name' in childChild.attrib.keys(): name = childChild.attrib['name'] self.raiseADebug('Reading type '+str(childChild.tag)+' with name '+name) #place the instance in the proper dictionary (self.whichDict[Type]) under his name as key, #the type is the general class (sampler, data, etc) while childChild.tag is the sub type #if name not in self.whichDict[Class].keys(): self.whichDict[Class][name] = self.addWhatDict[Class].returnInstance(childChild.tag,self) if Class != 'OutStreams': if name not in self.whichDict[Class].keys(): if "needsRunInfo" in self.addWhatDict[Class].__dict__: self.whichDict[Class][name] = self.addWhatDict[Class].returnInstance(childChild.tag,self.runInfoDict,self) else: self.whichDict[Class][name] = self.addWhatDict[Class].returnInstance(childChild.tag,self) else: self.raiseAnError(IOError,'Redundant naming in the input for class '+Class+' and name '+name) else: if name not in self.whichDict[Class][subType].keys(): self.whichDict[Class][subType][name] = self.addWhatDict[Class][subType].returnInstance(childChild.tag,self) else: self.raiseAnError(IOError,'Redundant naming in the input for class '+Class+' and sub Type'+subType+' and name '+name) #now we can read the info for this object #if globalAttributes and 'verbosity' in globalAttributes.keys(): localVerbosity = globalAttributes['verbosity'] #else : localVerbosity = self.verbosity if Class != 'OutStreams': self.whichDict[Class][name].readXML(childChild, self.messageHandler, varGroups, globalAttributes=globalAttributes) else: self.whichDict[Class][subType][name].readXML(childChild, self.messageHandler, globalAttributes=globalAttributes) else: self.raiseAnError(IOError,'not found name attribute for one '+Class) else: #tag not in whichDict, check if it's a documentation tag if child.tag not in ['TestInfo']: self.raiseAnError(IOError,'<'+child.tag+'> is not among the known simulation components '+repr(child)) # If requested, duplicate input # ###NOTE: All substitutions to the XML input tree should be done BEFORE this point!! if self.runInfoDict.get('printInput',False): fileName = os.path.join(self.runInfoDict['WorkingDir'],self.runInfoDict['printInput']) self.raiseAMessage('Writing duplicate input file:',fileName) outFile = open(fileName,'w') outFile.writelines(utils.toString(TreeStructure.tostring(xmlNode))+'\n') #\n for no-end-of-line issue outFile.close() if not set(self.stepSequenceList).issubset(set(self.stepsDict.keys())): self.raiseAnError(IOError,'The step list: '+str(self.stepSequenceList)+' contains steps that have not been declared: '+str(list(self.stepsDict.keys())))
def __init__(self, inputFile): """ Constructor @ In, inputFile, string, input file name @ Out, None """ self.printTag = 'RAVEN_PARSER' # print tag self.inputFile = inputFile # input file name self.outStreamsNames = {} # {'outStreamName':[DataObjectName,DataObjectType]} self.varGroups = {} # variable groups, names and values if not os.path.exists(inputFile): raise IOError(self.printTag+' ERROR: Not found RAVEN input file') try: tree = ET.parse(open(inputFile,'r')) except IOError as e: raise IOError(self.printTag+' ERROR: Input Parsing error!\n' +str(e)+'\n') self.tree = tree.getroot() # expand the ExteranlXML nodes cwd = os.path.dirname(inputFile) xmlUtils.expandExternalXML(self.tree,cwd) # get the NAMES of the variable groups variableGroupNode = self.tree.find('VariableGroups') if variableGroupNode is not None: # make a messageHandler and messageUsesr to handle variable group creation ## if made generally available to this parser, this can be relocated and used generally messageHandler = MessageHandler.MessageHandler() messageHandler.initialize({'verbosity':'quiet'}) messageUser = MessageHandler.MessageUser() self.varGroups = xmlUtils.readVariableGroups(variableGroupNode,messageHandler,messageUser) # do some sanity checks sequence = [step.strip() for step in self.tree.find('.//RunInfo/Sequence').text.split(",")] # firstly no multiple sublevels of RAVEN can be handled now for code in self.tree.findall('.//Models/Code'): if 'subType' not in code.attrib: raise IOError(self.printTag+' ERROR: Not found subType attribute in <Code> XML blocks!') if code.attrib['subType'].strip() == 'RAVEN': raise IOError(self.printTag+' ERROR: Only one level of RAVEN runs are allowed (Not a chain of RAVEN runs). Found a <Code> of subType RAVEN!') # find steps and check if there are active outstreams (Print) foundOutStreams = False for step in self.tree.find('.//Steps'): if step.attrib['name'] in sequence: for role in step: if role.tag.strip() == 'Output': mainClass, subType = role.attrib['class'].strip(), role.attrib['type'].strip() if mainClass == 'OutStreams' and subType == 'Print': outStream = self.tree.find('.//OutStreams/Print[@name="'+role.text.strip()+ '"]'+'/source') if outStream is None: raise IOError(self.printTag+' ERROR: The OutStream of type "Print" named "'+role.text.strip()+'" has not been found!') dataObjectType = None linkedDataObjectPointSet = self.tree.find('.//DataObjects/PointSet[@name="'+outStream.text.strip()+ '"]') if linkedDataObjectPointSet is None: linkedDataObjectHistorySet = self.tree.find('.//DataObjects/HistorySet[@name="'+outStream.text.strip()+ '"]') if linkedDataObjectHistorySet is None: # try dataset linkedDataObjectHistorySet = self.tree.find('.//DataObjects/DataSet[@name="'+outStream.text.strip()+ '"]') if linkedDataObjectHistorySet is None: raise IOError(self.printTag+' ERROR: The OutStream of type "Print" named "'+role.text.strip()+'" is linked to not existing DataObject!') dataObjectType, xmlNode = "HistorySet", linkedDataObjectHistorySet else: dataObjectType, xmlNode = "PointSet", linkedDataObjectPointSet self.outStreamsNames[role.text.strip()] = [outStream.text.strip(),dataObjectType,xmlNode] foundOutStreams = True if not foundOutStreams: raise IOError(self.printTag+' ERROR: at least one <OutStreams> of type "Print" needs to be inputted in the active Steps!!') # Now we grep the paths of all the inputs the SLAVE RAVEN contains in the workind directory. self.workingDir = self.tree.find('.//RunInfo/WorkingDir').text.strip() # Find the Files self.slaveInputFiles = self.findSlaveFiles(self.tree, self.workingDir)