Commit 3971ebe6 authored by Marco Selig's avatar Marco Selig

initial commit.

parents
*.html
*.o
*.so
*.pyc
*.log
*.egg
*.egg-info
*.png
*.pdf
*.tiff
*~
.git/
.svn/
.spyderproject
demos/
!demos/demo_faraday.py
!demos/demo_faraday_map.npy
!demos/demo_excaliwir.py
#demos/demo_imaging*.py
#demos/demo_wiener.py
#demos/test.txt
\ No newline at end of file
This diff is collapsed.
NIFTY -- Numerical Information Field Theory
===========================================
**NIFTY** project homepage: `<http://www.mpa-garching.mpg.de/ift/nifty/>`_
Summary
-------
Description
...........
**NIFTY**, "\ **N**\umerical **I**\nformation **F**\ield **T**\heor\ **y**\ ",
is a versatile library designed to enable the development of signal inference
algorithms that operate regardless of the underlying spatial grid and its
resolution. Its object-oriented framework is written in Python, although it
accesses libraries written in Cython, C++, and C for efficiency.
NIFTY offers a toolkit that abstracts discretized representations of continuous
spaces, fields in these spaces, and operators acting on fields into classes.
Thereby, the correct normalization of operations on fields is taken care of
automatically without concerning the user. This allows for an abstract
formulation and programming of inference algorithms, including those derived
within information field theory. Thus, NIFTY permits its user to rapidly
prototype algorithms in 1D, and then apply the developed code in
higher-dimensional settings of real world problems. The set of spaces on which
NIFTY operates comprises point sets, *n*-dimensional regular grids, spherical
spaces, their harmonic counterparts, and product spaces constructed as
combinations of those.
Class & Feature Overview
........................
The NIFTY library features three main classes: **spaces** that represent
certain grids, **fields** that are defined on spaces, and **operators** that
apply to fields.
- `Spaces <http://www.mpa-garching.mpg.de/ift/nifty/space.html>`_
- ``point_space`` -- unstructured list of points
- ``rg_space`` -- *n*-dimensional regular Euclidean grid
- ``lm_space`` -- spherical harmonics
- ``gl_space`` -- Gauss-Legendre grid on the 2-sphere
- ``hp_space`` -- `HEALPix <http://sourceforge.net/projects/healpix/>`_
grid on the 2-sphere
- ``nested_space`` -- arbitrary product of grids
- `Fields <http://www.mpa-garching.mpg.de/ift/nifty/field.html>`_
- ``field`` -- generic class for (discretized) fields::
field.cast_domain field.hat field.power field.smooth
field.conjugate field.inverse_hat field.pseudo_dot field.tensor_dot
field.dim field.norm field.set_target field.transform
field.dot field.plot field.set_val field.weight
- `Operators <http://www.mpa-garching.mpg.de/ift/nifty/operator.html>`_
- ``diagonal_operator`` -- purely diagonal matrices in a specified basis
- ``projection_operator`` -- projections onto subsets of a specified basis
- ``vecvec_operator`` -- matrices derived from the outer product of a
vector
- ``response_operator`` -- exemplary responses that include a convolution,
masking and projection
- (and more)
- (and more)
*Parts of this summary are taken* [1]_.
Installation
------------
Requirements
............
- `Python <http://www.python.org/>`_ (v2.7.x)
- `NumPy <http://www.numpy.org/>`_ and `SciPy <http://www.scipy.org/>`_
- `matplotlib <http://matplotlib.org/>`_
- `multiprocessing <http://docs.python.org/2/library/multiprocessing.html>`_
(standard library)
- `GFFT <https://github.com/mrbell/gfft>`_ (v0.1.0) -- Generalized Fast Fourier
Transformations for Python
- `HEALPy <https://github.com/healpy/healpy>`_ (v1.4 without openmp) -- A
Python wrapper for `HEALPix <http://sourceforge.net/projects/healpix/>`_
- `libsharp-wrapper <https://github.com/mselig/libsharp-wrapper>`_ (v0.1.2
without openmp) -- A Python wrapper for the
`libsharp <http://sourceforge.net/projects/libsharp/>`_ library
Download
........
The latest release is tagged **v0.2.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::
git clone git://github.com/mselig/nifty.git
cd nifty
Installation
............
NIFTY is installed using Distutils by running the following command::
python setup.py install
Alternatively, a private or user specific installation can be done by::
python setup.py install --user
python setup.py install --install-lib=/SOMEWHERE
Acknowledgement
---------------
Please, acknowledge the use of NIFTY in your publication(s) by using a phrase
such as the following:
*"Some of the results in this publication have been derived using the NIFTY
[M. Selig et al., 2013] package."*
References
..........
.. [1] M. Selig et al., "NIFTY -- Numerical Information Field Theory -- a
versatile Python library for signal inference", submitted to IEEE, 2013;
`arXiv:XXXX.XXXX <http://www.arxiv.org/abs/XXXX.XXXX>`_
Release Notes
-------------
The NIFTY package is licensed under the
`GPLv3 <http://www.gnu.org/licenses/gpl.html>`_ and is distributed *without any
warranty*.
**NIFTY** project homepage: `<http://www.mpa-garching.mpg.de/ift/nifty/>`_
## NIFTY (Numerical Information Field Theory) has been developed at the
## Max-Planck-Institute for Astrophysics.
##
## Copyright (C) 2013 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/>.
from __future__ import division
from nifty_core import *
#from nifty_power import *
#from nifty_cmaps import *
##-----------------------------------------------------------------------------
import copy_reg as cr
from types import MethodType as mt
def _pickle_method(method):
fct_name = method.im_func.__name__
obj = method.im_self
cl = method.im_class
## handle mangled function name
if(fct_name.startswith("__"))and(not fct_name.endswith("__")):
cl_name = cl.__name__.lstrip("_")
fct_name = "_" + cl_name + fct_name
return _unpickle_method, (fct_name, obj, cl)
def _unpickle_method(fct_name, obj, cl):
for oo in cl.__mro__:
try:
fct = oo.__dict__[fct_name]
except(KeyError):
pass
else:
break
return fct.__get__(obj, cl)
## enable instance methods pickling
cr.pickle(mt, _pickle_method, _unpickle_method)
##-----------------------------------------------------------------------------
\ No newline at end of file
This diff is collapsed.
## NIFTY (Numerical Information Field Theory) has been developed at the
## Max-Planck-Institute for Astrophysics.
##
## Copyright (C) 2013 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/>.
"""
.. __ ____ __
.. /__/ / _/ / /_
.. __ ___ __ / /_ / _/ __ __
.. / _ | / / / _/ / / / / / /
.. / / / / / / / / / /_ / /_/ /
.. /__/ /__/ /__/ /__/ \___/ \___ / demo
.. /______/
NIFTY demo applying transformations to the "Faraday Map" [#]_.
References
----------
.. [#] N. Opermann et. al., "An improved map of the Galactic Faraday sky",
Astronomy & Astrophysics, Volume 542, id.A93, 06/2012;
`arXiv:1111.6186 <http://www.arxiv.org/abs/1111.6186>`_
"""
from __future__ import division
from nifty import *
from nifty.nifty_cmaps import *
about.warnings.off()
about.infos.off()
##-----------------------------------------------------------------------------
## spaces
h = hp_space(128)
l = lm_space(383)
g = gl_space(384) ## nlon == 767
g_ = gl_space(384, nlon=768)
r = rg_space([768, 384], dist=[1/360, 1/180])
r_ = rg_space([256, 128], dist=[1/120, 1/60])
## map
m = field(h, val=np.load("demo_faraday_map.npy"))
## projection operator
Sk = None
##-----------------------------------------------------------------------------
##=============================================================================
def run(projection=False, power=False):
"""
Runs the demo.
Parameters
----------
projection : bool, *optional*
Whether to additionaly include projections in the demo or not. If
``projection == True`` the projection operator `Sk` will be
defined. (default: False)
power : bool, *optional*
Whether to additionaly show power spectra in the demo or not.
(default: False)
"""
global Sk
## start in hp_space
m0 = m
## transform to lm_space
m1 = m0.transform(l)
if(projection):
## define projection operator
powerindex = l.get_power_index()
Sk = projection_operator(l, assign=powerindex)
## project quadrupole
m2 = Sk(m0, band=2)
## transform to gl_space
m3 = m1.transform(g)
## transform to rg_space
m4 = m1.transform(g_) ## auxiliary gl_space
m4.cast_domain(r) ## rg_space cast
m4.set_val(np.roll(m4.val[::-1, ::-1], g.nlon()//2, axis=1)) ## rearrange
if(power):
## restrict to central window
m5 = field(r_, val=m4[128:256, 256:512]).transform()
## plots
m0.plot(title=r"$m$ on a HEALPix grid", vmin=-4, vmax=4, cmap=ncmap.fm())
if(power):
m1.plot(title=r"angular power spectrum of $m$", vmin=1E-2, vmax=1E+1, mono=False)
if(projection):
m2.plot(title=r"quadrupole of $m$ on a HEALPix grid", vmin=-4, vmax=4, cmap=ncmap.fm())
m3.plot(title=r"$m$ on a spherical Gauss-Legendre grid", vmin=-4, vmax=4, cmap=ncmap.fm())
m4.plot(title=r"$m$ on a regular 2D grid", vmin=-4, vmax=4, cmap=ncmap.fm())
if(power):
m5.plot(title=r"(restricted) Fourier power spectrum of $m$", vmin=1E-3, vmax=1E+0, mono=False)
##=============================================================================
This diff is collapsed.
## nifty configuration
##
## errors colour code
0
## warnings
1
## warnings colour code
0
## infos
0
## infos colour code
0
## multiprocessing
1
## hermitianize
1
## lm2gl
1
##
##
\ No newline at end of file
This diff is collapsed.
## NIFTY (Numerical Information Field Theory) has been developed at the
## Max-Planck-Institute for Astrophysics.
##
## Copyright (C) 2013 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/>.
"""
.. __ ____ __
.. /__/ / _/ / /_
.. __ ___ __ / /_ / _/ __ __
.. / _ | / / / _/ / / / / / /
.. / / / / / / / / / /_ / /_/ /
.. /__/ /__/ /__/ /__/ \___/ \___ / power
.. /______/
NIFTy offers a number of automatized routines for handling
power spectra. It is possible to draw a field from a random distribution
with a certain autocorrelation or, equivalently, with a certain
power spectrum in its conjugate space (see :py:func:`field.random`). In
NIFTy, it is usually assumed that such a field follows statistical
homogeneity and isotropy. Fields which are only statistically homogeneous
can also be created using the diagonal operator routine.
In the moment, NIFTy offers one additional routine for power spectrum
manipulation, the smooth_power function to smooth a power spectrum with a
Gaussian convolution kernel. This can be necessary in cases where power
spectra are reconstructed and reused in an interative algorithm, where
too much statistical variation might effect severely the results.
"""
from __future__ import division
import numpy as np
import smoothing as gs
##-----------------------------------------------------------------------------
def smooth_power(power,kindex,exclude=1,sigma=-1):
"""
Smoothes a power spectrum via convolution with a Gaussian kernel.
Parameters
----------
power : ndarray
The power spectrum to be smoothed.
kindex : ndarray
The array specifying the coordinate indices in conjugate space.
exclude : scalar
Excludes the first power spectrum entries from smoothing, indicated by
the given integer scalar (default=1, the monopol is not smoothed).
smooth_length : scalar
FWHM of Gaussian convolution kernel.
Returns
-------
smoothpower : ndarray
The smoothed power spectrum.
"""
return gs.smooth_power(power,kindex,exclude=exclude,smooth_length=sigma)
##-----------------------------------------------------------------------------
This diff is collapsed.
## NIFTY (Numerical Information Field Theory) has been developed at the
## Max-Planck-Institute for Astrophysics.
##
## Copyright (C) 2013 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/>.
from distutils.core import setup
import os
setup(name="nifty",
version="0.2.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"],
package_dir={"nifty": ""},
package_data={"nifty": ["demos/demo_excaliwir.py",
"demos/demo_faraday.py",
"demos/demo_faraday_map.npy"]},
data_files=[(os.path.expanduser('~') + "/.nifty", ["nifty_config"])])
\ No newline at end of file
## NIFTY (Numerical Information Field Theory) has been developed at the
## Max-Planck-Institute for Astrophysics.
##
## Copyright (C) 2013 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/>.
## TODO: optimize
from __future__ import division
import gfft as gf
import numpy as np
def smooth_power(power, k, exclude=1, smooth_length=None):
"""
"""
if smooth_length == 0:
# No smoothing requested, just return the input array.
return power
if (exclude > 0):
k = k[exclude:]
excluded_power = np.copy(power[:exclude])
power = power[exclude:]
kmin = k[0]
kdiff = np.abs(k[:-1] - k[1:])
# Use the maximum difference between k values to define the bin width.
# This should ensure that we always have some points in each bin.
dk = np.max(kdiff)
nk = int(max(k - kmin) / dk + 1.)
if (smooth_length is None) or (smooth_length < 0):
#smooth_length = np.abs(k[0]-k[-1])/(3*nk)
smooth_length = dk
# Store the number of data points that have contributed to each bin
# counter = np.zeros(nk, dtype=float)
counter = np.zeros(nk, dtype=np.int)
# The binned power spectrum
pbinned = np.zeros(nk, dtype=power.dtype)
# do the binning
for i in range(len(k)):
ndx = int((k[i] - kmin) / dk)
pbinned[ndx] += power[i]
counter[ndx] += 1
pbinned = pbinned / counter
nmirror = int(5 * smooth_length / dk) + 2
zpbinned = np.r_[(2 * pbinned[0] - pbinned[1:nmirror][::-1]), pbinned,
(2 * pbinned[-1] - pbinned[-nmirror:-1][::-1])]
zpbinned = np.maximum(0, zpbinned)
tpbinned = np.fft.fftshift(np.fft.fft(zpbinned))
tkernel = gaussian_kernel(zpbinned.size, dk, smooth_length)
pbinned2 = np.fft.ifft(np.fft.ifftshift(tpbinned * tkernel))
pbinned2 = np.abs(pbinned2[nmirror - 1:-nmirror + 1])
# Un-bin the results
power2 = np.zeros(len(power), dtype=power.dtype)
for i in range(len(k)):
ndx = int((k[i] - kmin) / dk)
power2[i] = pbinned2[ndx]
if(exclude > 0):
return np.r_[excluded_power, power2]
else:
return power2
def smooth_field(val, fourier, zero_center, enforce_hermitian_symmetry, vol, \
smooth_length=0.):
"""
A function to smooth a regularly spaced field with a Gaussian smoothing
kernel.
Args:
val: An ndarray containing the field values to be smoothed.
fourier: A boolean indicating whether the field is in Fourier space
or not.
zero_center: A list of booleans stating whether the field is
zero centered or not along each axis.
enforce_hermitian_symmetry: A flag indicating whether the input
field should be considered one half of a hermetian symmetric field
vol: An iterable containing the pixel space volume of each axis on
the regular grid.
smooth_length: The standard deviation of the Gaussian smoothing
kernel, in units of dist. [0]
Returns:
sval: The smoothed field values.
"""
# if smooth_length == 0.:
# return val
#
if(fourier):
tfield = val
vol = 1/np.array(val.shape)/vol
else:
#
tfield = gf.gfft(val, ftmachine='fft', \
in_zero_center=zero_center, out_zero_center=True, \
enforce_hermitian_symmetry=enforce_hermitian_symmetry, W=-1, \
alpha=-1, verbose=False)
# Construct the Fourier transformed smoothing kernel
tkernel = gaussian_kernel(val.shape, vol, smooth_length)
# Multiply the smoothing kernel and the transformed spectrum
tfield = tfield*tkernel
#
if(fourier):
sfield = tfield
else:
#
# Transform back to the signal space using GFFT.
sfield = gf.gfft(tfield, ftmachine='ifft', \
in_zero_center=True, out_zero_center=zero_center, \
enforce_hermitian_symmetry=enforce_hermitian_symmetry, W=-1, \
alpha=-1, verbose=False)
return sfield
def gaussian_kernel(nx, dx, smooth_length):
"""
Returns an image of the Fourier transform of a Gaussian smoothing kernel.
Args:
nx: A scalar or iterable of axis lengths defining the grid on which the
smoothing kernel shall be applied.
dx: A scalar or iterable of pixel volumes defining the grid on which the
smoothing kernel shall be applied.
smooth_length: The standard deviation of the Gaussian smoothing kernel,
defined in units of dx.
Returns:
kernel: The Fourier transform of the Gaussian smoothing kernel.
"""
## FIXME: out source lambda function
# The Fourier transform of a Gaussian function having amplitude 1.
func = lambda x: np.exp(-2.*np.pi**2*x**2*smooth_length**2)
## TODO: check necessity of checks
if np.isscalar(nx) and np.isscalar(dx):
ndim = 1
nx = [nx]
dx = [dx]
elif np.isscalar(nx) and not np.isscalar(dx) or \
not np.isscalar(nx) and np.isscalar(dx):
raise Exception("nx and dx must both be scalars or arrays. "+\
"No mixtures allowed!")