From fbda6ab53b3d5c47c4f0e507f2c64ea0745484db Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 1 Jun 2015 09:34:16 -0700 Subject: [PATCH] updates to init of propMap --- SimPEG/Utils/PropMaps.py | 76 +++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/SimPEG/Utils/PropMaps.py b/SimPEG/Utils/PropMaps.py index e4c49407..7b40a0ec 100644 --- a/SimPEG/Utils/PropMaps.py +++ b/SimPEG/Utils/PropMaps.py @@ -98,6 +98,14 @@ class _PropMapMetaClass(type): attrs['_properties'] = _properties + # You are only allowed one default inversion property. + defaultInvProps = [] + for p in _properties: + if _properties[p].defaultInvProp: + defaultInvProps += [p] + if len(defaultInvProps) > 1: + raise Exception('You have more than one default inversion property: %s' % defaultInvProps) + newClass = super(_PropMapMetaClass, cls).__new__(cls, name, bases, attrs) newClass.PropModel = cls.createPropModelClass(newClass, name, _properties) @@ -126,11 +134,65 @@ class _PropMapMetaClass(type): class PropMap(object): __metaclass__ = _PropMapMetaClass - def __init__(self, ): + def __init__(self, mappings): """ PropMap takes a multi parameter model and maps it to the equivalent PropModel """ - pass + if type(mappings) is dict: + assert np.all([k in ['maps', 'slices'] for k in mappings]), 'Dict must only have properties "maps" and "slices"' + self.setup(mappings['maps'], slices=mappings['slices']) + if type(mappings) is list: + self.setup(mappings) + elif isinstance(mappings, Maps.IdentityMap): + self.setup([(self.defaultInvProp, mappings)]) + else: + raise Exception('mappings must be a dict, a mapping, or a list of tuples.') + + + def setup(self, maps, slices=None): + """ + Sets up the maps and slices for the PropertyMap + + + :param list maps: [('sigma', sigmaMap), ('mu', muMap), ...] + :param list slices: [('sigma', slice(0,nP)), ('mu', [1,2,5,6]), ...] + + """ + assert np.all([ + type(m) is tuple and + len(m)==2 and + type(m[0]) is str and + m[0] in self._properties and + isinstance(m[1], Maps.IdentityMap) + for m in maps]), "Use signature: [%s]" % (', '.join(["('%s', %sMap)"%(p,p) for p in self._properties])) + if slices is None: + slices = dict() + else: + assert np.all([ + s in self._properties and + (type(s) in [slice, list] or isinstance(s, np.ndarray)) + for s in slices]), 'Slices must be for each property' + + self.clearMaps() + + nP = 0 + for name, mapping in maps: + setattr(self, '%sMap'%name, mapping) + setattr(self, '%sIndex'%name, slices.get(name, slice(nP, nP + mapping.nP))) + nP += mapping.nP + + + @property + def defaultInvProp(self): + for name in self._properties: + p = self._properties[name] + if p.defaultInvProp: + return p.name + + def clearMaps(self): + for name in self._properties: + setattr(self, '%sMap'%name, None) + setattr(self, '%sIndex'%name, None) def __call__(self, vec): return self.PropModel(self, vec) @@ -138,9 +200,6 @@ class PropMap(object): class MyPropMap(PropMap): sigma = Property("Electrical Conductivity", defaultInvProp=True) - # rho = InveseProperty(sigma) - -class My2PropMap(MyPropMap): mu = Property("Electrical Conductivity", defaultVal=4e-10) @@ -154,13 +213,14 @@ if __name__ == '__main__': print expMap.nP # propMap = MyPropMap([('sigma', expMap), ('mu', IMap)], indices={'sigma':[1,2,3,4,7,8]}) - propMap = MyPropMap() - print [n for n in dir(propMap) if n[0] is not '_'] - propMap = My2PropMap() + propMap = MyPropMap([('sigma',expMap)]) print [n for n in dir(propMap) if n[0] is not '_'] + # propMap = My2PropMap() + # print [n for n in dir(propMap) if n[0] is not '_'] propMap.sigmaMap = expMap + print propMap.defaultInvProp print propMap.sigmaMap print propMap.sigmaIndex