We would like to invite to a Crash Course on NIFTy (Numerical Information Field TheorY) and on the new GRAVITY imaging tool. The course will take place from August 24th to 27th, 2021 in an hybrid in-person/video-conference format.
The first half of the course will be done by Philipp Arras (MPA/TUM) on the Python package NIFTy. NIFTy is a versatile library that can be used in a variety of inference and data analysis applications. Examples include (x-ray, optical, radio, VLBI) imaging, data calibration applications and the reconstruction of light curves. NIFTy excels in high-dimensional Bayesian inference applications. Basic information can be found in the NIFTy documentation.
The second half of the course will be done by Julia and is specific to GRAVITY imaging with the help of NIFTy.
Closed.
All times refer to CEST.
The course includes hands-on sessions during which the participants can experiment with NIFTy themselves. For this, please install NIFTy beforehand. The latest stable version is available on PyPI and can be installed via:
pip3 install nifty7
In order to check that the installation was successful, you may run the following script.
import nifty7 as ift
import numpy as np
= ift.RGSpace([500, 500], harmonic=True)
dom = ift.HarmonicTransformOperator(dom)
HT = ift.PowerSpace(dom)
pdom = ift.PowerDistributor(dom, pdom)
PD = ift.DiagonalOperator(PD(ift.PS_field(pdom, lambda k: 100./(20. + k**3))))
S = S.draw_sample_with_dtype(dtype=np.float64)
s ="nifty_test.png") ift.single_plot(HT(s), name
If the resulting file nifty_test.png
looks like the
following, NIFTy is correctly installed.
Please find the tutorial scripts here.
# 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/>.
#
# Copyright(C) 2013-2021 Max-Planck-Society
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
import numpy as np
import nifty7 as ift
from helpers import generate_wf_data, plot_WF
# Want to implement: m = Dj = (S^{-1} + R^T N^{-1} R)^{-1} R^T N^{-1} d
111)
ift.random.push_sseq_from_seed(
= ift.RGSpace(256, 1/256)
position_space = ift.UnstructuredDomain(256)
data_space = lambda k: 1/(10. + k**2.5)
prior_spectrum
= generate_wf_data(position_space, prior_spectrum)
data, ground_truth
= ift.makeField(position_space, ground_truth)
ground_truth = ift.makeField(data_space, data)
data
"1_data", ground_truth, data)
plot_WF(
= position_space.get_default_codomain()
harmonic_space
= ift.HarmonicTransformOperator(harmonic_space, position_space) # basically just a Fast Fourier transform
HT
# Define prior covariance in harmonic space
= ift.create_power_operator(harmonic_space, prior_spectrum)
Sh
= np.ones(256, np.bool)
mask 50:150] = False
mask[180:190] = False
mask[= ift.makeField(position_space, mask)
mask
#class BoilerplateLinearOperator(ift.LinearOperator):
# def __init__(self, mask):
# self._domain = ift.makeDomain(...)
# self._target = ift.makeDomain(...)
# self._capability = self.TIMES | self.ADJOINT_TIMES
#
# def apply(self, x, mode):
# self._check_input(x, mode)
# if mode == self.TIMES:
# raise NotImplementedError
# elif mode == self.ADJOINT_TIMES:
# raise NotImplementedError
# raise RuntimeError
class MaskingOperator(ift.LinearOperator):
def __init__(self, mask):
= np.sum(mask.val)
n_data_points assert mask.s_sum() == n_data_points
self._domain = ift.makeDomain(mask.domain)
self._target = ift.makeDomain(ift.UnstructuredDomain(n_data_points))
self._capability = self.TIMES | self.ADJOINT_TIMES
self._mask = mask.val
def apply(self, x, mode):
self._check_input(x, mode)
if mode == self.TIMES:
= x.val # Unwrapping from field
x = x[self._mask] # Actual code
res return ift.makeField(self._target, res) # Wrapping as field
else: # mode == self.ADJOINT_TIMES
= x.val # Unwrapping from field
x = np.zeros(self._domain.shape, dtype=x.dtype)
res self._mask] = x
res[return ift.makeField(self._domain, res) # Wrapping as field
= MaskingOperator(mask)
mask_op
ift.extra.check_linear_operator(mask_op)
= mask_op.target
data_space = ift.makeField(data_space, data.val[mask.val])
data
= mask_op @ HT
R
= ift.ScalingOperator(data_space, 0.1)
N
= (R.adjoint @ N.inverse)(data)
j
#ift.single_plot(j)
= ift.GradientNormController(iteration_limit=256)
ic = ift.WienerFilterCurvature(R, N, Sh, ic, ic)
metric = metric.inverse
D
# Same as
#D = (Sh.inverse + R.adjoint @ N.inverse @ R).inverse
= D(j)
m
# plot_WF("1_result", ground_truth, data, HT(m))
= 10
n_samples = [HT(m + D.draw_sample()) for _ in range(n_samples)]
samples
1.)), name="1_data_coverage.png")
ift.single_plot(mask_op.adjoint(ift.full(data_space, ="1_posterior_samples.png")
ift.single_plot(samples, name
# plot_WF("1_result_sample", ground_truth, data, samples[0])
# plot_WF("1_result_uncertainty", ground_truth, data, HT(m), samples=samples)