property links

This commit is contained in:
Rowan Cockett
2015-06-01 15:06:58 -07:00
parent 760f24ea33
commit 4df00148a3
2 changed files with 77 additions and 16 deletions
+30 -5
View File
@@ -4,7 +4,6 @@ class Property(object):
name = ''
doc = ''
# mappingPair = None
defaultVal = None
defaultInvProp = False
@@ -14,11 +13,23 @@ class Property(object):
self.doc = doc
Utils.setKwargs(self, **kwargs)
@property
def propertyLink(self):
"Can be something like: ('sigma', Maps.ReciprocalMap)"
return getattr(self, '_propertyLink', None)
@propertyLink.setter
def propertyLink(self, value):
assert type(value) is tuple and len(value) == 2 and type(value[0]) is str and issubclass(value[1], Maps.IdentityMap), 'Use format: ("%s", Maps.ReciprocalMap)'%self.name
self._propertyLink = value
def _getMapProperty(self):
prop = self
def fget(self):
return getattr(self, '_%sMap'%prop.name, None)
def fset(self, val):
if prop.propertyLink is not None:
linkName, linkMap = prop.propertyLink
assert getattr(self, '%sMap'%linkName, None) is None, 'Cannot set both sides of a linked property.'
# TODO: Check if the mapping can be correct
setattr(self, '_%sMap'%prop.name, val)
return property(fget=fget, fset=fset, doc=prop.doc)
@@ -35,19 +46,33 @@ class Property(object):
prop = self
def fget(self):
mapping = getattr(self, '%sMap'%prop.name)
if mapping is None:
if mapping is None and prop.propertyLink is None:
return prop.defaultVal
m = getattr(self, '%sModel'%prop.name)
if mapping is None and prop.propertyLink is not None:
linkName, linkMapClass = prop.propertyLink
linkMap = linkMapClass(None)
m = getattr(self, '%s'%linkName)
return linkMap * m
m = getattr(self, '%sModel'%prop.name)
return mapping * m
return property(fget=fget)
def _getModelDerivProperty(self):
prop = self
def fget(self):
m = getattr(self, '%sModel'%prop.name)
mapping = getattr(self, '%sMap'%prop.name)
if mapping is None:
if mapping is None and prop.propertyLink is None:
return None
if mapping is None and prop.propertyLink is not None:
linkName, linkMapClass = prop.propertyLink
linkMap = linkMapClass(None) * getattr(self, '%sMap'%linkName)
m = getattr(self, '%s'%linkName)
return linkMap.deriv( m )
m = getattr(self, '%sModel'%prop.name)
return mapping.deriv( m )
return property(fget=fget)
+47 -11
View File
@@ -5,7 +5,12 @@ from scipy.constants import mu_0
class MyPropMap(Maps.PropMap):
sigma = Maps.Property("Electrical Conductivity", defaultInvProp=True)
mu = Maps.Property("Electrical Conductivity", defaultVal=mu_0)
mu = Maps.Property("Mu", defaultVal=mu_0)
class MyReciprocalPropMap(Maps.PropMap):
sigma = Maps.Property("Electrical Conductivity", defaultInvProp=True, propertyLink=('rho', Maps.ReciprocalMap))
rho = Maps.Property("Electrical Resistivity", propertyLink=('sigma', Maps.ReciprocalMap))
mu = Maps.Property("Mu", defaultVal=mu_0)
class TestPropMaps(unittest.TestCase):
@@ -30,15 +35,15 @@ class TestPropMaps(unittest.TestCase):
assert PM.muMap is None
assert PM.muIndex is None
m = PM(np.r_[1,2,3])
m = PM(np.r_[1.,2,3])
assert m.mu == mu_0
assert m.muModel is None
assert m.muMap is None
assert m.muDeriv is None
assert np.all(m.sigmaModel == np.r_[1,2,3])
assert np.all(m.sigmaModel == np.r_[1.,2,3])
assert m.sigmaMap is expMap
assert np.all(m.sigma == np.exp(np.r_[1,2,3]))
assert np.all(m.sigma == np.exp(np.r_[1.,2,3]))
assert m.sigmaDeriv is not None
assert m.nP == 3
@@ -47,7 +52,7 @@ class TestPropMaps(unittest.TestCase):
expMap = Maps.ExpMap(Mesh.TensorMesh((3,)))
PM = MyPropMap({'maps':[('sigma', expMap)], 'slices':{'sigma':[2,1,0]}})
assert PM.sigmaIndex == [2,1,0]
m = PM(np.r_[1,2,3])
m = PM(np.r_[1.,2,3])
assert np.all(m.sigmaModel == np.r_[3,2,1])
assert np.all(m.sigma == np.exp(np.r_[3,2,1]))
@@ -57,14 +62,14 @@ class TestPropMaps(unittest.TestCase):
iMap = Maps.IdentityMap(m)
PM = MyPropMap([('sigma', expMap), ('mu', iMap)])
pm = PM(np.r_[1,2,3,4,5,6])
pm = PM(np.r_[1.,2,3,4,5,6])
assert pm.nP == 6
assert np.all(pm.sigmaModel == [1,2,3])
assert np.all(pm.sigma == np.exp([1,2,3]))
assert np.all(pm.muModel == [4,5,6])
assert np.all(pm.mu == [4,5,6])
assert np.all(pm.sigmaModel == [1.,2,3])
assert np.all(pm.sigma == np.exp([1.,2,3]))
assert np.all(pm.muModel == [4.,5,6])
assert np.all(pm.mu == [4.,5,6])
def test_multiMapCompressed(self):
@@ -73,7 +78,7 @@ class TestPropMaps(unittest.TestCase):
iMap = Maps.IdentityMap(m)
PM = MyPropMap({'maps':[('sigma', expMap), ('mu', iMap)],'slices':{'mu':[0,1,2]}})
pm = PM(np.r_[1,2,3])
pm = PM(np.r_[1,2.,3])
assert pm.nP == 3
@@ -82,6 +87,37 @@ class TestPropMaps(unittest.TestCase):
assert np.all(pm.muModel == [1,2,3])
assert np.all(pm.mu == [1,2,3])
def test_Links(self):
m = Mesh.TensorMesh((3,))
expMap = Maps.ExpMap(m)
iMap = Maps.IdentityMap(m)
PM = MyReciprocalPropMap([('sigma', iMap)])
pm = PM(np.r_[1,2.,3])
# print pm.sigma
# print pm.sigmaMap
assert np.all(pm.sigma == [1,2,3])
assert np.all(pm.rho == 1./np.r_[1,2,3])
assert pm.sigmaMap is iMap
assert pm.rhoMap is None
assert pm.sigmaDeriv is not None
assert pm.rhoDeriv is not None
PM = MyReciprocalPropMap([('rho', iMap)])
pm = PM(np.r_[1,2.,3])
# print pm.sigma
# print pm.sigmaMap
assert np.all(pm.sigma == 1./np.r_[1,2,3])
assert np.all(pm.rho == [1,2,3])
assert pm.sigmaMap is None
assert pm.rhoMap is iMap
assert pm.sigmaDeriv is not None
assert pm.rhoDeriv is not None
self.assertRaises(AssertionError, MyReciprocalPropMap, [('rho', iMap), ('sigma', iMap)])
self.assertRaises(AssertionError, MyReciprocalPropMap, [('sigma', iMap), ('rho', iMap)])
MyReciprocalPropMap([('sigma', iMap), ('mu', iMap)]) # This should be fine
if __name__ == '__main__':
unittest.main()