diff --git a/.gitignore b/.gitignore
index 6991ad8a9491a97c929d18d68cbda3343a339b73..ebdda7ed5cb0ca821b845769630e81d438ba9731 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@
 build
 
 demos/*
+!demos/__init__.py
 !demos/demo_faraday.py
 !demos/demo_faraday_map.npy
 !demos/demo_excaliwir.py
diff --git a/README.rst b/README.rst
index 9e9f12d275c2f67a435e49e9a80316b9bfe9523c..005dd18c5c6b2def265046ab476b7bd700d5bb4b 100644
--- a/README.rst
+++ b/README.rst
@@ -99,7 +99,7 @@ Requirements
 Download
 ........
 
-The latest release is tagged **v0.8.0** and is available as a source package
+The latest release is tagged **v0.9.0** and is available as a source package
 at `<https://github.com/mselig/nifty/tags>`_. The current version can be
 obtained by cloning the repository::
 
diff --git a/__init__.py b/__init__.py
index 564ff2ecefcd9fa0d6030dff5673895eee08bc74..4121b411ac2e59bfc35bd7008e16beea14fcb4b6 100644
--- a/__init__.py
+++ b/__init__.py
@@ -26,7 +26,7 @@ from nifty_power import *
 from nifty_tools import *
 from nifty_explicit import *
 
-from nifty_power_conversion import *
+#from nifty_power_conversion import *
 
 
 ##-----------------------------------------------------------------------------
diff --git a/demos/__init__.py b/demos/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9456ac3f7be17e93bbf5678e3670e4cddb9137d
--- /dev/null
+++ b/demos/__init__.py
@@ -0,0 +1,23 @@
+## NIFTY (Numerical Information Field Theory) has been developed at the
+## Max-Planck-Institute for Astrophysics.
+##
+## Copyright (C) 2014 Max-Planck-Society
+##
+## Author: Marco Selig
+## Project homepage: <http://www.mpa-garching.mpg.de/ift/nifty/>
+##
+## This program is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+## See the GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+pass
+
diff --git a/nifty_cmaps.py b/nifty_cmaps.py
index 34fce2a01a9534a6a0ed37a9f956220e48be7aae..014367951b74e051b11024bf6a1acbc3dbba51ae 100644
--- a/nifty_cmaps.py
+++ b/nifty_cmaps.py
@@ -237,4 +237,43 @@ class ncmap(object):
 
         return cm("Plus Minus", segmentdata, N=int(ncolors), gamma=1.0)
 
+    ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+    @staticmethod
+    def planck(ncolors=256):
+        """
+            Returns a color map similar to the one used for the "Planck CMB Map".
+
+            Parameters
+            ----------
+            ncolors : int, *optional*
+                Number of color segments (default: 256).
+
+            Returns
+            -------
+            cmap : matplotlib.colors.LinearSegmentedColormap instance
+                Linear segmented color map.
+
+        """
+        segmentdata = {"red":   [(0.0, 0.00, 0.00), (0.1, 0.00, 0.00),
+                                 (0.2, 0.00, 0.00), (0.3, 0.00, 0.00),
+                                 (0.4, 0.00, 0.00), (0.5, 1.00, 1.00),
+                                 (0.6, 1.00, 1.00), (0.7, 1.00, 1.00),
+                                 (0.8, 0.83, 0.83), (0.9, 0.67, 0.67),
+                                 (1.0, 0.50, 0.50)],
+                       "green": [(0.0, 0.00, 0.00), (0.1, 0.00, 0.00),
+                                 (0.2, 0.00, 0.00), (0.3, 0.30, 0.30),
+                                 (0.4, 0.70, 0.70), (0.5, 1.00, 1.00),
+                                 (0.6, 0.70, 0.70), (0.7, 0.30, 0.30),
+                                 (0.8, 0.00, 0.00), (0.9, 0.00, 0.00),
+                                 (1.0, 0.00, 0.00)],
+                       "blue":  [(0.0, 0.50, 0.50), (0.1, 0.67, 0.67),
+                                 (0.2, 0.83, 0.83), (0.3, 1.00, 1.00),
+                                 (0.4, 1.00, 1.00), (0.5, 1.00, 1.00),
+                                 (0.6, 0.00, 0.00), (0.7, 0.00, 0.00),
+                                 (0.8, 0.00, 0.00), (0.9, 0.00, 0.00),
+                                 (1.0, 0.00, 0.00)]}
+
+        return cm("Planck-like", segmentdata, N=int(ncolors), gamma=1.0)
+
 ##-----------------------------------------------------------------------------
diff --git a/nifty_core.py b/nifty_core.py
index 338f35c543ff2315f201c91283eeec3e5604694f..4a72131b8704d31455199fcd7dfd38430ed8d59c 100644
--- a/nifty_core.py
+++ b/nifty_core.py
@@ -514,7 +514,7 @@ class _about(object): ## nifty support class for global settings
 
         """
         ## version
-        self._version = "0.8.4"
+        self._version = "0.9.0"
 
         ## switches and notifications
         self._errors = notification(default=True,ccode=notification._code)
@@ -2485,7 +2485,7 @@ class rg_space(space):
             config = {"binbounds":kwargs.get("binbounds",None),"log":kwargs.get("log",None),"nbin":kwargs.get("nbin",None)}
         ## power indices
         about.infos.cflush("INFO: setting power indices ...")
-        pindex,kindex,rho = gp.get_power_indices(self.para[:(np.size(self.para)-1)//2],self.vol,self.para[-((np.size(self.para)-1)//2):].astype(np.bool),fourier=True)
+        pindex,kindex,rho = gp.get_power_indices2(self.para[:(np.size(self.para)-1)//2],self.vol,self.para[-((np.size(self.para)-1)//2):].astype(np.bool),fourier=True)
         ## bin if ...
         if(config.get("log") is not None)or(config.get("nbin") is not None)or(config.get("binbounds") is not None):
             pindex,kindex,rho = gp.bin_power_indices(pindex,kindex,rho,**config)
@@ -3195,6 +3195,9 @@ class rg_space(space):
                     about.infos.cprint("INFO: absolute values and phases are plotted.")
                     if(title):
                         title += " "
+                    if(bool(kwargs.get("save",False))):
+                        save_ = os.path.splitext(os.path.basename(str(kwargs.get("save"))))
+                        kwargs.update(save=save_[0]+"_absolute"+save_[1])
                     self.get_plot(np.absolute(x),title=title+"(absolute)",vmin=vmin,vmax=vmax,power=False,unit=unit,norm=norm,cmap=cmap,cbar=cbar,other=None,legend=False,**kwargs)
 #                    self.get_plot(np.real(x),title=title+"(real part)",vmin=vmin,vmax=vmax,power=False,unit=unit,norm=norm,cmap=cmap,cbar=cbar,other=None,legend=False,**kwargs)
 #                    self.get_plot(np.imag(x),title=title+"(imaginary part)",vmin=vmin,vmax=vmax,power=False,unit=unit,norm=norm,cmap=cmap,cbar=cbar,other=None,legend=False,**kwargs)
@@ -3202,6 +3205,8 @@ class rg_space(space):
                         unit = "rad"
                     if(cmap is None):
                         cmap = pl.cm.hsv_r
+                    if(bool(kwargs.get("save",False))):
+                        kwargs.update(save=save_[0]+"_phase"+save_[1])
                     self.get_plot(np.angle(x,deg=False),title=title+"(phase)",vmin=-3.1416,vmax=3.1416,power=False,unit=unit,norm=None,cmap=cmap,cbar=cbar,other=None,legend=False,**kwargs) ## values in [-pi,pi]
                     return None ## leave method
                 else:
@@ -4011,11 +4016,16 @@ class lm_space(space):
             if(np.iscomplexobj(x)):
                 if(title):
                     title += " "
+                if(bool(kwargs.get("save",False))):
+                    save_ = os.path.splitext(os.path.basename(str(kwargs.get("save"))))
+                    kwargs.update(save=save_[0]+"_absolute"+save_[1])
                 self.get_plot(np.absolute(x),title=title+"(absolute)",vmin=vmin,vmax=vmax,power=False,norm=norm,cmap=cmap,cbar=cbar,other=None,legend=False,**kwargs)
 #                self.get_plot(np.real(x),title=title+"(real part)",vmin=vmin,vmax=vmax,power=False,norm=norm,cmap=cmap,cbar=cbar,other=None,legend=False,**kwargs)
 #                self.get_plot(np.imag(x),title=title+"(imaginary part)",vmin=vmin,vmax=vmax,power=False,norm=norm,cmap=cmap,cbar=cbar,other=None,legend=False,**kwargs)
                 if(cmap is None):
                     cmap = pl.cm.hsv_r
+                if(bool(kwargs.get("save",False))):
+                    kwargs.update(save=save_[0]+"_phase"+save_[1])
                 self.get_plot(np.angle(x,deg=False),title=title+"(phase)",vmin=-3.1416,vmax=3.1416,power=False,norm=None,cmap=cmap,cbar=cbar,other=None,legend=False,**kwargs) ## values in [-pi,pi]
                 return None ## leave method
             else:
@@ -5413,7 +5423,7 @@ class nested_space(space):
         self.datatype = self.nest[-1].datatype
 
         self.discrete = np.prod([nn.discrete for nn in self.nest],axis=0,dtype=np.bool,out=None)
-        self.vol = None ## not needed
+        self.vol = np.prod([nn.get_meta_volume(total=True) for nn in self.nest],axis=0,dtype=None,out=None) ## total volume
 
     ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
@@ -5738,7 +5748,7 @@ class nested_space(space):
         """
         if(total):
             ## product
-            return np.prod([nn.get_meta_volume(total=True) for nn in self.nest],axis=0,dtype=None,out=None)
+            return self.vol ## == np.prod([nn.get_meta_volume(total=True) for nn in self.nest],axis=0,dtype=None,out=None)
         else:
             mol = self.nest[0].get_meta_volume(total=False)
             ## tensor product
@@ -8280,26 +8290,52 @@ class operator(object):
 
     def det(self):
         """
-            Computes the determinant of the operator
+            Computes the determinant of the operator.
 
             Returns
             -------
             det : float
                 The determinant
+
         """
         raise NotImplementedError(about._errors.cstring("ERROR: no generic instance method 'det'."))
 
     def inverse_det(self):
         """
-            Computes the determinant of the inverse operator
+            Computes the determinant of the inverse operator.
 
             Returns
             -------
             det : float
                 The determinant
+
         """
         raise NotImplementedError(about._errors.cstring("ERROR: no generic instance method 'inverse_det'."))
 
+    def log_det(self):
+        """
+            Computes the logarithm of the determinant of the operator (if applicable).
+
+            Returns
+            -------
+            logdet : float
+                The logarithm of the determinant
+
+        """
+        raise NotImplementedError(about._errors.cstring("ERROR: no generic instance method 'log_det'."))
+
+    def tr_log(self):
+        """
+            Computes the trace of the logarithm of the operator (if applicable).
+
+            Returns
+            -------
+            logdet : float
+                The trace of the logarithm
+
+        """
+        return self.log_det()
+
     ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
     def hat(self,bare=False,domain=None,target=None,**kwargs):
@@ -9119,6 +9155,23 @@ class diagonal_operator(operator):
         else:
             raise ValueError(about._errors.cstring("ERROR: singular operator."))
 
+    def log_det(self):
+        """
+            Computes the logarithm of the determinant of the operator.
+
+            Returns
+            -------
+            logdet : float
+                The logarithm of the determinant
+
+        """
+        if(self.uni): ## identity
+            return 0
+        elif(self.domain.dim(split=False)<self.domain.dof()): ## hidden degrees of freedom
+            return self.domain.calc_dot(np.ones(self.domain.dim(split=True),dtype=self.domain.datatype,order='C'),np.log(self.val))
+        else:
+            return np.sum(np.log(self.val),axis=None,dtype=None,out=None)
+
     ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
     def get_random_field(self,domain=None,target=None,**kwargs):
@@ -10201,7 +10254,8 @@ class vecvec_operator(operator):
 
     def inverse_diag(self):
         """
-        Inverse is ill-defined for this operator.
+            Inverse is ill-defined for this operator.
+
         """
         raise AttributeError(about._errors.cstring("ERROR: singular operator."))
 
@@ -10209,18 +10263,27 @@ class vecvec_operator(operator):
 
     def det(self):
         """
-            Computes the determinant of the operator
+            Computes the determinant of the operator.
 
             Returns
             -------
             det : 0
                 The determinant
+
         """
         return 0
 
     def inverse_det(self):
         """
-        Inverse is ill-defined for this operator.
+            Inverse is ill-defined for this operator.
+
+        """
+        raise AttributeError(about._errors.cstring("ERROR: singular operator."))
+
+    def log_det(self):
+        """
+            Logarithm of the determinant is ill-defined for this singular operator.
+
         """
         raise AttributeError(about._errors.cstring("ERROR: singular operator."))
 
diff --git a/nifty_explicit.py b/nifty_explicit.py
index 5e2a11072d4872bea877c1a0b278b22c1f9b0238..29c5dd5ba231deb45e45ec64a468b5b85056012a 100644
--- a/nifty_explicit.py
+++ b/nifty_explicit.py
@@ -1077,7 +1077,11 @@ class explicit_operator(operator):
 
         if(np.any(self._hidden)):
             about.warnings.cprint("WARNING: inappropriate determinant calculation.")
-        return np.linalg.det(self.weight(rowpower=0.5,colpower=0.5,overwrite=False))
+        det = np.linalg.det(self.weight(rowpower=0.5,colpower=0.5,overwrite=False))
+        if(np.isreal(det)):
+            return np.asscalar(np.real(det))
+        else:
+            return det
 
     def inverse_det(self):
         """
@@ -1104,6 +1108,44 @@ class explicit_operator(operator):
         else:
             raise ValueError(about._errors.cstring("ERROR: singular matrix."))
 
+    def log_det(self):
+        """
+            Computes the logarithm of the determinant of the operator
+            (if applicable).
+
+            Returns
+            -------
+            logdet : float
+                The logarithm of the determinant
+
+            See Also
+            --------
+            numpy.linalg.slogdet
+
+            Raises
+            ------
+            ValueError
+                If `domain` and `target` are unequal or it is non-positive
+                definite matrix.
+
+        """
+        if(self.domain!=self.target):
+            raise ValueError(about._errors.cstring("ERROR: determinant ill-defined."))
+
+        if(np.any(self._hidden)):
+            about.warnings.cprint("WARNING: inappropriate determinant calculation.")
+        sign,logdet = np.linalg.slogdet(self.weight(rowpower=0.5,colpower=0.5,overwrite=False))
+        if(abs(sign)<0.1): ## abs(sign) << 1
+            raise ValueError(about._errors.cstring("ERROR: singular matrix."))
+        if(sign==-1):
+            raise ValueError(about._errors.cstring("ERROR: non-positive definite matrix."))
+        else:
+            logdet += np.log(sign)
+            if(np.isreal(logdet)):
+                return np.asscalar(np.real(logdet))
+            else:
+                return logdet
+
     ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
     def __len__(self):
@@ -2324,7 +2366,11 @@ def explicify(op,newdomain=None,newtarget=None,ncpu=2,nper=1,loop=False,**quargs
         raise TypeError(about._errors.cstring("ERROR: invalid input."))
     elif(newdomain is not None)and(newtarget is None)and(op.domain==op.target):
         newtarget = newdomain
-    return explicit_probing(op=op,function=op.times,domain=newdomain,codomain=newtarget,target=op.domain,ncpu=ncpu,nper=nper,**quargs)(loop=loop)
+    if(newdomain is None)or(newdomain==op.domain):
+        target_ = None
+    else:
+        target_ = op.domain
+    return explicit_probing(op=op,function=op.times,domain=newdomain,codomain=newtarget,target=target_,ncpu=ncpu,nper=nper,**quargs)(loop=loop)
 
 ##-----------------------------------------------------------------------------
 
diff --git a/nifty_power.py b/nifty_power.py
index 00534780814d571703f88442d3c8393b32217453..9c46ab0e364013afef61f9ff6066bc82cf01bafe 100644
--- a/nifty_power.py
+++ b/nifty_power.py
@@ -575,7 +575,7 @@ def infer_power(m,domain=None,Sk=None,D=None,pindex=None,pundex=None,kindex=None
 
 ##-----------------------------------------------------------------------------
 
-def interpolate_power(spec,mode="linear",domain=None,kindex=None,newkindex=None,**kwargs):
+def interpolate_power(spec,mode="linear",domain=None,kindex=None,newkindex=None,loglog=False,**kwargs):
     """
         Interpolates a given power spectrum at new k(-indices).
 
@@ -604,6 +604,9 @@ def interpolate_power(spec,mode="linear",domain=None,kindex=None,newkindex=None,
             Scales corresponding to each band in the new power spectrum;
             can be retrieved from `domain` if `kindex` is given
             (default: None).
+        loglog : bool, *optional*
+            Flag specifying whether the interpolation is done on log-log-scale
+            (ignoring the monopole) or not (default: False)
 
         Returns
         -------
@@ -719,7 +722,13 @@ def interpolate_power(spec,mode="linear",domain=None,kindex=None,newkindex=None,
         spec = np.r_[spec,np.exp(2*np.log(spec[-1])-np.log(spec[-nmirror:-1][::-1]))]
         kindex = np.r_[kindex,(2*kindex[-1]-kindex[-nmirror:-1][::-1])]
     ## interpolation
-    newspec = ip(kindex,spec,kind=mode,axis=0,copy=True,bounds_error=True,fill_value=np.NAN)(newkindex)
+    if(loglog):
+        ## map to log-log-scale ignoring monopole
+        logspec = np.log(spec[1:])
+        logspec = ip(np.log(kindex[1:]),logspec,kind=mode,axis=0,copy=True,bounds_error=True,fill_value=np.NAN)(np.log(newkindex[1:]))
+        newspec = np.concatenate([[spec[0]],np.exp(logspec)])
+    else:
+        newspec = ip(kindex,spec,kind=mode,axis=0,copy=True,bounds_error=True,fill_value=np.NAN)(newkindex)
     ## check new power spectrum
     if(not np.all(np.isfinite(newspec))):
         raise ValueError(about._errors.cstring("ERROR: infinite value(s)."))
diff --git a/nifty_power_conversion.py b/nifty_power_conversion.py
index 999e18f32e8090f58fcfa0719fc9af21904e2681..50e820d67c1d87aa6dbd9a5fdf6a673f1ca450bf 100644
--- a/nifty_power_conversion.py
+++ b/nifty_power_conversion.py
@@ -1,3 +1,24 @@
+## NIFTY (Numerical Information Field Theory) has been developed at the
+## Max-Planck-Institute for Astrophysics.
+##
+## Copyright (C) 2014 Max-Planck-Society
+##
+## Author: Maksim Greiner
+## Project homepage: <http://www.mpa-garching.mpg.de/ift/nifty/>
+##
+## This program is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+## See the GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 from nifty import *
 
 def power_backward_conversion_rg(k_space,p,mean=None,bare=True):
@@ -16,12 +37,12 @@ def power_backward_conversion_rg(k_space,p,mean=None,bare=True):
             Needs to have the same number of entries as
             `k_space.get_power_indices()[0]`
         mean : float, *optional*
-            specifies the mean of the log-normal field. If `mean` is not 
+            specifies the mean of the log-normal field. If `mean` is not
             specified the function will use the monopole of the power spectrum.
-            If it is specified the function will NOT use the monopole of the 
+            If it is specified the function will NOT use the monopole of the
             spectrum (default: None).
             WARNING: a mean that is too low can violate positive definiteness
-            of the log-normal field. In this case the function produces an 
+            of the log-normal field. In this case the function produces an
             error.
         bare : bool, *optional*
             whether `p` is the bare power spectrum or not (default: True).
@@ -34,7 +55,7 @@ def power_backward_conversion_rg(k_space,p,mean=None,bare=True):
             the power spectrum of the underlying Gaussian field, where the
             monopole has been set to zero. Eventual monopole power has been
             shifted to the mean.
-                        
+
         References
         ----------
         .. [#] M. Greiner and T.A. Ensslin, "Log-transforming the matter power spectrum";
@@ -42,41 +63,41 @@ def power_backward_conversion_rg(k_space,p,mean=None,bare=True):
     """
     pindex = k_space.get_power_indices()[2]
     V = k_space.vol.prod()**(-1)
-    
+
     mono_ind = np.where(pindex==0)
-    
+
     spec = power_operator(k_space,spec=p,bare=bare).get_power(bare=False)
-    
+
     if(mean is None):
         mean = 0.
     else:
         spec[0] = 0.
-    
+
     pf = field(k_space,val=spec[pindex]).transform()+mean**2
-    
+
     if(np.any(pf.val<0.)):
         raise ValueError(about._errors.cstring("ERROR: spectrum or mean incompatible with positive definiteness.\n Try increasing the mean."))
         return None
-    
+
     p1 = sqrt(log(pf).power())
-    
+
     p1[0] = (log(pf)).transform()[mono_ind][0]
-    
+
     p2 = 0.5*V*log(k_space.calc_weight(spec[pindex],1).sum()+mean**2)
-    
+
     logmean = 1/V * (p1[0]-p2)
-    
+
     p1[0] = 0.
-    
+
     if(np.any(p1<0.)):
         raise ValueError(about._errors.cstring("ERROR: spectrum or mean incompatible with positive definiteness.\n Try increasing the mean."))
         return None
-    
+
     if(bare==True):
         return logmean.real,power_operator(k_space,spec=p1,bare=False).get_power(bare=True).real
     else:
         return logmean.real,p1.real
-        
+
 def power_forward_conversion_rg(k_space,p,mean=0,bare=True):
     """
         This function is designed to convert a theoretical/statistical power
@@ -101,31 +122,31 @@ def power_forward_conversion_rg(k_space,p,mean=0,bare=True):
         -------
         p1 : np.array,
             the power spectrum of the exponentiated Gaussian field.
-                        
+
         References
         ----------
         .. [#] M. Greiner and T.A. Ensslin, "Log-transforming the matter power spectrum";
             `arXiv:1312.1354 <http://arxiv.org/abs/1312.1354>`_
     """
-    
+
     pindex = k_space.get_power_indices()[2]
-    
+
     spec = power_operator(k_space,spec=p,bare=bare).get_power(bare=False)
-    
+
     S_x = field(k_space,val=spec[pindex]).transform()
-    
+
     S_0 = k_space.calc_weight(spec[pindex],1).sum()
-    
+
     pf = exp(S_x+S_0+2*mean)
-    
+
     p1 = sqrt(pf.power())
-    
+
     if(bare==True):
         return power_operator(k_space,spec=p1,bare=False).get_power(bare=True).real
     else:
         return p1.real
-        
-        
+
+
 
 def power_backward_conversion_lm(k_space,p,mean=None):
     """
@@ -143,12 +164,12 @@ def power_backward_conversion_lm(k_space,p,mean=None):
             Needs to have the same number of entries as
             `k_space.get_power_indices()[0]`
         mean : float, *optional*
-            specifies the mean of the log-normal field. If `mean` is not 
+            specifies the mean of the log-normal field. If `mean` is not
             specified the function will use the monopole of the power spectrum.
-            If it is specified the function will NOT use the monopole of the 
+            If it is specified the function will NOT use the monopole of the
             spectrum. (default: None)
             WARNING: a mean that is too low can violate positive definiteness
-            of the log-normal field. In this case the function produces an 
+            of the log-normal field. In this case the function produces an
             error.
 
         Returns
@@ -159,13 +180,13 @@ def power_backward_conversion_lm(k_space,p,mean=None):
             the power spectrum of the underlying Gaussian field, where the
             monopole has been set to zero. Eventual monopole power has been
             shifted to the mean.
-                        
+
         References
         ----------
         .. [#] M. Greiner and T.A. Ensslin, "Log-transforming the matter power spectrum";
             `arXiv:1312.1354 <http://arxiv.org/abs/1312.1354>`_
     """
-    
+
     p = np.copy(p)
     if(mean is not None):
         p[0] = 4*pi*mean**2
@@ -174,7 +195,7 @@ def power_backward_conversion_lm(k_space,p,mean=None):
     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()
-    
+
     if(np.any(C_0_Omega.val<0.)):
         raise ValueError(about._errors.cstring("ERROR: spectrum or mean incompatible with positive definiteness.\n Try increasing the mean."))
         return None
@@ -186,20 +207,20 @@ def power_backward_conversion_lm(k_space,p,mean=None):
     spec = Z.val[:len(klen)]
 
     mean = (spec[0]-0.5*sqrt(4*pi)*log((p*(2*klen+1)/(4*pi)).sum()))/sqrt(4*pi)
-    
+
     spec[0] = 0.
 
     spec = spec*sqrt(4*pi)/sqrt(2*klen+1)
-    
+
     spec = np.real(spec)
-    
+
     if(np.any(spec<0.)):
         spec = spec*(spec>0.)
         about.warnings.cprint("WARNING: negative modes set to zero.")
 
     return mean.real,spec
-    
-    
+
+
 def power_forward_conversion_lm(k_space,p,mean=0):
     """
         This function is designed to convert a theoretical/statistical power
@@ -217,12 +238,12 @@ def power_forward_conversion_lm(k_space,p,mean=0):
             `k_space.get_power_indices()[0]`
         m : float, *optional*
             specifies the mean of the Gaussian field (default: 0).
-            
+
         Returns
         -------
         p1 : np.array,
             the power spectrum of the exponentiated Gaussian field.
-            
+
         References
         ----------
         .. [#] M. Greiner and T.A. Ensslin, "Log-transforming the matter power spectrum";
@@ -233,7 +254,7 @@ def power_forward_conversion_lm(k_space,p,mean=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()
-    
+
     C_0_0 = (p*(2*klen+1)/(4*pi)).sum()
 
     exC = exp(C_0_Omega+C_0_0+2*m)
@@ -243,9 +264,9 @@ def power_forward_conversion_lm(k_space,p,mean=0):
     spec = Z.val[:len(klen)]
 
     spec = spec*sqrt(4*pi)/sqrt(2*klen+1)
-    
+
     spec = np.real(spec)
-    
+
     if(np.any(spec<0.)):
         spec = spec*(spec>0.)
         about.warnings.cprint("WARNING: negative modes set to zero.")
diff --git a/nifty_tools.py b/nifty_tools.py
index a91d83881b4d81dffaaa04d0d56f960e3dbb6b23..582fdee054f3422aa4173d1e249f0d8d7527c510 100644
--- a/nifty_tools.py
+++ b/nifty_tools.py
@@ -774,10 +774,7 @@ class conjugate_gradient(object):
 
             delta = delta_*np.absolute(gamma)**0.5
             self.note.cflush("\niteration : %08u   alpha = %3.1E   beta = %3.1E   delta = %3.1E"%(ii,np.real(alpha),np.real(beta),np.real(delta)))
-            if(ii==limii):
-                self.note.cprint("\n... quit.")
-                break
-            elif(gamma==0):
+            if(gamma==0):
                 convergence = clevel+1
                 self.note.cprint("   convergence level : INF\n... done.")
                 break
@@ -789,6 +786,9 @@ class conjugate_gradient(object):
                     break
             else:
                 convergence = max(0,convergence-1)
+            if(ii==limii):
+                self.note.cprint("\n... quit.")
+                break
 
             if(self.spam is not None):
                 self.spam(self.x,ii)
@@ -843,10 +843,7 @@ class conjugate_gradient(object):
 
             delta = delta_*np.absolute(gamma)**0.5
             self.note.cflush("\niteration : %08u   alpha = %3.1E   beta = %3.1E   delta = %3.1E"%(ii,np.real(alpha),np.real(beta),np.real(delta)))
-            if(ii==limii):
-                self.note.cprint("\n... quit.")
-                break
-            elif(gamma==0):
+            if(gamma==0):
                 convergence = clevel+1
                 self.note.cprint("   convergence level : INF\n... done.")
                 break
@@ -858,6 +855,9 @@ class conjugate_gradient(object):
                     break
             else:
                 convergence = max(0,convergence-1)
+            if(ii==limii):
+                self.note.cprint("\n... quit.")
+                break
 
             if(self.spam is not None):
                 self.spam(self.x,ii)
@@ -1066,10 +1066,7 @@ class steepest_descent(object):
                 alpha *= a
 
             norm = g.norm() ## gradient norm
-            if(ii==limii):
-                self.note.cprint("\n... quit.")
-                break
-            elif(delta==0):
+            if(delta==0):
                 convergence = clevel+2
                 self.note.cprint("   convergence level : %u\n... done."%convergence)
                 break
@@ -1082,6 +1079,9 @@ class steepest_descent(object):
                     break
             else:
                 convergence = max(0,convergence-1)
+            if(ii==limii):
+                self.note.cprint("\n... quit.")
+                break
 
             if(self.spam is not None):
                 self.spam(self.x,ii)
diff --git a/powerspectrum.py b/powerspectrum.py
index de135bb57975b8ee1407224f57a83e146769fdb2..b4938708e02461428cabaddf7de8aaf20f979a5f 100644
--- a/powerspectrum.py
+++ b/powerspectrum.py
@@ -385,6 +385,66 @@ def get_power_indices(axes,dgrid,zerocentered,fourier=True):
     return ind,klength,rho
 
 
+def get_power_indices2(axes,dgrid,zerocentered,fourier=True):
+    """
+        Returns the index of the Fourier grid points in a numpy
+        array, ordered following the zerocentered flag.
+
+        Parameters
+        ----------
+        axes : ndarray
+            An array with the length of each axis.
+
+        dgrid : ndarray
+            An array with the pixel length of each axis.
+
+        zerocentered : bool
+            Whether the output array should be zerocentered, i.e. starting with
+            negative Fourier modes going over the zero mode to positive modes,
+            or not zerocentered, where zero, positive and negative modes are
+            simpy ordered consecutively.
+
+        irred : bool : *optional*
+            If True, the function returns an array of all k-vector lengths and
+            their degeneracy factors. If False, just the power index array is
+            returned.
+
+        fourier : bool : *optional*
+            Whether the output should be in Fourier space or not
+            (default=False).
+
+        Returns
+        -------
+        index, klength, rho : ndarrays
+            Returns the power index array, an array of all k-vector lengths and
+            their degeneracy factors.
+
+    """
+
+    ## kdict, klength
+    if(np.any(zerocentered==False)):
+        kdict = np.fft.fftshift(nkdict_fast2(axes,dgrid,fourier),axes=shiftaxes(zerocentered,st_to_zero_mode=True))
+    else:
+        kdict = nkdict_fast2(axes,dgrid,fourier)
+
+    klength,rho,ind = nkdict_to_indices(kdict)
+
+    return ind,klength,rho
+
+
+def nkdict_to_indices(kdict):
+
+    kindex,pindex = np.unique(kdict,return_inverse=True)
+    pindex = pindex.reshape(kdict.shape)
+
+    rho = pindex.flatten()
+    rho.sort()
+    rho = np.unique(rho,return_index=True,return_inverse=False)[1]
+    rho = np.append(rho[1:]-rho[:-1],[np.prod(pindex.shape)-rho[-1]])
+
+    return kindex,rho,pindex
+
+
 def bin_power_indices(pindex,kindex,rho,log=False,nbin=None,binbounds=None):
     """
         Returns the (re)binned power indices associated with the Fourier grid.
@@ -622,6 +682,31 @@ def nkdict_fast(axes,dgrid,fourier=True):
     return np.sqrt(np.sum((temp_vecs),axis=-1))
 
 
+def nkdict_fast2(axes,dgrid,fourier=True):
+    """
+        Calculates an n-dimensional array with its entries being the lengths of
+        the k-vectors from the zero point of the grid.
+
+    """
+    if(fourier):
+        dk = dgrid
+    else:
+        dk = np.array([1/dgrid[i]/axes[i] for i in range(len(axes))])
+
+    inds = []
+    for a in axes:
+        inds += [slice(0,a)]
+
+    cords = np.ogrid[inds]
+
+    dists = ((cords[0]-axes[0]//2)*dk[0])**2
+    for ii in range(1,len(axes)):
+        dists = dists + ((cords[ii]-axes[ii]//2)*dk[ii])**2
+    dists = np.sqrt(dists)
+
+    return dists
+
+
 def nklength(kdict):
     return np.sort(list(set(kdict.flatten())))
 
diff --git a/setup.py b/setup.py
index 21175525c87332b48aee9f24c75461e5369eeb56..f2ea738b5272120b4dd1a49a3434a223dd1a9c3c 100644
--- a/setup.py
+++ b/setup.py
@@ -23,17 +23,12 @@ from distutils.core import setup
 import os
 
 setup(name="nifty",
-      version="0.8.0",
+      version="0.9.0",
       description="Numerical Information Field Theory",
       author="Marco Selig",
       author_email="mselig@mpa-garching.mpg.de",
       url="http://www.mpa-garching.mpg.de/ift/nifty/",
-      packages=["nifty"],
+      packages=["nifty", "nifty.demos"],
       package_dir={"nifty": ""},
-      package_data={"nifty": ["demos/demo_excaliwir.py",
-                              "demos/demo_faraday.py",
-                              "demos/demo_faraday_map.npy",
-                              "demos/demo_wf1.py",
-                              "demos/demo_wf2.py",
-                              "demos/demo_wf3.py"]},
-      data_files=[(os.path.expanduser('~') + "/.nifty", ["nifty_config"])])
\ No newline at end of file
+      data_files=[(os.path.expanduser('~') + "/.nifty", ["nifty_config"])])
+