From 5b3640bb5c9d1be1f51554eb0e37fed3422be37a Mon Sep 17 00:00:00 2001
From: Martin Reinecke <martin@mpa-garching.mpg.de>
Date: Wed, 4 Dec 2019 22:51:00 +0100
Subject: [PATCH] stage 3

---
 nifty6/domains/lm_space.py                    |  8 +++---
 nifty6/library/correlated_fields.py           | 14 +++++-----
 nifty6/library/dynamic_operator.py            |  4 +--
 nifty6/library/gridder.py                     |  6 ++---
 nifty6/library/light_cone_operator.py         | 10 +++----
 nifty6/library/los_response.py                | 17 ++++++------
 nifty6/multi_field.py                         |  8 ++----
 nifty6/operator_spectrum.py                   |  2 +-
 nifty6/operators/distributors.py              |  2 +-
 .../operators/domain_tuple_field_inserter.py  |  8 +++---
 nifty6/operators/field_zero_padder.py         |  5 ++--
 nifty6/operators/linear_interpolation.py      |  4 +--
 nifty6/operators/mask_operator.py             | 11 +++-----
 nifty6/operators/regridding_operator.py       |  1 +
 nifty6/operators/simple_linear_operators.py   |  4 +--
 nifty6/plot.py                                | 14 +++++-----
 nifty6/sugar.py                               | 27 +++----------------
 test/test_field.py                            |  1 -
 test/test_kl.py                               | 10 +++----
 test/test_linearization.py                    |  8 +++---
 test/test_multi_field.py                      |  6 ++---
 test/test_operators/test_adjoint.py           |  6 ++---
 test/test_operators/test_composed_operator.py |  8 +++---
 .../test_convolution_operators.py             | 10 +++----
 test/test_operators/test_correlated_fields.py |  8 +++---
 test/test_operators/test_diagonal_operator.py |  4 +--
 test/test_operators/test_fft_operator.py      | 14 +++++-----
 .../test_harmonic_transform_operator.py       |  2 +-
 test/test_operators/test_nft.py               |  8 +++---
 test/test_operators/test_regridding.py        |  2 +-
 test/test_operators/test_representation.py    |  6 ++---
 test/test_operators/test_simplification.py    | 16 +++++------
 .../test_operators/test_smoothing_operator.py |  2 +-
 test/test_operators/test_value_inserter.py    |  4 +--
 test/test_plot.py                             | 10 +++----
 test/test_spaces/test_lm_space.py             |  3 +--
 test/test_spaces/test_power_space.py          |  8 +++---
 test/test_spaces/test_rg_space.py             |  2 +-
 38 files changed, 126 insertions(+), 157 deletions(-)

diff --git a/nifty6/domains/lm_space.py b/nifty6/domains/lm_space.py
index 520d1c878..ad5799bfd 100644
--- a/nifty6/domains/lm_space.py
+++ b/nifty6/domains/lm_space.py
@@ -123,15 +123,15 @@ class LMSpace(StructuredDomain):
         lm0 = gl.get_default_codomain()
         theta = pyHealpix.GL_thetas(gl.nlat)
         # evaluate the kernel function at the required thetas
-        kernel_sphere = Field.from_global_data(gl, func(theta))
+        kernel_sphere = Field.from_arr(gl, func(theta))
         # normalize the kernel such that the integral over the sphere is 4pi
         kernel_sphere = kernel_sphere * (4 * np.pi / kernel_sphere.integrate())
         # compute the spherical harmonic coefficients of the kernel
         op = HarmonicTransformOperator(lm0, gl)
-        kernel_lm = op.adjoint_times(kernel_sphere.weight(1)).to_global_data()
+        kernel_lm = op.adjoint_times(kernel_sphere.weight(1)).val
         # evaluate the k lengths of the harmonic space
-        k_lengths = self.get_k_length_array().to_global_data().astype(np.int)
-        return Field.from_global_data(self, kernel_lm[k_lengths])
+        k_lengths = self.get_k_length_array().val.astype(np.int)
+        return Field.from_arr(self, kernel_lm[k_lengths])
 
     @property
     def lmax(self):
diff --git a/nifty6/library/correlated_fields.py b/nifty6/library/correlated_fields.py
index 63a710fd9..f99ab8d51 100644
--- a/nifty6/library/correlated_fields.py
+++ b/nifty6/library/correlated_fields.py
@@ -103,7 +103,7 @@ def _stats(op, samples):
     sc = StatCalculator()
     for s in samples:
         sc.add(op(s.extract(op.domain)))
-    return sc.mean.to_global_data(), sc.var.sqrt().to_global_data()
+    return sc.mean.val, sc.var.sqrt().val
 
 
 class _LognormalMomentMatching(Operator):
@@ -140,7 +140,7 @@ class _SlopeRemover(EndomorphicOperator):
 
     def apply(self, x, mode):
         self._check_input(x, mode)
-        x = x.to_global_data()
+        x = x.val
         if mode == self.TIMES:
             res = x - x[self._last]*self._sc[self._extender]
         else:
@@ -175,14 +175,14 @@ class _TwoLogIntegrations(LinearOperator):
         reverse = sl + (slice(None, None, -1),)
 
         if mode == self.TIMES:
-            x = x.to_global_data()
+            x = x.val
             res = np.empty(self._target.shape)
             res[first] = res[second] = 0
             res[from_third] = np.cumsum(x[second], axis=axis)
             res[from_third] = (res[from_third] + res[no_border])/2*self._log_vol[extender_sl] + x[first]
             res[from_third] = np.cumsum(res[from_third], axis=axis)
         else:
-            x = x.to_global_data_rw()
+            x = x.val.copy()
             res = np.zeros(self._domain.shape)
             x[from_third] = np.cumsum(x[from_third][reverse], axis=axis)[reverse]
             res[first] += x[from_third]
@@ -200,7 +200,7 @@ class _Normalization(Operator):
         hspace[space] = hspace[space].harmonic_partner
         hspace = makeDomain(hspace)
         pd = PowerDistributor(hspace, power_space=self._domain[space], space=space)
-        mode_multiplicity = pd.adjoint(full(pd.target, 1.)).to_global_data_rw()
+        mode_multiplicity = pd.adjoint(full(pd.target, 1.)).val.copy()
         zero_mode = (slice(None),)*self._domain.axes[space][0] + (0,)
         mode_multiplicity[zero_mode] = 0
         self._mode_multiplicity = from_global_data(self._domain, mode_multiplicity)
@@ -237,7 +237,7 @@ class _Distributor(LinearOperator):
 
     def apply(self, x, mode):
         self._check_input(x, mode)
-        x = x.to_global_data()
+        x = x.val
         if mode == self.TIMES:
             res = x[self._dofdex]
         else:
@@ -504,7 +504,7 @@ class CorrelatedFieldMaker:
         scm = 1.
         for a in self._a:
             op = a.fluctuation_amplitude*self._azm.one_over()
-            res = np.array([op(from_random('normal', op.domain)).to_global_data()
+            res = np.array([op(from_random('normal', op.domain)).val
                             for _ in range(nsamples)])
             scm *= res**2 + 1.
         return fluctuations_slice_mean/np.mean(np.sqrt(scm))
diff --git a/nifty6/library/dynamic_operator.py b/nifty6/library/dynamic_operator.py
index 089ed00ae..8a16ae3ea 100644
--- a/nifty6/library/dynamic_operator.py
+++ b/nifty6/library/dynamic_operator.py
@@ -121,11 +121,11 @@ def _make_dynamic_operator(target,
         elif len(sigc) != len(m.target.shape) - 1:
             raise (ValueError, "Shape mismatch!")
         c = FieldAdapter(UnstructuredDomain(len(sigc)), keys[1])
-        c = makeOp(Field.from_global_data(c.target, np.array(sigc)))(c)
+        c = makeOp(Field(c.target, np.array(sigc)))(c)
 
         lightspeed = ScalingOperator(-0.5, c.target)(c).exp()
         scaling = np.array(m.target[0].distances[1:])/m.target[0].distances[0]
-        scaling = DiagonalOperator(Field.from_global_data(c.target, scaling))
+        scaling = DiagonalOperator(Field(c.target, scaling))
         ops['lightspeed'] = scaling(lightspeed)
 
         c = LightConeOperator(c.target, m.target, quant)(c.exp())
diff --git a/nifty6/library/gridder.py b/nifty6/library/gridder.py
index 4160b69f8..bba43f087 100644
--- a/nifty6/library/gridder.py
+++ b/nifty6/library/gridder.py
@@ -80,7 +80,7 @@ class _RestOperator(LinearOperator):
 
     def apply(self, x, mode):
         self._check_input(x, mode)
-        res = x.to_global_data()
+        res = x.val
         if mode == self.TIMES:
             res = self._gconf.grid2dirty(res)
         else:
@@ -102,10 +102,10 @@ class RadioGridder(LinearOperator):
         import nifty_gridder
         self._check_input(x, mode)
         if mode == self.TIMES:
-            x = self._bl.ms2vis(x.to_global_data().reshape((-1, 1)), self._idx)
+            x = self._bl.ms2vis(x.val.reshape((-1, 1)), self._idx)
             res = nifty_gridder.vis2grid(self._bl, self._gconf, self._idx, x)
         else:
             res = nifty_gridder.grid2vis(self._bl, self._gconf, self._idx,
-                                         x.to_global_data())
+                                         x.val)
             res = self._bl.vis2ms(res, self._idx).reshape((-1,))
         return from_global_data(self._tgt(mode), res)
diff --git a/nifty6/library/light_cone_operator.py b/nifty6/library/light_cone_operator.py
index f02129d27..df037de17 100644
--- a/nifty6/library/light_cone_operator.py
+++ b/nifty6/library/light_cone_operator.py
@@ -27,7 +27,7 @@ from ..operators.operator import Operator
 def _field_from_function(domain, func, absolute=False):
     domain = DomainTuple.make(domain)
     k_array = _make_coords(domain, absolute=absolute)
-    return Field.from_global_data(domain, func(k_array))
+    return Field(domain, func(k_array))
 
 
 def _make_coords(domain, absolute=False):
@@ -57,14 +57,14 @@ class _LightConeDerivative(LinearOperator):
 
     def apply(self, x, mode):
         self._check_input(x, mode)
-        x = x.to_global_data()
+        x = x.val
         res = np.zeros(self._tgt(mode).shape, dtype=self._derivatives.dtype)
         for i in range(self.domain.shape[0]):
             if mode == self.TIMES:
                 res += self._derivatives[i]*x[i]
             else:
                 res[i] = np.sum(self._derivatives[i]*x.real)
-        return Field.from_global_data(self._tgt(mode), res)
+        return Field(self._tgt(mode), res)
 
 
 def _cone_arrays(c, domain, sigx, want_gradient):
@@ -133,9 +133,9 @@ class LightConeOperator(Operator):
 
     def apply(self, x):
         islin = isinstance(x, Linearization)
-        val = x.val.to_global_data() if islin else x.to_global_data()
+        val = x.val.val if islin else x.val
         a, derivs = _cone_arrays(val, self.target, self._sigx, islin)
-        res = Field.from_global_data(self.target, a)
+        res = Field(self.target, a)
         if not islin:
             return res
         jac = _LightConeDerivative(x.jac.target, self.target, derivs)(x.jac)
diff --git a/nifty6/library/los_response.py b/nifty6/library/los_response.py
index d1b3a01bf..25e05de19 100644
--- a/nifty6/library/los_response.py
+++ b/nifty6/library/los_response.py
@@ -178,7 +178,7 @@ class LOSResponse(LinearOperator):
         # get the shape of the local data slice
         w_i = _comp_traverse(localized_pixel_starts,
                              localized_pixel_ends,
-                             self._local_shape,
+                             self.domain[0].shape,
                              np.array(self.domain[0].distances),
                              1./(1./difflen+truncation*sigmas),
                              difflen,
@@ -188,7 +188,7 @@ class LOSResponse(LinearOperator):
 
         boxsz = 16
         nlos = len(w_i)
-        npix = np.prod(self._local_shape)
+        npix = np.prod(self.domain[0].shape)
         ntot = 0
         for i in w_i:
             ntot += len(i[1])
@@ -203,12 +203,12 @@ class LOSResponse(LinearOperator):
             ilos[ofs:ofs+nval] = cnt
             iarr[ofs:ofs+nval] = i[0]
             xwgt[ofs:ofs+nval] = i[1]
-            fullidx = np.unravel_index(i[0], self._local_shape)
+            fullidx = np.unravel_index(i[0], self.domain[0].shape)
             tmp = np.zeros(nval, dtype=np.float64)
             fct = 1.
             for j in range(ndim):
                 tmp += (fullidx[j]//boxsz)*fct
-                fct *= self._local_shape[j]
+                fct *= self.domain[0].shape[j]
             tmp += cnt/float(nlos)
             tmp += iarr[ofs:ofs+nval]/(float(nlos)*float(npix))
             pri[ofs:ofs+nval] = tmp
@@ -220,7 +220,7 @@ class LOSResponse(LinearOperator):
         xwgt = xwgt[xtmp]
         self._smat = aslinearoperator(
             coo_matrix((xwgt, (ilos, iarr)),
-                       shape=(nlos, np.prod(self._local_shape))))
+                       shape=(nlos, np.prod(self.domain[0].shape))))
 
         self._target = DomainTuple.make(UnstructuredDomain(nlos))
 
@@ -228,8 +228,7 @@ class LOSResponse(LinearOperator):
         self._check_input(x, mode)
         if mode == self.TIMES:
             result_arr = self._smat.matvec(x.val.reshape(-1))
-            return Field.from_global_data(self._target, result_arr,
-                                          sum_up=True)
-        local_input_data = x.to_global_data().reshape(-1)
-        res = self._smat.rmatvec(local_input_data).reshape(self._local_shape)
+            return Field(self._target, result_arr)
+        local_input_data = x.val.reshape(-1)
+        res = self._smat.rmatvec(local_input_data).reshape(self.domain[0].shape)
         return Field(self._domain, res)
diff --git a/nifty6/multi_field.py b/nifty6/multi_field.py
index b9d5d2167..744a9c488 100644
--- a/nifty6/multi_field.py
+++ b/nifty6/multi_field.py
@@ -132,14 +132,10 @@ class MultiField(object):
         return MultiField(domain, tuple(Field(dom, val)
                           for dom in domain._domains))
 
-    def to_global_data(self):
-        return {key: val.to_global_data()
-                for key, val in zip(self._domain.keys(), self._val)}
-
     @staticmethod
-    def from_global_data(domain, arr, sum_up=False):
+    def from_global_data(domain, arr):
         return MultiField(
-            domain, tuple(Field.from_global_data(domain[key], arr[key], sum_up)
+            domain, tuple(Field(domain[key], arr[key])
                           for key in domain.keys()))
 
     def norm(self, ord=2):
diff --git a/nifty6/operator_spectrum.py b/nifty6/operator_spectrum.py
index 398032163..74d520470 100644
--- a/nifty6/operator_spectrum.py
+++ b/nifty6/operator_spectrum.py
@@ -137,7 +137,7 @@ def operator_spectrum(A, k, hermitian, which='LM', tol=0):
     Ar = SandwichOperator.make(_DomRemover(A.domain).adjoint, A)
     M = ssl.LinearOperator(
         shape=2*(size,),
-        matvec=lambda x: Ar(from_global_data(Ar.domain, x)).to_global_data())
+        matvec=lambda x: Ar(from_global_data(Ar.domain, x)).val)
     f = ssl.eigsh if hermitian else ssl.eigs
     eigs = f(M, k=k, tol=tol, return_eigenvectors=False, which=which)
     return np.flip(np.sort(eigs), axis=0)
diff --git a/nifty6/operators/distributors.py b/nifty6/operators/distributors.py
index 752c5c2ba..ee7e102ef 100644
--- a/nifty6/operators/distributors.py
+++ b/nifty6/operators/distributors.py
@@ -74,7 +74,7 @@ class DOFDistributor(LinearOperator):
             wgt = np.bincount(dofdex.val.ravel(), minlength=nbin)
             wgt = wgt*partner.scalar_dvol
         else:
-            dvol = Field.from_global_data(partner, partner.dvol).val
+            dvol = Field.from_arr(partner, partner.dvol).val
             wgt = np.bincount(dofdex.val.ravel(),
                               minlength=nbin, weights=dvol)
         # The explicit conversion to float64 is necessary because bincount
diff --git a/nifty6/operators/domain_tuple_field_inserter.py b/nifty6/operators/domain_tuple_field_inserter.py
index f6fcc5221..49909b2bf 100644
--- a/nifty6/operators/domain_tuple_field_inserter.py
+++ b/nifty6/operators/domain_tuple_field_inserter.py
@@ -58,11 +58,9 @@ class DomainTupleFieldInserter(LinearOperator):
 
     def apply(self, x, mode):
         self._check_input(x, mode)
-        # FIXME Make fully MPI compatible without global_data
         if mode == self.TIMES:
             res = np.zeros(self.target.shape, dtype=x.dtype)
-            res[self._slc] = x.to_global_data()
-            return Field.from_global_data(self.target, res)
+            res[self._slc] = x.val
+            return Field(self.target, res)
         else:
-            return Field.from_global_data(self.domain,
-                                          x.to_global_data()[self._slc])
+            return Field(self.domain, x.val[self._slc])
diff --git a/nifty6/operators/field_zero_padder.py b/nifty6/operators/field_zero_padder.py
index afd3e47a7..70e39e0b9 100644
--- a/nifty6/operators/field_zero_padder.py
+++ b/nifty6/operators/field_zero_padder.py
@@ -92,7 +92,7 @@ class FieldZeroPadder(LinearOperator):
 #                         i1 = idx+(-Nyquist,)
 #                         xnew[i1] *= 0.5
                 else:
-                    xnew[idx + (slice(0, v.shape[d]),)] = x
+                    xnew[idx + (slice(0, v.shape[d]),)] = v
             else:  # ADJOINT_TIMES
                 if self._central:
                     shp = list(x.shape)
@@ -110,4 +110,5 @@ class FieldZeroPadder(LinearOperator):
                     xnew = v[idx + (slice(0, tgtshp[d]),)]
 
             curshp[d] = xnew.shape[d]
-        return Field(self._tgt(mode), xnew)
+            v = xnew.copy()
+        return Field(self._tgt(mode), v)
diff --git a/nifty6/operators/linear_interpolation.py b/nifty6/operators/linear_interpolation.py
index 8858fbf38..ef5cf9ad7 100644
--- a/nifty6/operators/linear_interpolation.py
+++ b/nifty6/operators/linear_interpolation.py
@@ -95,9 +95,9 @@ class LinearInterpolator(LinearOperator):
 
     def apply(self, x, mode):
         self._check_input(x, mode)
-        x_val = x.to_global_data()
+        x_val = x.val
         if mode == self.TIMES:
             res = self._mat.matvec(x_val.reshape(-1))
         else:
             res = self._mat.rmatvec(x_val).reshape(self.domain.shape)
-        return Field.from_global_data(self._tgt(mode), res)
+        return Field(self._tgt(mode), res)
diff --git a/nifty6/operators/mask_operator.py b/nifty6/operators/mask_operator.py
index 551b664cd..11adb3b4e 100644
--- a/nifty6/operators/mask_operator.py
+++ b/nifty6/operators/mask_operator.py
@@ -23,9 +23,6 @@ from ..field import Field
 from .linear_operator import LinearOperator
 
 
-# MR FIXME: this needs a redesign to avoid most _global_data() calls
-# Possible approach: keep everything defined on `domain` distributed and only
-# collect the unstructured Fields.
 class MaskOperator(LinearOperator):
     """Implementation of a mask response
 
@@ -41,17 +38,17 @@ class MaskOperator(LinearOperator):
         if not isinstance(flags, Field):
             raise TypeError
         self._domain = DomainTuple.make(flags.domain)
-        self._flags = np.logical_not(flags.to_global_data())
+        self._flags = np.logical_not(flags.val)
         self._target = DomainTuple.make(UnstructuredDomain(self._flags.sum()))
         self._capability = self.TIMES | self.ADJOINT_TIMES
 
     def apply(self, x, mode):
         self._check_input(x, mode)
-        x = x.to_global_data()
+        x = x.val
         if mode == self.TIMES:
             res = x[self._flags]
-            return Field.from_global_data(self.target, res)
+            return Field(self.target, res)
         res = np.empty(self.domain.shape, x.dtype)
         res[self._flags] = x
         res[~self._flags] = 0
-        return Field.from_global_data(self.domain, res)
+        return Field(self.domain, res)
diff --git a/nifty6/operators/regridding_operator.py b/nifty6/operators/regridding_operator.py
index 404882cbe..3a4d0aa39 100644
--- a/nifty6/operators/regridding_operator.py
+++ b/nifty6/operators/regridding_operator.py
@@ -91,4 +91,5 @@ class RegriddingOperator(LinearOperator):
                 xnew += v[idx + (self._bindex[d-d0]+1,)] * wgt
 
             curshp[d] = xnew.shape[d]
+            v = xnew.copy()
         return Field(self._tgt(mode), xnew)
diff --git a/nifty6/operators/simple_linear_operators.py b/nifty6/operators/simple_linear_operators.py
index 64b9d33b6..f3248b388 100644
--- a/nifty6/operators/simple_linear_operators.py
+++ b/nifty6/operators/simple_linear_operators.py
@@ -374,7 +374,7 @@ class MatrixProductOperator(EndomorphicOperator):
 
     def apply(self, x, mode):
         self._check_input(x, mode)
-        res = x.to_global_data()
+        res = x.val
         f = self._mat.dot if mode == self.TIMES else self._mat_tr.dot
         res = f(res)
-        return Field.from_global_data(self._domain, res)
+        return Field(self._domain, res)
diff --git a/nifty6/plot.py b/nifty6/plot.py
index 11921756e..cafea8554 100644
--- a/nifty6/plot.py
+++ b/nifty6/plot.py
@@ -298,7 +298,7 @@ def _plot1D(f, ax, **kwargs):
         dist = dom.distances[0]
         xcoord = np.arange(npoints, dtype=np.float64)*dist
         for i, fld in enumerate(f):
-            ycoord = fld.to_global_data()
+            ycoord = fld.val
             plt.plot(xcoord, ycoord, label=label[i],
                      linewidth=linewidth[i], alpha=alpha[i])
         _limit_xy(**kwargs)
@@ -310,7 +310,7 @@ def _plot1D(f, ax, **kwargs):
         plt.yscale(kwargs.pop("yscale", "log"))
         xcoord = dom.k_lengths
         for i, fld in enumerate(f):
-            ycoord = fld.to_global_data_rw()
+            ycoord = fld.val.copy()
             ycoord[0] = ycoord[1]
             plt.plot(xcoord, ycoord, label=label[i],
                      linewidth=linewidth[i], alpha=alpha[i])
@@ -336,9 +336,9 @@ def _plot2D(f, ax, **kwargs):
             raise TypeError("need 1D RGSpace as second domain")
         if dom[1].shape[0] == 1:
             from .sugar import from_global_data
-            f = from_global_data(f.domain[0], f.to_global_data()[..., 0])
+            f = from_global_data(f.domain[0], f.val[..., 0])
         else:
-            rgb = _rgb_data(f.to_global_data())
+            rgb = _rgb_data(f.val)
             have_rgb = True
 
     foo = kwargs.pop("norm", None)
@@ -363,7 +363,7 @@ def _plot2D(f, ax, **kwargs):
                 **aspect)
         else:
             im = ax.imshow(
-                f.to_global_data().T, extent=[0, nx*dx, 0, ny*dy],
+                f.val.T, extent=[0, nx*dx, 0, ny*dy],
                 vmin=kwargs.get("zmin"), vmax=kwargs.get("zmax"),
                 cmap=cmap, origin="lower", **norm, **aspect)
             plt.colorbar(im)
@@ -385,7 +385,7 @@ def _plot2D(f, ax, **kwargs):
             if have_rgb:
                 res[mask] = rgb[base.ang2pix(ptg)]
             else:
-                res[mask] = f.to_global_data()[base.ang2pix(ptg)]
+                res[mask] = f.val[base.ang2pix(ptg)]
         else:
             ra = np.linspace(0, 2*np.pi, dom.nlon+1)
             dec = pyHealpix.GL_thetas(dom.nlat)
@@ -395,7 +395,7 @@ def _plot2D(f, ax, **kwargs):
             if have_rgb:
                 res[mask] = rgb[ilat*dom[0].nlon + ilon]
             else:
-                res[mask] = f.to_global_data()[ilat*dom.nlon + ilon]
+                res[mask] = f.val[ilat*dom.nlon + ilon]
         plt.axis('off')
         if have_rgb:
             plt.imshow(res, origin="lower")
diff --git a/nifty6/sugar.py b/nifty6/sugar.py
index 87b602647..8a2b2903b 100644
--- a/nifty6/sugar.py
+++ b/nifty6/sugar.py
@@ -35,7 +35,7 @@ from .plot import Plot
 
 __all__ = ['PS_field', 'power_analyze', 'create_power_operator',
            'create_harmonic_smoothing_operator', 'from_random',
-           'full', 'from_global_data', 'from_local_data',
+           'full', 'from_global_data',
            'makeDomain', 'sqrt', 'exp', 'log', 'tanh', 'sigmoid',
            'sin', 'cos', 'tan', 'sinh', 'cosh', 'log10',
            'absolute', 'one_over', 'clip', 'sinc', "log1p", "expm1",
@@ -297,28 +297,7 @@ def from_global_data(domain, arr):
         The newly created random field
     """
     if isinstance(domain, (dict, MultiDomain)):
-        return MultiField.from_global_data(domain, arr, sum_up)
-    return Field.from_arr(domain, arr)
-
-
-def from_local_data(domain, arr):
-    """Convenience function creating Fields/MultiFields from Numpy arrays or
-    dicts of Numpy arrays.
-
-    Parameters
-    ----------
-    domain : Domainoid
-        the intended domain of the output field
-    arr : Numpy array if `domain` corresponds to a `DomainTuple`,
-          dictionary of Numpy arrays if `domain` corresponds to a `MultiDomain`
-
-    Returns
-    -------
-    Field or MultiField
-        The newly created field
-    """
-    if isinstance(domain, (dict, MultiDomain)):
-        return MultiField.from_local_data(domain, arr)
+        return MultiField.from_global_data(domain, arr)
     return Field.from_arr(domain, arr)
 
 
@@ -512,7 +491,7 @@ def calculate_position(operator, output):
         raise TypeError
     if output.domain != operator.target:
         raise TypeError
-    cov = 1e-3*output.to_global_data().max()**2
+    cov = 1e-3*output.val.max()**2
     invcov = ScalingOperator(cov, output.domain).inverse
     d = output + invcov.draw_sample(from_inverse=True)
     lh = GaussianEnergy(d, invcov)(operator)
diff --git a/test/test_field.py b/test/test_field.py
index 54b830c62..8bdc13ec9 100644
--- a/test/test_field.py
+++ b/test/test_field.py
@@ -175,7 +175,6 @@ def test_dataconv():
     s1 = ift.RGSpace((10,))
     ld = np.arange(s1.shape[0])
     gd = np.arange(s1.shape[0])
-    assert_equal(ld, ift.from_local_data(s1, ld).val)
     assert_equal(gd, ift.from_global_data(s1, gd).val)
 
 
diff --git a/test/test_kl.py b/test/test_kl.py
index 965ce10c5..31ff18755 100644
--- a/test/test_kl.py
+++ b/test/test_kl.py
@@ -57,10 +57,10 @@ def test_kl(constants, point_estimates, mirror_samples):
 
     # Test gradient
     for kk in h.domain.keys():
-        res0 = klpure.gradient.to_global_data()[kk]
+        res0 = klpure.gradient[kk].val
         if kk in constants:
             res0 = 0*res0
-        res1 = kl.gradient.to_global_data()[kk]
+        res1 = kl.gradient[kk].val
         assert_allclose(res0, res1)
 
     # Test number of samples
@@ -70,13 +70,13 @@ def test_kl(constants, point_estimates, mirror_samples):
     # Test point_estimates (after drawing samples)
     for kk in point_estimates:
         for ss in kl.samples:
-            ss = ss.to_global_data()[kk]
+            ss = ss[kk].val
             assert_allclose(ss, 0*ss)
 
     # Test constants (after some minimization)
     cg = ift.GradientNormController(iteration_limit=5)
     minimizer = ift.NewtonCG(cg)
     kl, _ = minimizer(kl)
-    diff = (mean0 - kl.position).to_global_data()
+    diff = (mean0 - kl.position).to_dict()
     for kk in constants:
-        assert_allclose(diff[kk], 0*diff[kk])
+        assert_allclose(diff[kk].val, 0*diff[kk].val)
diff --git a/test/test_linearization.py b/test/test_linearization.py
index bcf7a4a26..16b80fef3 100644
--- a/test/test_linearization.py
+++ b/test/test_linearization.py
@@ -25,7 +25,7 @@ pmp = pytest.mark.parametrize
 
 
 def _lin2grad(lin):
-    return lin.jac(ift.full(lin.domain, 1.)).to_global_data()
+    return lin.jac(ift.full(lin.domain, 1.)).val
 
 
 def jt(lin, check):
@@ -36,7 +36,7 @@ def test_special_gradients():
     dom = ift.UnstructuredDomain((1,))
     f = ift.full(dom, 2.4)
     var = ift.Linearization.make_var(f)
-    s = f.to_global_data()
+    s = f.val
 
     jt(var.clip(0, 10), np.ones_like(s))
     jt(var.clip(-1, 0), np.zeros_like(s))
@@ -62,8 +62,8 @@ def test_actual_gradients(f):
     eps = 1e-8
     var0 = ift.Linearization.make_var(fld)
     var1 = ift.Linearization.make_var(fld + eps)
-    f0 = getattr(var0, f)().val.to_global_data()
-    f1 = getattr(var1, f)().val.to_global_data()
+    f0 = getattr(var0, f)().val.val
+    f1 = getattr(var1, f)().val.val
     df0 = (f1 - f0)/eps
     df1 = _lin2grad(getattr(var0, f)())
     assert_allclose(df0, df1, rtol=100*eps)
diff --git a/test/test_multi_field.py b/test/test_multi_field.py
index fe27c5f75..72f1de3f7 100644
--- a/test/test_multi_field.py
+++ b/test/test_multi_field.py
@@ -32,12 +32,12 @@ def test_vdot():
 def test_func():
     f1 = ift.from_random("normal", domain=dom, dtype=np.complex128)
     assert_allclose(
-        ift.log(ift.exp((f1)))["d1"].local_data, f1["d1"].local_data)
+        ift.log(ift.exp((f1)))["d1"].val, f1["d1"].val)
 
 
 def test_multifield_field_consistency():
     f1 = ift.full(dom, 27)
-    f2 = ift.from_global_data(dom['d1'], f1['d1'].to_global_data())
+    f2 = ift.from_global_data(dom['d1'], f1['d1'].val)
     assert_equal(f1.sum(), f2.sum())
     assert_equal(f1.size, f2.size)
 
@@ -46,7 +46,7 @@ def test_dataconv():
     f1 = ift.full(dom, 27)
     f2 = ift.from_global_data(dom, f1.to_global_data())
     for key, val in f1.items():
-        assert_equal(val.local_data, f2[key].local_data)
+        assert_equal(val.val, f2[key].val)
     if "d1" not in f2:
         raise KeyError()
     assert_equal({"d1": f1}, f2.to_dict())
diff --git a/test/test_operators/test_adjoint.py b/test/test_operators/test_adjoint.py
index 9586edc9d..0f3b2622a 100644
--- a/test/test_operators/test_adjoint.py
+++ b/test/test_operators/test_adjoint.py
@@ -127,7 +127,7 @@ def testDOFDistributor(sp, dtype):
     if sp.size < 4:
         return
     dofdex = np.arange(sp.size).reshape(sp.shape) % 3
-    dofdex = ift.Field.from_global_data(sp, dofdex)
+    dofdex = ift.Field.from_arr(sp, dofdex)
     op = ift.DOFDistributor(dofdex)
     ift.extra.consistency_check(op, dtype, dtype)
 
@@ -171,10 +171,10 @@ def testHarmonic(sp, dtype):
 @pmp('sp', _p_spaces)
 def testMask(sp, dtype):
     # Create mask
-    f = ift.from_random('normal', sp).to_global_data()
+    f = ift.from_random('normal', sp).val
     mask = np.zeros_like(f)
     mask[f > 0] = 1
-    mask = ift.Field.from_global_data(sp, mask)
+    mask = ift.Field.from_arr(sp, mask)
     # Test MaskOperator
     op = ift.MaskOperator(mask)
     ift.extra.consistency_check(op, dtype, dtype)
diff --git a/test/test_operators/test_composed_operator.py b/test/test_operators/test_composed_operator.py
index aa710d429..cfe587dc0 100644
--- a/test/test_operators/test_composed_operator.py
+++ b/test/test_operators/test_composed_operator.py
@@ -60,7 +60,7 @@ def test_times_inverse_times(space1, space2):
     rand1 = ift.Field.from_random('normal', domain=(space1, space2))
     tt1 = op.inverse_times(op.times(rand1))
 
-    assert_allclose(tt1.local_data, rand1.local_data)
+    assert_allclose(tt1.val, rand1.val)
 
 
 def test_sum(space1):
@@ -70,7 +70,7 @@ def test_sum(space1):
     x = ift.Field.full(space1, 1.)
     res = full_op(x)
     assert_equal(isinstance(full_op, ift.DiagonalOperator), True)
-    assert_allclose(res.local_data, 11.)
+    assert_allclose(res.val, 11.)
 
 
 def test_chain(space1):
@@ -80,7 +80,7 @@ def test_chain(space1):
     x = ift.Field.full(space1, 1.)
     res = full_op(x)
     assert_equal(isinstance(full_op, ift.DiagonalOperator), True)
-    assert_allclose(res.local_data, 432.)
+    assert_allclose(res.val, 432.)
 
 
 def test_mix(space1):
@@ -90,4 +90,4 @@ def test_mix(space1):
     x = ift.Field.full(space1, 1.)
     res = full_op(x)
     assert_equal(isinstance(full_op, ift.DiagonalOperator), True)
-    assert_allclose(res.local_data, 42.)
+    assert_allclose(res.val, 42.)
diff --git a/test/test_operators/test_convolution_operators.py b/test/test_operators/test_convolution_operators.py
index d61baf69c..c1963bde7 100644
--- a/test/test_operators/test_convolution_operators.py
+++ b/test/test_operators/test_convolution_operators.py
@@ -32,7 +32,7 @@ space = list2fixture([
 def test_const_func(space):
     sig = ift.Field.from_random('normal', domain=space)
     fco_op = ift.FuncConvolutionOperator(space, lambda x: np.ones(x.shape))
-    vals = fco_op(sig).to_global_data()
+    vals = fco_op(sig).val
     vals = np.round(vals, decimals=5)
     assert len(np.unique(vals)) == 1
 
@@ -49,9 +49,9 @@ def test_gaussian_smoothing():
     sig = ift.exp(ift.Field.from_random('normal', dom))
     fco_op = ift.FuncConvolutionOperator(dom, lambda x: gauss(x, sigma))
     sm_op = ift.HarmonicSmoothingOperator(dom, sigma)
-    assert_allclose(fco_op(sig).to_global_data(),
-                    sm_op(sig).to_global_data(),
+    assert_allclose(fco_op(sig).val,
+                    sm_op(sig).val,
                     rtol=1e-05)
-    assert_allclose(fco_op.adjoint_times(sig).to_global_data(),
-                    sm_op.adjoint_times(sig).to_global_data(),
+    assert_allclose(fco_op.adjoint_times(sig).val,
+                    sm_op.adjoint_times(sig).val,
                     rtol=1e-05)
diff --git a/test/test_operators/test_correlated_fields.py b/test/test_operators/test_correlated_fields.py
index c28425950..99279323d 100644
--- a/test/test_operators/test_correlated_fields.py
+++ b/test/test_operators/test_correlated_fields.py
@@ -36,7 +36,7 @@ def testAmplitudesConsistency(rseed, sspace, Astds, offset_std):
         sc = ift.StatCalculator()
         for s in samples:
             sc.add(op(s.extract(op.domain)))
-        return sc.mean.to_global_data(), sc.var.sqrt().to_global_data()
+        return sc.mean.val, sc.var.sqrt().val
     seed(rseed)
     nsam = 100
 
@@ -54,7 +54,7 @@ def testAmplitudesConsistency(rseed, sspace, Astds, offset_std):
     offset_std,_ = stats(fa.amplitude_total_offset,samples)
     intergated_fluct_std0,_ = stats(fa.average_fluctuation(0),samples)
     intergated_fluct_std1,_ = stats(fa.average_fluctuation(1),samples)
-    
+
     slice_fluct_std0,_ = stats(fa.slice_fluctuation(0),samples)
     slice_fluct_std1,_ = stats(fa.slice_fluctuation(1),samples)
 
@@ -84,6 +84,6 @@ def testAmplitudesConsistency(rseed, sspace, Astds, offset_std):
     em, estd = stats(fa.slice_fluctuation(0),samples)
 
     assert_allclose(m, em, rtol=0.5)
-    
+
     assert op.target[0] == sspace
-    assert op.target[1] == fsspace
\ No newline at end of file
+    assert op.target[1] == fsspace
diff --git a/test/test_operators/test_diagonal_operator.py b/test/test_operators/test_diagonal_operator.py
index 0ff501949..2993652af 100644
--- a/test/test_operators/test_diagonal_operator.py
+++ b/test/test_operators/test_diagonal_operator.py
@@ -52,7 +52,7 @@ def test_times_inverse(space):
     diag = ift.Field.from_random('normal', domain=space)
     D = ift.DiagonalOperator(diag)
     tt1 = D.times(D.inverse_times(rand1))
-    assert_allclose(rand1.local_data, tt1.local_data)
+    assert_allclose(rand1.val, tt1.val)
 
 
 def test_times(space):
@@ -91,4 +91,4 @@ def test_diagonal(space):
     diag = ift.Field.from_random('normal', domain=space)
     D = ift.DiagonalOperator(diag)
     diag_op = D(ift.Field.full(space, 1.))
-    assert_allclose(diag.local_data, diag_op.local_data)
+    assert_allclose(diag.val, diag_op.val)
diff --git a/test/test_operators/test_fft_operator.py b/test/test_operators/test_fft_operator.py
index 3f9c178ea..57e7a43ed 100644
--- a/test/test_operators/test_fft_operator.py
+++ b/test/test_operators/test_fft_operator.py
@@ -48,7 +48,7 @@ def test_fft1D(d, dtype, op):
     inp = ift.Field.from_random(
         domain=a, random_type='normal', std=7, mean=3, dtype=dtype)
     out = fft.inverse_times(fft.times(inp))
-    assert_allclose(inp.local_data, out.local_data, rtol=tol, atol=tol)
+    assert_allclose(inp.val, out.val, rtol=tol, atol=tol)
 
     a, b = b, a
 
@@ -56,7 +56,7 @@ def test_fft1D(d, dtype, op):
     inp = ift.Field.from_random(
         domain=a, random_type='normal', std=7, mean=3, dtype=dtype)
     out = fft.inverse_times(fft.times(inp))
-    assert_allclose(inp.local_data, out.local_data, rtol=tol, atol=tol)
+    assert_allclose(inp.val, out.val, rtol=tol, atol=tol)
 
 
 @pmp('dim1', [12, 15])
@@ -76,7 +76,7 @@ def test_fft2D(dim1, dim2, d1, d2, dtype, op, nthreads):
     inp = ift.Field.from_random(
         domain=a, random_type='normal', std=7, mean=3, dtype=dtype)
     out = fft.inverse_times(fft.times(inp))
-    assert_allclose(inp.local_data, out.local_data, rtol=tol, atol=tol)
+    assert_allclose(inp.val, out.val, rtol=tol, atol=tol)
 
     a, b = b, a
 
@@ -84,7 +84,7 @@ def test_fft2D(dim1, dim2, d1, d2, dtype, op, nthreads):
     inp = ift.Field.from_random(
         domain=a, random_type='normal', std=7, mean=3, dtype=dtype)
     out = fft.inverse_times(fft.times(inp))
-    assert_allclose(inp.local_data, out.local_data, rtol=tol, atol=tol)
+    assert_allclose(inp.val, out.val, rtol=tol, atol=tol)
     ift.fft.set_nthreads(1)
 
 
@@ -100,7 +100,7 @@ def test_composed_fft(index, dtype, op):
     inp = ift.Field.from_random(
         domain=(a1, a2, a3), random_type='normal', std=7, mean=3, dtype=dtype)
     out = fft.inverse_times(fft.times(inp))
-    assert_allclose(inp.local_data, out.local_data, rtol=tol, atol=tol)
+    assert_allclose(inp.val, out.val, rtol=tol, atol=tol)
 
 
 @pmp('space', [
@@ -119,5 +119,5 @@ def test_normalisation(space, dtype, op):
     out2 = fft2.inverse_times(inp)
     zero_idx = tuple([0]*len(space.shape))
     assert_allclose(
-        inp.to_global_data()[zero_idx], out.integrate(), rtol=tol, atol=tol)
-    assert_allclose(out.local_data, out2.local_data, rtol=tol, atol=tol)
+        inp.val[zero_idx], out.integrate(), rtol=tol, atol=tol)
+    assert_allclose(out.val, out2.val, rtol=tol, atol=tol)
diff --git a/test/test_operators/test_harmonic_transform_operator.py b/test/test_operators/test_harmonic_transform_operator.py
index c275750da..f28e40d80 100644
--- a/test/test_operators/test_harmonic_transform_operator.py
+++ b/test/test_operators/test_harmonic_transform_operator.py
@@ -72,4 +72,4 @@ def test_normalisation(space, tp):
     out = fft.times(inp)
     zero_idx = tuple([0]*len(space.shape))
     assert_allclose(
-        inp.to_global_data()[zero_idx], out.integrate(), rtol=tol, atol=tol)
+        inp.val[zero_idx], out.integrate(), rtol=tol, atol=tol)
diff --git a/test/test_operators/test_nft.py b/test/test_operators/test_nft.py
index a9ff43222..aaedcff62 100644
--- a/test/test_operators/test_nft.py
+++ b/test/test_operators/test_nft.py
@@ -47,7 +47,7 @@ def test_gridding(nu, nv, N, eps):
     vis2 = ift.from_global_data(ift.UnstructuredDomain(vis.shape), vis)
 
     Op = GM.getFull()
-    pynu = Op(vis2).to_global_data()
+    pynu = Op(vis2).val
     # DFT
     x, y = np.meshgrid(
         *[-ss/2 + np.arange(ss) for ss in [nu, nv]], indexing='ij')
@@ -73,14 +73,14 @@ def test_cartesian():
     op = GM.getFull().adjoint
 
     fld = ift.from_random('normal', dom)
-    arr = fld.to_global_data()
+    arr = fld.val
 
     fld2 = ift.from_global_data(dom, np.roll(arr, (nx//2, ny//2), axis=(0, 1)))
-    res = op(fld2).to_global_data().reshape(nx, ny)
+    res = op(fld2).val.reshape(nx, ny)
 
     fft = ift.FFTOperator(dom.get_default_codomain(), target=dom).adjoint
     vol = ift.full(dom, 1.).integrate()
-    res1 = fft(fld).to_global_data()
+    res1 = fft(fld).val
 
     # FIXME: we don't understand the conjugate() yet
     np.testing.assert_allclose(res, res1.conjugate()*vol)
diff --git a/test/test_operators/test_regridding.py b/test/test_operators/test_regridding.py
index d786f9731..1cb8b3849 100644
--- a/test/test_operators/test_regridding.py
+++ b/test/test_operators/test_regridding.py
@@ -31,4 +31,4 @@ s = list2fixture([
 def test_value(s):
     Regrid = ift.RegriddingOperator(s, s.shape)
     f = ift.from_random('normal', Regrid.domain)
-    assert_allclose(f.to_global_data(), Regrid(f).to_global_data())
+    assert_allclose(f.val, Regrid(f).val)
diff --git a/test/test_operators/test_representation.py b/test/test_operators/test_representation.py
index 453bbb82e..efa87b848 100644
--- a/test/test_operators/test_representation.py
+++ b/test/test_operators/test_representation.py
@@ -102,7 +102,7 @@ def testDOFDistributor(sp, dtype):
     if sp.size < 4:
         return
     dofdex = np.arange(sp.size).reshape(sp.shape) % 3
-    dofdex = ift.Field.from_global_data(sp, dofdex)
+    dofdex = ift.Field.from_arr(sp, dofdex)
     _check_repr(ift.DOFDistributor(dofdex))
 
 
@@ -137,10 +137,10 @@ def testHarmonic(sp, dtype):
 @pmp('sp', _p_spaces)
 def testMask(sp, dtype):
     # Create mask
-    f = ift.from_random('normal', sp).to_global_data()
+    f = ift.from_random('normal', sp).val
     mask = np.zeros_like(f)
     mask[f > 0] = 1
-    mask = ift.Field.from_global_data(sp, mask)
+    mask = ift.Field.from_arr(sp, mask)
     # Test MaskOperator
     _check_repr(ift.MaskOperator(mask))
 
diff --git a/test/test_operators/test_simplification.py b/test/test_operators/test_simplification.py
index e8732b0a6..bf46361fd 100644
--- a/test/test_operators/test_simplification.py
+++ b/test/test_operators/test_simplification.py
@@ -26,14 +26,14 @@ def test_simplification():
     op = ift.FFTOperator(f1.domain)
     _, op2 = op.simplify_for_constant_input(f1)
     assert_equal(isinstance(op2, _ConstantOperator), True)
-    assert_allclose(op(f1).local_data, op2(f1).local_data)
+    assert_allclose(op(f1).val, op2(f1).val)
 
     dom = {"a": ift.RGSpace(10)}
     f1 = ift.full(dom, 2.)
     op = ift.FFTOperator(f1.domain["a"]).ducktape("a")
     _, op2 = op.simplify_for_constant_input(f1)
     assert_equal(isinstance(op2, _ConstantOperator), True)
-    assert_allclose(op(f1).local_data, op2(f1).local_data)
+    assert_allclose(op(f1).val, op2(f1).val)
 
     dom = {"a": ift.RGSpace(10), "b": ift.RGSpace(5)}
     f1 = ift.full(dom, 2.)
@@ -45,10 +45,10 @@ def test_simplification():
           o2.ducktape("b").ducktape_left("b"))
     _, op2 = op.simplify_for_constant_input(f2)
     assert_equal(isinstance(op2._op1, _ConstantOperator), True)
-    assert_allclose(op(f1)["a"].local_data, op2(f1)["a"].local_data)
-    assert_allclose(op(f1)["b"].local_data, op2(f1)["b"].local_data)
+    assert_allclose(op(f1)["a"].val, op2(f1)["a"].val)
+    assert_allclose(op(f1)["b"].val, op2(f1)["b"].val)
     lin = ift.Linearization.make_var(ift.MultiField.full(op2.domain, 2.), True)
-    assert_allclose(op(lin).val["a"].local_data,
-                    op2(lin).val["a"].local_data)
-    assert_allclose(op(lin).val["b"].local_data,
-                    op2(lin).val["b"].local_data)
+    assert_allclose(op(lin).val["a"].val,
+                    op2(lin).val["a"].val)
+    assert_allclose(op(lin).val["b"].val,
+                    op2(lin).val["b"].val)
diff --git a/test/test_operators/test_smoothing_operator.py b/test/test_operators/test_smoothing_operator.py
index 493a515b1..71ce7b825 100644
--- a/test/test_operators/test_smoothing_operator.py
+++ b/test/test_operators/test_smoothing_operator.py
@@ -56,7 +56,7 @@ def test_times(space, sigma):
     op = ift.HarmonicSmoothingOperator(space, sigma=sigma)
     fld = np.zeros(space.shape, dtype=np.float64)
     fld[0] = 1.
-    rand1 = ift.Field.from_global_data(space, fld)
+    rand1 = ift.Field.from_arr(space, fld)
     tt1 = op.times(rand1)
     assert_allclose(1, tt1.sum())
 
diff --git a/test/test_operators/test_value_inserter.py b/test/test_operators/test_value_inserter.py
index e5259e1bb..d420585b3 100644
--- a/test/test_operators/test_value_inserter.py
+++ b/test/test_operators/test_value_inserter.py
@@ -35,7 +35,7 @@ def test_value_inserter(sp, seed):
     ind = tuple([np.random.randint(0, ss - 1) for ss in sp.shape])
     op = ift.ValueInserter(sp, ind)
     f = ift.from_random('normal', op.domain)
-    inp = f.to_global_data()
-    ret = op(f).to_global_data()
+    inp = f.val
+    ret = op(f).val
     assert_(ret[ind] == inp)
     assert_(np.sum(ret) == inp)
diff --git a/test/test_plot.py b/test/test_plot.py
index 909ca1f20..3f220c317 100644
--- a/test/test_plot.py
+++ b/test/test_plot.py
@@ -29,12 +29,12 @@ def test_plots():
 
     fft = ift.FFTOperator(rg_space2)
 
-    field_rg1_1 = ift.Field.from_global_data(rg_space1, np.random.randn(100))
-    field_rg1_2 = ift.Field.from_global_data(rg_space1, np.random.randn(100))
-    field_rg2 = ift.Field.from_global_data(
+    field_rg1_1 = ift.Field(rg_space1, np.random.randn(100))
+    field_rg1_2 = ift.Field(rg_space1, np.random.randn(100))
+    field_rg2 = ift.Field(
         rg_space2, np.random.randn(80*60).reshape((80, 60)))
-    field_hp = ift.Field.from_global_data(hp_space, np.random.randn(12*64**2))
-    field_gl = ift.Field.from_global_data(gl_space, np.random.randn(32640))
+    field_hp = ift.Field(hp_space, np.random.randn(12*64**2))
+    field_gl = ift.Field(gl_space, np.random.randn(32640))
     field_ps = ift.power_analyze(fft.times(field_rg2))
 
     plot = ift.Plot()
diff --git a/test/test_spaces/test_lm_space.py b/test/test_spaces/test_lm_space.py
index 94a47c553..9cf2f79da 100644
--- a/test/test_spaces/test_lm_space.py
+++ b/test/test_spaces/test_lm_space.py
@@ -85,5 +85,4 @@ def test_dvol():
 
 @pmp('lmax, expected', get_k_length_array_configs())
 def test_k_length_array(lmax, expected):
-    assert_allclose(ift.LMSpace(lmax).get_k_length_array().to_global_data(),
-                    expected)
+    assert_allclose(ift.LMSpace(lmax).get_k_length_array().val, expected)
diff --git a/test/test_spaces/test_power_space.py b/test/test_spaces/test_power_space.py
index 39564ecbb..5ec2f131b 100644
--- a/test/test_spaces/test_power_space.py
+++ b/test/test_spaces/test_power_space.py
@@ -63,7 +63,7 @@ CONSTRUCTOR_CONFIGS = [
             'binbounds':
             None,
             'pindex':
-            ift.dobj.from_global_data(np.array([0, 1, 2, 3, 4, 3, 2, 1])),
+            np.array([0, 1, 2, 3, 4, 3, 2, 1]),
             'k_lengths':
             np.array([0., 1., 2., 3., 4.]),
         }
@@ -79,7 +79,7 @@ CONSTRUCTOR_CONFIGS = [
             ift.RGSpace((8,), harmonic=True),
             'binbounds': (0.5, 1.3228756555322954, 3.5),
             'pindex':
-            ift.dobj.from_global_data(np.array([0, 1, 2, 2, 3, 2, 2, 1])),
+            np.array([0, 1, 2, 2, 3, 2, 2, 1]),
             'k_lengths':
             np.array([0., 1., 2.5, 4.]),
         }
@@ -97,7 +97,7 @@ def k_lengths_configs():
 @pmp('attribute, expected_type', [
     ['harmonic_partner', ift.StructuredDomain],
     ['binbounds', type(None)],
-    ['pindex', ift.dobj.data_object],
+    ['pindex', np.ndarray],
     ['k_lengths', np.ndarray],
 ])
 def test_property_ret_type(attribute, expected_type):
@@ -112,7 +112,7 @@ def test_rhopindexConsistency(harmonic_partner, binbounds, nbin, logarithmic):
     p = ift.PowerSpace(harmonic_partner=harmonic_partner, binbounds=bb)
 
     assert_equal(
-        np.bincount(ift.dobj.to_global_data(p.pindex).ravel()),
+        np.bincount(p.pindex.ravel()),
         p.dvol,
         err_msg='rho is not equal to pindex degeneracy')
 
diff --git a/test/test_spaces/test_rg_space.py b/test/test_spaces/test_rg_space.py
index fdf23053a..1cb535c6b 100644
--- a/test/test_spaces/test_rg_space.py
+++ b/test/test_spaces/test_rg_space.py
@@ -90,7 +90,7 @@ def test_constructor(shape, distances, harmonic, expected):
 @pmp('shape, distances, expected', get_k_length_array_configs())
 def test_k_length_array(shape, distances, expected):
     r = ift.RGSpace(shape=shape, distances=distances, harmonic=True)
-    assert_allclose(r.get_k_length_array().to_global_data(), expected)
+    assert_allclose(r.get_k_length_array().val, expected)
 
 
 @pmp('shape, distances, harmonic, power', get_dvol_configs())
-- 
GitLab