Index: /issm/trunk-jpl/src/m/classes/qmu/normal_uncertain.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/qmu/normal_uncertain.m	(revision 24846)
+++ /issm/trunk-jpl/src/m/classes/qmu/normal_uncertain.m	(revision 24847)
@@ -3,12 +3,12 @@
 %   Usage:
 %      nuv=normal_uncertain('descriptor',descriptor,'mean',mean,'stddev',stddev,'partition',partition);
-%      where nuv is the normal_uncertain object returned by the constructor, mean and stddev are self 
-%      explanatory.  partition is the partition vector for distributed variables. Can be a partition 
+%      where nuv is the normal_uncertain object returned by the constructor, mean and stddev are self
+%      explanatory.  partition is the partition vector for distributed variables. Can be a partition
 %      vector over elements or vertices.
-% 
+%
 %   Example:
 %      md.qmu.variables.rheology=normal_uncertain('descriptor','RheologyBBar','mean',1,'stddev',.05);
 %      md.qmu.variables.rheology=normal_uncertain('descriptor','scaled_RheologyBBar','mean',1,'stddev',.05,'partition',vpartition);
-% 
+%
 
 classdef normal_uncertain
@@ -22,14 +22,14 @@
 		function self=normal_uncertain(varargin) %constructor {{{
 
-			%recover options: 
+			%recover options:
 			options = pairoptions(varargin{:});
 
-			%initialize fields: 
+			%initialize fields:
 			self.descriptor=getfieldvalue(options,'descriptor');
 			self.mean=getfieldvalue(options,'mean');
 			self.stddev=getfieldvalue(options,'stddev');
-			
-			%if the variable is scaled,  a partition vector should have been supplied, and 
-			%that partition vector should have as many partitions as the mean and stddev 
+
+			%if the variable is scaled,  a partition vector should have been supplied, and
+			%that partition vector should have as many partitions as the mean and stddev
 			%vectors:
 			if self.isscaled(),
@@ -40,5 +40,5 @@
 				end
 				if npart~=length(self.stddev),
-					error(['normal_uncertain constructor: for the scaled variable' self.described ' the stddev field is not currently a vector of values for all the partitions described in the partition vector']);
+					error(['normal_uncertain constructor: for the scaled variable' self.descriptor ' the stddev field is not currently a vector of values for all the partitions described in the partition vector']);
 				end
 			end
@@ -55,5 +55,5 @@
 			fielddisplay(self,'partition','partition vector defining where sampling will occur');
 		end
-	end 
+	end
 	%}}}
 	function md=checkconsistency(self,md,solution,analyses) % {{{
@@ -65,9 +65,9 @@
 				error('normal_uncertain is a scaled variable, but it''s missing a partition vector');
 			end
-			%better have a partition vector that has as many partitions as stddev's size: 
-			if  length(self.stddev)~=partition_npart(self.partition),
+			%better have a partition vector that has as many partitions as stddev's size:
+			if length(self.stddev)~=partition_npart(self.partition),
 				error('normal_uncertain error message: stddev and partition should be vectors of identical size');
 			end
-			if  length(self.mean)~=partition_npart(self.partition),
+			if length(self.mean)~=partition_npart(self.partition),
 				error('normal_uncertain error message: mean and partition should be vectors of identical size');
 			end
@@ -77,6 +77,6 @@
 				error('normal_uncertain error message: partition should be a column vector');
 			end
-			partcheck=unique(self.partition); 
-			partmin=min(partcheck); 
+			partcheck=unique(self.partition);
+			partmin=min(partcheck);
 			partmax=max(partcheck);
 			if partmax<-1,
@@ -120,8 +120,8 @@
 	%default
 	function [abscissas] =prop_abscissas(hbu) % {{{
-		abscissas=[]; 
+		abscissas=[];
 	end % }}}
 	function [counts] =prop_counts(hbu) % {{{
-		counts=[]; 
+		counts=[];
 	end % }}}
 	function [pairs_per_variable] =prop_pairs_per_variable(hbu) % {{{
@@ -146,5 +146,5 @@
 		scale=[];
 	end % }}}
-	%new methods: 
+	%new methods:
 	function scaled =isscaled(self) % {{{
 		if strncmp(self.descriptor,'scaled_',7),
Index: /issm/trunk-jpl/src/m/classes/qmu/normal_uncertain.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/qmu/normal_uncertain.py	(revision 24846)
+++ /issm/trunk-jpl/src/m/classes/qmu/normal_uncertain.py	(revision 24847)
@@ -1,161 +1,157 @@
 import numpy as np
-from MatlabArray import *
+from pairoptions import pairoptions
 
 
 class normal_uncertain(object):
     '''
-  definition for the normal_uncertain class.
+    NORMAL_UNCERTAIN class definition
 
-  [nuv] = normal_uncertain.normal_uncertain(args)
-   nuv = normal_uncertain()
+        Usage:
+            nuv = normal_uncertain('descriptor',descriptor,'mean',mean,'stddev',stddev,'partition',partition)
+            where nuv is the normal_uncertain object returned by the constructor, mean and stddev are self
+            explanatory.  partition is the partition vector for distributed variables. Can be a partition
+            vector over elements or vertices.
 
-  where the required args are:
-    descriptor    (str, description, '')
-    mean          (float, mean, float('NaN'))
-    stddev        (float, standard deviation, float('NaN'))
-  and the optional args and defaults are:
-    lower         (float, lower bound, -np.Inf)
-    upper         (float, upper bound, np.Inf)
-
-  note that zero arguments constructs a default instance, one
-  argument of the class copies the instance, and three or more
-  arguments constructs a new instance from the arguments.
-'''
-    def __init__(self):
+        Example:
+            md.qmu.variables.rheology=normal_uncertain('descriptor','RheologyBBar','mean',1,'stddev',.05);
+            md.qmu.variables.rheology=normal_uncertain('descriptor','scaled_RheologyBBar','mean',1,'stddev',.05,'partition',vpartition);
+    '''
+    def __init__(self, *args): #{{{
         self.descriptor = ''
         self.mean = float('NaN')
         self.stddev = float('NaN')
-        self.lower = -np.Inf
-        self.upper = np.Inf
+        self.partition = []
+
+        #recover options:
+        options = pairoptions(*args)
+
+        #initialize fields:
+        self.descriptor = getfieldvalue(options, 'descriptor')
+        self.mean = getfieldvalue(options, 'mean')
+        self.stddev = getfieldvalue(options, 'stddev')
+
+        #if the variable is scales, a partition vector should have been supplied, and
+        #that partition vector should have as many partitions as the mean and stddev
+        #vectors:
+        if self.isscaled():
+            self.partition = getfieldvalue(options, 'partition')
+            npart = partition_npart(self.partition)
+            if npart != len(self.mean):
+                error("normal_uncertain constructor: for the scaled variable %s the mean field is not currently a vector of values for all the partitions described in the partition vector" % self.descriptor)
+            if npart != len(self.stddev):
+                error("normal_uncertain constructor: for the scaled variable %s the stddev field is not cureently a vector of values for all the partitions described in the partition vector" % self.descriptor)
+    #}}}
+
+    def __repr__(self):
+        string = '\n'
+        string += 'normal uncertain variable: '
+        string += "%s\n%s" % (string, fielddisplay(self, 'descriptor', 'name tag'))
+        string += "%s\n%s" % (string, fielddisplay(self, 'mean', 'pdf mean'))
+        string += "%s\n%s" % (string, fielddisplay(self, 'stddev', 'pdf standard deviation'))
+        if self.partition:
+            string += "%s\n%s" % (string, fielddisplay(self, 'partition', 'partitionb vector defining where sampling will occur'))
+        return string
+    #}}}
+
+    def checkconsistency(self, md, solution, analyses): #{{{
+        md = checkfield(md, 'field', self.mean, 'fieldname', 'normal_uncertain.mean', 'NaN', 1, 'Inf', 1, '>=', 0)
+        md = checkfield(md, 'field', self.stddev, 'fieldname', 'normal_uncertain.stddev', 'NaN', 1, 'Inf', 1, '>=', 0, 'numel', len(self.mean))
+        if self.isscaled():
+            if not self.partition:
+                error("normal_uncertain is a scaled variable, but it's missing a partition vector")
+            #better have a partition vector that has as many partitions as stddev's size:
+            if len(self.stddev) != partition_npart(self.partititon):
+                error("normal_uncertain error message: stddev and partition should be vectors of identical size")
+            if len(self.mean) != partition_npart(self.partition):
+                error("normal_uncertain error message: mean and partition should be vectors of identical size")
+            md = checkfield(md, 'field', self.partition, 'fieldname', 'normal_uncertain.partition', 'NaN', 1, 'Inf', 1, '>=', -1, 'numel', [md.mesh.numberofvertices, md.mesh.numberofvertices])
+            if self.partition.shape[1] > 1:
+                error("normal_uncertain error message: partition should be a column vector")
+            partcheck = np.unique(self.partition)
+            partmin = min(partcheck)
+            partmax = max(partcheck)
+            if partmax < -1:
+                error("normal_uncertain error message: partition vector's min value should be -1 (for no partition), or start at 0")
+            nmax = max(md.mesh.numberofelements, md.mesh.numberofvertices)
+            if partmax > nmax:
+                error("normal_uncertain error message: partition vector's values cannot go over the number of vertices or elements")
+    #}}}
+
+    #virtual functions needed by qmu processing algorithms
+    #implemented:
 
     @staticmethod
-    def normal_uncertain(*args):
-        nargin = len(args)
-
-        # create a default object
-        if nargin == 0:
-            return normal_uncertain()
-
-        # copy the object
-        elif nargin == 1:
-            if isinstance(args[0], normal_uncertain):
-                nuv = args[0]
-            else:
-                raise RuntimeError('Object ' + str(args[0]) + ' is a ' + str(type(args[0])) + ' class object, not "normal_uncertain".')
-
-        # not enough arguments
-        elif nargin == 2:
-            raise RuntimeError('Construction of "normal_uncertain" class object requires at least 3 inputs.')
-
-    # create the object from the input
-        else:
-            # lines differ here in other classes / tests; see asizec problem in notes
-            nuv = normal_uncertain()
-            nuv.descriptor = str(args[0])
-            nuv.mean = args[1]
-            nuv.stddev = args[2]
-            if nargin >= 4:
-                nuv.lower = args[3]
-            if nargin >= 5:
-                nuv.upper = args[4]
-            if nargin > 5:
-                print('WARNING: normal_uncertain:extra_arg: Extra arguments for object of class ' + str(type(nuv)) + '.')
-
-        return [nuv]
-
-    def __repr__(self):
-        # display an individual object
-        string = '\n'
-        string += 'class "normal_uncertain" object = \n'
-        string += '    descriptor: ' + str(self.descriptor) + '\n'
-        string += '          mean: ' + str(self.mean) + '\n'
-        string += '        stddev: ' + str(self.stddev) + '\n'
-        string += '         lower: ' + str(self.lower) + '\n'
-        string += '         upper: ' + str(self.upper) + '\n'
-
-        return string
-
-    # from here on, nuv is either a single, or a 1d vector of, normal_uncertain
-
-    @staticmethod
-    def prop_desc(nuv, dstr):
-        if type(nuv) not in [list, np.ndarray]:
-            if nuv.descriptor != '' or type(nuv.descriptor) != str:
-                desc = str(nuv.descriptor)
-            elif dstr != '':
-                desc = str(dstr)
-            else:
-                desc = 'nuv'
-            return desc
-
+    def prop_desc(nuv, dstr): #{{{
         desc = ['' for i in range(np.size(nuv))]
         for i in range(np.size(nuv)):
-            if nuv[i].descriptor != '' or type(nuv[i].descriptor) != str:
+            if nuv[i].descriptor:
                 desc[i] = str(nuv[i].descriptor)
-            elif dstr != '':
+            elif dstr:
                 desc[i] = str(dstr) + str(string_dim(nuv, i, 'vector'))
             else:
                 desc[i] = 'nuv' + str(string_dim(nuv, i, 'vector'))
-
         desc = allempty(desc)
 
         return desc
+    #}}}
 
     @staticmethod
-    def prop_initpt(nuv):
+    def prop_mean(nuv): #{{{
+        mean = np.zeros(np.size(nuv))
+        for i in range(np.size(nuv)):
+            mean[i] = nuv[i].mean
+        return mean
+    #}}}
+
+    @staticmethod
+    def prop_stddev(nuv): #{{{
+        stddev = np.zeros(np.size(nuv))
+        for i in range(np.size(nuv)):
+            stddev[i] = nuv[i].stddev
+        return stddev
+    #}}}
+
+    #default
+    @staticmethod
+    def prop_abscissas(nbu): #{{{
+        abscissas = []
+        return abscissas
+    #}}}
+
+    @staticmethod
+    def prop_counts(nbu): #{{{
+        counts = []
+        return counts
+    #}}}
+
+    @staticmethod
+    def prop_pairs_per_variable(nbu): #{{{
+        pairs_per_variable = []
+        return pairs_per_variable
+    #}}}
+
+    @staticmethod
+    def prop_initpt(nuv): #{{{
         initpt = []
         return initpt
+    #}}}
 
     @staticmethod
-    def prop_lower(nuv):
-        if type(nuv) not in [list, np.ndarray]:
-            return nuv.lower
-
-        lower = np.zeros(np.size(nuv))
-        for i in range(np.size(nuv)):
-            lower[i] = nuv[i].lower
-
-        lower = allequal(lower, -np.inf)
-
+    def prop_lower(nuv): #{{{
+        lower = []
         return lower
+    #}}}
 
     @staticmethod
     def prop_upper(nuv):
-        if type(nuv) not in [list, np.ndarray]:
-            return nuv.upper
-
-        upper = np.zeros(np.size(nuv))
-        for i in range(np.size(nuv)):
-            upper[i] = nuv[i].upper
-
-        upper = allequal(upper, -np.inf)
+        upper = []
         return upper
-
-    @staticmethod
-    def prop_mean(nuv):
-        if type(nuv) not in [list, np.ndarray]:
-            return nuv.mean
-
-        mean = np.zeros(np.size(nuv))
-        for i in range(np.size(nuv)):
-            mean[i] = nuv[i].mean
-
-        return mean
-
-    @staticmethod
-    def prop_stddev(nuv):
-        if type(nuv) not in [list, np.ndarray]:
-            return nuv.stddev
-
-        stddev = np.zeros(np.size(nuv))
-        for i in range(np.size(nuv)):
-            stddev[i] = nuv[i].stddev
-
-        return stddev
+    #}}}
 
     @staticmethod
     def prop_initst(nuv):
-        initst = []
-        return initst
+        inist = []
+        return inist
+    #}}}
 
     @staticmethod
@@ -163,4 +159,5 @@
         stype = []
         return stype
+    #}}}
 
     @staticmethod
@@ -168,12 +165,23 @@
         scale = []
         return scale
+    #}}}
+
+    #new methods:
+    def isscaled(self): #{{{
+        if self.descriptor[:7] == 'scaled_':
+            return 1
+        else:
+            return 0
+    #}}}
 
     @staticmethod
-    def dakota_write(fidi, dvar):
+    def dakota_write(fidi, dvar): #{{{
         # collect only the variables of the appropriate class
         nuv = [struc_class(i, 'normal_uncertain', 'nuv') for i in dvar]
 
-    # possible namespace pollution, the above import seems not to work
-        from vlist_write import vlist_write
-    # write variables
+        # # possible namespace pollution, the above import seems not to work
+        # from vlist_write import vlist_write
+
+        # write variables
         vlist_write(fidi, 'normal_uncertain', 'nuv', nuv)
+    #}}}
