Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Daniel Boeckenhoff
tfields
Commits
ed4777c7
Commit
ed4777c7
authored
May 23, 2018
by
Daniel Böckenhoff
Browse files
tensorFields.fields is None sometimes -> fixme
parent
56cd389f
Changes
4
Hide whitespace changes
Inline
Side-by-side
tfields/__init__.py
View file @
ed4777c7
...
...
@@ -7,3 +7,15 @@ from .lib import *
from
.core
import
Tensors
,
TensorFields
,
TensorMaps
from
.points3D
import
Points3D
from
.mask
import
getMask
# methods:
from
.mask
import
getMask
# NOQA
from
.lib
import
*
# NOQA
# classes:
from
.points3D
import
Points3D
# NOQA
from
.mesh3D
import
Mesh3D
# NOQA
from
.triangles3D
import
Triangles3D
# NOQA
from
.scalarField3D
import
ScalarField3D
# NOQA
from
.vectorField3D
import
VectorField3D
# NOQA
from
.planes3D
import
Planes3D
# NOQA
tfields/core.py
View file @
ed4777c7
...
...
@@ -14,7 +14,6 @@ from collections import Counter
import
sympy
import
scipy
as
sp
import
scipy.spatial
# NOQA: F401
import
scipy.stats
as
stats
import
os
from
six
import
string_types
import
pathlib
...
...
@@ -97,7 +96,10 @@ class AbstractNdarray(np.ndarray):
if
attr
not
in
kwargs
:
kwargs
[
attr
]
=
default
if
dtype
is
not
None
:
kwargs
[
attr
]
=
np
.
array
(
kwargs
[
attr
],
dtype
=
dtype
)
try
:
kwargs
[
attr
]
=
np
.
array
(
kwargs
[
attr
],
dtype
=
dtype
)
except
Exception
as
err
:
raise
ValueError
(
str
(
attr
)
+
str
(
dtype
)
+
str
(
kwargs
[
attr
])
+
str
(
err
))
def
__setattr__
(
self
,
name
,
value
):
if
name
in
self
.
__slots__
:
...
...
@@ -323,12 +325,17 @@ class Tensors(AbstractNdarray):
__slot_setters__
=
[
tfields
.
bases
.
get_coord_system_name
]
def
__new__
(
cls
,
tensors
,
**
kwargs
):
dtype
=
kwargs
.
pop
(
'dtype'
,
np
.
float64
)
order
=
kwargs
.
pop
(
'order'
,
None
)
''' copy constructor '''
if
issubclass
(
type
(
tensors
),
cls
):
obj
=
tensors
.
copy
()
if
dtype
!=
obj
.
dtype
or
order
is
not
None
:
obj
.
astype
(
dtype
,
order
=
order
)
coordSys
=
kwargs
.
pop
(
'coordSys'
,
None
)
if
kwargs
:
raise
AttributeError
(
"In copy constructor only 'coordSys' "
raise
AttributeError
(
"In copy constructor only
'dtype' and
'coordSys' "
"attribute is supported. Kwargs {kwargs} "
"are not consumed"
.
format
(
**
locals
()))
...
...
@@ -336,8 +343,6 @@ class Tensors(AbstractNdarray):
obj
.
transform
(
coordSys
)
return
obj
dtype
=
kwargs
.
pop
(
'dtype'
,
np
.
float64
)
order
=
kwargs
.
pop
(
'order'
,
None
)
dim
=
kwargs
.
pop
(
'dim'
,
None
)
''' process empty inputs '''
...
...
@@ -367,7 +372,7 @@ class Tensors(AbstractNdarray):
''' set kwargs to slots attributes '''
for
attr
in
kwargs
:
if
attr
not
in
cls
.
_iter_slots
():
raise
AttributeError
(
"Keywordargument {attr} not accepted "
raise
AttributeError
(
"Keyword
argument {attr} not accepted "
"for class {cls}"
.
format
(
**
locals
()))
setattr
(
obj
,
attr
,
kwargs
[
attr
])
...
...
@@ -740,18 +745,7 @@ class Tensors(AbstractNdarray):
Args:
moment (int): n-th moment
"""
if
moment
==
0
:
return
0
if
moment
==
1
:
# center of mass
return
np
.
average
(
self
,
axis
=
0
)
elif
moment
==
2
:
# variance
return
np
.
var
(
self
,
axis
=
0
)
elif
moment
==
3
and
stats
:
# skewness
return
stats
.
skew
(
self
,
axis
=
0
)
elif
moment
==
4
and
stats
:
# kurtosis
return
stats
.
kurtosis
(
self
,
axis
=
0
)
else
:
raise
NotImplementedError
(
"Moment %i not implemented."
%
moment
)
return
tfields
.
lib
.
stats
.
getMoment
(
self
,
moment
)
def
closestPoints
(
self
,
other
,
**
kwargs
):
"""
...
...
@@ -838,14 +832,6 @@ class Tensors(AbstractNdarray):
inst
=
self
[
mask
].
copy
()
return
inst
def
mapToCut
(
self
,
cutOrMeshMap
,
coordSys
=
None
,
atIntersection
=
"remove"
):
"""
Args:
cutOrMeshMap (cutExpression / Mesh3D with faceScalars)
"""
# in current implementation Points3D use always cut method, never MeshMap
return
self
.
cut
(
cutOrMeshMap
,
coordSys
=
coordSys
),
None
def
distances
(
self
,
other
,
**
kwargs
):
"""
Args:
...
...
@@ -959,19 +945,110 @@ class TensorFields(Tensors):
>>> multiField.fields[1].dim
3
Copying
>>> cp = TensorFields(vectorField)
>>> assert vectorField.equal(cp)
"""
__slots__
=
[
'coordSys'
,
'fields'
]
def
__new__
(
cls
,
tensors
,
*
fields
,
**
kwargs
):
obj
=
super
(
TensorFields
,
cls
).
__new__
(
cls
,
tensors
,
**
kwargs
)
obj
.
fields
=
list
(
fields
)
if
fields
or
(
issubclass
(
type
(
tensors
),
cls
)
and
fields
):
obj
.
fields
=
[
Tensors
(
field
)
for
field
in
fields
]
return
obj
def
__getitem__
(
self
,
index
):
"""
In addition to the usual, also slice fields
Examples:
>>> from tfields import Tensors, TensorFields
>>> import numpy as np
>>> vectors = Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]])
>>> scalarField = TensorFields(vectors, [42, 21, 10.5], [1, 2, 3])
Slicing
>>> sliced = scalarField[2:]
>>> assert isinstance(sliced, TensorFields)
>>> assert isinstance(sliced.fields[0], Tensors)
>>> assert sliced.fields[0].equal([10.5])
Picking
>>> picked = scalarField[1]
>>> assert np.array_equal(picked, [0, 0, 1])
Masking
>>> masked = scalarField[[True, False, True]]
>>> assert masked.equal([[0, 0, 0], [0, -1, 0]])
>>> assert masked.fields[0].equal([42, 10.5])
>>> assert masked.fields[1].equal([1, 3])
"""
item
=
super
(
TensorFields
,
self
).
__getitem__
(
index
)
if
isinstance
(
item
,
TensorFields
):
if
isinstance
(
index
,
slice
):
item
.
fields
=
[
field
.
__getitem__
(
index
)
for
field
in
item
.
fields
]
elif
isinstance
(
index
,
tuple
):
item
.
fields
=
[
field
.
__getitem__
(
index
[
0
])
for
field
in
item
.
fields
]
else
:
item
.
fields
=
[
field
.
__getitem__
(
index
)
for
field
in
item
.
fields
]
return
item
def
__setitem__
(
self
,
index
,
item
):
"""
In addition to the usual, also slice fields
Examples:
>>> from tfields import Tensors, TensorFields
>>> import numpy as np
>>> original = TensorFields([[0, 0, 0], [0, 0, 1], [0, -1, 0]],
... [42, 21, 10.5], [1, 2, 3])
>>> obj = TensorFields([[0, 0, 0], [0, 0, np.nan], [0, -1, 0]],
... [42, 22, 10.5], [1, -1, 3])
>>> slice_obj = obj.copy()
>>> assert not obj.equal(original)
>>> obj[1] = original[1]
>>> assert obj[:2].equal(original[:2])
>>> assert not slice_obj.equal(original)
>>> slice_obj[:] = original[:]
>>> assert slice_obj.equal(original)
"""
super
(
TensorFields
,
self
).
__setitem__
(
index
,
item
)
if
isinstance
(
item
,
TensorFields
):
if
isinstance
(
index
,
slice
):
for
i
,
field
in
enumerate
(
item
.
fields
):
self
.
fields
[
i
].
__setitem__
(
index
,
field
)
elif
isinstance
(
index
,
tuple
):
for
i
,
field
in
enumerate
(
item
.
fields
):
self
.
fields
[
i
].
__setitem__
(
index
[
0
],
field
)
else
:
for
i
,
field
in
enumerate
(
item
.
fields
):
self
.
fields
[
i
].
__setitem__
(
index
,
field
)
def
transform
(
self
,
coordSys
):
super
(
TensorFields
,
self
).
transform
(
coordSys
)
for
field
in
self
.
fields
:
field
.
transform
(
coordSys
)
def
equal
(
self
,
other
,
**
kwargs
):
"""
Test, whether the instance has the same content as other.
Args:
optional:
see Tensors.equal
"""
if
not
issubclass
(
type
(
other
),
Tensors
):
return
super
(
TensorFields
,
self
).
equal
(
other
,
**
kwargs
)
else
:
with
other
.
tmp_transform
(
self
.
coordSys
):
mask
=
super
(
TensorFields
,
self
).
equal
(
other
,
**
kwargs
)
if
issubclass
(
type
(
other
),
TensorFields
):
for
i
,
field
in
enumerate
(
self
.
fields
):
mask
&=
field
.
equal
(
other
.
fields
[
i
],
**
kwargs
)
return
mask
class
TensorMaps
(
TensorFields
):
"""
...
...
@@ -986,21 +1063,182 @@ class TensorMaps(TensorFields):
>>> from tfields import Tensors, TensorMaps
>>> scalars = Tensors([0, 1, 2])
>>> vectors = Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]])
>>> mesh = TensorMaps(vectors, scalars, maps=[[[0, 1, 2], [0, 1, 2]],
... [[1, 1, 1], [2, 2, 2]]])
>>> mesh.maps
array([[[0, 1, 2],
[0, 1, 2]],
<BLANKLINE>
[[1, 1, 1],
[2, 2, 2]]])
>>> maps = [TensorFields([[0, 1, 2], [0, 1, 2]], [42, 21]),
... TensorFields([[1], [2]], [-42, -21])]
>>> mesh = TensorMaps(vectors, scalars,
... maps=maps)
>>> assert isinstance(mesh.maps, list)
>>> assert len(mesh.maps) == 2
>>> print mesh.fields
>>> print mesh.maps[0].fields
"""
__slots__
=
[
'coordSys'
,
'fields'
,
'maps'
]
__slotDtypes__
=
[
None
,
None
,
int
]
def
__new__
(
cls
,
tensors
,
*
fields
,
**
kwargs
):
maps
=
kwargs
.
pop
(
'maps'
,
[])
maps_cp
=
[]
for
mp
in
maps
:
try
:
mp
=
TensorFields
(
mp
,
dtype
=
int
)
except
Exception
as
err
:
raise
ValueError
(
"Could not cast map {mp} to TensorFields instance."
" Error '{err}' occured."
.
format
(
**
locals
()))
maps_cp
.
append
(
mp
)
kwargs
[
'maps'
]
=
maps_cp
obj
=
super
(
TensorMaps
,
cls
).
__new__
(
cls
,
tensors
,
*
fields
,
**
kwargs
)
return
obj
def
stale
(
self
):
"""
Returns:
Mask for all vertices that are stale i.e. are not refered by maps
Examples:
>>> from tfields import Tensors, TensorMaps
>>> vectors = Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0], [4, 4, 4]])
>>> tm = TensorMaps(vectors, maps=[[[0, 1, 2], [0, 1, 2]],
... [[1, 1], [2, 2]]])
>>> assert np.array_equal(tm.stale(), [False, False, False, True])
"""
staleMask
=
np
.
full
(
self
.
shape
[
0
],
False
,
dtype
=
bool
)
used
=
set
([
ind
for
mp
in
self
.
maps
for
ind
in
mp
.
flatten
()])
for
i
in
range
(
self
.
shape
[
0
]):
if
i
not
in
used
:
staleMask
[
i
]
=
True
return
staleMask
def
cleaned
(
self
,
stale
=
True
,
duplicates
=
True
):
"""
Args:
stale (bool): remove stale vertices
duplicates (bool): replace duplicate vertices by originals
Examples:
>>> import tfields
>>> mp1 = tfields.TensorFields([[0, 1, 2], [3, 4, 5]],
... [[1,2,3,4,5], [6,7,8,9,0]])
>>> mp2 = tfields.TensorFields([[0], [3]])
>>> tm = tfields.TensorMaps([[0,0,0], [1,1,1], [2,2,2], [0,0,0],
... [3,3,3], [4,4,4], [5,6,7]],
... maps=[mp1, mp2])
# >>> c = tm.cleaned()
# >>> assert c.equal([[0., 0., 0.],
# ... [1., 1., 1.],
# ... [2., 2., 2.],
# ... [3., 3., 3.],
# ... [4., 4., 4.]])
# >>> c.maps
# [array([[0, 1, 2],
# [0, 3, 4]]),
# array([[0], [0]])]
Returns:
copy of self without stale vertices and duplicat points (depending on arguments)
"""
# remove stale vertices
if
stale
:
stale_mask
=
self
.
stale
()
else
:
stale_mask
=
np
.
full
(
self
.
shape
[
0
],
False
,
dtype
=
bool
)
# remove duplicates in order to not have any artificial separations
inst
=
self
if
duplicates
:
inst
=
self
.
copy
()
duplicates
=
tfields
.
duplicates
(
self
,
axis
=
0
)
for
tensor_index
,
duplicate_index
in
zip
(
range
(
self
.
shape
[
0
]),
duplicates
):
if
duplicate_index
!=
tensor_index
:
stale_mask
[
tensor_index
]
=
True
# redirect maps
for
map_index
in
range
(
len
(
self
.
maps
)):
for
f
in
range
(
self
.
maps
[
map_index
].
shape
[
0
]):
if
tensor_index
in
self
.
maps
[
f
]:
index
=
tfields
.
index
(
self
.
maps
[
map_index
][
f
],
tensor_index
)
inst
.
maps
[
map_index
][
f
][
index
]
=
duplicate_index
return
inst
.
removed
(
stale_mask
)
def
removed
(
self
,
remove_condition
):
"""
Return copy of self without vertices where remove_condition is True
Copy because self is immutable
Examples:
>>> m = tfields.TensorMaps([[0,0,0], [1,1,1], [2,2,2], [0,0,0],
... [3,3,3], [4,4,4], [5,5,5]],
... maps=[TensorFields([[0, 1, 2], [0, 1, 3],
... [3, 4, 5], [3, 4, 1],
... [3, 4, 6]],
... [[1,2], [3,4], [5,6], [7,8], [9,0]])])
>>> m.maps[0].fields
>>> c = m.removed([True, True, True, False, False, False, False])
>>> c
TensorMaps([[ 0., 0., 0.],
[ 3., 3., 3.],
[ 4., 4., 4.],
[ 5., 5., 5.]])
>>> c.maps[0]
array([[0, 1, 2],
[0, 1, 3]])
>>> c.maps[0].fields
array([[ 5., 6.],
[ 9., 0.]])
"""
remove_condition
=
np
.
array
(
remove_condition
)
# built instance that only contains the vaild points
inst
=
self
[
~
remove_condition
].
copy
()
delete_indices
=
np
.
arange
(
self
.
shape
[
0
])[
remove_condition
]
face_keep_masks
=
self
.
to_maps_masks
(
~
remove_condition
)
for
map_index
,
face_keep_mask
in
enumerate
(
face_keep_masks
):
moveUpCounter
=
np
.
zeros
(
self
.
maps
[
map_index
].
shape
,
dtype
=
int
)
# correct map:
for
p
in
delete_indices
:
moveUpCounter
[
self
.
maps
[
map_index
]
>
p
]
-=
1
inst
.
maps
[
map_index
]
=
(
self
.
maps
[
map_index
]
+
moveUpCounter
)[
face_keep_mask
]
return
inst
def
to_maps_masks
(
self
,
mask
):
"""
Examples:
>>> from tfields import TensorMaps
>>> m = TensorMaps([[1,2,3], [3,3,3], [0,0,0], [5,6,7]],
... maps=[[0, 1, 2], [1, 2, 3]])
>>> from sympy.abc import x,y,z
>>> vertexMask = m.getMask(z < 6)
>>> faceMask = m.to_maps_masks(vertexMask)
>>> faceMask
array([ True, False], dtype=bool)
Returns:
mask of faces with all vertices in mask
"""
indices
=
np
.
array
(
range
(
len
(
mask
)))
delete_indices
=
indices
[
~
mask
]
delete_indices
=
set
(
delete_indices
)
# set speeds up everything enormously
masks
=
[]
for
map_index
in
range
(
len
(
self
.
maps
)):
map_delete_mask
=
np
.
full
((
len
(
self
.
maps
[
map_index
]),),
False
,
dtype
=
bool
)
for
i
,
mp
in
enumerate
(
self
.
maps
[
0
]):
for
index
in
set
(
mp
):
if
index
in
delete_indices
:
map_delete_mask
[
i
]
=
True
break
masks
.
append
(
~
map_delete_mask
)
return
masks
if
__name__
==
'__main__'
:
# pragma: no cover
import
doctest
doctest
.
testmod
()
# doctest.run_docstring_examples(TensorMaps, globals())
# doctest.testmod()
# doctest.run_docstring_examples(TensorMaps.cleaned, globals())
doctest
.
run_docstring_examples
(
TensorMaps
,
globals
())
tfields/lib/__init__.py
View file @
ed4777c7
...
...
@@ -106,3 +106,5 @@ if __name__ == '__main__':
else
:
from
.
import
grid
from
.grid
import
igrid
from
.
import
stats
from
.stats
import
mode
,
median
,
mean
tfields/points3D.py
View file @
ed4777c7
...
...
@@ -4,17 +4,9 @@
Author: Daniel Boeckenhoff
Mail: daniel.boeckenhoff@ipp.mpg.de
basic threedimensional tensor
basic threedimensional tensor
s
"""
import
tfields
import
numpy
as
np
import
pathlib
import
os
import
osTools
import
ioTools
import
warnings
import
loggingTools
logger
=
loggingTools
.
Logger
(
__name__
)
class
Points3D
(
tfields
.
Tensors
):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment