Skip to content

Commit

Permalink
Merge 4148210 into de60b72
Browse files Browse the repository at this point in the history
  • Loading branch information
to266 committed Jul 29, 2016
2 parents de60b72 + 4148210 commit b798cdf
Show file tree
Hide file tree
Showing 43 changed files with 1,929 additions and 525 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ before_install:
- conda update --yes conda

install:
- DEPS="nose numpy scipy matplotlib ipython h5py sympy scikit-learn dill natsort setuptools scikit-image cython lxml ipyparallel"
- DEPS="nose numpy scipy matplotlib ipython h5py sympy scikit-learn dill natsort setuptools scikit-image cython lxml ipyparallel dask"
- conda create -n testenv --yes $DEPS
- source activate testenv
- conda install pip
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ environment:
CONDA_NPY: "19"
WP_URL: 'https://github.com/winpython/winpython/releases/download/1.3.20160209/WinPython-32bit-3.5.1.2.exe'
WP_CRC: '172d19a743ccfaf55af779d15f29f67fca83a46f08b0af855dfaf809b4184c0d'
DEPS: "numpy scipy matplotlib ipython h5py sympy scikit-learn dill setuptools natsort scikit-image cython lxml ipyparallel"
DEPS: "numpy scipy matplotlib ipython h5py sympy scikit-learn dill setuptools natsort scikit-image cython lxml ipyparallel dask"

- PYTHON: "C:\\Miniconda35-x64"
PYTHON_VERSION: "3.5.x"
Expand All @@ -30,7 +30,7 @@ environment:
CONDA_NPY: "19"
WP_URL: 'https://github.com/winpython/winpython/releases/download/1.3.20160209/WinPython-64bit-3.5.1.2.exe'
WP_CRC: '07e854b9aa7a31d8bbf7829d04a45b6d6266603690520e365199af2d98751ab1'
DEPS: "numpy scipy matplotlib ipython h5py sympy scikit-learn dill setuptools natsort scikit-image cython lxml ipyparallel"
DEPS: "numpy scipy matplotlib ipython h5py sympy scikit-learn dill setuptools natsort scikit-image cython lxml ipyparallel dask"



Expand Down
23 changes: 18 additions & 5 deletions hyperspy/_components/gaussian.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import math

import numpy as np
import dask.array as da

from hyperspy.component import Component

Expand All @@ -39,18 +40,30 @@ def _estimate_gaussian_parameters(signal, x1, x2, only_current):
i = axis.index_in_array
data_gi = [slice(None), ] * len(signal.data.shape)
data_gi[axis.index_in_array] = slice(i1, i2)
data = signal.data[data_gi]
data = signal.data[tuple(data_gi)]
X_shape = [1, ] * len(signal.data.shape)
X_shape[axis.index_in_array] = data.shape[i]
centre_shape = list(data.shape)
centre_shape[i] = 1

centre = np.sum(X.reshape(X_shape) * data, i) / np.sum(data, i)
if isinstance(data, da.Array):
_sum = da.sum
_sqrt = da.sqrt
_abs = da.numpy_compat.builtins.abs
else:
_sum = np.sum
_sqrt = np.sqrt
_abs = np.abs

centre = _sum(X.reshape(X_shape) * data, i) / _sum(data, i)

sigma = np.sqrt(np.abs(np.sum((X.reshape(X_shape) - centre.reshape(
centre_shape)) ** 2 * data, i) / np.sum(data, i)))
sigma = _sqrt(_abs(_sum((X.reshape(X_shape) - centre.reshape(
centre_shape)) ** 2 * data, i) / _sum(data, i)))
height = data.max(i)
return centre, height, sigma
if isinstance(data, da.Array):
return da.compute(centre, height, sigma)
else:
return centre, height, sigma


class Gaussian(Component):
Expand Down
202 changes: 137 additions & 65 deletions hyperspy/_signals/complex_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,91 +16,82 @@
# You should have received a copy of the GNU General Public License
# along with HyperSpy. If not, see <http://www.gnu.org/licenses/>.

from functools import wraps

import numpy as np
import dask.array as da
import h5py

from hyperspy.signal import BaseSignal
from hyperspy._signals.lazy import LazySignal
from hyperspy.docstrings.plot import (
BASE_PLOT_DOCSTRING, COMPLEX_DOCSTRING, KWARGS_DOCSTRING)


class ComplexSignal(BaseSignal):
def format_title(thing):
def title_decorator(func):
@wraps(func)
def signal_wrapper(*args, **kwargs):
signal = func(*args, **kwargs)
if signal.metadata.General.title:
title = signal.metadata.General.title
else:
title = 'Untitled Signal'
signal.metadata.General.title = thing + '({})'.format(title)
return signal
return signal_wrapper
return title_decorator


class ComplexSignal_mixin:

"""BaseSignal subclass for complex data."""

_dtype = "complex"

@property
def real(self):
"""Get/set the real part of the data. Returns an appropriate HyperSpy signal."""
real = self._deepcopy_with_new_data(np.real(self.data))
if real.metadata.General.title:
title = real.metadata.General.title
else:
title = 'Untitled Signal'
real.metadata.General.title = 'real({})'.format(title)
@format_title('real')
def _get_real(self):
real = self._deepcopy_with_new_data(self.data.real)
real._assign_subclass()
return real

@real.setter
def real(self, real):
if isinstance(real, BaseSignal):
self.real.isig[:] = real
else:
self.data.real[:] = real
real = property(lambda s: s._get_real(),
lambda s, v: s._set_real(v),
doc="""Get/set the real part of the data. Returns an
appropriate HyperSpy signal."""
)

@property
def imag(self):
"""Get/set imaginary part of the data. Returns an appropriate HyperSpy signal."""
imag = self._deepcopy_with_new_data(np.imag(self.data))
if imag.metadata.General.title:
title = imag.metadata.General.title
else:
title = 'Untitled Signal'
imag.metadata.General.title = 'imag({})'.format(title)
@format_title('imag')
def _get_imag(self):
imag = self._deepcopy_with_new_data(self.data.imag)
imag._assign_subclass()
return imag

@imag.setter
def imag(self, imag):
if isinstance(imag, BaseSignal):
self.imag.isig[:] = imag
else:
self.data.imag[:] = imag
imag = property(lambda s: s._get_imag(),
lambda s, v: s._set_imag(v),
doc="""Get/set imaginary part of the data. Returns an
appropriate HyperSpy signal."""
)

@property
def amplitude(self):
"""Get/set the amplitude of the data. Returns an appropriate HyperSpy signal."""
amplitude = np.abs(self)
def _get_amplitude(self, amplitude):
amplitude._assign_subclass()
return amplitude

@amplitude.setter
def amplitude(self, amplitude):
if isinstance(amplitude, BaseSignal):
self.isig[:] = amplitude * np.exp(self.angle() * 1j)
else:
self.data[:] = amplitude * np.exp(1j * np.angle(self.data))
amplitude = property(lambda s: s._get_amplitude(),
lambda s, v: s._set_amplitude(v),
doc="""Get/set the amplitude of the data. Returns an
appropriate HyperSpy signal.""")

@property
def phase(self):
"""Get/set the phase of the data. Returns an appropriate HyperSpy signal."""
phase = self._deepcopy_with_new_data(np.angle(self.data))
if phase.metadata.General.title:
title = phase.metadata.General.title
else:
title = 'Untitled Signal'
phase.metadata.General.title = 'phase({})'.format(title)
@format_title('phase')
def _get_phase(self, phase):
phase._assign_subclass()
return phase

@phase.setter
def phase(self, phase):
if isinstance(phase, BaseSignal):
self.isig[:] = np.abs(self) * np.exp(phase * 1j)
else:
self.data[:] = np.abs(self.data) * np.exp(1j * phase)
phase = property(lambda s: s._get_phase(),
lambda s, v: s._set_phase(v),
doc="""Get/set the phase of the data. Returns an appropriate
HyperSpy signal."""
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand All @@ -123,7 +114,8 @@ def change_dtype(self, dtype):
raise AttributeError(
'Complex data can only be converted into other complex dtypes!')

def angle(self, deg=False):
@format_title('angle')
def angle(self, angle, deg=False):
"""Return the angle (also known as phase or argument). If the data is real, the angle is 0
for positive values and 2$\pi$ for negative values.
Expand All @@ -139,14 +131,8 @@ def angle(self, deg=False):
with dtype as numpy.float64.
"""
sig = self._deepcopy_with_new_data(np.angle(self.data, deg))
sig.set_signal_type("")
if sig.metadata.General.title:
title = sig.metadata.General.title
else:
title = 'Untitled Signal'
sig.metadata.General.title = 'angle({})'.format(title)
return sig
angle.set_signal_type('')
return angle

def unwrapped_phase(self, wrap_around=False, seed=None,
show_progressbar=None):
Expand Down Expand Up @@ -227,3 +213,89 @@ def plot(self, navigator="auto", axes_manager=None,
raise ValueError('{}'.format(representation) +
'is not a valid input for representation (use "cartesian" or "polar")!')
plot.__doc__ %= BASE_PLOT_DOCSTRING, COMPLEX_DOCSTRING, KWARGS_DOCSTRING


class ComplexSignal(ComplexSignal_mixin, BaseSignal):

def _get_phase(self):
phase = self._deepcopy_with_new_data(np.angle(self.data))
return super()._get_phase(phase)

def _get_amplitude(self):
amplitude = np.abs(self)
return super()._get_amplitude(amplitude)

def _set_real(self, real):
if isinstance(real, BaseSignal):
self.real.isig[:] = real
else:
self.data.real[:] = real
self.events.data_changed.trigger(self)

def _set_imag(self, imag):
if isinstance(imag, BaseSignal):
self.imag.isig[:] = imag
else:
self.data.imag[:] = imag
self.events.data_changed.trigger(self)

def _set_amplitude(self, amplitude):
if isinstance(amplitude, BaseSignal):
self.isig[:] = amplitude * np.exp(self.angle() * 1j)
else:
self.data[:] = amplitude * np.exp(1j * np.angle(self.data))
self.events.data_changed.trigger(self)

def _set_phase(self, phase):
if isinstance(phase, BaseSignal):
self.isig[:] = np.abs(self) * np.exp(phase * 1j)
else:
self.data[:] = np.abs(self.data) * np.exp(1j * phase)
self.events.data_changed.trigger(self)

def angle(self, deg=False):
angle = self._deepcopy_with_new_data(np.angle(self.data, deg))
return super().angle(angle, deg=deg)
angle.__doc__ = ComplexSignal_mixin.angle.__doc__


class LazyComplexSignal(ComplexSignal_mixin, LazySignal):

@format_title('absolute')
def _get_amplitude(self):
amplitude = da.numpy_compat.builtins.abs(self)
return super()._get_amplitude(amplitude)

def _get_phase(self):
phase = self._deepcopy_with_new_data(da.angle(self.data))
return super()._get_phase(phase)

def _set_real(self, real):
if isinstance(real, BaseSignal):
real = real.data.real
self.data = 1j * self.data.imag + real
self.events.data_changed.trigger(self)

def _set_imag(self, imag):
if isinstance(imag, BaseSignal):
imag = imag.data.real
self.data = self.data.real + 1j * imag
self.events.data_changed.trigger(self)

def _set_amplitude(self, amplitude):
if isinstance(amplitude, BaseSignal):
amplitude = amplitude.data.real
self.data = amplitude * da.exp(1j * da.angle(self.data))
self.events.data_changed.trigger(self)

def _set_phase(self, phase):
if isinstance(phase, BaseSignal):
phase = phase.data.real
self.data = da.numpy_compat.builtins.abs(self.data) * \
da.exp(1j * phase)
self.events.data_changed.trigger(self)

def angle(self, deg=False):
angle = self._deepcopy_with_new_data(da.angle(self.data, deg))
return super().angle(angle, deg=deg)
angle.__doc__ = ComplexSignal_mixin.angle.__doc__
15 changes: 14 additions & 1 deletion hyperspy/_signals/complex_signal1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


from hyperspy._signals.common_signal1d import CommonSignal1D
from hyperspy._signals.complex_signal import ComplexSignal
from hyperspy._signals.complex_signal import (ComplexSignal, LazyComplexSignal)


class ComplexSignal1D(ComplexSignal, CommonSignal1D):
Expand All @@ -32,3 +32,16 @@ def __init__(self, *args, **kwargs):
if self.axes_manager.signal_dimension != 1:
self.axes_manager.set_signal_dimension(1)
self.metadata.Signal.binned = False


class LazyComplexSignal1D(LazyComplexSignal, CommonSignal1D):

"""BaseSignal subclass for lazy complex 1-dimensional data."""

_signal_dimension = 1

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.axes_manager.signal_dimension != 1:
self.axes_manager.set_signal_dimension(1)
self.metadata.Signal.binned = False
16 changes: 14 additions & 2 deletions hyperspy/_signals/complex_signal2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@


from hyperspy._signals.common_signal2d import CommonSignal2D
from hyperspy._signals.complex_signal import ComplexSignal
from hyperspy._signals.complex_signal import (ComplexSignal, LazyComplexSignal)
from hyperspy.docstrings.plot import (
BASE_PLOT_DOCSTRING, PLOT2D_DOCSTRING, COMPLEX_DOCSTRING, KWARGS_DOCSTRING)


class ComplexSignal2D(ComplexSignal, CommonSignal2D):
class Complex2Dmixin:

"""BaseSignal subclass for complex 2-dimensional data."""

Expand Down Expand Up @@ -88,3 +88,15 @@ def plot(self,
)
plot.__doc__ %= (BASE_PLOT_DOCSTRING, PLOT2D_DOCSTRING,
COMPLEX_DOCSTRING, KWARGS_DOCSTRING)


class ComplexSignal2D(Complex2Dmixin, ComplexSignal, CommonSignal2D):

"""BaseSignal subclass for complex 2-dimensional data."""
pass


class LazyComplexSignal2D(Complex2Dmixin, LazyComplexSignal, CommonSignal2D):

"""BaseSignal subclass for lazy complex 2-dimensional data."""
pass

0 comments on commit b798cdf

Please sign in to comment.