Commit 110a3ce5 authored by Martin Reinecke's avatar Martin Reinecke
Browse files

Merge branch 'NIFTy_4' into notebook_demo

parents 81cab5d6 9a5abf11
...@@ -17,10 +17,11 @@ test_min: ...@@ -17,10 +17,11 @@ test_min:
stage: test stage: test
script: script:
- pip install --user . - pip install --user .
- nosetests -q --with-coverage --cover-package=nifty4 --cover-branches
- OMP_NUM_THREADS=1 mpiexec --allow-run-as-root -n 4 nosetests -q
- pip3 install --user . - pip3 install --user .
- nosetests -q
- nosetests3 -q - nosetests3 -q
- OMP_NUM_THREADS=1 mpiexec --allow-run-as-root -n 4 nosetests3 -q - OMP_NUM_THREADS=1 mpiexec --allow-run-as-root -n 4 nosetests -q 2>/dev/null
- OMP_NUM_THREADS=1 mpiexec --allow-run-as-root -n 4 nosetests3 -q 2>/dev/null
- nosetests -q --with-coverage --cover-package=nifty4 --cover-branches --cover-erase
- > - >
coverage report | grep TOTAL | awk '{ print "TOTAL: "$6; }' || true coverage report | grep TOTAL | awk '{ print "TOTAL: "$6; }'
...@@ -37,13 +37,11 @@ if __name__ == "__main__": ...@@ -37,13 +37,11 @@ if __name__ == "__main__":
R = R*ift.DiagonalOperator(mask) R = R*ift.DiagonalOperator(mask)
R = R*ht R = R*ht
R = R * ift.create_harmonic_smoothing_operator((harmonic_space,),0,response_sigma) R = R * ift.create_harmonic_smoothing_operator((harmonic_space,),0,response_sigma)
#R = ift.ResponseOperator(signal_space, sigma=(response_sigma,),
# sensitivity=(mask,))
data_domain = R.target[0] data_domain = R.target[0]
# Setting up the noise covariance and drawing a random noise realization # Setting up the noise covariance and drawing a random noise realization
noiseless_data = R(mock_signal) noiseless_data = R(mock_signal)
noise_amplitude = noiseless_data.std()/signal_to_noise noise_amplitude = noiseless_data.val.std()/signal_to_noise
N = ift.DiagonalOperator( N = ift.DiagonalOperator(
ift.Field.full(data_domain, noise_amplitude**2)) ift.Field.full(data_domain, noise_amplitude**2))
noise = ift.Field.from_random( noise = ift.Field.from_random(
...@@ -58,16 +56,15 @@ if __name__ == "__main__": ...@@ -58,16 +56,15 @@ if __name__ == "__main__":
inverter = ift.ConjugateGradient(controller=ctrl) inverter = ift.ConjugateGradient(controller=ctrl)
energy = ift.library.LogNormalWienerFilterEnergy(m0, data, R, energy = ift.library.LogNormalWienerFilterEnergy(m0, data, R,
N, S, inverter=inverter) N, S, inverter=inverter)
# minimizer = ift.VL_BFGS(controller=ctrl2, max_history_length=20) #minimizer = ift.VL_BFGS(controller=ctrl2, max_history_length=20)
minimizer = ift.RelaxedNewton(controller=ctrl2) minimizer = ift.RelaxedNewton(controller=ctrl2)
# minimizer = ift.SteepestDescent(controller=ctrl2) #minimizer = ift.SteepestDescent(controller=ctrl2)
me = minimizer(energy) me = minimizer(energy)
m = ht(me[0].position) m = ht(me[0].position)
# Plotting # Plotting
plotdict = {"xlabel": "Pixel index", "ylabel": "Pixel index", plotdict = {"colormap": "Planck-like"}
"colormap": "Planck-like"}
ift.plot(ht(mock_signal), name="mock_signal.png", **plotdict) ift.plot(ht(mock_signal), name="mock_signal.png", **plotdict)
logdata = np.log(ift.dobj.to_global_data(data.val)).reshape(signal_space.shape) logdata = np.log(ift.dobj.to_global_data(data.val)).reshape(signal_space.shape)
ift.plot(ift.Field(signal_space, val=ift.dobj.from_global_data(logdata)), ift.plot(ift.Field(signal_space, val=ift.dobj.from_global_data(logdata)),
......
...@@ -24,10 +24,10 @@ if __name__ == "__main__": ...@@ -24,10 +24,10 @@ if __name__ == "__main__":
# Set up position space # Set up position space
# s_space = ift.RGSpace([1024]) # s_space = ift.RGSpace([1024])
s_space = ift.HPSpace(32) s_space = ift.HPSpace(32)
h_space = s_space.get_default_codomain()
# Define harmonic transformation and associated harmonic space # Define harmonic transformation and associated harmonic space
FFT = ift.FFTOperator(s_space) HT = ift.HarmonicTransformOperator(h_space, target=s_space)
h_space = FFT.target[0]
# Setting up power space # Setting up power space
p_space = ift.PowerSpace(h_space, p_space = ift.PowerSpace(h_space,
...@@ -51,22 +51,28 @@ if __name__ == "__main__": ...@@ -51,22 +51,28 @@ if __name__ == "__main__":
mask = ift.Field(s_space, val=ift.dobj.from_global_data(mask)) mask = ift.Field(s_space, val=ift.dobj.from_global_data(mask))
MaskOperator = ift.DiagonalOperator(mask) MaskOperator = ift.DiagonalOperator(mask)
InstrumentResponse = ift.ResponseOperator(s_space, sigma=[0.0], R = ift.GeometryRemover(s_space)
exposure=[1.0]) R = R*MaskOperator
MeasurementOperator = InstrumentResponse*MaskOperator #R = R*HT
#R = R * ift.create_harmonic_smoothing_operator((harmonic_space,),0,response_sigma)
MeasurementOperator = R
d_space = MeasurementOperator.target d_space = MeasurementOperator.target
noise_covariance = ift.Field(d_space, val=noise_level**2).weight()
N = ift.DiagonalOperator(noise_covariance)
n = ift.Field.from_random(domain=d_space, random_type='normal',
std=noise_level)
Projection = ift.PowerProjectionOperator(domain=h_space, Projection = ift.PowerProjectionOperator(domain=h_space,
power_space=p_space) power_space=p_space)
power = Projection.adjoint_times(ift.exp(0.5*log_p)) power = Projection.adjoint_times(ift.exp(0.5*log_p))
# Creating the mock data # Creating the mock data
true_sky = nonlinearity(FFT.adjoint_times(power*sh)) true_sky = nonlinearity(HT(power*sh))
d = MeasurementOperator(true_sky) + n noiseless_data = MeasurementOperator(true_sky)
noise_amplitude = noiseless_data.val.std()*noise_level
N = ift.DiagonalOperator(
ift.Field.full(d_space, noise_amplitude**2))
n = ift.Field.from_random(
domain=d_space, random_type='normal',
std=noise_amplitude, mean=0)
# Creating the mock data
d = noiseless_data + n
m0 = ift.power_synthesize(ift.Field(p_space, val=1e-7)) m0 = ift.power_synthesize(ift.Field(p_space, val=1e-7))
t0 = ift.Field(p_space, val=-4.) t0 = ift.Field(p_space, val=-4.)
...@@ -84,7 +90,7 @@ if __name__ == "__main__": ...@@ -84,7 +90,7 @@ if __name__ == "__main__":
for i in range(20): for i in range(20):
power0 = Projection.adjoint_times(ift.exp(0.5*t0)) power0 = Projection.adjoint_times(ift.exp(0.5*t0))
map0_energy = ift.library.NonlinearWienerFilterEnergy( map0_energy = ift.library.NonlinearWienerFilterEnergy(
m0, d, MeasurementOperator, nonlinearity, FFT, power0, N, S, m0, d, MeasurementOperator, nonlinearity, HT, power0, N, S,
inverter=inverter) inverter=inverter)
# Minimization with chosen minimizer # Minimization with chosen minimizer
...@@ -96,7 +102,7 @@ if __name__ == "__main__": ...@@ -96,7 +102,7 @@ if __name__ == "__main__":
# Initializing the power energy with updated parameters # Initializing the power energy with updated parameters
power0_energy = ift.library.NonlinearPowerEnergy( power0_energy = ift.library.NonlinearPowerEnergy(
position=t0, d=d, N=N, m=m0, D=D0, FFT=FFT, position=t0, d=d, N=N, xi=m0, D=D0, ht=HT,
Instrument=MeasurementOperator, nonlinearity=nonlinearity, Instrument=MeasurementOperator, nonlinearity=nonlinearity,
Projection=Projection, sigma=1., samples=2, inverter=inverter) Projection=Projection, sigma=1., samples=2, inverter=inverter)
...@@ -110,6 +116,6 @@ if __name__ == "__main__": ...@@ -110,6 +116,6 @@ if __name__ == "__main__":
m0, t0 = adjust_zero_mode(m0, t0) m0, t0 = adjust_zero_mode(m0, t0)
ift.plot(true_sky) ift.plot(true_sky)
ift.plot(nonlinearity(FFT.adjoint_times(power0*m0)), ift.plot(nonlinearity(HT(power0*m0)),
title='reconstructed_sky') title='reconstructed_sky')
ift.plot(MeasurementOperator.adjoint_times(d)) ift.plot(MeasurementOperator.adjoint_times(d))
...@@ -81,10 +81,10 @@ if __name__ == "__main__": ...@@ -81,10 +81,10 @@ if __name__ == "__main__":
data_domain = R.target data_domain = R.target
noiseless_data = R(mock_signal) noiseless_data = R(mock_signal)
noise_amplitude = noiseless_data.std()/signal_to_noise noise_amplitude = noiseless_data.val.std()/signal_to_noise
# Setting up the noise covariance and drawing a random noise realization # Setting up the noise covariance and drawing a random noise realization
ndiag = ift.Field.full(data_domain, noise_amplitude**2) #ndiag = ift.Field.full(data_domain, noise_amplitude**2)
N = ift.DiagonalOperator(ndiag) N = ift.ScalingOperator(noise_amplitude**2, data_domain)
noise = ift.Field.from_random( noise = ift.Field.from_random(
domain=data_domain, random_type='normal', domain=data_domain, random_type='normal',
std=noise_amplitude, mean=0) std=noise_amplitude, mean=0)
...@@ -108,12 +108,5 @@ if __name__ == "__main__": ...@@ -108,12 +108,5 @@ if __name__ == "__main__":
ift.plot(ift.Field(plot_space,val=data.val), name='data.png', **plotdict) ift.plot(ift.Field(plot_space,val=data.val), name='data.png', **plotdict)
ift.plot(ift.Field(plot_space,val=m.val), name='map.png', **plotdict) ift.plot(ift.Field(plot_space,val=m.val), name='map.png', **plotdict)
# sampling the uncertainty map # sampling the uncertainty map
sample_variance = ift.Field.zeros(signal_domain) mean, variance = ift.probe_with_posterior_samples(wiener_curvature, ht, 10)
sample_mean = ift.Field.zeros(signal_domain)
n_samples = 10
for i in range(n_samples):
sample = ht(wiener_curvature.generate_posterior_sample()) + m
sample_variance += sample**2
sample_mean += sample
variance = sample_variance/n_samples - (sample_mean/n_samples)**2
ift.plot(ift.Field(plot_space, val=ift.sqrt(variance).val), name="uncertainty.png", **plotdict) ift.plot(ift.Field(plot_space, val=ift.sqrt(variance).val), name="uncertainty.png", **plotdict)
...@@ -42,7 +42,7 @@ if __name__ == "__main__": ...@@ -42,7 +42,7 @@ if __name__ == "__main__":
data_domain = R.target[0] data_domain = R.target[0]
noiseless_data = R(mock_signal) noiseless_data = R(mock_signal)
noise_amplitude = noiseless_data.std()/signal_to_noise noise_amplitude = noiseless_data.val.std()/signal_to_noise
# Setting up the noise covariance and drawing a random noise realization # Setting up the noise covariance and drawing a random noise realization
ndiag = ift.Field.full(data_domain, noise_amplitude**2) ndiag = ift.Field.full(data_domain, noise_amplitude**2)
N = ift.DiagonalOperator(ndiag) N = ift.DiagonalOperator(ndiag)
......
...@@ -42,7 +42,7 @@ if __name__ == "__main__": ...@@ -42,7 +42,7 @@ if __name__ == "__main__":
noiseless_data = R(sh) noiseless_data = R(sh)
signal_to_noise = 1. signal_to_noise = 1.
noise_amplitude = noiseless_data.std()/signal_to_noise noise_amplitude = noiseless_data.val.std()/signal_to_noise
N = ift.DiagonalOperator(ift.Field.full(s_space, noise_amplitude**2)) N = ift.DiagonalOperator(ift.Field.full(s_space, noise_amplitude**2))
n = ift.Field.from_random(domain=s_space, n = ift.Field.from_random(domain=s_space,
random_type='normal', random_type='normal',
......
...@@ -58,7 +58,7 @@ if __name__ == "__main__": ...@@ -58,7 +58,7 @@ if __name__ == "__main__":
data_domain = R.target[0] data_domain = R.target[0]
noiseless_data = R(mock_signal) noiseless_data = R(mock_signal)
noise_amplitude = noiseless_data.std()/signal_to_noise noise_amplitude = noiseless_data.val.std()/signal_to_noise
N = ift.DiagonalOperator( N = ift.DiagonalOperator(
ift.Field.full(data_domain, noise_amplitude**2)) ift.Field.full(data_domain, noise_amplitude**2))
noise = ift.Field.from_random( noise = ift.Field.from_random(
......
...@@ -36,7 +36,7 @@ if __name__ == "__main__": ...@@ -36,7 +36,7 @@ if __name__ == "__main__":
R = Instrument*ht R = Instrument*ht
noiseless_data = R(sh) noiseless_data = R(sh)
signal_to_noise = 1. signal_to_noise = 1.
noise_amplitude = noiseless_data.std()/signal_to_noise noise_amplitude = noiseless_data.val.std()/signal_to_noise
N = ift.DiagonalOperator(ift.Field.full(s_space, noise_amplitude**2)) N = ift.DiagonalOperator(ift.Field.full(s_space, noise_amplitude**2))
n = ift.Field.from_random(domain=s_space, n = ift.Field.from_random(domain=s_space,
random_type='normal', random_type='normal',
...@@ -68,12 +68,6 @@ if __name__ == "__main__": ...@@ -68,12 +68,6 @@ if __name__ == "__main__":
sample_variance = ift.Field.zeros(s_space) sample_variance = ift.Field.zeros(s_space)
sample_mean = ift.Field.zeros(s_space) sample_mean = ift.Field.zeros(s_space)
n_samples = 50 mean, variance = ift.probe_with_posterior_samples(D, ht, 50)
for i in range(n_samples):
sample = ht(D.generate_posterior_sample() + m)
sample_variance += sample**2
sample_mean += sample
sample_mean /= n_samples
sample_variance /= n_samples
variance = sample_variance - sample_mean**2
ift.plot(variance, name="variance.png", colormap="Planck-like") ift.plot(variance, name="variance.png", colormap="Planck-like")
ift.plot(mean, name="mean.png", colormap="Planck-like")
Significant differences between NIFTy nightly and nifty2go Significant differences between NIFTy3 and nifty4
========================================================== =================================================
1) Field domains in nifty2go are stored in DomainTuple objects, which makes 1) Field domains in nifty4 are stored in DomainTuple objects, which makes
comparisons between domains and computation of axis indices etc. much simpler comparisons between domains and computation of axis indices etc. much simpler
and more efficient. and more efficient.
No impact on the user ... these objects are generated whenever needed and No impact on the user ... these objects are generated whenever needed and
have all necessary functions to make them look like tuples of spaces. have all necessary functions to make them look like tuples of spaces.
2) In nifty2go an operator's domain and target refer to the _full_ domains of 2) In nifty4 an operator's domain and target refer to the _full_ domains of
the input and output fields read/written by times(), adjoint_times() etc. the input and output fields read/written by times(), adjoint_times() etc.
In NIFTy nightly, domain and target only refer to the (sub-)domain on In NIFTy nightly, domain and target only refer to the (sub-)domain on
which the operator actually acts. This leads to complications like the need which the operator actually acts. This leads to complications like the need
for the "default_spaces" argument in the operator constructor and the for the "default_spaces" argument in the operator constructor and the
"spaces" keywords in all operator calls. "spaces" keywords in all operator calls.
Advantages of the nifty2go approach: Advantages of the nifty4 approach:
- less error-prone and easier to understand; less code overall - less error-prone and easier to understand; less code overall
- operators have more knowledge and may tune themselves better - operators have more knowledge and may tune themselves better
- difficulties with the design of ComposedOperator (issue 152) resolve - difficulties with the design of ComposedOperator (issue 152) resolve
...@@ -25,13 +25,13 @@ Significant differences between NIFTy nightly and nifty2go ...@@ -25,13 +25,13 @@ Significant differences between NIFTy nightly and nifty2go
However, I have not found any such situation in the current code base, so However, I have not found any such situation in the current code base, so
it appears to be rare. it appears to be rare.
3) nifty2go uses one of two different "data_object" modules for array 3) nifty4 uses one of two different "data_object" modules for array
storage instead of D2O. storage instead of D2O.
A "data_object" module consists of a class called "data_object" which A "data_object" module consists of a class called "data_object" which
provides a subset of the numpy.ndarray interface, plus a few additional provides a subset of the numpy.ndarray interface, plus a few additional
functions for manipulating these data objects. functions for manipulating these data objects.
If no MPI support is found on the system, or if a computation is run on a If no MPI support is found on the system, or if a computation is run on a
single task, nifty2go automatically loads a minimalistic "data_object" single task, nifty4 automatically loads a minimalistic "data_object"
module where the data_object class is simply identical to numpy.ndarray. module where the data_object class is simply identical to numpy.ndarray.
The support functions are mostly trivial as well. The support functions are mostly trivial as well.
If MPI is required, another module is loaded, which supports parallel If MPI is required, another module is loaded, which supports parallel
...@@ -53,11 +53,11 @@ Significant differences between NIFTy nightly and nifty2go ...@@ -53,11 +53,11 @@ Significant differences between NIFTy nightly and nifty2go
kindex -> k_lengths kindex -> k_lengths
(because this is not an index) (because this is not an index)
6) In nifty2go, PowerSpace is not a harmonic space. 6) In nifty4, PowerSpace is not a harmonic space.
7) In nifty2go, parallel probing should work (needs systematic testing) 7) In nifty4, parallel probing should work (needs systematic testing)
9) Many default arguments have been removed in nifty2go, wherever there is no 9) Many default arguments have been removed in nifty4, wherever there is no
sensible default (in my opinion). My personal impression is that this has sensible default (in my opinion). My personal impression is that this has
actually made the demos more readable, but I'm sure not everyone will agree actually made the demos more readable, but I'm sure not everyone will agree
:) :)
...@@ -80,8 +80,16 @@ Significant differences between NIFTy nightly and nifty2go ...@@ -80,8 +80,16 @@ Significant differences between NIFTy nightly and nifty2go
more or less always needed). more or less always needed).
14) A new approach is used for FFTs along axes that are distributed among 14) A new approach is used for FFTs along axes that are distributed among
MPI tasks. As a consequence, nifty2go works well with the standard version MPI tasks. As a consequence, nifty4 works well with the standard version
of pyfftw and does not need the MPI-enabled fork. of pyfftw and does not need the MPI-enabled fork.
15) Arithmetic functions working on Fields have been moved from 15) Arithmetic functions working on Fields have been moved from
basic_arithmetics.py to field.py. basic_arithmetics.py to field.py.
16) Operators can be comined via "*", "+" and "-", resulting in new combined
operators.
17) Every operator has the properties ".adjoint" and ".inverse", which return
its adjoint and inverse, respectively.
18) Handling of volume factors has been changed completely.
...@@ -2,10 +2,9 @@ from .version import __version__ ...@@ -2,10 +2,9 @@ from .version import __version__
from . import dobj from . import dobj
from .domain_object import DomainObject from .spaces.domain import Domain
from .spaces.unstructured_domain import UnstructuredDomain
from .spaces.field_array import FieldArray from .spaces.structured_domain import StructuredDomain
from .spaces.space import Space
from .spaces.rg_space import RGSpace from .spaces.rg_space import RGSpace
from .spaces.lm_space import LMSpace from .spaces.lm_space import LMSpace
from .spaces.hp_space import HPSpace from .spaces.hp_space import HPSpace
...@@ -23,8 +22,7 @@ from .operators.harmonic_transform_operator import HarmonicTransformOperator ...@@ -23,8 +22,7 @@ from .operators.harmonic_transform_operator import HarmonicTransformOperator
from .operators.fft_operator import FFTOperator from .operators.fft_operator import FFTOperator
from .operators.fft_smoothing_operator import FFTSmoothingOperator from .operators.fft_smoothing_operator import FFTSmoothingOperator
from .operators.direct_smoothing_operator import DirectSmoothingOperator from .operators.direct_smoothing_operator import DirectSmoothingOperator
from .operators.response_operator import ResponseOperator from .operators.geometry_remover import GeometryRemover
from .operators.response_operator import GeometryRemover
from .operators.laplace_operator import LaplaceOperator from .operators.laplace_operator import LaplaceOperator
from .operators.power_projection_operator import PowerProjectionOperator from .operators.power_projection_operator import PowerProjectionOperator
from .operators.inversion_enabler import InversionEnabler from .operators.inversion_enabler import InversionEnabler
...@@ -34,6 +32,7 @@ from .field import Field, sqrt, exp, log ...@@ -34,6 +32,7 @@ from .field import Field, sqrt, exp, log
from .probing.prober import Prober from .probing.prober import Prober
from .probing.diagonal_prober_mixin import DiagonalProberMixin from .probing.diagonal_prober_mixin import DiagonalProberMixin
from .probing.trace_prober_mixin import TraceProberMixin from .probing.trace_prober_mixin import TraceProberMixin
from .probing.utils import probe_with_posterior_samples
from .minimization.line_search import LineSearch from .minimization.line_search import LineSearch
from .minimization.line_search_strong_wolfe import LineSearchStrongWolfe from .minimization.line_search_strong_wolfe import LineSearchStrongWolfe
...@@ -55,11 +54,11 @@ from .sugar import * ...@@ -55,11 +54,11 @@ from .sugar import *
from .plotting.plot import plot from .plotting.plot import plot
from . import library from . import library
__all__ = ["DomainObject", "FieldArray", "Space", "RGSpace", "LMSpace", __all__ = ["Domain", "UnstructuredDomain", "StructuredDomain", "RGSpace", "LMSpace",
"HPSpace", "GLSpace", "DOFSpace", "PowerSpace", "DomainTuple", "HPSpace", "GLSpace", "DOFSpace", "PowerSpace", "DomainTuple",
"LinearOperator", "EndomorphicOperator", "ScalingOperator", "LinearOperator", "EndomorphicOperator", "ScalingOperator",
"DiagonalOperator", "FFTOperator", "FFTSmoothingOperator", "DiagonalOperator", "FFTOperator", "FFTSmoothingOperator",
"DirectSmoothingOperator", "ResponseOperator", "LaplaceOperator", "DirectSmoothingOperator", "LaplaceOperator",
"PowerProjectionOperator", "InversionEnabler", "PowerProjectionOperator", "InversionEnabler",
"Field", "sqrt", "exp", "log", "Field", "sqrt", "exp", "log",
"Prober", "DiagonalProberMixin", "TraceProberMixin"] "Prober", "DiagonalProberMixin", "TraceProberMixin"]
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
from functools import reduce from functools import reduce
from .domain_object import DomainObject from .spaces.domain import Domain
class DomainTuple(object): class DomainTuple(object):
...@@ -28,12 +28,10 @@ class DomainTuple(object): ...@@ -28,12 +28,10 @@ class DomainTuple(object):
self._axtuple = self._get_axes_tuple() self._axtuple = self._get_axes_tuple()
shape_tuple = tuple(sp.shape for sp in self._dom) shape_tuple = tuple(sp.shape for sp in self._dom)
self._shape = reduce(lambda x, y: x + y, shape_tuple, ()) self._shape = reduce(lambda x, y: x + y, shape_tuple, ())
self._dim = reduce(lambda x, y: x * y, self._shape, 1) self._size = reduce(lambda x, y: x * y, self._shape, 1)
self._accdims = (1,)
prod = 1 prod = 1
for dom in self._dom: for dom in self._dom:
prod *= dom.dim prod *= dom.size
self._accdims += (prod,)
def _get_axes_tuple(self): def _get_axes_tuple(self):
i = 0 i = 0
...@@ -60,16 +58,16 @@ class DomainTuple(object): ...@@ -60,16 +58,16 @@ class DomainTuple(object):
def _parse_domain(domain): def _parse_domain(domain):
if domain is None: if domain is None:
return () return ()
if isinstance(domain, DomainObject): if isinstance(domain, Domain):
return (domain,) return (domain,)
if not isinstance(domain, tuple): if not isinstance(domain, tuple):
domain = tuple(domain) domain = tuple(domain)
for d in domain: for d in domain:
if not isinstance(d, DomainObject): if not isinstance(d, Domain):
raise TypeError( raise TypeError(
"Given object contains something that is not an " "Given object contains something that is not an "
"instance of DomainObject class.") "instance of Domain class.")
return domain return domain
def __getitem__(self, i): def __getitem__(self, i):
...@@ -80,8 +78,8 @@ class DomainTuple(object): ...@@ -80,8 +78,8 @@ class DomainTuple(object):
return self._shape return self._shape
@property @property
def dim(self): def size(self):
return self._dim return self._size
@property @property
def axes(self): def axes(self):
......
...@@ -35,7 +35,7 @@ class Field(object): ...@@ -35,7 +35,7 @@ class Field(object):
Parameters Parameters
---------- ----------
domain : None, DomainTuple, tuple of DomainObjects, or single DomainObject domain : None, DomainTuple, tuple(Domain), or Domain
val : None, Field, data_object, or scalar val : None, Field, data_object, or scalar
The values the array should contain after init. A scalar input will The values the array should contain after init. A scalar input will
...@@ -156,7 +156,7 @@ class Field(object): ...@@ -156,7 +156,7 @@ class Field(object):
'pm1', 'normal', 'uniform' are the supported arguments for this 'pm1', 'normal', 'uniform' are the supported arguments for this
method. method.
domain : DomainObject domain : DomainTuple
The domain of the output random field The domain of the output random field
dtype : type dtype : type
...@@ -201,7 +201,7 @@ class Field(object): ...@@ -201,7 +201,7 @@ class Field(object):
return self._domain.shape return self._domain.shape
@property @property
def dim(self): def size(self):
""" Returns the total number of pixel-dimensions the field has. """ Returns the total number of pixel-dimensions the field has.
Effectively, all values from shape are multiplied. Effectively, all values from shape are multiplied.
...@@ -211,13 +211,13 @@ class Field(object): ...@@ -211,13 +211,13 @@ class Field(object):
out : int out : int
The dimension of the Field. The dimension of the Field.
""" """
return self._domain.dim return self._domain.size
@property @property
def real(self): def real(self):
""" The real part of the field (data is not copied).""" """ The real part of the field (data is not copied)."""
if not np.issubdtype(self.dtype, np.complexfloating): if not np.issubdtype(self.dtype, np.complexfloating):
raise ValueError(".real called on a non-complex Field") return self
return Field(self._domain, self.val.real) return Field(self._domain, self.val.real)
@property @property
......
...@@ -74,32 +74,8 @@ class WienerFilterCurvature(EndomorphicOperator): ...@@ -74,32 +74,8 @@ class WienerFilterCurvature(EndomorphicOperator):
covariance. covariance.
""" """