Commit 46a81e34 authored by dboe's avatar dboe
Browse files

indexing tests work

parent 309bb161
......@@ -71,6 +71,40 @@ class Tensors_Check(AbstractNdarray_Check):
self.assertEqual(self._inst.coord_sys, other.coord_sys)
self.assertEqual(self._inst.name, other.name)
def test_slice_indexing(self):
self.demand_index_equal(slice(0, None, None), 'type')
def test_pick_indexing(self):
self.demand_index_equal(0, (np.ndarray, np.integer, np.float))
def test_mask_indexing(self):
mask = np.array([True if i % 2 == 0 else False
for i in range(len(self._inst))])
self.demand_index_equal(mask, 'type')
def test_iteration(self):
# iteration
iterator = iter(self._inst)
if len(self._inst) > 0:
next(iterator)
def demand_index_equal(self, index, check_type):
if check_type == 'type':
check_type = type(self._inst)
tensors = np.array(self._inst)
if len(self._inst) > 0:
item = self._inst[index]
self.assertTrue(np.array_equal(item, tensors[index]))
self.assertIsInstance(item, check_type)
def check_indexing(self):
if not self._inst.fields and len(self._inst) == 0:
return
fields = [np.array(field) for field in self._inst.fields]
for f, field in enumerate(fields):
self._inst.fields[f]
def test_self_equality(self):
# Test equality
self.demand_equal(self._inst)
......@@ -126,6 +160,7 @@ class Tensors_Check(AbstractNdarray_Check):
class TensorFields_Check(Tensors_Check):
def test_fields(self):
self.assertIsNotNone(self._inst.fields)
if self._inst.fields:
# field is of type list
self.assertTrue(isinstance(self._inst.fields, list))
......@@ -136,11 +171,27 @@ class TensorFields_Check(Tensors_Check):
# fields are copied not reffered by a pointer
self.assertFalse(field is target_field)
def demand_index_equal(self, index, check_type):
super().demand_index_equal(index, check_type)
if len(self._inst) > 0:
item = self._inst[index]
for i, field in enumerate(self._inst.fields):
if check_type == 'type':
check_type = type(self._inst.fields[i])
self.assertTrue(np.array_equal(
item.fields[i], np.array(self._inst.fields[i])[index]))
self.assertIsInstance(item.fields[i], check_type)
class TensorMaps_Check(TensorFields_Check):
def test_maps(self):
self.assertIsNotNone(self._inst.maps)
def demand_index_equal(self, index, check_type):
super().demand_index_equal(index, check_type)
# TODO: this is hard to check generically
"""
EMPTY TESTS
......@@ -200,6 +251,14 @@ class TensorMaps_Test(TensorMaps_Empty_Test):
maps=self._maps)
class TensorMaps_NoFields_Test(TensorMaps_Test):
def setUp(self):
self._inst = tfields.TensorMaps(
[[1, 2, 3], [3, 3, 3], [0, 0, 0], [5, 6, 7]],
maps=[[[0, 1, 2], [1, 2, 3]], [[1]], [[0, 1, 2, 3]]]
)
class Maps_Test(Base_Check, unittest.TestCase):
def demand_equal(self, other):
self._inst.equal(other)
......
......@@ -4,13 +4,13 @@ import unittest
import sympy # NOQA: F401
import os
import sys
from .test_core import TensorFields_Check
from .test_core import TensorMaps_Check
THIS_DIR = os.path.dirname(
os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__))))
sys.path.append(os.path.normpath(os.path.join(THIS_DIR)))
class Mesh3D_Check(TensorFields_Check):
class Mesh3D_Check(TensorMaps_Check):
def test_cut_split(self):
x, y, z = sympy.symbols('x y z')
self._inst.cut(x + 1./100*y > 0, at_intersection='split')
......
......@@ -557,8 +557,10 @@ class AbstractNdarray(np.ndarray, AbstractObject):
>>> import tfields
>>> m = tfields.TensorMaps(
... [[1,2,3], [3,3,3], [0,0,0], [5,6,7]],
... maps=[[[0, 1, 2], [1, 2, 3]], [1, 2])])
... maps=[[[0, 1, 2], [1, 2, 3]], [[1]], [[0, 1, 2, 3]]])
>>> mc = m.copy()
>>> mc.equal(m)
True
>>> mc is m
False
>>> mc.maps[3].fields[0] is m.maps[3].fields[0]
......@@ -1828,10 +1830,11 @@ class TensorFields(Tensors):
>>> import tfields
>>> import numpy as np
>>> vectors = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]])
>>> scalar_field = tfields.TensorFields(vectors,
... [42, 21, 10.5],
... [1, 2, 3],
... [[0, 0], [-1, -1], [-2, -2]])
>>> scalar_field = tfields.TensorFields(
... vectors,
... [42, 21, 10.5],
... [1, 2, 3],
... [[0, 0], [-1, -1], [-2, -2]])
Slicing
......@@ -1858,7 +1861,7 @@ class TensorFields(Tensors):
>>> _ = [point for point in scalar_field]
"""
item = super(TensorFields, self).__getitem__(index)
item = super().__getitem__(index)
try:
if issubclass(type(item), TensorFields):
if isinstance(index, tuple):
......@@ -2112,36 +2115,41 @@ class Maps(sortedcontainers.SortedDict, AbstractObject):
sortedcontainers.SortedItemsView):
args = tuple([v for k, v in args[0]])
elif len(args) == 1 and isinstance(args[0], list):
if args[0]:
# not not Maps([])
if issubclass(type(args[0][0]), tuple):
# Maps([(key, value), (key, value), ...])
args = tuple(v for k,v in args[0])
new_args = tuple()
for entry in args[0]:
if issubclass(type(entry), tuple):
if np.issubdtype(type(entry[0]), np.integer):
# Maps([(key, value), ...])
new_args += (entry[1])
else:
# Maps([(tensors, field1, field2), ...])
new_args += (entry)
else:
# Maps([mp, mp, ...])
args = tuple(args[0])
else:
# Maps([]) -> Maps()
args = tuple()
args = new_args
elif len(args) == 1 and issubclass(type(args[0]), dict):
# Maps([]) - includes Maps i.e. copy
# dangerous because we run beefore super init
args = tuple(args[0].values())
elif len(args) == 0 and kwargs:
args = tuple(kwargs.values())
kwags = {}
kwargs = {}
# By now everything must have been converted to flat args
# Maps(tfields.TensorFields([], dim=3), [[1,2,3]])
arg_tuple_list = []
for i, arg in enumerate(args):
if not isinstance(type(arg), tuple):
dimension = dim(arg)
mp = arg
if isinstance(type(arg), list):
mp = self.to_map(*arg, copy=True)
dimension = dim(mp)
elif not isinstance(type(arg), tuple):
mp = self.to_map(arg, copy=True)
dimension = dim(mp)
else:
dimension, mp = arg
dimension = int(dimension)
arg_tuple_list.append((dimension, self.to_map(mp, copy=True)))
mp = self.to_map(mp, copy=True)
arg_tuple_list.append((dimension, mp))
super().__init__(arg_tuple_list, **kwargs)
......@@ -2149,7 +2157,7 @@ class Maps(sortedcontainers.SortedDict, AbstractObject):
def to_map(mp, *fields, copy=False):
if not copy:
if isinstance(mp, TensorFields) and not fields:
if not np.issubdtype(np.int32, np.integer):
if not np.issubdtype(mp.dtype, np.integer):
mp = mp.astype(int)
else:
copy = True
......@@ -2161,28 +2169,19 @@ class Maps(sortedcontainers.SortedDict, AbstractObject):
)
return mp
def __setitem__(self, dim, mp):
def __setitem__(self, dimension, mp):
mp = self.to_map(mp)
if not dim == mp.dim:
if not dimension == mp.dim:
raise KeyError(
"Incorrect map dimension {mp.dim} for index {dim}"
.format(**locals())
)
if dim == 0:
warnings.warn(
"Using map dimension {dim}"
.format(**locals())
)
super().__setitem__(dim, mp)
super().__setitem__(dimension, mp)
def __getitem__(self, dim):
if dim == 0:
warnings.warn(
"Using map dimension {dim}"
.format(**locals())
)
return super().__getitem__(dim)
def __getitem__(self, dimension):
if dimension == 0:
warnings.warn("Using map dimension 0")
return super().__getitem__(dimension)
def _args(self):
return super()._args() + tuple(self.values())
......@@ -2195,8 +2194,8 @@ class Maps(sortedcontainers.SortedDict, AbstractObject):
"""
if not self.keys() == other.keys():
return False
for dim in self.keys():
if not self[dim].equal(other[dim], **kwargs):
for dimension in self.keys():
if not self[dimension].equal(other[dimension], **kwargs):
return False
return True
......@@ -2311,14 +2310,15 @@ class TensorMaps(TensorFields):
index = index[0]
if item.maps:
item.maps = Maps(item.maps)
indices = np.array(range(len(self)))
indices = np.arange(len(self))
keep_indices = indices[index]
if isinstance(keep_indices, (int, np.int64, np.int32)):
if np.issubdtype(keep_indices.dtype, np.integer):
keep_indices = [keep_indices]
delete_indices = set(indices).difference(set(keep_indices))
delete_indices = set(indices.flatten())\
.difference(set(keep_indices.flatten))
# correct all maps that contain deleted indices
for map_dim in self.maps.keys():
for map_dim in self.maps:
# build mask, where the map should be deleted
map_delete_mask = np.full(
(len(self.maps[map_dim]),), False, dtype=bool
......
......@@ -141,15 +141,12 @@ def fields_to_scalars(fields):
def faces_to_maps(faces, *fields):
# TODO: replace by Maps.to_maps or so
return tfields.Maps(
tfields.TensorFields(faces, *fields, dtype=int, dim=3)
)
def maps_to_faces(maps):
return np.array(maps[3])
class Mesh3D(tfields.TensorMaps):
# pylint: disable=R0904
"""
......@@ -226,8 +223,7 @@ class Mesh3D(tfields.TensorMaps):
else:
map_fields = []
if faces is not None:
kwargs['maps'] = faces_to_maps(faces,
*map_fields)
kwargs['maps'] = [(faces,) + tuple(map_fields)]
obj = super(Mesh3D, cls).__new__(cls, tensors, *fields, **kwargs)
if len(obj.maps) > 1:
raise ValueError("Mesh3D only allows one map")
......@@ -264,7 +260,8 @@ class Mesh3D(tfields.TensorMaps):
norm = colors.Normalize(vmin, vmax)
color_map = plt.get_cmap(cmap)
else:
# switch for not coloring the triangles and thus not producing the materials
# switch for not coloring the triangles and thus not producing the
# materials
norm = None
if len(kwargs) != 0:
......@@ -286,7 +283,8 @@ class Mesh3D(tfields.TensorMaps):
mf.write("Kd 0 0 0\n\n")
else:
mf.write("newmtl mtl_{0}\n".format(s))
mf.write("Kd {c[0]} {c[1]} {c[2]}\n\n".format(c=color_map(norm(s))))
mf.write("Kd {c[0]} {c[1]} {c[2]}\n\n"
.format(c=color_map(norm(s))))
else:
sorted_faces = self.faces
......@@ -493,18 +491,25 @@ class Mesh3D(tfields.TensorMaps):
@property
def faces(self):
return maps_to_faces(self.maps)
if self.maps:
return self.maps[3]
else:
return tfields.Maps.to_map(np.empty((0, 3))) # empty TensorFields object
@faces.setter
def faces(self, faces):
self.maps = faces_to_maps(faces)
self.maps = tfields.Maps() # circumvent the copy constructor
mp = tfields.Maps.to_map(faces)
self.maps[tfields.dim(mp)] = mp
@property
def faceScalars(self):
# TODO: BAD NAME
return fields_to_scalars(self.maps[3].fields)
@faceScalars.setter
def faceScalars(self, scalars):
# TODO: BAD NAME
self.maps[3].fields = scalars_to_fields(scalars)
@cached_property()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment