Skip to content

Commit

Permalink
Merge pull request #1067 from to266/fixing_model_slicing_annoyances
Browse files Browse the repository at this point in the history
fixing model slicing test annoyances
  • Loading branch information
francisco-dlp committed Jun 14, 2016
2 parents 76a8cfb + 7116491 commit a3aa128
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 19 deletions.
9 changes: 5 additions & 4 deletions hyperspy/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,8 @@ def __init__(self, parameter_name_list):
'active': None
}
self._slicing_whitelist = {'_active_array': 'inav'}
self._slicing_order = ('active', 'active_is_multidimensional',
'_active_array',)

_name = ''
_active_is_multidimensional = False
Expand All @@ -674,9 +676,7 @@ def active_is_multidimensional(self, value):

if value: # Turn on
if self._axes_manager.navigation_size < 2:
warnings.warn(
'`navigation_size` < 2, skipping',
RuntimeWarning)
_logger.warning('`navigation_size` < 2, skipping')
return
# Store value at current position
self._create_active_array()
Expand Down Expand Up @@ -751,7 +751,6 @@ def _set_active(self, arg):
self._active = arg
if self.active_is_multidimensional is True:
self._store_active_value_in_array(arg)

self.events.active_changed.trigger(active=self._active, obj=self)
self.trait_property_changed('active', old_value, self._active)

Expand Down Expand Up @@ -821,6 +820,8 @@ def _create_active_array(self):
shape = [1, ]
if (not isinstance(self._active_array, np.ndarray)
or self._active_array.shape != shape):
_logger.debug('Creating _active_array for {}.\n\tCurrent array '
'is:\n{}'.format(self, self._active_array))
self._active_array = np.ones(shape, dtype=bool)

def _create_arrays(self):
Expand Down
32 changes: 25 additions & 7 deletions hyperspy/misc/slicing.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from operator import attrgetter
import numpy as np
from hyperspy.misc.utils import attrsetter
from hyperspy.misc.export_dictionary import parse_flag_string

import numpy as np


def _slice_target(target, dims, both_slices, slice_nav=None, issignal=False):
"""Slices the target if appropriate
Expand Down Expand Up @@ -35,18 +34,20 @@ def _slice_target(target, dims, both_slices, slice_nav=None, issignal=False):
if isinstance(target, np.ndarray):
return np.atleast_1d(target[tuple(array_slices[:nav_dims])])
raise ValueError(
'tried to slice with navigation dimensions, but was neither a signal nor an array')
'tried to slice with navigation dimensions, but was neither a '
'signal nor an array')
if slice_nav is False: # check explicitly
if issignal:
return target.isig[slices]
if isinstance(target, np.ndarray):
return np.atleast_1d(target[tuple(array_slices[-sig_dims:])])
raise ValueError(
'tried to slice with signal dimensions, but was neither a signal nor an array')
# return thing
'tried to slice with navigation dimensions, but was neither a '
'signal nor an array')


def copy_slice_from_whitelist(_from, _to, dims, both_slices, isNav):
def copy_slice_from_whitelist(
_from, _to, dims, both_slices, isNav, order=None):
"""Copies things from one object to another, according to whitelist, slicing
where required.
Expand All @@ -64,6 +65,10 @@ def copy_slice_from_whitelist(_from, _to, dims, both_slices, isNav):
isNav : bool
if the slicing operation is performed on navigation dimensions of the
object
order : tuple, None
if given, performs the copying in the order given. If not all attributes
given, the rest is random (the order a whitelist.keys() returns them).
If given in the object, _slicing_order is looked up.
"""

def make_slice_navigation_decision(flags, isnav):
Expand All @@ -79,7 +84,20 @@ def make_slice_navigation_decision(flags, isnav):
if hasattr(_from, '_slicing_whitelist'):
swl = _from._slicing_whitelist

for key, val in _from._whitelist.items():
if order is not None and not isinstance(order, tuple):
raise ValueError('order argument has to be None or a tuple of strings')

if order is None:
order = ()
if hasattr(_from, '_slicing_order'):
order = order + \
tuple(k for k in _from._slicing_order if k not in order)

keys = order + tuple(k for k in _from._whitelist.keys() if k not in
order)

for key in keys:
val = _from._whitelist[key]
if key == 'self':
target = None
else:
Expand Down
20 changes: 12 additions & 8 deletions hyperspy/tests/model/test_fancy_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,7 @@ def test_model_navigation_indexer_slice(self):
self.model.axes_manager.indices = (0, 0)
self.model[0].active = False

# Make sure the array we copy has been appropriatelly updated before
# slicing
_test = self.model[0]._active_array[0, 0]
while _test:
time.sleep(0.1)
_test = self.model[0]._active_array[0, 0]

m = self.model.inav[0::2]
m = self.model.inav[0::2, :]
np.testing.assert_array_equal(
m.chisq.data, self.model.chisq.data[:, 0::2])
np.testing.assert_array_equal(m.dof.data, self.model.dof.data[:, 0::2])
Expand All @@ -95,6 +88,17 @@ def test_model_navigation_indexer_slice(self):
for p_new, p_old in zip(c.parameters, self.model[ic].parameters):
nt.assert_true((p_old.map[:, 0::2] == p_new.map).all())

# test that explicitly does the wrong thing by mixing up the order
def test_component_copying_order(self):
self.model.axes_manager.indices = (0, 0)
self.model[0].active = False
g = self.model[0]
g._slicing_order = ('_active_array', 'active_is_multidimensional',
'active')
nt.assert_false(g._active_array[0, 0])
m = self.model.inav[0:2, 0:2]
nt.assert_true(m[0]._active_array[0, 0])


class TestModelIndexingClass:

Expand Down

0 comments on commit a3aa128

Please sign in to comment.