diff --git a/developer_tools/XSDSchemas/Optimizers.xsd b/developer_tools/XSDSchemas/Optimizers.xsd
index cd120ea283..3539b07805 100644
--- a/developer_tools/XSDSchemas/Optimizers.xsd
+++ b/developer_tools/XSDSchemas/Optimizers.xsd
@@ -28,6 +28,7 @@
+
@@ -65,6 +66,7 @@
+
diff --git a/developer_tools/XSDSchemas/Samplers.xsd b/developer_tools/XSDSchemas/Samplers.xsd
index b33d644d3f..c9f1dbad22 100644
--- a/developer_tools/XSDSchemas/Samplers.xsd
+++ b/developer_tools/XSDSchemas/Samplers.xsd
@@ -88,9 +88,9 @@
-
+
@@ -117,6 +117,7 @@
+
@@ -139,6 +140,7 @@
+
@@ -155,6 +157,7 @@
+
@@ -187,6 +190,7 @@
+
@@ -232,6 +236,7 @@
+
@@ -255,6 +260,7 @@
+
@@ -268,6 +274,7 @@
+
@@ -335,6 +342,7 @@
+
@@ -367,6 +375,7 @@
+
@@ -391,6 +400,7 @@
+
@@ -430,6 +440,7 @@
+
@@ -448,6 +459,7 @@
+
@@ -461,6 +473,7 @@
+
@@ -488,6 +501,7 @@
+
diff --git a/doc/user_manual/sampler.tex b/doc/user_manual/sampler.tex
index 2815404ebd..b90621fe91 100644
--- a/doc/user_manual/sampler.tex
+++ b/doc/user_manual/sampler.tex
@@ -13,6 +13,29 @@ \section{Samplers}
\nb As with other objects, this identifier can be used to reference this
specific entity from other input blocks in the XML.
}
+\newcommand{\shapeVariableDescription}
+{
+ \xmlAttr{shape},
+ \xmlDesc{comma-separated integers, optional field},
+ determines the number of samples and shape of samples
+ to be taken. For example, \xmlAttr{shape}=``2,3'' will provide a 2 by 3
+ matrix of values, while \xmlAttr{shape}=``10'' will produce a vector of 10 values.
+ Omitting this optional attribute will result in a single scalar value instead.
+ Each of the values in the matrix or vector will be the same as the single sampled value.
+ \nb A model interface must be prepared to handle non-scalar inputs to use this option.
+}
+\newcommand{\shapeConstantDescription}
+{
+ \xmlAttr{shape},
+ \xmlDesc{comma-separated integers, optional field},
+ determines the shape of samples of the constant value.
+ For example, \xmlAttr{shape}=``2,3'' will shape the values into a 2 by 3
+ matrix, while \xmlAttr{shape}=``10'' will shape into a vector of 10 values.
+ Unlike the \xmlNode{variable}, the constant requires each value be entered; the number
+ of required values is equal to the product of the \xmlAttr{shape}.
+ \nb A model interface must be prepared to handle non-scalar inputs to use this option.
+}
+
\renewcommand{\specBlock}[2]
{
The specifications of this sampler must be defined within #1 \xmlNode{#2} XML
@@ -98,10 +121,11 @@ \section{Samplers}
\newcommand{\variableDescription}
{
\xmlNode{variable}, \xmlDesc{XML node,
- required parameter} will specify one attribute:
+ required parameter} can specify the following attribute:
\begin{itemize}
\item \xmlAttr{name}, \xmlDesc{required string attribute}, user-defined name
of this variable.
+ \item \shapeVariableDescription
\end{itemize}
}
@@ -112,7 +136,12 @@ \section{Samplers}
kept constant.
For doing this, as many \xmlNode{constant} nodes as needed can be
input, where the body of the node contains the constant value that is
- going to be injected as an additional variable
+ going to be injected as an additional variable. The constant has the following attributes:
+ \begin{itemize}
+ \item \xmlAttr{name}, \xmlDesc{required string attribute}, user-defined name
+ of this constant.
+ \item \shapeConstantDescription
+ \end{itemize}
}
\newcommand{\distributionDescription}
@@ -133,16 +162,6 @@ \section{Samplers}
\nb{Alternatively, this node must be ommitted
if the \xmlNode{distribution} node is supplied.}
}
-\newcommand{\shapeDescription}
-{
- \xmlNode{shape}, \xmlDesc{comma-separated integers,
- optional field}, determines the number of samples and shape of samples
- to be taken. For example, \xmlNode{shape}2,3\xmlNode{/shape} will provide
- a 2 x 3 matrix of values. In general, samplers will simply replicate
- the single sampled value into each point of the matrix. Omitting this optional
- node will result in a single scalar value instead. \nb A model interface
- must be prepared to handle non-scalar inputs to use this option.
-}
@@ -577,7 +596,6 @@ \subsubsection{Monte Carlo}
\begin{itemize}
\item \distributionDescription
\item \functionDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -667,7 +685,6 @@ \subsubsection{Grid}
\item \distributionDescription
\item \functionDescription
\item \gridDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -764,7 +781,6 @@ \subsubsection{Sparse Grid Collocation}
\begin{itemize}
\item \distributionDescription
\item \functionDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -904,7 +920,6 @@ \subsubsection{Sobol}
\begin{itemize}
\item \distributionDescription
\item \functionDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -981,7 +996,6 @@ \subsubsection{Stratified}
\item \distributionDescription
\item \functionDescription
\item \gridDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -1196,7 +1210,6 @@ \subsubsection{Response Surface Design}
\item \functionDescription
\item \gridDescriptionOnlyCustom
\nb{Only the construction ``custom'' is available. In the \xmlNode{grid} body only the lower and upper bounds can be inputted (2 numbers only).}
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\item \xmlNode{ResponseSurfaceDesignSettings}, \xmlDesc{required},
@@ -1384,7 +1397,6 @@ \subsubsection{Factorial Design}
\item \distributionDescription
\item \functionDescription
\item \gridDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -1799,7 +1811,6 @@ \subsubsection{Dynamic Event Tree}
\item \distributionDescription
\item \functionDescription
\item \gridDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -1910,7 +1921,6 @@ \subsubsection{Hybrid Dynamic Event Tree}
\item \distributionDescription
\item \functionDescription
\item \gridDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -1948,7 +1958,6 @@ \subsubsection{Hybrid Dynamic Event Tree}
\begin{itemize}
\item \distributionDescription
\item \functionDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -2095,7 +2104,6 @@ \subsubsection{Limit Surface Search}
\begin{itemize}
\item \distributionDescription
\item \functionDescription
- \item \shapeDescription
\end{itemize}
\end{itemize}
@@ -2332,7 +2340,6 @@ \subsubsection{Adaptive Dynamic Event Tree}
\item \distributionDescription
\item \functionDescription
\item \gridDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -2487,7 +2494,6 @@ \subsubsection{Adaptive Hybrid Dynamic Event Tree}
\item \distributionDescription
\item \functionDescription
\item \gridDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -2560,7 +2566,6 @@ \subsubsection{Adaptive Hybrid Dynamic Event Tree}
\begin{itemize}
\item \distributionDescription
\item \functionDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -2658,7 +2663,6 @@ \subsubsection{Adaptive Sparse Grid}
\begin{itemize}
\item \distributionDescription
\item \functionDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
@@ -2839,7 +2843,6 @@ \subsubsection{Adaptive Sobol Decomposition}
\begin{itemize}
\item \distributionDescription
\item \functionDescription
- \item \shapeDescription
\end{itemize}
\item \constantVariablesDescription
\end{itemize}
diff --git a/framework/CodeInterfaces/RAVEN/RAVENInterface.py b/framework/CodeInterfaces/RAVEN/RAVENInterface.py
index 517d175445..1d2d276094 100644
--- a/framework/CodeInterfaces/RAVEN/RAVENInterface.py
+++ b/framework/CodeInterfaces/RAVEN/RAVENInterface.py
@@ -80,26 +80,40 @@ def _readMoreXML(self,xmlNode):
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")
+ self.conversionDict = {} # {modulePath : {'variables': [], 'noScalar': 0, 'scalar': 0}, etc }
+ child = xmlNode.find("conversion")
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"!')
+ 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 __findInputFile(self,inputFiles):
"""
@@ -185,42 +199,24 @@ def createNewInput(self,currentInputFiles,oriInputFiles,samplerType,**Kwargs):
self.innerWorkingDir = parser.workingDir
# get sampled variables
modifDict = Kwargs['SampledVars']
- # check if there are noscalar variables
- vectorVars = {}
- totSizeExpected = 0
- for var, value in modifDict.items():
- if np.asarray(value).size > 1:
- vectorVars[var] = np.asarray(value)
- totSizeExpected += vectorVars[var].size
- if len(vectorVars) > 0 and not self.hasMethods['noscalar']:
- raise IOError(self.printTag+' ERROR: No scalar variables ('+','.join(vectorVars.keys())
- + ') have been detected but no convertNotScalarSampledVariables has been inputted!')
- # check if ext module has been inputted
- if self.hasMethods['noscalar'] or self.hasMethods['scalar']:
- extModForVarsManipulation = utils.importFromPath(self.extModForVarsManipulationPath)
- if self.hasMethods['noscalar']:
- if len(vectorVars) > 0:
- toPopOut = vectorVars.keys()
- try:
- newVars = extModForVarsManipulation.convertNotScalarSampledVariables(vectorVars)
- if type(newVars).__name__ != 'dict':
- raise IOError(self.printTag+' ERROR: convertNotScalarSampledVariables must return a dictionary!')
- # DEBUGG this is failing b/c Index and Variable both being counted!
- #if len(newVars) != totSizeExpected:
- # raise IOError(self.printTag+' ERROR: The total number of variables expected from method convertNotScalarSampledVariables is "'+str(totSizeExpected)+'". Got:"'+str(len(newVars))+'"!')
- modifDict.update(newVars)
- for noscalarVar in toPopOut:
- modifDict.pop(noscalarVar)
- except TypeError:
- raise IOError(self.printTag+' ERROR: convertNotScalarSampledVariables accept only one argument convertNotScalarSampledVariables(variableDict)')
- else:
- print(self.printTag+' Warning: method "convertNotScalarSampledVariables" has been inputted but no "no scalar" variables have been found!')
- # check if ext module has the method to manipulate the variables
- if self.hasMethods['scalar']:
- try:
- extModForVarsManipulation.manipulateScalarSampledVariables(modifDict)
- except TypeError:
- raise IOError(self.printTag+' ERROR: manipulateScalarSampledVariables accept only one argument manipulateScalarSampledVariables(variableDict)')
+
+ # 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']
diff --git a/framework/CodeInterfaces/RAVEN/RAVENparser.py b/framework/CodeInterfaces/RAVEN/RAVENparser.py
index 518aaba73f..fd6adc9920 100644
--- a/framework/CodeInterfaces/RAVEN/RAVENparser.py
+++ b/framework/CodeInterfaces/RAVEN/RAVENparser.py
@@ -30,7 +30,7 @@
import numpy as np
from collections import OrderedDict
-from utils import xmlUtils
+from utils import xmlUtils, mathUtils
class RAVENparser():
"""
@@ -293,16 +293,30 @@ def modifyOrAdd(self,modiDictionary={},save=True, allowAdd = False):
subElement = ET.Element(nodeWithAttributeName, attrib=allowAddNodesPath[nodeWithAttributeName])
getFirstElement.append(subElement)
getFirstElement = subElement
+ # in the event of vector entries, handle those here
+ if mathUtils.isSingleValued(val):
+ val = str(val).strip()
+ else:
+ if len(val.shape) > 1:
+ raise IOError(self.printTag+'ERROR: RAVEN interface is not prepared to handle matrix value passing yet!')
+ val = ','.join(str(i) for i in val)
if changeTheNode:
- subElement.text = str(val).strip()
+ subElement.text = val
else:
- subElement.attrib[attribConstruct.keys()[-1]] = str(val).strip()
+ subElement.attrib[attribConstruct.keys()[-1]] = val
else:
nodeToChange = foundNodes[0]
pathNode = './/'
+ # in the event of vector entries, handle those here
+ if mathUtils.isSingleValued(val):
+ val = str(val).strip()
+ else:
+ if len(val.shape) > 1:
+ raise IOError(self.printTag+'ERROR: RAVEN interface is not prepared to handle matrix value passing yet!')
+ val = ','.join(str(i) for i in val)
if changeTheNode:
- nodeToChange.text = str(val).strip()
+ nodeToChange.text = val
else:
- nodeToChange.attrib[attribName] = str(val).strip()
+ nodeToChange.attrib[attribName] = val
return returnElement
diff --git a/framework/Optimizers/GradientBasedOptimizer.py b/framework/Optimizers/GradientBasedOptimizer.py
index 957596675a..43b16840e2 100644
--- a/framework/Optimizers/GradientBasedOptimizer.py
+++ b/framework/Optimizers/GradientBasedOptimizer.py
@@ -398,6 +398,10 @@ def printProgress(name,boolCheck,test,gold):
#same coordinate check
sameCoordinateCheck = True
for var,values in self.optVarsHist[traj][varsUpdate].items():
+ # don't check constants, of course they're the same
+ if var in self.constants:
+ continue
+ # differentiate vectors and scalars for checking
if hasattr(values,'__len__'):
if any(values != self.counter['recentOptHist'][traj][0][var]):
sameCoordinateCheck = False
diff --git a/framework/Optimizers/Optimizer.py b/framework/Optimizers/Optimizer.py
index b608f83a69..9744199c52 100644
--- a/framework/Optimizers/Optimizer.py
+++ b/framework/Optimizers/Optimizer.py
@@ -80,14 +80,13 @@ def getInputSpecification(cls):
inputSpecification.removeSub('variable')
variable = InputData.parameterInputFactory('variable', strictMode=True)
variable.addParam("name", InputData.StringType, True)
+ variable.addParam("shape", InputData.IntegerListType, required=False)
upperBound = InputData.parameterInputFactory('upperBound', contentType=InputData.FloatType, strictMode=True)
lowerBound = InputData.parameterInputFactory('lowerBound', contentType=InputData.FloatType, strictMode=True)
initial = InputData.parameterInputFactory('initial',contentType=InputData.StringListType)
- shape = InputData.parameterInputFactory('shape',contentType=InputData.StringListType)
variable.addSub(upperBound)
variable.addSub(lowerBound)
variable.addSub(initial)
- variable.addSub(shape)
inputSpecification.addSub(variable)
# constant -> use the Sampler's specs.
@@ -138,10 +137,10 @@ def getInputSpecification(cls):
stoch = InputData.parameterInputFactory('stochasticDistribution' , contentType=stochEnum )
bisect = InputData.parameterInputFactory('innerBisectionThreshold', contentType=InputData.FloatType )
loop = InputData.parameterInputFactory('innerLoopLimit' , contentType=InputData.IntegerType)
- param.addSub(num )
- param.addSub(stoch )
+ param.addSub(num)
+ param.addSub(stoch)
param.addSub(bisect)
- param.addSub(loop )
+ param.addSub(loop)
inputSpecification.addSub(param)
# multilevel
@@ -321,11 +320,12 @@ def _readMoreXMLbase(self,xmlNode):
if child.getName() == "variable":
if self.fullOptVars is None:
self.fullOptVars = []
- try:
- varName = child.parameterValues['name']
- self.optVarsInitialized[varName] = False
- except KeyError:
- self.raiseAnError(IOError, '"{}" node does not have the "name" attribute'.format(child.getName()))
+ # store variable name
+ varName = child.parameterValues['name']
+ self.optVarsInitialized[varName] = False
+ # store varible requested shape, if any
+ if 'shape' in child.parameterValues:
+ self.variableShapes[varName] = child.parameterValues['shape']
self.fullOptVars.append(varName)
self.optVarsInit['initial'][varName] = {}
for childChild in child.subparts:
@@ -341,24 +341,15 @@ def _readMoreXMLbase(self,xmlNode):
try:
self.optVarsInit['initial'][varName][trajInd] = float(initVal)
except ValueError:
- self.raiseAnError(ValueError, 'Unable to convert to float the intial value for variable "{}" in trajectory "{}": {}'.format(varName,trajInd,initVal))
+ self.raiseAnError(ValueError,
+ 'Unable to convert to float the intial value for variable "{}" in trajectory "{}": {}'
+ .format(varName,trajInd,initVal))
if self.optTraj == None:
self.optTraj = range(len(self.optVarsInit['initial'][varName].keys()))
- elif childChild.getName() == 'shape':
- try:
- variableShape = tuple(int(i) for i in childChild.value)
- except ValueError as e:
- self.raiseAnError(IOError,'Failed to interpret "shape" for variable "{}"! Should be comma-separated list of integers.'.format(varName))
- self.variableShapes[varName] = variableShape
elif child.getName() == "constant":
- value = utils.partialEval(child.value)
- if value is None:
- self.raiseAnError(IOError,'The body of "constant" XML block should be a number. Got: ' +child.value)
- try:
- self.constants[child.parameterValues['name']] = value
- except KeyError:
- self.raiseAnError(KeyError,child.getName()+'"constant" nodes must have the attribute "name" (missing in "{}").'.format(self.name))
+ name,value = self._readInConstant(child)
+ self.constants[child.parameterValues['name']] = value
elif child.getName() == "objectVar":
self.objVar = child.value.strip()
diff --git a/framework/Samplers/Sampler.py b/framework/Samplers/Sampler.py
index 017d3bb6de..ad7efbb30f 100644
--- a/framework/Samplers/Sampler.py
+++ b/framework/Samplers/Sampler.py
@@ -55,6 +55,8 @@ class cls.
specifying input of cls.
"""
inputSpecification = super(Sampler, cls).getInputSpecification()
+ # FIXME the DET HybridSampler doesn't use the "name" param for the samples it creates,
+ # so we can't require the name yet
inputSpecification.addParam("name", InputData.StringType)
outerDistributionInput = InputData.parameterInputFactory("Distribution")
@@ -64,12 +66,11 @@ class cls.
variableInput = InputData.parameterInputFactory("variable")
variableInput.addParam("name", InputData.StringType)
+ variableInput.addParam("shape", InputData.IntegerListType, required=False)
distributionInput = InputData.parameterInputFactory("distribution", contentType=InputData.StringType)
distributionInput.addParam("dim", InputData.IntegerType)
- shapeInput = InputData.parameterInputFactory("shape", contentType=InputData.StringType)
variableInput.addSub(distributionInput)
- variableInput.addSub(shapeInput)
functionInput = InputData.parameterInputFactory("function", contentType=InputData.StringType)
@@ -87,8 +88,9 @@ class cls.
inputSpecification.addSub(variablesTransformationInput)
- constantInput = InputData.parameterInputFactory("constant", contentType=InputData.StringType)
+ constantInput = InputData.parameterInputFactory("constant", contentType=InputData.InterpretedListType)
constantInput.addParam("name", InputData.StringType, True)
+ constantInput.addParam("shape", InputData.IntegerListType, required=False)
inputSpecification.addSub(constantInput)
@@ -239,6 +241,10 @@ def _readMoreXMLbase(self,xmlNode):
foundDistOrFunc = False
# store variable name for re-use
varName = child.parameterValues['name']
+ # set shape if present
+ if 'shape' in child.parameterValues:
+ self.variableShapes[varName] = child.parameterValues['shape']
+ # read subnodes
for childChild in child.subparts:
if childChild.getName() =='distribution':
# can only have a distribution if doesn't already have a distribution or function
@@ -270,13 +276,6 @@ def _readMoreXMLbase(self,xmlNode):
toBeSampled = childChild.value
# track variable as a functional sample
self.dependentSample[prefix+varName] = toBeSampled
- elif childChild.getName() == 'shape':
- try:
- variableShape = tuple(int(i) for i in childChild.value.split(','))
- except ValueError as e:
- self.raiseAnError(IOError,'Failed to interpret "shape" for variable "{}"! Should be comma-separated list of integers.'.format(varName))
- self.variableShapes[varName] = variableShape
- # TODO error check variable shape: all positive integers unless just 0?
if not foundDistOrFunc:
self.raiseAnError(IOError,'Sampled variable',varName,'has neither a nor node specified!')
@@ -301,13 +300,9 @@ def _readMoreXMLbase(self,xmlNode):
self.variablesTransformationDict[child.parameterValues['distribution']] = transformationDict
elif child.getName() == "constant":
- value = utils.partialEval(child.value)
- if value is None:
- self.raiseAnError(IOError,'The body of "constant" XML block should be a number. Got: ' +child.value)
- try:
- self.constants[child.parameterValues['name']] = value
- except KeyError:
- self.raiseAnError(KeyError,child.getName()+' must have the attribute "name"!!!')
+ name,value = self._readInConstant(child)
+ self.constants[name] = value
+
elif child.getName() == "restartTolerance":
self.restartTolerance = child.value
@@ -387,6 +382,32 @@ def _readMoreXMLbase(self,xmlNode):
self.variablesTransformationDict[dist]['latentVariablesIndex'] = listIndex
return paramInput
+ def _readInConstant(self,inp):
+ """
+ Reads in a "constant" input parameter node.
+ @ In, inp, utils.InputParameter.ParameterInput, input parameter node to read from
+ @ Out, name, string, name of constant
+ @ Out, value, float or np.array,
+ """
+ value = inp.value
+ name = inp.parameterValues['name']
+ shape = inp.parameterValues.get('shape',None)
+ # if single entry, remove array structure; if multiple entries, cast them as numpy array
+ if len(value) == 1:
+ value = value[0]
+ else:
+ value = np.asarray(value)
+ # if specific shape requested, then reshape it
+ if shape is not None:
+ try:
+ value = value.reshape(shape)
+ except ValueError:
+ self.raiseAnError(IOError,
+ ('Requested shape "{}" ({} entries) for constant "{}"' +\
+ ' is not consistent with the provided values ({} entries)!')
+ .format(shape,np.prod(shape),name,len(value)))
+ return name, value
+
def getInitParams(self):
"""
This function is called from the base class to print some of the information inside the class.
diff --git a/framework/utils/InputData.py b/framework/utils/InputData.py
index 14de6a9778..08fe2e73d9 100644
--- a/framework/utils/InputData.py
+++ b/framework/utils/InputData.py
@@ -20,7 +20,7 @@
"""
from __future__ import division, print_function, unicode_literals, absolute_import
import xml.etree.ElementTree as ET
-from utils import utils
+from utils import utils,mathUtils
class InputType(object):
"""
@@ -133,6 +133,37 @@ def convert(cls, value):
FloatType.createClass("float","xsd:double")
+#
+#
+#
+#
+class InterpretedListType(InputType):
+ """
+ A type for lists with unknown (but consistent) type; could be string, float, etc
+ """
+
+ @classmethod
+ def convert(cls, value):
+ """
+ Converts value from string to a listi with string, integer, or float type.
+ @ In, value, string, the value to convert
+ @ Out, convert, list, the converted value
+ """
+ values = value.split(",")
+ base = utils.partialEval(values[0].strip())
+ # three possibilities: string, integer, or float
+ if mathUtils.isAString(base):
+ conv = str
+ elif mathUtils.isAnInteger(base):
+ conv = int
+ else: #float
+ conv = float
+ return [conv(x.strip()) for x in values]
+
+#Note, XSD's list type is split by spaces, not commas, so using xsd:string
+InterpretedListType.createClass("stringtype","xsd:string")
+
+
#
#
#
@@ -155,6 +186,50 @@ def convert(cls, value):
StringListType.createClass("stringtype","xsd:string")
+#
+#
+#
+#
+class FloatListType(InputType):
+ """
+ A type for float lists "1.1, 2.0, 3.4" -> [1.1, 2.0, 3.4]
+ """
+
+ @classmethod
+ def convert(cls, value):
+ """
+ Converts value from string to a float list.
+ @ In, value, string, the value to convert
+ @ Out, convert, list, the converted value
+ """
+ return [float(x.strip()) for x in value.split(",")]
+
+#Note, XSD's list type is split by spaces, not commas, so using xsd:string
+FloatListType.createClass("stringtype","xsd:string")
+
+
+#
+#
+#
+#
+class IntegerListType(InputType):
+ """
+ A type for integer lists "1, 2, 3" -> [1,2,3]
+ """
+
+ @classmethod
+ def convert(cls, value):
+ """
+ Converts value from string to an integer list.
+ @ In, value, string, the value to convert
+ @ Out, convert, list, the converted value
+ """
+ return [int(x.strip()) for x in value.split(",")]
+
+#Note, XSD's list type is split by spaces, not commas, so using xsd:string
+IntegerListType.createClass("stringtype","xsd:string")
+
+
#
#
#
@@ -425,7 +500,7 @@ def handleError(s):
if node.tag != self.name:
#should this be an error or a warning? Or even that?
#handleError('XML node "{}" != param spec name "{}"'.format(node.tag,self.name))
- print('Note: XML node "{}" != param spec name "{}". This should not usually be an issue.'.format(node.tag,self.name))
+ print('Using param spec "{}" to read XML node "{}.'.format(self.name,node.tag))
if self.contentType:
self.value = self.contentType.convert(node.text)
else:
diff --git a/tests/framework/CodeInterfaceTests/test_raven_running_raven_int_models.xml b/tests/framework/CodeInterfaceTests/test_raven_running_raven_int_models.xml
index a0b893d91b..2a8b50deae 100644
--- a/tests/framework/CodeInterfaceTests/test_raven_running_raven_int_models.xml
+++ b/tests/framework/CodeInterfaceTests/test_raven_running_raven_int_models.xml
@@ -46,7 +46,11 @@
%FRAMEWORK_DIR%/../raven_frameworkoutputMontecarloRom_dump,outputMontecarloRomHS_dump
- raven_running_raven_internal_models/testConversionModule.py
+
+
+ Models|ROM@subType:SciKitLearn@name:ROM1|C
+
+ Models|ROM@subType:SciKitLearn@name:ROM1|CModels|ROM@subType:SciKitLearn@name:ROM1|tolSamplers|Grid@name:gridRom|constant@name:DG1recoveryTime
diff --git a/tests/framework/DataObjects/load_csv_dataset.xml b/tests/framework/DataObjects/load_csv_dataset.xml
index b091b08e00..9499212615 100644
--- a/tests/framework/DataObjects/load_csv_dataset.xml
+++ b/tests/framework/DataObjects/load_csv_dataset.xml
@@ -59,9 +59,8 @@
342
-
+ uni
- 110.0
diff --git a/tests/framework/Optimizers/RavenRunningRaven/inner_opt.xml b/tests/framework/Optimizers/RavenRunningRaven/inner_opt.xml
index 75a994de31..828dc92443 100644
--- a/tests/framework/Optimizers/RavenRunningRaven/inner_opt.xml
+++ b/tests/framework/Optimizers/RavenRunningRaven/inner_opt.xml
@@ -39,6 +39,8 @@
-0.751
+ 1
+ 1reg
diff --git a/tests/framework/Optimizers/custom_vector_init.xml b/tests/framework/Optimizers/custom_vector_init.xml
index 6eca404d9f..07ba4ad520 100644
--- a/tests/framework/Optimizers/custom_vector_init.xml
+++ b/tests/framework/Optimizers/custom_vector_init.xml
@@ -68,10 +68,9 @@
6-6
-
+ 6-6
- 11ans-2
-
+ 6-60
- 11ans
diff --git a/tests/framework/Samplers/VectorSamples/gold/MC/solns.csv b/tests/framework/Samplers/VectorSamples/gold/MC/solns.csv
index 6e5d57ff22..5b66cb6afc 100644
--- a/tests/framework/Samplers/VectorSamples/gold/MC/solns.csv
+++ b/tests/framework/Samplers/VectorSamples/gold/MC/solns.csv
@@ -1,31 +1,31 @@
-t,scalarIn,vectorIn,scalarOut,vectorOut
-0,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-1,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-2,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-3,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-4,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-5,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-6,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-7,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-8,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-9,1.3745401144,2.79654298439,1.88936052609,7.82065266352
-0,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-1,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-2,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-3,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-4,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-5,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-6,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-7,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-8,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-9,1.95071431178,2.18343478771,3.8052863262,4.7673874722
-0,1.7319939385,2.77969099762,2.999803003,7.72668204227
-1,1.7319939385,2.77969099762,2.999803003,7.72668204227
-2,1.7319939385,2.77969099762,2.999803003,7.72668204227
-3,1.7319939385,2.77969099762,2.999803003,7.72668204227
-4,1.7319939385,2.77969099762,2.999803003,7.72668204227
-5,1.7319939385,2.77969099762,2.999803003,7.72668204227
-6,1.7319939385,2.77969099762,2.999803003,7.72668204227
-7,1.7319939385,2.77969099762,2.999803003,7.72668204227
-8,1.7319939385,2.77969099762,2.999803003,7.72668204227
-9,1.7319939385,2.77969099762,2.999803003,7.72668204227
+t,scalarIn,vectorIn,scalarOut,vectorOut,vectorConst1,vectorConst2
+0,1.3745401144,2.79654298439,1.88936052609,7.82065266352,1,a
+1,1.3745401144,2.79654298439,1.88936052609,7.82065266352,2,b
+2,1.3745401144,2.79654298439,1.88936052609,7.82065266352,3,c
+3,1.3745401144,2.79654298439,1.88936052609,7.82065266352,4,d
+4,1.3745401144,2.79654298439,1.88936052609,7.82065266352,5,e
+5,1.3745401144,2.79654298439,1.88936052609,7.82065266352,6,f
+6,1.3745401144,2.79654298439,1.88936052609,7.82065266352,7,g
+7,1.3745401144,2.79654298439,1.88936052609,7.82065266352,8,h
+8,1.3745401144,2.79654298439,1.88936052609,7.82065266352,9,i
+9,1.3745401144,2.79654298439,1.88936052609,7.82065266352,10,j
+0,1.95071431178,2.18343478771,3.8052863262,4.7673874722,1,a
+1,1.95071431178,2.18343478771,3.8052863262,4.7673874722,2,b
+2,1.95071431178,2.18343478771,3.8052863262,4.7673874722,3,c
+3,1.95071431178,2.18343478771,3.8052863262,4.7673874722,4,d
+4,1.95071431178,2.18343478771,3.8052863262,4.7673874722,5,e
+5,1.95071431178,2.18343478771,3.8052863262,4.7673874722,6,f
+6,1.95071431178,2.18343478771,3.8052863262,4.7673874722,7,g
+7,1.95071431178,2.18343478771,3.8052863262,4.7673874722,8,h
+8,1.95071431178,2.18343478771,3.8052863262,4.7673874722,9,i
+9,1.95071431178,2.18343478771,3.8052863262,4.7673874722,10,j
+0,1.7319939385,2.77969099762,2.999803003,7.72668204227,1,a
+1,1.7319939385,2.77969099762,2.999803003,7.72668204227,2,b
+2,1.7319939385,2.77969099762,2.999803003,7.72668204227,3,c
+3,1.7319939385,2.77969099762,2.999803003,7.72668204227,4,d
+4,1.7319939385,2.77969099762,2.999803003,7.72668204227,5,e
+5,1.7319939385,2.77969099762,2.999803003,7.72668204227,6,f
+6,1.7319939385,2.77969099762,2.999803003,7.72668204227,7,g
+7,1.7319939385,2.77969099762,2.999803003,7.72668204227,8,h
+8,1.7319939385,2.77969099762,2.999803003,7.72668204227,9,i
+9,1.7319939385,2.77969099762,2.999803003,7.72668204227,10,j
diff --git a/tests/framework/Samplers/VectorSamples/mc.xml b/tests/framework/Samplers/VectorSamples/mc.xml
index 24deca70f4..4d49900ae7 100644
--- a/tests/framework/Samplers/VectorSamples/mc.xml
+++ b/tests/framework/Samplers/VectorSamples/mc.xml
@@ -48,10 +48,11 @@
u1
-
+ u2
- 10
+ 1,2,3,4,5,6,7,8,9,10
+ a,b,c,d,e,f,g,h,i,j
@@ -68,8 +69,8 @@
scalarIn,vectorIn
-
- vectorIn,vectorOut
+
+ vectorIn,vectorOut,vectorConst1,vectorConst2