response_operator.py 3.21 KB
Newer Older
Martin Reinecke's avatar
Martin Reinecke committed
1
from builtins import range
2
import numpy as np
3
4
5
from ... import Field,\
                FieldArray
from ..linear_operator import LinearOperator
Martin Reinecke's avatar
Martin Reinecke committed
6
from ..smoothing_operator import FFTSmoothingOperator
7
8
from ..composed_operator import ComposedOperator
from ..diagonal_operator import DiagonalOperator
9

10

11
class ResponseOperator(LinearOperator):
Theo Steininger's avatar
Theo Steininger committed
12
    """ NIFTy ResponseOperator (example)
13

14
15
16
17
18
19
20
    This NIFTy ResponseOperator provides the user with an example how a
    ResponseOperator can look like. It smoothes and exposes a field. The
    outcome of the Operator is geometrically not ordered as typical data
    set are.

    Parameters
    ----------
Theo Steininger's avatar
Theo Steininger committed
21
    domain : tuple of DomainObjects, i.e. Spaces and FieldTypes
22
23
24
25
26
27
        The domains on which the operator lives. Either one space or a list
        of spaces
    sigma : list(np.float)
        Defines the smoothing length of the operator for each space it lives on
    exposure : list(np.float)
        Defines the exposure of the operator for each space it lives on
28
29
30
    default_spaces : tuple of ints *optional*
        Defines on which space(s) of a given field the Operator acts by
        default (default: None)
31
32
33

    Attributes
    ----------
34
35
36
    domain : tuple of DomainObjects, i.e. Spaces and FieldTypes
        The domain on which the Operator's input Field lives.
    target : tuple of DomainObjects, i.e. Spaces and FieldTypes
Martin Reinecke's avatar
Martin Reinecke committed
37
        The domain in which the outcome of the operator lives.
38
39
    unitary : boolean
        Indicates whether the Operator is unitary or not.
40
41
42
43
44
45
46
47
48

    Raises
    ------
    ValueError:
        raised if:
            * len of sigma-list and exposure-list are not equal

    """

49
    def __init__(self, domain, sigma=[1.], exposure=[1.],
50
51
                 default_spaces=None):
        super(ResponseOperator, self).__init__(default_spaces)
52

53
        if len(sigma) != len(exposure):
54
55
            raise ValueError("Length of smoothing kernel and length of"
                             "exposure do not match")
Martin Reinecke's avatar
updates    
Martin Reinecke committed
56
        nsigma = len(sigma)
57

Martin Reinecke's avatar
updates    
Martin Reinecke committed
58
59
60
61
62
63
        self._domain = self._parse_domain(domain)

        kernel_smoothing = [FFTSmoothingOperator(self._domain[x], sigma[x])
                            for x in range(nsigma)]
        kernel_exposure = [DiagonalOperator(self._domain[x],
                           diagonal=exposure[x]) for x in range(nsigma)]
64
65
66

        self._composed_kernel = ComposedOperator(kernel_smoothing)
        self._composed_exposure = ComposedOperator(kernel_exposure)
67

Martin Reinecke's avatar
updates    
Martin Reinecke committed
68
        target_list = [FieldArray(x.shape) for x in self.domain]
69
70
        self._target = self._parse_domain(target_list)

71
72
73
74
75
76
77
78
79
80
    @property
    def domain(self):
        return self._domain

    @property
    def target(self):
        return self._target

    @property
    def unitary(self):
81
        return False
82
83

    def _times(self, x, spaces):
84
85
        res = self._composed_kernel.times(x, spaces)
        res = self._composed_exposure.times(res, spaces)
86
87
        # removing geometric information
        return Field(self._target, val=res.val)
88
89
90

    def _adjoint_times(self, x, spaces):
        # setting correct spaces
91
92
        res = Field(self.domain, val=x.val)
        res = self._composed_exposure.adjoint_times(res, spaces)
93
        res = res.weight(power=-1)
Martin Reinecke's avatar
updates    
Martin Reinecke committed
94
        return self._composed_kernel.adjoint_times(res, spaces)