wiener_filter.py 3.28 KB
Newer Older
Martin Reinecke's avatar
Martin Reinecke committed
1
import nifty4 as ift
Theo Steininger's avatar
Theo Steininger committed
2 3 4 5
import numpy as np


if __name__ == "__main__":
Martin Reinecke's avatar
Martin Reinecke committed
6
    # Setting up parameters
Martin Reinecke's avatar
Martin Reinecke committed
7 8 9 10
    L = 2.                         # Total side-length of the domain
    N_pixels = 512                 # Grid resolution (pixels per axis)
    correlation_length_scale = 1.  # Typical distance over which the field is
                                   # correlated
Theo Steininger's avatar
Theo Steininger committed
11
    fluctuation_scale = 2.         # Variance of field in position space
Martin Reinecke's avatar
Martin Reinecke committed
12
    response_sigma = 0.05          # Smoothing length of response
Theo Steininger's avatar
Theo Steininger committed
13 14
    signal_to_noise = 1.5          # The signal to noise ratio
    np.random.seed(43)             # Fixing the random seed
Martin Reinecke's avatar
Martin Reinecke committed
15

Theo Steininger's avatar
Theo Steininger committed
16 17 18 19 20
    def power_spectrum(k):         # Defining the power spectrum
        a = 4 * correlation_length_scale * fluctuation_scale**2
        return a / (1 + (k * correlation_length_scale)**2) ** 2

    signal_space = ift.RGSpace([N_pixels, N_pixels], distances=L/N_pixels)
Martin Reinecke's avatar
Martin Reinecke committed
21
    harmonic_space = signal_space.get_default_codomain()
Martin Reinecke's avatar
Martin Reinecke committed
22
    fft = ift.FFTOperator(harmonic_space, target=signal_space)
Martin Reinecke's avatar
Martin Reinecke committed
23 24 25
    power_space = ift.PowerSpace(
        harmonic_space, binbounds=ift.PowerSpace.useful_binbounds(
            harmonic_space, logarithmic=True))
Theo Steininger's avatar
Theo Steininger committed
26

Martin Reinecke's avatar
Martin Reinecke committed
27 28 29
    # Creating the mock signal
    S = ift.create_power_operator(harmonic_space,
                                  power_spectrum=power_spectrum)
Martin Reinecke's avatar
Martin Reinecke committed
30
    mock_power = ift.PS_field(power_space, power_spectrum)
Martin Reinecke's avatar
adjust  
Martin Reinecke committed
31
    mock_signal = fft(ift.power_synthesize(mock_power, real_signal=True))
Theo Steininger's avatar
Theo Steininger committed
32 33

    # Setting up an exemplary response
Martin Reinecke's avatar
Martin Reinecke committed
34
    mask = np.ones(signal_space.shape)
Theo Steininger's avatar
Theo Steininger committed
35
    N10 = int(N_pixels/10)
Martin Reinecke's avatar
Martin Reinecke committed
36 37 38 39
    mask[N10*5:N10*9, N10*5:N10*9] = 0.
    mask = ift.Field(signal_space, ift.dobj.from_global_data(mask))
    R = ift.ResponseOperator(signal_space, sigma=(response_sigma,),
                             exposure=(mask,))
Theo Steininger's avatar
Theo Steininger committed
40
    data_domain = R.target[0]
Martin Reinecke's avatar
Martin Reinecke committed
41
    R_harmonic = R * fft
Theo Steininger's avatar
Theo Steininger committed
42 43

    # Setting up the noise covariance and drawing a random noise realization
44
    ndiag = ift.Field.full(data_domain, mock_signal.var()/signal_to_noise)
45
    N = ift.DiagonalOperator(ndiag.weight(1))
Martin Reinecke's avatar
Martin Reinecke committed
46 47 48
    noise = ift.Field.from_random(
        domain=data_domain, random_type='normal',
        std=mock_signal.std()/np.sqrt(signal_to_noise), mean=0)
Martin Reinecke's avatar
Martin Reinecke committed
49
    data = R(mock_signal) + noise
Theo Steininger's avatar
Theo Steininger committed
50 51 52

    # Wiener filter
    j = R_harmonic.adjoint_times(N.inverse_times(data))
Martin Reinecke's avatar
Martin Reinecke committed
53
    ctrl = ift.GradientNormController(verbose=True, tol_abs_gradnorm=0.1)
54
    inverter = ift.ConjugateGradient(controller=ctrl)
55 56
    wiener_curvature = ift.library.WienerFilterCurvature(
        S=S, N=N, R=R_harmonic, inverter=inverter)
Martin Reinecke's avatar
Martin Reinecke committed
57
    m_k = wiener_curvature.inverse_times(j)
Theo Steininger's avatar
Theo Steininger committed
58 59
    m = fft(m_k)

Martin Reinecke's avatar
Martin Reinecke committed
60 61 62 63 64
    # Probing the uncertainty
    class Proby(ift.DiagonalProberMixin, ift.Prober):
        pass
    proby = Proby(signal_space, probe_count=1, ncpu=1)
    proby(lambda z: fft(wiener_curvature.inverse_times(fft.inverse_times(z))))
Theo Steininger's avatar
Theo Steininger committed
65

Martin Reinecke's avatar
Martin Reinecke committed
66
    sm = ift.FFTSmoothingOperator(signal_space, sigma=0.03)
Martin Reinecke's avatar
Martin Reinecke committed
67
    variance = ift.sqrt(sm(proby.diagonal.weight(-1)))
68

Martin Reinecke's avatar
Martin Reinecke committed
69
    # Plotting
Martin Reinecke's avatar
Martin Reinecke committed
70 71 72 73
    plotdict = {"xlabel": "Pixel index", "ylabel": "Pixel index",
                "colormap": "Planck-like"}
    ift.plotting.plot(variance, name="uncertainty.png", **plotdict)
    ift.plotting.plot(mock_signal, name="mock_signal.png", **plotdict)
Martin Reinecke's avatar
Martin Reinecke committed
74
    ift.plotting.plot(ift.Field(signal_space, val=data.val),
Martin Reinecke's avatar
Martin Reinecke committed
75 76
                      name="data.png", **plotdict)
    ift.plotting.plot(m, name="map.png", **plotdict)