def __genBasePointSampler(self,**Kwargs): """ Figure out which distributions need to be handled by the grid or Stratified samplers by modifying distributions in the .i file. Let the regular moose point sampler take care of the rest. Returns (distributions,listDict) where listDict is the start of the listDict that tells how to modify the input, and distributions is a dictionary with keys that are the 'variable name' and values of [computedValue,distribution name in .i file] Note that the key has "<distribution>" in front of the variable name. The actual variable can be gotten from the full key by: key[len('<distribution>'):] TODO This should check that the distributions in the .i file (if they exist) are consistent with the ones in the .xml file. TODO For variables, it should add them to the .csv file. @ In, **Kwargs, dict, kwared dictionary containing the values of the parameters to be changed @ Out, returnTuple, tuple, returnTuple[0] distributions dictionaries returnTuple[0] modified dictionary """ distributionKeys = [key for key in Kwargs["SampledVars"] if key.startswith("<distribution>")] distributions = {} for key in distributionKeys: distributionName = Kwargs['distributionName'][key] distributionType = Kwargs['distributionType'][key] crowDistribution = json.loads(Kwargs['crowDist'][key]) distributions[key] = [Kwargs["SampledVars"].pop(key),distributionName, distributionType,crowDistribution] mooseInterface = utils.importFromPath(os.path.join(os.path.join(uppath(os.path.dirname(__file__),1),'MooseBasedApp'),'MooseBasedAppInterface.py'),False) mooseApp = mooseInterface.MooseBasedApp() returnTuple = distributions, mooseApp.pointSamplerForMooseBasedApp(**Kwargs) return returnTuple
def localInputAndChecks(self, xmlNode): """ Function to read the portion of the xml input that belongs to this specialized class and initialize some stuff based on the inputs got @ In, xmlNode, xml.etree.ElementTree.Element, Xml element node @ Out, None """ #Model._readMoreXML(self, xmlNode) paramInput = ExternalModel.getInputSpecification()() paramInput.parseNode(xmlNode) if 'ModuleToLoad' in paramInput.parameterValues: self.ModuleToLoad = paramInput.parameterValues['ModuleToLoad'] moduleToLoadString, self.ModuleToLoad = utils.identifyIfExternalModelExists( self, self.ModuleToLoad, self.workingDir) # load the external module and point it to self.sim self.sim = utils.importFromPath( moduleToLoadString, self.messageHandler.getDesiredVerbosity(self) > 1) elif len(paramInput.parameterValues['subType'].strip()) > 0: # it is a plugin. Look for the type in the plugins class list if paramInput.parameterValues[ 'subType'] not in ExternalModel.plugins.knownTypes(): self.raiseAnError( IOError, 'The "subType" named "' + paramInput.parameterValues['subType'] + '" does not belong to any ExternalModel plugin available. ' + 'Available plugins are "' + ','.join(ExternalModel.plugins.knownTypes())) self.sim = ExternalModel.plugins.returnPlugin( "ExternalModel", paramInput.parameterValues['subType'], self) else: self.raiseAnError( IOError, '"ModuleToLoad" attribute or "subType" not provided for Model "ExternalModel" named "' + self.name + '"!') # check if there are variables and, in case, load them for child in paramInput.subparts: if child.getName() == 'variable': self.raiseAnError( IOError, '"variable" node included but has been depreciated! Please list variables in a "variables" node instead. Remove this message by Dec 2016.' ) elif child.getName() == 'variables': if len(child.parameterValues) > 0: self.raiseAnError( IOError, 'the block ' + child.getName() + ' named ' + child.value + ' should not have attributes!!!!!') for var in child.value.split(','): var = var.strip() self.modelVariableType[var] = None # adjust model-aware variables based on aliases self._replaceVariablesNamesWithAliasSystem(self.modelVariableType, 'inout') self.listOfRavenAwareVars.extend(self.modelVariableType.keys()) # check if there are other information that the external module wants to load #TODO this needs to be converted to work with paramInput if '_readMoreXML' in dir(self.sim): self.sim._readMoreXML(self.initExtSelf, xmlNode)
def _readMoreXML(self,xmlNode): """ Function to read the portion of the xml input that belongs to this specialized class and initialize some members based on inputs. This can be overloaded in specialize code interface in order to read specific flags. In this case, this is used for locating an external python module where the variables can be modified and the "vector" variables can be splitted in multiple single variables @ In, xmlNode, xml.etree.ElementTree.Element, Xml element node @ Out, None. """ if os.path.basename(xmlNode.find("executable").text) != 'raven_framework': raise IOError(self.printTag+' ERROR: executable must be "raven_framework" (in whatever location)!') linkedDataObjects = xmlNode.find("outputExportOutStreams") if linkedDataObjects is None: raise IOError(self.printTag+' ERROR: outputExportOutStreams node not present. You must input at least one OutStream (max 2)!') self.linkedDataObjectOutStreamsNames = linkedDataObjects.text.split(",") if len(self.linkedDataObjectOutStreamsNames) > 2: raise IOError(self.printTag+' ERROR: outputExportOutStreams node. The maximum number of linked OutStreams are 2 (1 for PointSet and 1 for HistorySet)!') self.conversionDict = {} # {modulePath : {'variables': [], 'noScalar': 0, 'scalar': 0}, etc } child = xmlNode.find("conversion") if child is not None: for moduleNode in child: # get the module to be used for conversion source = moduleNode.attrib.get('source',None) if source is None: raise IOError(self.printTag+' ERROR: no module "source" listed in "conversion" subnode attributes!') # fix up the path source = os.path.expanduser(source) if not os.path.isabs(source): source = os.path.abspath(source) # check for existence if not os.path.exists(source): raise IOError(self.printTag+' ERROR: the conversionModule "{}" was not found!' .format(self.extModForVarsManipulationPath)) # check module is imported checkImport = utils.importFromPath(source) if checkImport is None: raise IOError(self.printTag+' ERROR: the conversionModule "{}" failed on import!' .format(self.extModForVarsManipulationPath)) # check methods are in place noScalar = 'convertNotScalarSampledVariables' in checkImport.__dict__ scalar = 'manipulateScalarSampledVariables' in checkImport.__dict__ if not (noScalar or scalar): raise IOError(self.printTag +' ERROR: the conversionModule "'+source +'" does not contain any of the usable methods! Expected at least ' +'one of: "manipulateScalarSampledVariables" and/or "manipulateScalarSampledVariables"!') # acquire the variables to be modified varNode = moduleNode.find('variables') if varNode is None: raise IOError(self.printTag+' ERROR: no node "variables" listed in "conversion|module" subnode!') variables = [x.strip() for x in varNode.text.split(',')] self.conversionDict[source] = {'variables':variables, 'noScalar':noScalar, 'scalar':scalar}
def _readMoreXML(self,xmlNode): """ Function to read the portion of the xml input that belongs to this specialized class and initialize some variables based on the inputs received. @ In, xmlNode, xml.etree.ElementTree.Element, XML element node that represents the portion of the input that belongs to this class @ Out, None """ if 'file' in xmlNode.attrib.keys(): self.functionFile = xmlNode.attrib['file'] # get the module to load and the filename without path moduleToLoadString, self.functionFile = utils.identifyIfExternalModelExists(self, self.functionFile, self.workingDir) # import the external function importedModule = utils.importFromPath(moduleToLoadString,self.messageHandler.getDesiredVerbosity(self)>1) if not importedModule: self.raiseAnError(IOError,'Failed to import the module '+moduleToLoadString+' supposed to contain the function: '+self.name) #here the methods in the imported file are brought inside the class for method in importedModule.__dict__.keys(): if method in ['__residuumSign__','__residuumSign','residuumSign', '__supportBoundingTest__','__supportBoundingTest','supportBoundingTest', '__residuum__','__residuum','residuum','__gradient__','__gradient','gradient']: if method in ['__residuumSign__','__residuumSign','residuumSign']: self.__residuumSign = importedModule.__dict__[method] self.__actionDictionary['residuumSign' ] = self.__residuumSign self.__actionImplemented['residuumSign'] = True if method in ['__supportBoundingTest__','__supportBoundingTest','supportBoundingTest']: self.__supportBoundingTest = importedModule.__dict__[method] self.__actionDictionary['supportBoundingTest' ] = self.__supportBoundingTest self.__actionImplemented['supportBoundingTest'] = True if method in ['__residuum__','__residuum','residuum']: self.__residuum = importedModule.__dict__[method] self.__actionDictionary['residuum' ] = self.__residuum self.__actionImplemented['residuum'] = True if method in ['__gradient__','__gradient','gradient']: self.__gradient = importedModule.__dict__[method] self.__actionDictionary['gradient'] = self.__gradient self.__actionImplemented['gradient'] = True else: #custom self.__actionDictionary[method] = importedModule.__dict__[method] self.__actionImplemented[method] = True else: self.raiseAnError(IOError,'No file name for the external function has been provided for external function '+self.name+' of type '+self.type) cnt = 0 for child in xmlNode: if child.tag=='variable': execCommand('self.'+child.text+' = None',self=self) self.__inputVariables.append(child.text) cnt +=1 if len(child.attrib.keys()) > 0: self.raiseAnError(IOError,'variable block in the definition of the function '+self.name + ' should not have any attribute!') if cnt == 0: self.raiseAnError(IOError,'not variable found in the definition of the function '+self.name)
def createNewInput(self, currentInputFiles, oriInputFiles, samplerType, **Kwargs): """ This method is used to generate an input based on the information passed in. @ In, currentInputFiles, list, list of current input files (input files from last this method call) @ In, oriInputFiles, list, list of the original input files @ In, samplerType, string, Sampler type (e.g. MonteCarlo, Adaptive, etc. see manual Samplers section) @ In, Kwargs, dictionary, kwarded dictionary of parameters. In this dictionary there is another dictionary called "SampledVars" where RELAP7 stores the variables that got sampled (e.g. Kwargs['SampledVars'] => {'var1':10,'var2':40}) @ Out, newInputFiles, list, list of newer input files, list of the new input files (modified and not) """ MOOSEparser = utils.importFromPath( os.path.join( os.path.join(uppath(os.path.dirname(__file__), 1), 'MooseBasedApp'), 'MOOSEparser.py'), False) self._samplersDictionary = {} self._samplersDictionary[samplerType] = self.gridForRELAP7 self._samplersDictionary['MonteCarlo'] = self.monteCarloForRELAP7 self._samplersDictionary['Grid'] = self.gridForRELAP7 self._samplersDictionary[ 'LimitSurfaceSearch'] = self.gridForRELAP7 # same Grid Fashion. It forces a dist to give a particular value self._samplersDictionary['Stratified'] = self.latinHyperCubeForRELAP7 self._samplersDictionary[ 'DynamicEventTree'] = self.dynamicEventTreeForRELAP7 self._samplersDictionary['FactorialDesign'] = self.gridForRELAP7 self._samplersDictionary['ResponseSurfaceDesign'] = self.gridForRELAP7 self._samplersDictionary[ 'AdaptiveDynamicEventTree'] = self.dynamicEventTreeForRELAP7 self._samplersDictionary['StochasticCollocation'] = self.gridForRELAP7 self._samplersDictionary['CustomSampler'] = self.gridForRELAP7 found = False for index, inputFile in enumerate(currentInputFiles): if inputFile.getExt() in self.getInputExtension(): found = True break if not found: raise IOError( 'None of the input files has one of the following extensions: ' + ' '.join(self.getInputExtension())) parser = MOOSEparser.MOOSEparser(currentInputFiles[index].getAbsFile()) Kwargs["distributionNode"] = parser.findNodeInXML("Distributions") if 'None' not in str(samplerType): modifDict = self._samplersDictionary[samplerType](**Kwargs) parser.modifyOrAdd(modifDict, False) #newInputFiles = copy.deepcopy(currentInputFiles) #if type(Kwargs['prefix']) in [str,type("")]:#Specifing string type for python 2 and 3 # newInputFiles[index].setBase(Kwargs['prefix']+"~"+newInputFiles[index].getBase()) #else: # newInputFiles[index].setBase(str(Kwargs['prefix'][1][0])+'~'+newInputFiles[index].getBase()) parser.printInput(currentInputFiles[index].getAbsFile()) return currentInputFiles
def _handleInput(self, paramInput): """ Method to handle the External Function parameter input. @ In, paramInput, InputData.ParameterInput, the already parsed input. @ Out, None """ self.functionFile = paramInput.parameterValues["file"] # get the module to load and the filename without path moduleToLoadString, self.functionFile = utils.identifyIfExternalModelExists( self, self.functionFile, self.workingDir) # import the external function importedModule = utils.importFromPath( moduleToLoadString, self.messageHandler.getDesiredVerbosity(self) > 1) if not importedModule: self.raiseAnError( IOError, 'Failed to import the module ' + moduleToLoadString + ' supposed to contain the function: ' + self.name) #here the methods in the imported file are brought inside the class for method, action in importedModule.__dict__.items(): if method in [ '__residuumSign__', '__residuumSign', 'residuumSign', '__supportBoundingTest__', '__supportBoundingTest', 'supportBoundingTest', '__residuum__', '__residuum', 'residuum', '__gradient__', '__gradient', 'gradient' ]: if method in [ '__residuumSign__', '__residuumSign', 'residuumSign' ]: self.__actionDictionary['residuumSign'] = action self.__actionImplemented['residuumSign'] = True if method in [ '__supportBoundingTest__', '__supportBoundingTest', 'supportBoundingTest' ]: self.__actionDictionary['supportBoundingTest'] = action self.__actionImplemented['supportBoundingTest'] = True if method in ['__residuum__', '__residuum', 'residuum']: self.__actionDictionary['residuum'] = action self.__actionImplemented['residuum'] = True if method in ['__gradient__', '__gradient', 'gradient']: self.__actionDictionary['gradient'] = action self.__actionImplemented['gradient'] = True else: #custom self.__actionDictionary[method] = action self.__actionImplemented[method] = True # get variables self.__inputVariables = paramInput.findFirst("variables").value # initialize variables for var in self.__inputVariables: execCommand('self.' + var + ' = None', self=self)
def read_input(self, xml): """ Sets settings from input file @ In, xml, xml.etree.ElementTree.Element, input from user @ Out, None """ Placeholder.read_input(self, xml) # load module load_string, _ = utils.identifyIfExternalModelExists(self, self._source, self._workingDir) module = utils.importFromPath(load_string, True) if not module: raise IOError('Module "{}" for function "{}" was not found!'.format(self._source, self.name)) # TODO do we need to set the var_names? self._var_names = _var_names self._set_callables(module)
def localInputAndChecks(self, xmlNode): """ Function to read the portion of the xml input that belongs to this specialized class and initialize some stuff based on the inputs got @ In, xmlNode, xml.etree.ElementTree.Element, Xml element node @ Out, None """ #Model._readMoreXML(self, xmlNode) paramInput = ExternalModel.getInputSpecification()() paramInput.parseNode(xmlNode) if 'ModuleToLoad' in paramInput.parameterValues: self.ModuleToLoad = paramInput.parameterValues['ModuleToLoad'] moduleToLoadString, self.ModuleToLoad = utils.identifyIfExternalModelExists( self, self.ModuleToLoad, self.workingDir) else: self.raiseAnError( IOError, 'ModuleToLoad not provided for module externalModule') # load the external module and point it to self.sim self.sim = utils.importFromPath( moduleToLoadString, self.messageHandler.getDesiredVerbosity(self) > 1) # check if there are variables and, in case, load them for child in paramInput.subparts: if child.getName() == 'variable': self.raiseAnError( IOError, '"variable" node included but has been depreciated! Please list variables in a "variables" node instead. Remove this message by Dec 2016.' ) elif child.getName() == 'variables': if len(child.parameterValues) > 0: self.raiseAnError( IOError, 'the block ' + child.getName() + ' named ' + child.value + ' should not have attributes!!!!!') for var in child.value.split(','): var = var.strip() self.modelVariableType[var] = None self.listOfRavenAwareVars.extend(self.modelVariableType.keys()) # check if there are other information that the external module wants to load #TODO this needs to be converted to work with paramInput if '_readMoreXML' in dir(self.sim): self.sim._readMoreXML(self.initExtSelf, xmlNode)
__moduleInterfaceList = [] startDir = os.path.join(os.path.dirname(__file__), 'CodeInterfaces') for dirr, _, _ in os.walk(startDir): __moduleInterfaceList.extend(glob(os.path.join(dirr, "*.py"))) utils.add_path(dirr) __moduleImportedList = [] """ Interface Dictionary (factory) (private) """ __base = 'Code' __interFaceDict = {} for moduleIndex in range(len(__moduleInterfaceList)): if 'class' in open(__moduleInterfaceList[moduleIndex]).read(): __moduleImportedList.append( utils.importFromPath(__moduleInterfaceList[moduleIndex], False)) for key, modClass in inspect.getmembers(__moduleImportedList[-1], inspect.isclass): # in this way we can get all the class methods classMethods = [ method for method in dir(modClass) if callable(getattr(modClass, method)) ] if 'createNewInput' in classMethods: __interFaceDict[key.replace("Interface", "")] = modClass __knownTypes = list(__interFaceDict.keys()) def knownTypes(): """ Method to return the list of known code interfaces' type
def createNewInput(self, currentInputFiles, oriInputFiles, samplerType, **Kwargs): """ this generates a new input file depending on which sampler has been chosen @ In, currentInputFiles, list, list of current input files (input files from last this method call) @ In, oriInputFiles, list, list of the original input files @ In, samplerType, string, Sampler type (e.g. MonteCarlo, Adaptive, etc. see manual Samplers section) @ In, Kwargs, dictionary, kwarded dictionary of parameters. In this dictionary there is another dictionary called "SampledVars" where RAVEN stores the variables that got sampled (e.g. Kwargs['SampledVars'] => {'var1':10,'var2':40}) @ Out, newInputFiles, list, list of newer input files, list of the new input files (modified and not) """ import RAVENparser if 'dynamiceventtree' in str(samplerType).strip().lower(): raise IOError( self.printTag + ' ERROR: DynamicEventTree-based sampling not supported!') index = self.__findInputFile(currentInputFiles) parser = RAVENparser.RAVENparser(currentInputFiles[index].getAbsFile()) # get sampled variables modifDict = Kwargs['SampledVars'] # apply conversion scripts for source, convDict in self.conversionDict.items(): module = utils.importFromPath(source) varVals = dict((var, np.asarray(modifDict[var])) for var in convDict['variables']) # modify vector+ variables that need to be flattened if convDict['noScalar']: # call conversion newVars = module.convertNotScalarSampledVariables(varVals) # check type if type(newVars).__name__ != 'dict': raise IOError( self.printTag + ' ERROR: convertNotScalarSampledVariables in "{}" must return a dictionary!' .format(source)) # apply new and/or updated values modifDict.update(newVars) # modify scalar variables if convDict['scalar']: # call conversion, value changes happen in-place module.manipulateScalarSampledVariables(modifDict) # we work on batchSizes here newBatchSize = Kwargs['NumMPI'] internalParallel = Kwargs.get('internalParallel', False) if int(Kwargs['numberNodes']) > 0: # we are in a distributed memory machine => we allocate a node file nodeFileToUse = os.path.join(Kwargs['BASE_WORKING_DIR'], "node_" + str(Kwargs['INDEX'])) if os.path.exists(nodeFileToUse): modifDict['RunInfo|mode'] = 'mpi' modifDict['RunInfo|mode|nodefile'] = nodeFileToUse else: raise IOError(self.printTag + ' ERROR: The nodefile "' + str(nodeFileToUse) + '" does not exist!') if internalParallel or newBatchSize > 1: # either we have an internal parallel or NumMPI > 1 modifDict['RunInfo|batchSize'] = newBatchSize #modifDict['RunInfo|internalParallel'] = internalParallel # make tree modifiedRoot = parser.modifyOrAdd(modifDict, save=True, allowAdd=True) # modify tree if self.inputManipulationModule is not None: module = utils.importFromPath(self.inputManipulationModule) modifiedRoot = module.modifyInput(modifiedRoot, modifDict) # write input file parser.printInput(modifiedRoot, currentInputFiles[index].getAbsFile()) # copy slave files parser.copySlaveFiles(currentInputFiles[index].getPath()) return currentInputFiles
def createNewInput(self,currentInputFiles,oriInputFiles,samplerType,**Kwargs): """ this generates a new input file depending on which sampler has been chosen @ In, currentInputFiles, list, list of current input files (input files from last this method call) @ In, oriInputFiles, list, list of the original input files @ In, samplerType, string, Sampler type (e.g. MonteCarlo, Adaptive, etc. see manual Samplers section) @ In, Kwargs, dictionary, kwarded dictionary of parameters. In this dictionary there is another dictionary called "SampledVars" where RAVEN stores the variables that got sampled (e.g. Kwargs['SampledVars'] => {'var1':10,'var2':40}) @ Out, newInputFiles, list, list of newer input files, list of the new input files (modified and not) """ import RAVENparser if 'dynamiceventtree' in str(samplerType).strip().lower(): raise IOError(self.printTag+' ERROR: DynamicEventTree-based sampling not supported!') index = self.__findInputFile(currentInputFiles) parser = RAVENparser.RAVENparser(currentInputFiles[index].getAbsFile()) # get the OutStreams names self.outStreamsNamesAndType = parser.returnOutstreamsNamesAnType() # check if the linked DataObjects are among the Outstreams pointSetNumber, historySetNumber = 0, 0 for outstream, dataObj in self.outStreamsNamesAndType.items(): if outstream in self.linkedDataObjectOutStreamsNames: if dataObj[1].strip() == 'PointSet': pointSetNumber+=1 else: historySetNumber+=1 if pointSetNumber > 1 or historySetNumber > 1: raise IOError(self.printTag+' ERROR: Only one OutStream for PointSet and/or one for HistorySet can be linked as output export!') if pointSetNumber == 0 and historySetNumber == 0: raise IOError(self.printTag+' ERROR: No one of the OutStreams linked to this interface have been found in the SLAVE RAVEN!' +' Expected: "'+' '.join(self.linkedDataObjectOutStreamsNames)+'" but found "' +' '.join(self.outStreamsNamesAndType.keys())+'"!') # get variable groups varGroupNames = parser.returnVarGroups() if len(varGroupNames) > 0: # check if they are not present in the linked outstreams for outstream in self.linkedDataObjectOutStreamsNames: inputNode = self.outStreamsNamesAndType[outstream][2].find("Input") outputNode = self.outStreamsNamesAndType[outstream][2].find("Output") inputVariables = inputNode.text.split(",") if inputNode is not None else [] outputVariables = outputNode.text.split(",") if outputNode is not None else [] if any (varGroupName in inputVariables+outputVariables for varGroupName in varGroupNames): raise IOError(self.printTag+' ERROR: The VariableGroup system is not supported in the current ' + 'implementation of the interface for the DataObjects specified in the '+ '<outputExportOutStreams> XML node!') # get inner working dir self.innerWorkingDir = parser.workingDir # get sampled variables modifDict = Kwargs['SampledVars'] # apply conversion scripts for source,convDict in self.conversionDict.items(): module = utils.importFromPath(source) varVals = dict((var,np.asarray(modifDict[var])) for var in convDict['variables']) # modify vector+ variables that need to be flattened if convDict['noScalar']: # call conversion newVars = module.convertNotScalarSampledVariables(varVals) # check type if type(newVars).__name__ != 'dict': raise IOError(self.printTag+' ERROR: convertNotScalarSampledVariables in "{}" must return a dictionary!'.format(source)) # apply new and/or updated values modifDict.update(newVars) # modify scalar variables if convDict['scalar']: # call conversion, value changes happen in-place module.manipulateScalarSampledVariables(modifDict) # we work on batchSizes here newBatchSize = Kwargs['NumMPI'] internalParallel = Kwargs.get('internalParallel',False) if int(Kwargs['numberNodes']) > 0: # we are in a distributed memory machine => we allocate a node file nodeFileToUse = os.path.join(Kwargs['BASE_WORKING_DIR'],"node_" +str(Kwargs['INDEX'])) if os.path.exists(nodeFileToUse): modifDict['RunInfo|mode' ] = 'mpi' modifDict['RunInfo|mode|nodefile' ] = nodeFileToUse else: raise IOError(self.printTag+' ERROR: The nodefile "'+str(nodeFileToUse)+'" does not exist!') if internalParallel or newBatchSize > 1: # either we have an internal parallel or NumMPI > 1 modifDict['RunInfo|batchSize' ] = newBatchSize #modifDict['RunInfo|internalParallel'] = internalParallel #make tree modifiedRoot = parser.modifyOrAdd(modifDict,save=True,allowAdd = True) #make input parser.printInput(modifiedRoot,currentInputFiles[index].getAbsFile()) # copy slave files parser.copySlaveFiles(currentInputFiles[index].getPath()) return currentInputFiles
def _readMoreXML(self, xmlNode): """ Function to read the portion of the xml input that belongs to this specialized class and initialize some members based on inputs. This can be overloaded in specialize code interface in order to read specific flags. In this case, this is used for locating an external python module where the variables can be modified and the "vector" variables can be splitted in multiple single variables @ In, xmlNode, xml.etree.ElementTree.Element, Xml element node @ Out, None. """ if os.path.basename( xmlNode.find("executable").text) != 'raven_framework': raise IOError( self.printTag + ' ERROR: executable must be "raven_framework" (in whatever location)!' ) linkedDataObjects = xmlNode.find("outputExportOutStreams") if linkedDataObjects is None: raise IOError( self.printTag + ' ERROR: outputExportOutStreams node not present. You must input at least one OutStream (max 2)!' ) self.linkedDataObjectOutStreamsNames = linkedDataObjects.text.split( ",") if len(self.linkedDataObjectOutStreamsNames) > 2: raise IOError( self.printTag + ' ERROR: outputExportOutStreams node. The maximum number of linked OutStreams are 2 (1 for PointSet and 1 for HistorySet)!' ) child = xmlNode.find("conversionModule") if child is not None: self.extModForVarsManipulationPath = os.path.expanduser( child.text.strip()) if not os.path.isabs(self.extModForVarsManipulationPath): self.extModForVarsManipulationPath = os.path.abspath( self.extModForVarsManipulationPath) # check if it exist if not os.path.exists(self.extModForVarsManipulationPath): raise IOError(self.printTag + ' ERROR: the conversionModule "' + self.extModForVarsManipulationPath + '" has not been found!') extModForVarsManipulation = utils.importFromPath( self.extModForVarsManipulationPath) if extModForVarsManipulation is None: raise IOError(self.printTag + ' ERROR: the conversionModule "' + self.extModForVarsManipulationPath + '" failed to be imported!') # check if the methods are there if 'convertNotScalarSampledVariables' in extModForVarsManipulation.__dict__.keys( ): self.hasMethods['noscalar'] = True if 'manipulateScalarSampledVariables' in extModForVarsManipulation.__dict__.keys( ): self.hasMethods['scalar'] = True if not self.hasMethods['scalar'] and not self.hasMethods[ 'noscalar']: raise IOError( self.printTag + ' ERROR: the conversionModule "' + self.extModForVarsManipulationPath + '" does not contain any of the usable methods! Expected at least ' + 'one of: "manipulateScalarSampledVariables" and/or "manipulateScalarSampledVariables"!' )
__moduleInterfaceList = [] startDir = os.path.join(os.path.dirname(__file__),'../../plugins') for dirr,_,_ in os.walk(startDir): __moduleInterfaceList.extend(glob(os.path.join(dirr,"*.py"))) utils.add_path(dirr) __moduleImportedList = [] __basePluginClasses = {'ExternalModel':'ExternalModelPluginBase'} """ Interface Dictionary (factory) (private) """ __base = 'ModelPlugins' __interFaceDict = defaultdict(dict) for moduleIndex in range(len(__moduleInterfaceList)): if 'class' in open(__moduleInterfaceList[moduleIndex]).read(): __moduleImportedList.append(utils.importFromPath(__moduleInterfaceList[moduleIndex],False)) for key,modClass in inspect.getmembers(__moduleImportedList[-1], inspect.isclass): for base in modClass.__bases__: for ravenEntityName, baseClassName in __basePluginClasses.items(): if base.__name__ == baseClassName: __interFaceDict[ravenEntityName][key] = modClass # check the validity of the plugin if not modClass.isAvalidPlugin(): raise IOError("The plugin based on the class "+ravenEntityName.strip()+" is not valid. Please check with the Plugin developer!") __knownTypes = [item for sublist in __interFaceDict.values() for item in sublist] def knownTypes(): """ Method to return the list of known model plugins @ In, None @ Out, __knownTypes, list, the list of known types