From e7fd7bd1555eff38d9b27145ccd0d7b200aedf04 Mon Sep 17 00:00:00 2001
From: theos <theo.steininger@ultimanet.de>
Date: Sat, 2 Jul 2016 01:46:41 +0200
Subject: [PATCH] Renamed field to Field; removed space; point_space is now
 called Space.

---
 __init__.py                     |  12 +-
 demos/demo_excaliwir.py         |   8 +-
 demos/demo_wf1.py               |   8 +-
 demos/demo_wf2.py               |   6 +-
 demos/demo_wf3.py               |   2 +-
 nifty_field.py => field.py      |  40 ++-
 lm/nifty_lm.py                  |  22 +-
 lm/nifty_power_conversion_lm.py |   6 +-
 nifty_paradict.py               | 178 ----------
 nifty_simple_math.py            |   2 +-
 nifty_utilities.py              |   1 +
 operators/nifty_minimization.py |   6 +-
 operators/nifty_operators.py    |  58 ++--
 operators/nifty_probing.py      |  25 +-
 rg/nifty_power_conversion_rg.py |   6 +-
 rg/nifty_rg.py                  |  16 +-
 setup.py                        |   2 +-
 space.py                        | 595 +-------------------------------
 test/test_nifty_field.py        |  25 +-
 test/test_nifty_spaces.py       |   4 +-
 20 files changed, 136 insertions(+), 886 deletions(-)
 rename nifty_field.py => field.py (97%)

diff --git a/__init__.py b/__init__.py
index e4acf586f..40ca99bae 100644
--- a/__init__.py
+++ b/__init__.py
@@ -38,17 +38,19 @@ from config import about,\
 from d2o import distributed_data_object, d2o_librarian
 
 from nifty_cmaps import ncmap
-from nifty_field import field
-from nifty_core import space,\
-                    point_space
+from field import Field
+from space import Space
+
+# this line exists for compatibility reasons
+# TODO: Remove this once the transition to field types is done.
+from space import Space as point_space
 
 from nifty_random import random
 from nifty_simple_math import *
 from nifty_utilities import *
 
 from nifty_paradict import space_paradict,\
-                            point_space_paradict,\
-                            nested_space_paradict
+                           nested_space_paradict
 
 from field_types import FieldType,\
                         FieldArray
diff --git a/demos/demo_excaliwir.py b/demos/demo_excaliwir.py
index 670963086..d94e714c7 100644
--- a/demos/demo_excaliwir.py
+++ b/demos/demo_excaliwir.py
@@ -112,7 +112,7 @@ class problem(object):
 
             Parameters
             ----------
-            newspace : {scalar, list, array, field, function}, *optional*
+            newspace : {scalar, list, array, Field, function}, *optional*
                 Assumed power spectrum (default: k ** -2).
 
         """
@@ -135,7 +135,7 @@ class problem(object):
 
             Parameters
             ----------
-            newspace : {scalar, list, array, field, function}, *optional*
+            newspace : {scalar, list, array, Field, function}, *optional*
                 Initial power spectrum (default: k ** -2).
             q : {scalar, list, array}, *optional*
                 Spectral scale parameter of the assumed inverse-Gamme prior
@@ -210,7 +210,7 @@ class problem(object):
         self.s.plot(title="signal", save="img/signal.png")
 
         try:
-            d_ = field(self.z, val=self.d.val, target=self.k)
+            d_ = Field(self.z, val=self.d.val, target=self.k)
             d_.plot(title="data", vmin=self.s.min(), vmax=self.s.max(),
                     save="img/data.png")
         except:
@@ -240,7 +240,7 @@ class problem(object):
         self.s.plot(title="signal")
         ## plot data
         try:
-            d_ = field(self.z, val=self.d.val, target=self.k)
+            d_ = Field(self.z, val=self.d.val, target=self.k)
             d_.plot(title="data", vmin=self.s.min(), vmax=self.s.max())
         except:
             pass
diff --git a/demos/demo_wf1.py b/demos/demo_wf1.py
index 2097828eb..372b41db4 100644
--- a/demos/demo_wf1.py
+++ b/demos/demo_wf1.py
@@ -72,7 +72,7 @@ if __name__ == "__main__":
 
     # some noise variance; e.g., signal-to-noise ratio of 1
     N = diagonal_operator(d_space, diag=s.var(), bare=True)          # define noise covariance
-    n = N.get_random_field(domain=d_space)                           # generate noise
+    n = N.get_random_Field(domain=d_space)                           # generate noise
 
 
     d = R(s) + n                                                     # compute data
@@ -84,7 +84,7 @@ if __name__ == "__main__":
     #m = D(j, tol=1E-8, limii=20, note=True, force=True)
     ident = identity(x_space)
 
-    #xi = field(x_space, random='gau', target=k_space)
+    #xi = Field(x_space, random='gau', target=k_space)
 
 
     m = D(j, W=S, tol=1E-8, limii=100, note=True)
@@ -101,11 +101,11 @@ if __name__ == "__main__":
            mono=False, save = 'power_plot_s.png', nbin=1000, log=True,
            vmax = 100, vmin=10e-7)
 
-    d_ = field(x_space, val=d.val, target=k_space)
+    d_ = Field(x_space, val=d.val, target=k_space)
     d_.plot(title="data", vmin=s.min(), vmax=s.max(), save = 'plot_d.png')
 
 
-    n_ = field(x_space, val=n.val, target=k_space)
+    n_ = Field(x_space, val=n.val, target=k_space)
     n_.plot(title="data", vmin=s.min(), vmax=s.max(), save = 'plot_n.png')
 
 
diff --git a/demos/demo_wf2.py b/demos/demo_wf2.py
index cd12d2418..8b1c56096 100644
--- a/demos/demo_wf2.py
+++ b/demos/demo_wf2.py
@@ -103,15 +103,15 @@ if __name__ == "__main__":
         return energy(x), gradient(x)
 
 
-    m = field(x_space, codomain=k_space)                               # reconstruct map
+    m = Field(x_space, codomain=k_space)                               # reconstruct map
 
     #with PyCallGraph(output=graphviz, config=config):
     m, convergence = steepest_descent(eggs=eggs, note=True)(m, tol=1E-3, clevel=3)
 
-    m = field(x_space, codomain=k_space)
+    m = Field(x_space, codomain=k_space)
     m, convergence = steepest_descent_new(energy, gradient, note=True)(m, tol=1E-3, clevel=3)
     #s.plot(title="signal")                                           # plot signal
-    #d_ = field(x_space, val=d.val, target=k_space)
+    #d_ = Field(x_space, val=d.val, target=k_space)
     #d_.plot(title="data", vmin=s.min(), vmax=s.max())                # plot data
     #m.plot(title="reconstructed map", vmin=s.min(), vmax=s.max())    # plot map
 
diff --git a/demos/demo_wf3.py b/demos/demo_wf3.py
index e8cda52dc..a97e48e87 100644
--- a/demos/demo_wf3.py
+++ b/demos/demo_wf3.py
@@ -79,7 +79,7 @@ if __name__ == "__main__":
 
     vminmax = {"vmin":1.5 * s.val.min(), "vmax":1.5 * s.val.max()}
     s.plot(title="signal", **vminmax)                                     # plot signal
-    d_ = field(x_space, val=d.val, target=k_space)
+    d_ = Field(x_space, val=d.val, target=k_space)
     d_.plot(title="data", **vminmax)                                      # plot data
     m.plot(title="reconstructed map", error=D.diag(bare=True), **vminmax) # plot map
     D.plot(title="information propagator", bare=True)                     # plot information propagator
diff --git a/nifty_field.py b/field.py
similarity index 97%
rename from nifty_field.py
rename to field.py
index 0a56875d3..5856db45a 100644
--- a/nifty_field.py
+++ b/field.py
@@ -9,10 +9,10 @@ from nifty.config import about, \
     nifty_configuration as gc, \
     dependency_injector as gdi
 
-from nifty.field_types import Field_type,\
-                              Field_array
+from nifty.field_types import FieldType,\
+                              FieldArray
 
-from nifty.nifty_core import space
+from nifty.space import Space
 
 import nifty.nifty_utilities as utilities
 from nifty_random import random
@@ -20,7 +20,7 @@ from nifty_random import random
 POINT_DISTRIBUTION_STRATEGIES = DISTRIBUTION_STRATEGIES['global']
 
 
-class field(object):
+class Field(object):
     """
         ..         ____   __             __          __
         ..       /   _/ /__/           /  /        /  /
@@ -133,7 +133,7 @@ class field(object):
         """
         # If the given val was a field, try to cast it accordingly to the given
         # domain and codomain, etc...
-        if isinstance(val, field):
+        if isinstance(val, Field):
             self._init_from_field(f=val,
                                   domain=domain,
                                   codomain=codomain,
@@ -273,7 +273,7 @@ class field(object):
         elif not isinstance(domain, tuple):
             domain = (domain,)
         for d in domain:
-            if not isinstance(d, space):
+            if not isinstance(d, Space):
                 raise TypeError(about._errors.cstring(
                     "ERROR: Given domain contains something that is not a "
                     "nifty.space."))
@@ -286,7 +286,7 @@ class field(object):
             raise ValueError(about._errors.cstring(
                 "ERROR: domain and codomain do not have the same length."))
         for (cd, d) in zip(codomain, domain):
-            if not isinstance(cd, space):
+            if not isinstance(cd, Space):
                 raise TypeError(about._errors.cstring(
                     "ERROR: Given codomain contains something that is not a"
                     "nifty.space."))
@@ -302,9 +302,9 @@ class field(object):
         elif not isinstance(field_type, tuple):
             field_type = (field_type,)
         for ft in field_type:
-            if not isinstance(ft, Field_type):
+            if not isinstance(ft, FieldType):
                 raise TypeError(about._errors.cstring(
-                    "ERROR: Given object is not a nifty.Field_type."))
+                    "ERROR: Given object is not a nifty.FieldType."))
         return field_type
 
     def _build_codomain(self, domain):
@@ -417,7 +417,7 @@ class field(object):
                 kwargs == {}):
             new_field = self._fast_copy_empty()
         else:
-            new_field = field(domain=domain, codomain=codomain, dtype=dtype,
+            new_field = Field(domain=domain, codomain=codomain, dtype=dtype,
                               comm=comm, datamodel=datamodel,
                               field_type=field_type, **kwargs)
         return new_field
@@ -543,7 +543,7 @@ class field(object):
                 Whether the method should raise a warning if information is
                 lost during casting (default: False).
         """
-        if isinstance(x, field):
+        if isinstance(x, Field):
             x = x.get_val()
 
         if dtype is None:
@@ -695,7 +695,7 @@ class field(object):
             return None
 
         # Case 2: x is a field
-        elif isinstance(x, field):
+        elif isinstance(x, Field):
             for ind, sp in enumerate(self.domain):
                 assert sp == x.domain[ind]
 
@@ -1281,8 +1281,8 @@ class field(object):
 
     def _binary_helper(self, other, op='None', inplace=False):
         # if other is a field, make sure that the domains match
-        if isinstance(other, field):
-            other = field(domain=self.domain,
+        if isinstance(other, Field):
+            other = Field(domain=self.domain,
                           val=other,
                           codomain=self.codomain,
                           copy=False)
@@ -1326,11 +1326,13 @@ class field(object):
                        'mean': lambda y: getattr(y, 'mean')(axis=axis),
                        'std': lambda y: getattr(y, 'std')(axis=axis),
                        'var': lambda y: getattr(y, 'var')(axis=axis),
-                       'argmin_nonflat': lambda y: getattr(y, 'argmin_nonflat')(
-                           axis=axis),
+                       'argmin_nonflat': lambda y: getattr(y,
+                                                           'argmin_nonflat')(
+                                                               axis=axis),
                        'argmin': lambda y: getattr(y, 'argmin')(axis=axis),
-                       'argmax_nonflat': lambda y: getattr(y, 'argmax_nonflat')(
-                           axis=axis),
+                       'argmax_nonflat': lambda y: getattr(y,
+                                                           'argmax_nonflat')(
+                                                               axis=axis),
                        'argmax': lambda y: getattr(y, 'argmax')(axis=axis),
                        'conjugate': lambda y: getattr(y, 'conjugate')(),
                        'sum': lambda y: getattr(y, 'sum')(axis=axis),
@@ -1451,6 +1453,6 @@ class field(object):
         return self._binary_helper(other, op='gt')
 
 
-class EmptyField(field):
+class EmptyField(Field):
     def __init__(self):
         pass
diff --git a/lm/nifty_lm.py b/lm/nifty_lm.py
index cf02f2fe4..2f0f44568 100644
--- a/lm/nifty_lm.py
+++ b/lm/nifty_lm.py
@@ -41,10 +41,9 @@ from matplotlib.ticker import LogFormatter as lf
 
 from d2o import STRATEGIES as DISTRIBUTION_STRATEGIES
 
-from nifty.nifty_core import space,\
-                             point_space
+from nifty.nifty_core import Space
 
-from nifty.nifty_field import field
+from nifty.field import Field
 
 from nifty.config import about,\
                          nifty_configuration as gc,\
@@ -63,7 +62,7 @@ GL_DISTRIBUTION_STRATEGIES = DISTRIBUTION_STRATEGIES['global']
 HP_DISTRIBUTION_STRATEGIES = DISTRIBUTION_STRATEGIES['global']
 
 
-class lm_space(point_space):
+class lm_space(Space):
     """
         ..       __
         ..     /  /
@@ -277,7 +276,7 @@ class lm_space(point_space):
         mol[self.paradict['lmax'] + 1:] = 2  # redundant: (l,m) and (l,-m)
         return mol
 
-    def _complement_cast(self, x, axis=None, **kwargs):
+    def complement_cast(self, x, axis=None, **kwargs):
         if axis is None:
             lmax = self.paradict['lmax']
             complexity_mask = x[:lmax+1].iscomplex()
@@ -912,7 +911,7 @@ class lm_space(point_space):
         return l, m
 
 
-class gl_space(point_space):
+class gl_space(Space):
     """
         ..                 __
         ..               /  /
@@ -1256,12 +1255,13 @@ class gl_space(point_space):
                                   p=np.float32(power),
                                   nlat=nlat, nlon=nlon,
                                   overwrite=False)
-        return self.cast(np_result)
+        # return self.cast(np_result)
+        return np_result
 
     def get_weight(self, power=1):
         # TODO: Check if this function is compatible to the rest of nifty
         # TODO: Can this be done more efficiently?
-        dummy = self.dtype(1)
+        dummy = self.dtype.type(1)
         weighted_dummy = self.calc_weight(dummy, power=power)
         return weighted_dummy / dummy
 
@@ -1571,7 +1571,7 @@ class gl_space(point_space):
             fig.canvas.draw()
 
 
-class hp_space(point_space):
+class hp_space(Space):
     """
         ..        __
         ..      /  /
@@ -2082,11 +2082,11 @@ class hp_space(point_space):
                 if(isinstance(other, tuple)):
                     other = list(other)
                     for ii in xrange(len(other)):
-                        if(isinstance(other[ii], field)):
+                        if(isinstance(other[ii], Field)):
                             other[ii] = other[ii].power(**kwargs)
                         else:
                             other[ii] = self.enforce_power(other[ii])
-                elif(isinstance(other, field)):
+                elif(isinstance(other, Field)):
                     other = [other.power(**kwargs)]
                 else:
                     other = [self.enforce_power(other)]
diff --git a/lm/nifty_power_conversion_lm.py b/lm/nifty_power_conversion_lm.py
index d30d9f52b..e7daa8491 100644
--- a/lm/nifty_power_conversion_lm.py
+++ b/lm/nifty_power_conversion_lm.py
@@ -23,7 +23,7 @@
 import numpy as np
 from numpy import pi
 from nifty.config import about
-from nifty.nifty_field import field
+from nifty.field import Field
 from nifty.nifty_simple_math import sqrt, exp, log
 
 
@@ -71,7 +71,7 @@ def power_backward_conversion_lm(k_space,p,mean=None):
         p[0] = 4*pi*mean**2
 
     klen = k_space.get_power_indices()[0]
-    C_0_Omega = field(k_space,val=0)
+    C_0_Omega = Field(k_space,val=0)
     C_0_Omega.val[:len(klen)] = p*sqrt(2*klen+1)/sqrt(4*pi)
     C_0_Omega = C_0_Omega.transform()
 
@@ -130,7 +130,7 @@ def power_forward_conversion_lm(k_space,p,mean=0):
     """
     m = mean
     klen = k_space.get_power_indices()[0]
-    C_0_Omega = field(k_space,val=0)
+    C_0_Omega = Field(k_space,val=0)
     C_0_Omega.val[:len(klen)] = p*sqrt(2*klen+1)/sqrt(4*pi)
     C_0_Omega = C_0_Omega.transform()
 
diff --git a/nifty_paradict.py b/nifty_paradict.py
index cff00ab08..809a6b774 100644
--- a/nifty_paradict.py
+++ b/nifty_paradict.py
@@ -48,22 +48,6 @@ class space_paradict(object):
         return result_hash
 
 
-class point_space_paradict(space_paradict):
-
-    def __setitem__(self, key, arg):
-        if key is not 'num':
-            raise ValueError(about._errors.cstring(
-                "ERROR: Unsupported point_space parameter"))
-        if not np.isscalar(arg):
-            raise ValueError(about._errors.cstring(
-                "ERROR: 'num' parameter must be scalar. Got: " + str(arg)))
-        if abs(arg) != arg:
-            raise ValueError(about._errors.cstring(
-                "ERROR: 'num' parameter must be positive. Got: " + str(arg)))
-        temp = np.int(arg)
-        self.parameters.__setitem__(key, temp)
-
-
 class rg_space_paradict(space_paradict):
 
     def __init__(self, shape, complexity, zerocenter):
@@ -218,165 +202,3 @@ class hp_space_paradict(space_paradict):
             raise ValueError(about._errors.cstring(
                 "ERROR: invalid parameter ( nside <> 2**n )."))
         self.parameters.__setitem__(key, temp)
-
-###################
-#
-#
-# class _space(object):
-#    def __init__(self):
-#        self.paradict = space_paradict(default=123)
-#        #self.para = [1,2,3]
-#
-#    @property
-#    def para(self):
-#        return self.paradict['default']
-#        #return self.distributed_val
-#
-#    @para.setter
-#    def para(self, x):
-#        self.paradict['default'] = x
-#
-###################
-###################
-#
-#
-#
-# class _point_space(object):
-#    def __init__(self):
-#        self.paradict = point_space_paradict()
-#        self.para = [10]
-#
-#    @property
-#    def para(self):
-#        temp = np.array([self.paradict['num']], dtype=int)
-#        return temp
-#        #return self.distributed_val
-#
-#    @para.setter
-#    def para(self, x):
-#        self.paradict['num'] = x
-#
-###################
-###################
-#
-#
-# class _rg_space(object):
-#    def __init__(self):
-#        self.paradict = rg_space_paradict(num=[10,100,200])
-#
-#    @property
-#    def para(self):
-#        temp = np.array(self.paradict['num'] + \
-#                         [self.paradict['hermitian']] + \
-#                         self.paradict['zerocenter'], dtype=int)
-#        return temp
-#
-#
-#    @para.setter
-#    def para(self, x):
-#        self.paradict['num'] = x[:(np.size(x)-1)//2]
-#        self.paradict['zerocenter'] = x[(np.size(x)+1)//2:]
-#        self.paradict['complexity'] = x[(np.size(x)-1)//2]
-#
-###################
-###################
-#
-# class _nested_space(object):
-#    def __init__(self):
-#        self.paradict = nested_space_paradict(ndim=10)
-#        for i in range(10):
-#            self.paradict[i] = [1+i, 2+i, 3+i]
-#
-#    @property
-#    def para(self):
-#        temp = []
-#        for i in range(self.paradict.ndim):
-#            temp = np.append(temp, self.paradict[i])
-#        return temp
-#
-#    @para.setter
-#    def para(self, x):
-#        dict_iter = 0
-#        x_iter = 0
-#        while dict_iter < self.paradict.ndim:
-#            temp = x[x_iter:x_iter+len(self.paradict[dict_iter])]
-#            self.paradict[dict_iter] = temp
-#            x_iter = x_iter+len(self.paradict[dict_iter])
-#            dict_iter += 1
-#
-###################
-###################
-#
-# class _lm_space(object):
-#    def __init__(self):
-#        self.paradict = lm_space_paradict(lmax = 10)
-#
-#    @property
-#    def para(self):
-#        temp = np.array([self.paradict['lmax'],
-#                         self.paradict['mmax']], dtype=int)
-#        return temp
-#
-#
-#    @para.setter
-#    def para(self, x):
-#        self.paradict['lmax'] = x[0]
-#        self.paradict['mmax'] = x[1]
-#
-#
-###################
-###################
-#
-# class _gl_space(object):
-#    def __init__(self):
-#        self.paradict = gl_space_paradict(nlat = 10)
-#
-#    @property
-#    def para(self):
-#        temp = np.array([self.paradict['nlat'],
-#                         self.paradict['nlon']], dtype=int)
-#        return temp
-#
-#
-#    @para.setter
-#    def para(self, x):
-#        self.paradict['nlat'] = x[0]
-#        self.paradict['nlon'] = x[1]
-#
-#
-###################
-###################
-#
-#
-# class _hp_space(object):
-#    def __init__(self):
-#        self.paradict = hp_space_paradict(nside=16)
-#
-#    @property
-#    def para(self):
-#        temp = np.array([self.paradict['nside']], dtype=int)
-#        return temp
-#
-#
-#    @para.setter
-#    def para(self, x):
-#        self.paradict['nside'] = x[0]
-#
-#
-#
-###################
-###################
-#
-#
-#
-# if __name__ == '__main__':
-#    myspace = _space()
-#    print myspace.para
-#    print myspace.paradict.parameters.items()
-#    myspace.para = [4,5,6]
-#    print myspace.para
-#    print myspace.paradict.parameters.items()
-#
-#    myspace.paradict.parameters['default'] = [1,4,7]
-#    print myspace.para
-#    print myspace.paradict.parameters.items()
diff --git a/nifty_simple_math.py b/nifty_simple_math.py
index 7481fd94c..785fcfb36 100644
--- a/nifty_simple_math.py
+++ b/nifty_simple_math.py
@@ -22,7 +22,7 @@
 
 ##-----------------------------------------------------------------------------
 import numpy as np
-#from nifty.nifty_core import field
+#from nifty.field import Field
 from nifty.config import about
 
 
diff --git a/nifty_utilities.py b/nifty_utilities.py
index f56707a72..5f402a7b4 100644
--- a/nifty_utilities.py
+++ b/nifty_utilities.py
@@ -5,6 +5,7 @@ from itertools import product
 
 from nifty.config import about
 
+
 def get_slice_list(shape, axes):
     """
     Helper function which generates slice list(s) to traverse over all
diff --git a/operators/nifty_minimization.py b/operators/nifty_minimization.py
index be20ce478..ff85e2a48 100644
--- a/operators/nifty_minimization.py
+++ b/operators/nifty_minimization.py
@@ -40,7 +40,7 @@ from __future__ import division
 #from nifty_core import *
 import numpy as np
 from nifty.config import notification, about
-from nifty.nifty_field import field
+from nifty.field import Field
 from nifty.nifty_simple_math import vdot
 
 
@@ -555,7 +555,7 @@ class steepest_descent(object):
                 has converged or not.
 
         """
-        if(not isinstance(x0,field)):
+        if(not isinstance(x0,Field)):
             raise TypeError(about._errors.cstring("ERROR: invalid input."))
         self.x = x0
 
@@ -844,7 +844,7 @@ class quasi_newton_minimizer(object):
                 has converged or not.
 
         """
-        if not isinstance(x0, field):
+        if not isinstance(x0, Field):
             raise TypeError(about._errors.cstring("ERROR: invalid input."))
         self.x = x0
 
diff --git a/operators/nifty_operators.py b/operators/nifty_operators.py
index f11726e2b..567641c05 100644
--- a/operators/nifty_operators.py
+++ b/operators/nifty_operators.py
@@ -22,9 +22,9 @@
 from __future__ import division
 import numpy as np
 from nifty.config import about
-from nifty.nifty_field import field
-from nifty.nifty_core import space, \
-    point_space
+from nifty.field import Field
+from nifty.space import Space
+
 from nifty_minimization import conjugate_gradient
 from nifty_probing import trace_prober,\
     inverse_trace_prober,\
@@ -227,7 +227,7 @@ class operator(object):
     def _briefing(self, x, domain, codomain, inverse):
         # make sure, that the result_field of the briefing lives in the
         # given domain and codomain
-        result_field = field(domain=domain, val=x, codomain=codomain,
+        result_field = Field(domain=domain, val=x, codomain=codomain,
                              copy=False)
 
         # weight if necessary
@@ -238,7 +238,7 @@ class operator(object):
     def _debriefing(self, x, y, target, cotarget, inverse):
         # The debriefing takes care that the result field lives in the same
         # fourier-type domain as the input field
-        assert(isinstance(y, field))
+        assert(isinstance(y, Field))
 
         # weight if necessary
         if (not self.imp) and (not target.discrete) and inverse:
@@ -1402,7 +1402,7 @@ class diagonal_operator(operator):
                 diag_val = self.domain.calc_weight(self.val, power=-1)
             else:
                 diag_val = self.val
-            diag = field(self.domain, codomain=self.codomain, val=diag_val)
+            diag = Field(self.domain, codomain=self.codomain, val=diag_val)
         else:
             diag = super(diagonal_operator, self).diag(bare=bare,
                                                        domain=domain,
@@ -1490,7 +1490,7 @@ class diagonal_operator(operator):
                                                            power=-1)
             else:
                 inverse_diag_val = inverse_val
-            inverse_diag = field(self.domain, codomain=self.codomain,
+            inverse_diag = Field(self.domain, codomain=self.codomain,
                                  val=inverse_diag_val)
 
         else:
@@ -1578,7 +1578,7 @@ class diagonal_operator(operator):
                 Random field.
 
         """
-        temp_field = field(domain=self.domain,
+        temp_field = Field(domain=self.domain,
                            codomain=self.codomain,
                            random='gau',
                            std=nifty_simple_math.sqrt(
@@ -1592,7 +1592,7 @@ class diagonal_operator(operator):
         else:
             codomain = domain.get_codomain()
 
-        return field(domain=domain, val=temp_field, codomain=codomain)
+        return Field(domain=domain, val=temp_field, codomain=codomain)
 
 #        if domain.harmonic != self.domain.harmonic:
 #            temp_field = temp_field.transform(new_domain=domain)
@@ -1802,7 +1802,7 @@ class power_operator(diagonal_operator):
 
         """
         # Set the domain
-        if not isinstance(domain, space):
+        if not isinstance(domain, Space):
             raise TypeError(about._errors.cstring(
                 "ERROR: The given domain is not a nifty space."))
         self.domain = domain
@@ -2173,7 +2173,7 @@ class projection_operator(operator):
 
         """
         # Check the domain
-        if not isinstance(domain, space):
+        if not isinstance(domain, Space):
             raise TypeError(about._errors.cstring(
                 "ERROR: The supplied domain is not a nifty space instance."))
         self.domain = domain
@@ -2275,7 +2275,7 @@ class projection_operator(operator):
                 raise TypeError(about._errors.cstring("ERROR: Invalid bands."))
 
             if bands_was_scalar:
-                new_field = fx * (self.assign == bands[0])
+                new_field = x * (self.assign == bands[0])
             else:
                 # build up the projection results
                 # prepare the projector-carrier
@@ -2367,12 +2367,13 @@ class projection_operator(operator):
         # Case 1: x is a field
         # -> Compute the diagonal of the corresponding vecvec-operator:
         # x * x^dagger
-        if isinstance(x, field):
+        if isinstance(x, Field):
             # check if field is in the same signal/harmonic space as the
             # domain of the projection operator
             if self.domain != x.domain:
                 # TODO: check if a exception should be raised, or if
                 # one should try to fix stuff.
+                pass
                 # x = x.transform(new_domain=self.domain)
             vecvec = vecvec_operator(val=x)
             return self.pseudo_tr(x=vecvec, axis=axis, **kwargs)
@@ -2386,6 +2387,7 @@ class projection_operator(operator):
             if self.domain != working_field.domain:
                 # TODO: check if a exception should be raised, or if
                 # one should try to fix stuff.
+                pass
                 # working_field = working_field.transform(new_domain=self.domain)
 
         # Case 3: x is something else
@@ -2472,13 +2474,13 @@ class vecvec_operator(operator):
             -------
             None
         """
-        if isinstance(val, field):
+        if isinstance(val, Field):
             if domain is None:
                 domain = val.domain
             if codomain is None:
                 codomain = val.codomain
 
-        if not isinstance(domain, space):
+        if not isinstance(domain, Space):
             raise TypeError(about._errors.cstring("ERROR: invalid input."))
         self.domain = domain
 
@@ -2489,7 +2491,7 @@ class vecvec_operator(operator):
 
         self.target = self.domain
         self.cotarget = self.codomain
-        self.val = field(domain=self.domain,
+        self.val = Field(domain=self.domain,
                          codomain=self.codomain,
                          val=val)
 
@@ -2778,7 +2780,7 @@ class response_operator(operator):
             -------
             None
         """
-        if not isinstance(domain, space):
+        if not isinstance(domain, Space):
             raise TypeError(about._errors.cstring(
                 "ERROR: The domain must be a space instance."))
         self.domain = domain
@@ -2838,12 +2840,13 @@ class response_operator(operator):
 
         if target is None:
             # set target
-            target = point_space(assignments,
+            # TODO: Fix the target spaces
+            target = Space(assignments,
                                  dtype=self.domain.dtype,
                                  datamodel=self.domain.datamodel)
         else:
             # check target
-            if not isinstance(target, space):
+            if not isinstance(target, Space):
                 raise TypeError(about._errors.cstring(
                     "ERROR: Given target is not a nifty space"))
             elif not target.discrete:
@@ -2915,7 +2918,7 @@ class response_operator(operator):
                 val = y.flatten(inplace=True)
             except TypeError:
                 val = y.flatten()
-        return field(self.target,
+        return Field(self.target,
                      val=val,
                      codomain=self.cotarget)
 
@@ -2928,14 +2931,14 @@ class response_operator(operator):
 
         y *= self.mask
         y = self.domain.calc_smooth(y, sigma=self.sigma)
-        return field(self.domain,
+        return Field(self.domain,
                      val=y,
                      codomain=self.codomain)
 
     def _briefing(self, x, domain, codomain, inverse):
         # make sure, that the result_field of the briefing lives in the
         # given domain and codomain
-        result_field = field(domain=domain, val=x, codomain=codomain,
+        result_field = Field(domain=domain, val=x, codomain=codomain,
                              copy=False)
 
         # weight if necessary
@@ -2947,7 +2950,7 @@ class response_operator(operator):
     def _debriefing(self, x, y, target, cotarget, inverse):
         # The debriefing takes care that the result field lives in the same
         # fourier-type domain as the input field
-        assert(isinstance(y, field))
+        assert(isinstance(y, Field))
 
         # weight if necessary
         if (not self.imp) and (not target.discrete) and \
@@ -3066,7 +3069,7 @@ class invertible_operator(operator):
                 the operator class can use (default: None).
 
         """
-        if not isinstance(domain, space):
+        if not isinstance(domain, Space):
             raise TypeError(about._errors.cstring("ERROR: invalid input."))
         self.domain = domain
         if self.domain.check_codomain(codomain):
@@ -3085,7 +3088,6 @@ class invertible_operator(operator):
         self.target = self.domain
         self.cotarget = self.codomain
 
-
     def _multiply(self, x, force=False, W=None, spam=None, reset=None,
                   note=False, x0=None, tol=1E-4, clevel=1, limii=None,
                   **kwargs):
@@ -3600,8 +3602,8 @@ class propagator_operator_old(operator):
 
     def _briefing(self, x):  # > prepares x for `multiply`
         # inspect x
-        if not isinstance(x, field):
-            return (field(self.domain, codomain=self.codomain,
+        if not isinstance(x, Field):
+            return (Field(self.domain, codomain=self.codomain,
                           val=x),
                     False)
         # check x.domain
@@ -3619,7 +3621,7 @@ class propagator_operator_old(operator):
         if x_ is None:
             return None
         # inspect x
-        elif isinstance(x, field):
+        elif isinstance(x, Field):
             # repair ...
             if in_codomain == True and x.domain != self.codomain:
                 x_ = x_.transform(new_domain=x.domain)  # ... domain
diff --git a/operators/nifty_probing.py b/operators/nifty_probing.py
index 1c8c23b5c..d86745b7b 100644
--- a/operators/nifty_probing.py
+++ b/operators/nifty_probing.py
@@ -22,13 +22,11 @@
 from __future__ import division
 
 from nifty.config import about
-from nifty.nifty_core import space
-from nifty.nifty_field import field
+from nifty.space import Space
+from nifty.field import Field
 from nifty.nifty_utilities import direct_vdot
 
 
-
-
 class prober(object):
     """
         ..                                    __        __
@@ -185,7 +183,7 @@ class prober(object):
                 raise ValueError(about._errors.cstring(
                   "ERROR: invalid input: No function given or not callable."))
             # check given domain
-            if domain is None or not isinstance(domain, space):
+            if domain is None or not isinstance(domain, Space):
                 raise ValueError(about._errors.cstring(
                     "ERROR: invalid input: given domain is not a nifty space"))
 
@@ -211,7 +209,7 @@ class prober(object):
                         "of the operator!"))
 
             # Check 2.3 extract domain
-            if domain is None or not isinstance(domain, space):
+            if domain is None or not isinstance(domain, Space):
                 if (function in [operator.inverse_times,
                                  operator.adjoint_times]):
                     try:
@@ -293,7 +291,7 @@ class prober(object):
                 each component
 
         """
-        return field(self.domain,
+        return Field(self.domain,
                      codomain=self.codomain,
                      random=self.random)
 
@@ -353,11 +351,10 @@ class prober(object):
         else:
             about.infos.cflush("\n")
 
-
-        if self.varQ == True:
+        if self.varQ:
             if num == 1:
                 about.warnings.cprint(
-                "WARNING: Only one probe available -> infinite variance.")
+                    "WARNING: Only one probe available -> infinite variance.")
                 return (sum_of_probes, None)
             else:
                 var = 1/(num-1)*(sum_of_squares - 1/num*(sum_of_probes**2))
@@ -365,9 +362,7 @@ class prober(object):
         else:
             return sum_of_probes*(1./num)
 
-
-
-    def print_progress(self, num): # > prints progress status by in upto 10 dots
+    def print_progress(self, num):  # > prints progress status upto 10 dots
         tenths = 1+(10*num//self.nrun)
         about.infos.cflush(("\b")*10+('.')*tenths+(' ')*(10-tenths))
     """
@@ -379,7 +374,7 @@ class prober(object):
         return self.probing(zipped[1],probe)
     """
 
-    def probe(self): # > performs the probing operations one after another
+    def probe(self):  # > performs the probing operations one after another
         # initialize the variables
         sum_of_probes = 0
         sum_of_squares = 0
@@ -479,7 +474,7 @@ class inverse_trace_prober(_specialized_prober):
 
     def _probing_function(self, probe):
         return direct_vdot(probe.conjugate(),
-                          self.operator.inverse_times(probe))
+                           self.operator.inverse_times(probe))
 
 
 class diagonal_prober(_specialized_prober):
diff --git a/rg/nifty_power_conversion_rg.py b/rg/nifty_power_conversion_rg.py
index 3fc4883fb..8255195f5 100644
--- a/rg/nifty_power_conversion_rg.py
+++ b/rg/nifty_power_conversion_rg.py
@@ -22,7 +22,7 @@
 
 import numpy as np
 from nifty.config import about
-from nifty.nifty_field import field
+from nifty.field import Field
 
 
 def power_backward_conversion_rg(k_space, p, mean=None, bare=True):
@@ -88,7 +88,7 @@ def power_backward_conversion_rg(k_space, p, mean=None, bare=True):
 
     p_val = pindex.apply_scalar_function(lambda x: spec[x],
                                          dtype=spec.dtype.type)
-    power_field = field(k_space, val=p_val, zerocenter=True).transform()
+    power_field = Field(k_space, val=p_val, zerocenter=True).transform()
     power_field += (mean**2)
 
     if power_field.min() < 0:
@@ -164,7 +164,7 @@ def power_forward_conversion_rg(k_space, p, mean=0, bare=True):
                                          dtype=spec.dtype.type)
 
     # S_x is a field
-    S_x = field(k_space, val=S_val, zerocenter=True).transform()
+    S_x = Field(k_space, val=S_val, zerocenter=True).transform()
     # s_0 is a scalar
     s_0 = k_space.calc_weight(S_val, power=1).sum()
 
diff --git a/rg/nifty_rg.py b/rg/nifty_rg.py
index 4ce2bfc77..c3330d28a 100644
--- a/rg/nifty_rg.py
+++ b/rg/nifty_rg.py
@@ -43,8 +43,8 @@ from matplotlib.ticker import LogFormatter as lf
 
 from d2o import STRATEGIES as DISTRIBUTION_STRATEGIES
 
-from nifty.nifty_core import point_space
-from nifty.nifty_field import field
+from nifty.space import Space
+from nifty.field import Field
 
 import nifty_fft
 from nifty.config import about,\
@@ -59,7 +59,7 @@ MPI = gdi[gc['mpi_module']]
 RG_DISTRIBUTION_STRATEGIES = DISTRIBUTION_STRATEGIES['global']
 
 
-class rg_space(point_space):
+class rg_space(Space):
     """
         ..      _____   _______
         ..    /   __/ /   _   /
@@ -153,7 +153,7 @@ class rg_space(point_space):
             -------
             None
         """
-        self._cache_dict = {'check_codomain':{}}
+        self._cache_dict = {'check_codomain': {}}
         self.paradict = rg_space_paradict(shape=shape,
                                           complexity=complexity,
                                           zerocenter=zerocenter)
@@ -252,7 +252,7 @@ class rg_space(point_space):
     def shape(self):
         return tuple(self.paradict['shape'])
 
-    def _complement_cast(self, x, axis=None, hermitianize=True):
+    def complement_cast(self, x, axis=None, hermitianize=True):
         if axis is None:
             if x is not None and hermitianize and self.paradict['complexity']\
                     == 1 and not x.hermitian:
@@ -1274,7 +1274,7 @@ class rg_space(point_space):
         """
         about.warnings.cflush(
             "WARNING: _enforce_values is deprecated function. Please use self.cast")
-        if(isinstance(x, field)):
+        if(isinstance(x, Field)):
             if(self == x.domain):
                 if(self.dtype is not x.domain.dtype):
                     raise TypeError(about._errors.cstring("ERROR: inequal data types ( '" + str(
@@ -1429,12 +1429,12 @@ class rg_space(point_space):
                 if(isinstance(other, tuple)):
                     other = list(other)
                     for ii in xrange(len(other)):
-                        if(isinstance(other[ii], field)):
+                        if(isinstance(other[ii], Field)):
                             other[ii] = other[ii].power(**kwargs)
                         else:
                             other[ii] = self.enforce_power(
                                 other[ii], size=np.size(xaxes), kindex=xaxes)
-                elif(isinstance(other, field)):
+                elif(isinstance(other, Field)):
                     other = [other.power(**kwargs)]
                 else:
                     other = [self.enforce_power(
diff --git a/setup.py b/setup.py
index 755fcb5ee..b0b6a8df0 100644
--- a/setup.py
+++ b/setup.py
@@ -34,7 +34,7 @@ setup(name="ift_nifty",
       url="http://www.mpa-garching.mpg.de/ift/nifty/",
       packages=["nifty", "nifty.demos", "nifty.rg", "nifty.lm",
                 "nifty.operators", "nifty.dummys", "nifty.field_types",
-                "nifty.config"],
+                "nifty.config", "nifty.power"],
       package_dir={"nifty": ""},
       zip_safe=False,
       dependency_links=[
diff --git a/space.py b/space.py
index b7286cfe7..39461f8d8 100644
--- a/space.py
+++ b/space.py
@@ -144,594 +144,15 @@ from __future__ import division
 import numpy as np
 import pylab as pl
 
-from d2o import distributed_data_object,\
-                STRATEGIES as DISTRIBUTION_STRATEGIES
+from d2o import STRATEGIES as DISTRIBUTION_STRATEGIES
 
-from nifty_paradict import space_paradict,\
-    point_space_paradict
+from nifty_paradict import space_paradict
 
 from nifty.config import about
 
-from nifty_random import random
-
 POINT_DISTRIBUTION_STRATEGIES = DISTRIBUTION_STRATEGIES['global']
 
 
-#class space(object):
-#    """
-#        ..     _______   ______    ____ __   _______   _______
-#        ..   /  _____/ /   _   | /   _   / /   ____/ /   __  /
-#        ..  /_____  / /  /_/  / /  /_/  / /  /____  /  /____/
-#        .. /_______/ /   ____/  \______|  \______/  \______/  class
-#        ..          /__/
-#
-#        NIFTY base class for spaces and their discretizations.
-#
-#        The base NIFTY space class is an abstract class from which other
-#        specific space subclasses, including those preimplemented in NIFTY
-#        (e.g. the regular grid class) must be derived.
-#
-#        Parameters
-#        ----------
-#        dtype : numpy.dtype, *optional*
-#            Data type of the field values for a field defined on this space
-#            (default: numpy.float64).
-#        datamodel :
-#
-#        See Also
-#        --------
-#        point_space :  A class for unstructured lists of numbers.
-#        rg_space : A class for regular cartesian grids in arbitrary dimensions.
-#        hp_space : A class for the HEALPix discretization of the sphere
-#            [#]_.
-#        gl_space : A class for the Gauss-Legendre discretization of the sphere
-#            [#]_.
-#        lm_space : A class for spherical harmonic components.
-#        nested_space : A class for product spaces.
-#
-#        References
-#        ----------
-#        .. [#] K.M. Gorski et al., 2005, "HEALPix: A Framework for
-#               High-Resolution Discretization and Fast Analysis of Data
-#               Distributed on the Sphere", *ApJ* 622..759G.
-#        .. [#] M. Reinecke and D. Sverre Seljebotn, 2013, "Libsharp - spherical
-#               harmonic transforms revisited";
-#               `arXiv:1303.4945 <http://www.arxiv.org/abs/1303.4945>`_
-#
-#        Attributes
-#        ----------
-#        para : {single object, list of objects}
-#            This is a freeform list of parameters that derivatives of the space
-#            class can use.
-#        dtype : numpy.dtype
-#            Data type of the field values for a field defined on this space.
-#        discrete : bool
-#            Whether the space is inherently discrete (true) or a discretization
-#            of a continuous space (false).
-#        vol : numpy.ndarray
-#            An array of pixel volumes, only one component if the pixels all
-#            have the same volume.
-#    """
-#
-#    def __init__(self):
-#        """
-#            Sets the attributes for a space class instance.
-#
-#            Parameters
-#            ----------
-#            dtype : numpy.dtype, *optional*
-#                Data type of the field values for a field defined on this space
-#                (default: numpy.float64).
-#            datamodel :
-#
-#            Returns
-#            -------
-#            None
-#        """
-#        self.paradict = space_paradict()
-#
-#    @property
-#    def para(self):
-#        return self.paradict['default']
-#
-#    @para.setter
-#    def para(self, x):
-#        self.paradict['default'] = x
-#
-#    def __hash__(self):
-#        return hash(())
-#
-#    def _identifier(self):
-#        """
-#        _identiftier returns an object which contains all information needed
-#        to uniquely idetnify a space. It returns a (immutable) tuple which
-#        therefore can be compared.
-#        """
-#        return tuple(sorted(vars(self).items()))
-#
-#    def __eq__(self, x):
-#        if isinstance(x, type(self)):
-#            return self._identifier() == x._identifier()
-#        else:
-#            return False
-#
-#    def __ne__(self, x):
-#        return not self.__eq__(x)
-#
-#    def __len__(self):
-#        return int(self.dim)
-#
-#    def copy(self):
-#        return space(para=self.para,
-#                     dtype=self.dtype)
-#
-#    def getitem(self, data, key):
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'getitem'."))
-#
-#    def setitem(self, data, update, key):
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'getitem'."))
-#
-#    def apply_scalar_function(self, x, function, inplace=False):
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'apply_scalar_function'."))
-#
-#    @property
-#    def shape(self):
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'shape'."))
-#
-#    @property
-#    def dim(self):
-#        """
-#            Computes the dimension of the space, i.e.\  the number of pixels.
-#
-#            Parameters
-#            ----------
-#            split : bool, *optional*
-#                Whether to return the dimension split up, i.e. the numbers of
-#                pixels in each direction, or not (default: False).
-#
-#            Returns
-#            -------
-#            dim : {int, numpy.ndarray}
-#                Dimension(s) of the space.
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'dim'."))
-#
-#    @property
-#    def dof(self):
-#        """
-#            Computes the number of degrees of freedom of the space.
-#
-#            Returns
-#            -------
-#            dof : int
-#                Number of degrees of freedom of the space.
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'dof'."))
-#
-#    @property
-#    def dof_split(self):
-#        """
-#            Computes the number of degrees of freedom of the space.
-#
-#            Returns
-#            -------
-#            dof : int
-#                Number of degrees of freedom of the space.
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'dof_split'."))
-#
-#    def complement_cast(self, x, axis=None):
-#        return x
-#
-#    # TODO: Move enforce power into power_indices class
-#    def enforce_power(self, spec, **kwargs):
-#        """
-#            Provides a valid power spectrum array from a given object.
-#
-#            Parameters
-#            ----------
-#            spec : {scalar, list, numpy.ndarray, nifty.field, function}
-#                Fiducial power spectrum from which a valid power spectrum is to
-#                be calculated. Scalars are interpreted as constant power
-#                spectra.
-#
-#            Returns
-#            -------
-#            spec : numpy.ndarray
-#                Valid power spectrum.
-#
-#            Other parameters
-#            ----------------
-#            size : int, *optional*
-#                Number of bands the power spectrum shall have (default: None).
-#            kindex : numpy.ndarray, *optional*
-#                Scale of each band.
-#            codomain : nifty.space, *optional*
-#                A compatible codomain for power indexing (default: None).
-#            log : bool, *optional*
-#                Flag specifying if the spectral binning is performed on
-#                logarithmic
-#                scale or not; if set, the number of used bins is set
-#                automatically (if not given otherwise); by default no binning
-#                is done (default: None).
-#            nbin : integer, *optional*
-#                Number of used spectral bins; if given `log` is set to
-#                ``False``;
-#                integers below the minimum of 3 induce an automatic setting;
-#                by default no binning is done (default: None).
-#            binbounds : {list, array}, *optional*
-#                User specific inner boundaries of the bins, which are preferred
-#                over the above parameters; by default no binning is done
-#                (default: None).
-#            vmin : {scalar, list, ndarray, field}, *optional*
-#                Lower limit of the uniform distribution if ``random == "uni"``
-#                (default: 0).
-#
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'enforce_power'."))
-#
-#    def check_codomain(self, codomain):
-#        """
-#            Checks whether a given codomain is compatible to the space or not.
-#
-#            Parameters
-#            ----------
-#            codomain : nifty.space
-#                Space to be checked for compatibility.
-#
-#            Returns
-#            -------
-#            check : bool
-#                Whether or not the given codomain is compatible to the space.
-#        """
-#        if codomain is None:
-#            return False
-#        else:
-#            raise NotImplementedError(about._errors.cstring(
-#                "ERROR: no generic instance method 'check_codomain'."))
-#
-#    def get_codomain(self, **kwargs):
-#        """
-#            Generates a compatible codomain to which transformations are
-#            reasonable, usually either the position basis or the basis of
-#            harmonic eigenmodes.
-#
-#            Parameters
-#            ----------
-#            coname : string, *optional*
-#                String specifying a desired codomain (default: None).
-#            cozerocenter : {bool, numpy.ndarray}, *optional*
-#                Whether or not the grid is zerocentered for each axis or not
-#                (default: None).
-#            conest : list, *optional*
-#                List of nested spaces of the codomain (default: None).
-#            coorder : list, *optional*
-#                Permutation of the list of nested spaces (default: None).
-#
-#            Returns
-#            -------
-#            codomain : nifty.space
-#                A compatible codomain.
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'get_codomain'."))
-#
-#    def get_random_values(self, **kwargs):
-#        """
-#            Generates random field values according to the specifications given
-#            by the parameters.
-#
-#            Returns
-#            -------
-#            x : numpy.ndarray
-#                Valid field values.
-#
-#            Other parameters
-#            ----------------
-#            random : string, *optional*
-#                Specifies the probability distribution from which the random
-#                numbers are to be drawn.
-#                Supported distributions are:
-#
-#                - "pm1" (uniform distribution over {+1,-1} or {+1,+i,-1,-i}
-#                - "gau" (normal distribution with zero-mean and a given
-#                    standard deviation or variance)
-#                - "syn" (synthesizes from a given power spectrum)
-#                - "uni" (uniform distribution over [vmin,vmax[)
-#
-#                (default: None).
-#            dev : float, *optional*
-#                Standard deviation (default: 1).
-#            var : float, *optional*
-#                Variance, overriding `dev` if both are specified
-#                (default: 1).
-#            spec : {scalar, list, numpy.ndarray, nifty.field, function},
-#                    *optional*
-#                Power spectrum (default: 1).
-#            pindex : numpy.ndarray, *optional*
-#                Indexing array giving the power spectrum index of each band
-#                (default: None).
-#            kindex : numpy.ndarray, *optional*
-#                Scale of each band (default: None).
-#            codomain : nifty.space, *optional*
-#                A compatible codomain with power indices (default: None).
-#            log : bool, *optional*
-#                Flag specifying if the spectral binning is performed on
-#                logarithmic
-#                scale or not; if set, the number of used bins is set
-#                automatically (if not given otherwise); by default no binning
-#                is done (default: None).
-#            nbin : integer, *optional*
-#                Number of used spectral bins; if given `log` is set to
-#                ``False``;
-#                integers below the minimum of 3 induce an automatic setting;
-#                by default no binning is done (default: None).
-#            binbounds : {list, array}, *optional*
-#                User specific inner boundaries of the bins, which are preferred
-#                over the above parameters; by default no binning is done
-#                (default: None).
-#            vmin : {scalar, list, ndarray, field}, *optional*
-#                Lower limit of the uniform distribution if ``random == "uni"``
-#                (default: 0).
-#            vmin : float, *optional*
-#                Lower limit for a uniform distribution (default: 0).
-#            vmax : float, *optional*
-#                Upper limit for a uniform distribution (default: 1).
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'get_random_values'."))
-#
-#    def calc_weight(self, x, power=1):
-#        """
-#            Weights a given array of field values with the pixel volumes (not
-#            the meta volumes) to a given power.
-#
-#            Parameters
-#            ----------
-#            x : numpy.ndarray
-#                Array to be weighted.
-#            power : float, *optional*
-#                Power of the pixel volumes to be used (default: 1).
-#
-#            Returns
-#            -------
-#            y : numpy.ndarray
-#                Weighted array.
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'calc_weight'."))
-#
-#    def get_weight(self, power=1):
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'get_weight'."))
-#
-#    def calc_norm(self, x, q):
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'norm'."))
-#
-#    def dot_contraction(self, x, axes):
-#        """
-#            Computes the discrete inner product of two given arrays of field
-#            values.
-#
-#            Parameters
-#            ----------
-#            x : numpy.ndarray
-#                First array
-#            y : numpy.ndarray
-#                Second array
-#
-#            Returns
-#            -------
-#            dot : scalar
-#                Inner product of the two arrays.
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'dot'."))
-#
-#    def calc_transform(self, x, codomain=None, **kwargs):
-#        """
-#            Computes the transform of a given array of field values.
-#
-#            Parameters
-#            ----------
-#            x : numpy.ndarray
-#                Array to be transformed.
-#            codomain : nifty.space, *optional*
-#                codomain space to which the transformation shall map
-#                (default: self).
-#
-#            Returns
-#            -------
-#            Tx : numpy.ndarray
-#                Transformed array
-#
-#            Other parameters
-#            ----------------
-#            iter : int, *optional*
-#                Number of iterations performed in specific transformations.
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'calc_transform'."))
-#
-#    def calc_smooth(self, x, sigma=0, **kwargs):
-#        """
-#            Smoothes an array of field values by convolution with a Gaussian
-#            kernel.
-#
-#            Parameters
-#            ----------
-#            x : numpy.ndarray
-#                Array of field values to be smoothed.
-#            sigma : float, *optional*
-#                Standard deviation of the Gaussian kernel, specified in units
-#                of length in position space (default: 0).
-#
-#            Returns
-#            -------
-#            Gx : numpy.ndarray
-#                Smoothed array.
-#
-#            Other parameters
-#            ----------------
-#            iter : int, *optional*
-#                Number of iterations (default: 0).
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'calc_smooth'."))
-#
-#    def calc_power(self, x, **kwargs):
-#        """
-#            Computes the power of an array of field values.
-#
-#            Parameters
-#            ----------
-#            x : numpy.ndarray
-#                Array containing the field values of which the power is to be
-#                calculated.
-#
-#            Returns
-#            -------
-#            spec : numpy.ndarray
-#                Power contained in the input array.
-#
-#            Other parameters
-#            ----------------
-#            pindex : numpy.ndarray, *optional*
-#                Indexing array assigning the input array components to
-#                components of the power spectrum (default: None).
-#            kindex : numpy.ndarray, *optional*
-#                Scale corresponding to each band in the power spectrum
-#                (default: None).
-#            rho : numpy.ndarray, *optional*
-#                Number of degrees of freedom per band (default: None).
-#            codomain : nifty.space, *optional*
-#                A compatible codomain for power indexing (default: None).
-#            log : bool, *optional*
-#                Flag specifying if the spectral binning is performed on
-#                logarithmic
-#                scale or not; if set, the number of used bins is set
-#                automatically (if not given otherwise); by default no binning
-#                is done (default: None).
-#            nbin : integer, *optional*
-#                Number of used spectral bins; if given `log` is set to
-#                ``False``;
-#                integers below the minimum of 3 induce an automatic setting;
-#                by default no binning is done (default: None).
-#            binbounds : {list, array}, *optional*
-#                User specific inner boundaries of the bins, which are preferred
-#                over the above parameters; by default no binning is done
-#                (default: None).
-#            vmin : {scalar, list, ndarray, field}, *optional*
-#                Lower limit of the uniform distribution if ``random == "uni"``
-#                (default: 0).
-#
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'calc_power'."))
-#
-#    def calc_real_Q(self, x):
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'calc_real_Q'."))
-#
-#    def calc_bincount(self, x, weights=None, minlength=None):
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'calc_bincount'."))
-#
-#    def get_plot(self, x, **kwargs):
-#        """
-#            Creates a plot of field values according to the specifications
-#            given by the parameters.
-#
-#            Parameters
-#            ----------
-#            x : numpy.ndarray
-#                Array containing the field values.
-#
-#            Returns
-#            -------
-#            None
-#
-#            Other parameters
-#            ----------------
-#            title : string, *optional*
-#                Title of the plot (default: "").
-#            vmin : float, *optional*
-#                Minimum value to be displayed (default: ``min(x)``).
-#            vmax : float, *optional*
-#                Maximum value to be displayed (default: ``max(x)``).
-#            power : bool, *optional*
-#                Whether to plot the power contained in the field or the field
-#                values themselves (default: False).
-#            unit : string, *optional*
-#                Unit of the field values (default: "").
-#            norm : string, *optional*
-#                Scaling of the field values before plotting (default: None).
-#            cmap : matplotlib.colors.LinearSegmentedColormap, *optional*
-#                Color map to be used for two-dimensional plots (default: None).
-#            cbar : bool, *optional*
-#                Whether to show the color bar or not (default: True).
-#            other : {single object, tuple of objects}, *optional*
-#                Object or tuple of objects to be added, where objects can be
-#                scalars, arrays, or fields (default: None).
-#            legend : bool, *optional*
-#                Whether to show the legend or not (default: False).
-#            mono : bool, *optional*
-#                Whether to plot the monopole or not (default: True).
-#            save : string, *optional*
-#                Valid file name where the figure is to be stored, by default
-#                the figure is not saved (default: False).
-#            error : {float, numpy.ndarray, nifty.field}, *optional*
-#                Object indicating some confidence interval to be plotted
-#                (default: None).
-#            kindex : numpy.ndarray, *optional*
-#                Scale corresponding to each band in the power spectrum
-#                (default: None).
-#            codomain : nifty.space, *optional*
-#                A compatible codomain for power indexing (default: None).
-#            log : bool, *optional*
-#                Flag specifying if the spectral binning is performed on
-#                logarithmic
-#                scale or not; if set, the number of used bins is set
-#                automatically (if not given otherwise); by default no binning
-#                is done (default: None).
-#            nbin : integer, *optional*
-#                Number of used spectral bins; if given `log` is set to
-#                ``False``;
-#                integers below the minimum of 3 induce an automatic setting;
-#                by default no binning is done (default: None).
-#            binbounds : {list, array}, *optional*
-#                User specific inner boundaries of the bins, which are preferred
-#                over the above parameters; by default no binning is done
-#                (default: None).
-#            vmin : {scalar, list, ndarray, field}, *optional*
-#                Lower limit of the uniform distribution if ``random == "uni"``
-#                (default: 0).
-#            iter : int, *optional*
-#                Number of iterations (default: 0).
-#
-#        """
-#        raise NotImplementedError(about._errors.cstring(
-#            "ERROR: no generic instance method 'get_plot'."))
-#
-#    def __repr__(self):
-#        string = ""
-#        string += str(type(self)) + "\n"
-#        string += "paradict: " + str(self.paradict) + "\n"
-#        return string
-#
-#    def __str__(self):
-#        return self.__repr__()
-
-
 class Space(object):
     """
         ..                            __             __
@@ -767,7 +188,7 @@ class Space(object):
             Pixel volume of the :py:class:`point_space`, which is always 1.
     """
 
-    def __init__(self, num, dtype=np.dtype('float')):
+    def __init__(self, dtype=np.dtype('float'), **kwargs):
         """
             Sets the attributes for a point_space class instance.
 
@@ -783,7 +204,7 @@ class Space(object):
             None.
         """
         self._cache_dict = {'check_codomain': {}}
-        self.paradict = point_space_paradict(num=num)
+        self.paradict = space_paradict(**kwargs)
 
         # parse dtype
         dtype = np.dtype(dtype)
@@ -832,8 +253,7 @@ class Space(object):
         return tuple(sorted(temp))
 
     def copy(self):
-        return point_space(num=self.paradict['num'],
-                           dtype=self.dtype)
+        return Space(dtype=self.dtype, **self.paradict.parameters)
 
     def getitem(self, data, key):
         return data[key]
@@ -937,6 +357,9 @@ class Space(object):
         mol = self.cast(1, dtype=np.dtype('float'))
         return self.calc_weight(mol, power=1)
 
+    def complement_cast(self, x, axis=None):
+        return x
+
     def enforce_power(self, spec, **kwargs):
         """
             Raises an error since the power spectrum is ill-defined for point
@@ -1041,7 +464,7 @@ class Space(object):
         if codomain is None:
             return False
 
-        if not isinstance(codomain, space):
+        if not isinstance(codomain, Space):
             raise TypeError(about._errors.cstring(
                 "ERROR: invalid input. The given input is not a nifty space."))
 
diff --git a/test/test_nifty_field.py b/test/test_nifty_field.py
index 92c496ea8..e30768d34 100644
--- a/test/test_nifty_field.py
+++ b/test/test_nifty_field.py
@@ -18,7 +18,7 @@ from nifty import space, \
     hp_space, \
     gl_space
 
-from nifty.nifty_field import field
+from nifty.field import Field
 
 from nifty.nifty_core import POINT_DISTRIBUTION_STRATEGIES
 from nifty.rg.nifty_rg import RG_DISTRIBUTION_STRATEGIES, \
@@ -118,6 +118,7 @@ def generate_data(space):
     a = np.arange(space.dim).reshape(space.shape)
     return distributed_data_object(a)
 
+
 ###############################################################################
 ###############################################################################
 
@@ -137,7 +138,7 @@ class Test_field_init(unittest.TestCase):
         s = rg_space(shape=shape, zerocenter=zerocenter,
                      complexity=complexity, distances=distances,
                      harmonic=harmonic, fft_module=fft_module)
-        f = field(domain=(s,), dtype=s.dtype, datamodel=datamodel)
+        f = Field(domain=(s,), dtype=s.dtype, datamodel=datamodel)
         assert (f.domain[0] is s)
         assert (s.check_codomain(f.codomain[0]))
         assert (s.shape == f.shape)
@@ -151,11 +152,12 @@ class Test_field_init2(unittest.TestCase):
     def test_successfull_init_and_attributes(self, name, num, datamodel):
         s = generate_space_with_size(name, num)
         d = generate_data(s)
-        f = field(val=d, domain=(s,), dtype=s.dtype, datamodel=datamodel)
+        f = Field(val=d, domain=(s,), dtype=s.dtype, datamodel=datamodel)
         assert (f.domain[0] is s)
         assert (s.check_codomain(f.codomain[0]))
         assert (s.shape == f.shape)
 
+
 class Test_field_multiple_rg_init(unittest.TestCase):
     @parameterized.expand(
         itertools.product([(1,)],
@@ -175,13 +177,14 @@ class Test_field_multiple_rg_init(unittest.TestCase):
         s2 = rg_space(shape=shape, zerocenter=zerocenter,
                       complexity=complexity, distances=distances,
                       harmonic=harmonic, fft_module=fft_module)
-        f = field(domain=(s1, s2), dtype=s1.dtype, datamodel=datamodel)
+        f = Field(domain=(s1, s2), dtype=s1.dtype, datamodel=datamodel)
         assert (f.domain[0] is s1)
         assert (f.domain[1] is s2)
         assert (s1.check_codomain(f.codomain[0]))
         assert (s2.check_codomain(f.codomain[1]))
         assert (s1.shape + s2.shape == f.shape)
 
+
 class Test_field_multiple_init(unittest.TestCase):
     @parameterized.expand(
         itertools.product(point_like_spaces, point_like_spaces, [4]),
@@ -189,14 +192,14 @@ class Test_field_multiple_init(unittest.TestCase):
     def test_multiple_space_init(self, space1, space2, shape):
         s1 = generate_space_with_size(space1, shape)
         s2 = generate_space_with_size(space2, shape)
-        f = field(domain=(s1, s2))
+        f = Field(domain=(s1, s2))
         assert (f.domain[0] is s1)
         assert (f.domain[1] is s2)
         assert (s1.check_codomain(f.codomain[0]))
         assert (s2.check_codomain(f.codomain[1]))
         assert (s1.shape + s2.shape == f.shape)
-        s3 = generate_space_with_size('hp_space',shape)
-        f = field(domain=(s1, s2, s3))
+        s3 = generate_space_with_size('hp_space', shape)
+        f = Field(domain=(s1, s2, s3))
         assert (f.domain[0] is s1)
         assert (f.domain[1] is s2)
         assert (f.domain[2] is s3)
@@ -220,10 +223,10 @@ class Test_axis(unittest.TestCase):
         s = generate_space_with_size(name, num)
         d = generate_data(s)
         a = d.get_full_data()
-        f = field(val=d, domain=(s,), dtype=s.dtype, datamodel=datamodel)
-        if op in ['argmin','argmax']:
+        f = Field(val=d, domain=(s,), dtype=s.dtype, datamodel=datamodel)
+        if op in ['argmin', 'argmax']:
             assert_almost_equal(getattr(f, op)(),
-                                    getattr(np, op)(a), decimal=4)
+                                getattr(np, op)(a), decimal=4)
         else:
             assert_almost_equal(getattr(f, op)(axis=axis),
                                 getattr(np, op)(a, axis=axis), decimal=4)
@@ -246,7 +249,7 @@ class Test_binary_operation(unittest.TestCase):
         s = generate_space_with_size(name, num)
         d = generate_data(s)
         a = d.get_full_data()
-        f = field(val=d, domain=(s,), dtype=s.dtype, datamodel=datamodel)
+        f = Field(val=d, domain=(s,), dtype=s.dtype, datamodel=datamodel)
         d2 = d[::-1]
         a2 = np.copy(a[::-1])
         if op[0] in ['iadd','isub','imul','idiv']:
diff --git a/test/test_nifty_spaces.py b/test/test_nifty_spaces.py
index bb37e19e5..f59f2b9ff 100644
--- a/test/test_nifty_spaces.py
+++ b/test/test_nifty_spaces.py
@@ -9,7 +9,7 @@ import unittest
 import itertools
 import numpy as np
 
-from nifty.nifty_field import field
+from nifty.field import Field
 
 from d2o import distributed_data_object
 
@@ -478,7 +478,7 @@ class Test_Point_Space(unittest.TestCase):
         num = 10
         a = np.arange(num,).astype(dtype)
         s = point_space(num, dtype)
-        f = field(s, val=a)
+        f = Field(s, val=a)
 
         d = distributed_data_object(a, dtype=dtype)
 
-- 
GitLab