Exemplo n.º 1
0
    def _get_unit_conversion_operator(self, nu):
        """
        Convert sky temperature into W / m^2 / Hz / pixel.

        If the scene has been initialised with the 'absolute' keyword, the
        scene is assumed to include the CMB background and the fluctuations
        (in Kelvin) and the operator follows the non-linear Planck law.
        Otherwise, the scene only includes the fluctuations (in microKelvin)
        and the operator is linear (i.e. the output also corresponds to power
        fluctuations).

        """
        if not self.temperature:
            return IdentityOperator()

        # solid angle of a sky pixel
        omega = 4 * np.pi / self.shape[0]
        a = 2 * omega * h * nu**3 / c**2
        if self.absolute:
            hnu_k = h * nu / k
            return a / asoperator(np.expm1)(hnu_k * ReciprocalOperator())
        T = self.T_cmb
        hnu_kT = h * nu / (k * T)
        val = 1e-6 * a * hnu_kT * np.exp(hnu_kT) / (np.expm1(hnu_kT)**2 * T)
        return asoperator(val)
Exemplo n.º 2
0
 def __init__(self, name, layout, image2object=None, object2image=None):
     if image2object is None and object2image is None:
         raise ValueError('Neither the image2object nor the object2image tr'
                          'ansforms are speficied.')
     Instrument.__init__(self, name, layout)
     if object2image is not None:
         self.object2image = asoperator(object2image)
         self.image2object = self.object2image.I
     else:
         self.image2object = asoperator(image2object)
         self.object2image = self.image2object.I
Exemplo n.º 3
0
 def __new__(cls, A):
     A = op.asoperator(A)
     if isinstance(A, op.IdentityOperator):
         return norm2
     norm = super(norm2_ellipsoid, cls).__new__(cls)
     norm.A = A
     return norm
Exemplo n.º 4
0
 def __new__(cls, A):
     A = op.asoperator(A)
     if isinstance(A, op.IdentityOperator):
         return norm2
     norm = super(norm2_ellipsoid, cls).__new__(cls)
     norm.A = A
     return norm
Exemplo n.º 5
0
    def __init__(self, shape, topixel=None, ndim=None, dtype=float,
                 **keywords):
        """
    Parameters
    ----------
    shape : tuple of integers
        The surface shape.
    ndim : int, optional
        The number of splittable (indexable) dimensions. It is the actual
        number of dimensions of the layout. It can be lower than that
        specified by the layout shape, in which case the extra dimensions
        are instructed not to be split.
    topixel : Operator, optional
        World-to-pixel coordinate transform.

        """
        PackedTable.__init__(self, shape, ndim=ndim)
        if topixel is None:
            topixel = IdentityOperator(self.shape[:self.ndim])
        else:
            topixel = asoperator(topixel)
        self.dtype = np.dtype(dtype)
        self.topixel = topixel
        self.toworld = topixel.I
        for k, v in keywords.items():
            setattr(self, k, v)
Exemplo n.º 6
0
    def __init__(self, shape, topixel=None, to1d=None, origin='upper',
                 startswith1=False, **keywords):
        """
        Parameters
        ----------
        shape : tuple of integers
            The surface shape.
        startswith1 : bool
            If True, columns and row starts with 1 instead of 0.
        topixel : Operator, optional
            World-to-pixel coordinate transform.
        to1d : Operator, optional
            Nd-to-1d pixel index transform.

        """
        origins = 'upper', 'lower'
        if not isinstance(origin, str):
            raise TypeError('Invalid origin.')
        origin = origin.lower()
        if origin not in origins:
            raise ValueError(
                'Invalid origin {0!r}. Expected values are {1}.'.format(
                    origin, strenum(origins)))
        Scene.__init__(self, shape, topixel=topixel, **keywords)
        if self.ndim != 2:
            raise ValueError('The scene is not 2-dimensional.')
        self.origin = origin
        self.startswith1 = bool(startswith1)
        if to1d is not None:
            to1d = asoperator(to1d)
            self.toNd = to1d.I
        else:
            self.toNd = None
        self.to1d = to1d
Exemplo n.º 7
0
def test_block_row2():
    p = np.matrix([[1, 0], [0, 2], [1, 0]])
    o = asoperator(np.matrix(p))
    r = BlockRowOperator([o, 2*o], axisin=0)
    assert_eq(r.todense(), np.hstack([p, 2*p]))
    assert_eq(r.T.todense(), r.todense().T)
    r = BlockRowOperator([o, 2*o], new_axisin=0)
    assert_eq(r.todense(), np.hstack([p, 2*p]))
    assert_eq(r.T.todense(), r.todense().T)
Exemplo n.º 8
0
def test_block_column2():
    p = np.matrix([[1, 0], [0, 2], [1, 0]])
    o = asoperator(np.matrix(p))
    e = BlockColumnOperator([o, 2*o], axisout=0)
    assert_eq(e.todense(), np.vstack([p, 2*p]))
    assert_eq(e.T.todense(), e.todense().T)
    e = BlockColumnOperator([o, 2*o], new_axisout=0)
    assert_eq(e.todense(), np.vstack([p, 2*p]))
    assert_eq(e.T.todense(), e.todense().T)
Exemplo n.º 9
0
def test_block_row2():
    p = np.matrix([[1, 0], [0, 2], [1, 0]])
    o = asoperator(np.matrix(p))
    r = BlockRowOperator([o, 2 * o], axisin=0)
    assert_eq(r.todense(), np.hstack([p, 2 * p]))
    assert_eq(r.T.todense(), r.todense().T)
    r = BlockRowOperator([o, 2 * o], new_axisin=0)
    assert_eq(r.todense(), np.hstack([p, 2 * p]))
    assert_eq(r.T.todense(), r.todense().T)
Exemplo n.º 10
0
def test_block_column2():
    p = np.matrix([[1, 0], [0, 2], [1, 0]])
    o = asoperator(np.matrix(p))
    e = BlockColumnOperator([o, 2 * o], axisout=0)
    assert_eq(e.todense(), np.vstack([p, 2 * p]))
    assert_eq(e.T.todense(), e.todense().T)
    e = BlockColumnOperator([o, 2 * o], new_axisout=0)
    assert_eq(e.todense(), np.vstack([p, 2 * p]))
    assert_eq(e.T.todense(), e.todense().T)
Exemplo n.º 11
0
    def get_unit_conversion_operator(self, nu):
        """
        Return an operator to convert sky temperatures into
        W / m^2 / Hz / pixel.

        If the scene has been initialized with the 'absolute' keyword, the
        scene is assumed to include the CMB background and the fluctuations
        (in Kelvin) and the operator follows the non-linear Planck law.
        Otherwise, the scene only includes the fluctuations (in microKelvin)
        and the operator is linear (i.e. the output also corresponds to power
        fluctuations).

        Parameter
        ---------
        nu : float
            The frequency, at which the conversion is performed [Hz].

        Example
        -------
        > scene = SceneHealpixCMB(256, absolute=False)
        > op = scene.get_unit_conversion_operator(150e9)
        > dT = 200  # µK
        > print(op(dT))  # W / m^2 / Hz / pixel
        1.2734621598076659e-26

        > scene = SceneHealpixCMB(256, absolute=True)
        > op = scene.get_unit_conversion_operator(150e9)
        > T = 2.7  # K
        > print(op(T))  # W / m^2 / Hz / pixel
        5.94046610468e-23

        """
        a = 2 * self.solid_angle * h * nu**3 / c**2
        if self.absolute:
            hnu_k = h * nu / k
            return a / asoperator(np.expm1)(hnu_k * ReciprocalOperator())
        T = self.temperature
        hnu_kT = h * nu / (k * T)
        val = 1e-6 * a * hnu_kT * np.exp(hnu_kT) / (np.expm1(hnu_kT)**2 * T)
        return asoperator(val)
Exemplo n.º 12
0
    def get_unit_conversion_operator(self, nu):
        """
        Return an operator to convert sky temperatures into
        W / m^2 / Hz / pixel.

        If the scene has been initialized with the 'absolute' keyword, the
        scene is assumed to include the CMB background and the fluctuations
        (in Kelvin) and the operator follows the non-linear Planck law.
        Otherwise, the scene only includes the fluctuations (in microKelvin)
        and the operator is linear (i.e. the output also corresponds to power
        fluctuations).

        Parameter
        ---------
        nu : float
            The frequency, at which the conversion is performed [Hz].

        Example
        -------
        > scene = SceneHealpixCMB(256, absolute=False)
        > op = scene.get_unit_conversion_operator(150e9)
        > dT = 200  # µK
        > print(op(dT))  # W / m^2 / Hz / pixel
        1.2734621598076659e-26

        > scene = SceneHealpixCMB(256, absolute=True)
        > op = scene.get_unit_conversion_operator(150e9)
        > T = 2.7  # K
        > print(op(T))  # W / m^2 / Hz / pixel
        5.94046610468e-23

        """
        a = 2 * self.solid_angle * h * nu**3 / c**2
        if self.absolute:
            hnu_k = h * nu / k
            return a / asoperator(np.expm1)(hnu_k * ReciprocalOperator())
        T = self.temperature
        hnu_kT = h * nu / (k * T)
        val = 1e-6 * a * hnu_kT * np.exp(hnu_kT) / (np.expm1(hnu_kT)**2 * T)
        return asoperator(val)
Exemplo n.º 13
0
def cg(A, b, x0=None, tol=1.e-5, maxiter=300, M=None, disp=False,
       callback=None):
    """ OpenMPI/MPI hybrid conjugate gradient solver with preconditioning. """

    A = asoperator(A)
    comm = A.commin or MPI.COMM_WORLD

    if M is None:
        M = IdentityOperator()
    M = asoperator(M)

    maxRelError = tol**2

    shape = b.shape
    x = np.empty(shape)
    d = np.empty(shape)
    q = np.empty(shape)
    r = np.empty(shape)
    s = np.empty(shape)
    xfinal = np.zeros(shape)

    if x0 is None:
        x[...] = 0
    else:
        x[...] = x0

    norm = norm2(b, comm=comm)
    if norm == 0:
        return xfinal, 0

    r[...] = b
    r -= A(x)
    epsilon = norm2(r, comm=comm) / norm
    minEpsilon = epsilon

    M(r, d)
    delta0 = dot(r, d, comm=comm)
    deltaNew = delta0

    for iter_ in xrange(maxiter):
        if epsilon <= maxRelError:
            break
        
        A(d, q)

        alpha = deltaNew / dot(d, q, comm=comm)
        x += alpha * d
        r -= alpha * q
        epsilon = norm2(r, comm=comm) / norm
        if disp:
            print '{0:4}: {1}'.format(iter_ + 1, np.sqrt(epsilon))

        if callback is not None:
            resid = np.sqrt(epsilon)
            callback(x)

        if epsilon < minEpsilon:
            xfinal[...] = x
            minEpsilon = epsilon

        M(r, s)

        deltaOld = deltaNew

        deltaNew = dot(r, s, comm=comm)
        beta = deltaNew / deltaOld
        d *= beta
        d += s
    
    minEpsilon  = np.sqrt(minEpsilon)
    maxRelError = np.sqrt(maxRelError)

    return xfinal.reshape(b.shape), int(minEpsilon > maxRelError)
Exemplo n.º 14
0
def _tod2map(acq, tod, coverage_threshold, max_nbytes, callback, disp_pcg,
             maxiter, tol, criterion, full_output, save_map, hyper):
    # coverage normalization:
    # sum coverage = #detectors x #samplings for a uniform secondary beam
    H = acq.get_operator()
    coverage = H.T(ones(H.shapeout))
    if acq.scene.kind == 'IQU':
        coverage = coverage[..., 0]
    elif acq.scene.kind == 'QU':
        raise NotImplementedError()
    theta, phi = acq.instrument.detector.theta, acq.instrument.detector.phi
    ndetectors = acq.instrument.detector.comm.allreduce(
        np.sum(acq.instrument.secondary_beam(theta, phi)))
    nsamplings = acq.sampling.comm.allreduce(len(acq.sampling))
    coverage *= ndetectors * nsamplings / np.sum(coverage)
    cov = coverage[coverage > 0]
    i = np.argsort(cov)
    cdf = np.cumsum(cov[i])
    j = np.argmax(cdf >= coverage_threshold * cdf[-1])
    threshold = cov[i[j]]
    mask = coverage >= threshold
    rejected = 1 - np.sum(mask) / cov.size
    if acq.comm.rank == 0 and coverage_threshold > 0:
        print('Total coverage:', cdf[-1])
        print('Threshold coverage set to:', threshold)
        print('Fraction of rejected observed pixels:', rejected)
    header = OrderedDict()
    coverage = coverage.view(ndarraywrap)
    coverage.header = header
    header['thresrel'] = coverage_threshold, 'Relative coverage threshold'
    header['thresabs'] = threshold, 'Absolute coverage threshold'
    header['fracrej'] = rejected, 'Fraction of rejected observed pixels'

    acq_restricted = acq[..., mask]
    H = acq_restricted.get_operator()
    invNtt = acq_restricted.get_invntt_operator()
    M = (H.T * H * np.ones(H.shapein))[..., 0]
    preconditioner = DiagonalOperator(1 / M, broadcast='rightward')
    #    preconditioner = DiagonalOperator(1/coverage[mask], broadcast='rightward')
    nsamplings = acq.comm.allreduce(len(acq.sampling))
    npixels = np.sum(mask)

    A = H.T * invNtt * H / nsamplings
    if hyper != 0:
        L = HealpixLaplacianOperator(acq.scene.nside)
        L = L.restrict(mask, inplace=True).corestrict(mask, inplace=True)
        A = A - hyper / npixels / 4e5 * L

    if criterion:

        def f(x):
            Hx_y = H(x)
            Hx_y -= tod
            out = [np.dot(Hx_y.ravel(), invNtt(Hx_y).ravel()) / nsamplings]
            if hyper != 0:
                out += [
                    -np.dot(x.ravel(), hyper / npixels / 4e5 * L(x).ravel())
                ]
            else:
                out += [0.]
            return out

        def callback(self):
            criteria = f(self.x)
            if len(criteria) == 1:
                details = ''
            else:
                fmt = ', '.join(len(criteria) * ['{:e}'])
                details = ' (' + fmt.format(*criteria) + ')'
            print('{:4}: {:e} {:e}{}'.format(self.niterations, self.error,
                                             sum(criteria), details))
            if not hasattr(self, 'history'):
                self.history = {}
                self.history['criterion'] = []
                self.history['error'] = []
                self.history['iteration'] = []
            self.history['criterion'].append(criteria)
            self.history['error'].append(self.error)
            self.history['iteration'].append(self.niterations)
            if save_map is not None and self.niterations in save_map:
                if not hasattr(self, 'xs'):
                    self.xs = {}
                self.xs[self.niterations] = self.x.copy()

    solution = pcg(A,
                   H.T(invNtt(tod)) / nsamplings,
                   M=preconditioner,
                   callback=callback,
                   disp=disp_pcg,
                   maxiter=maxiter,
                   tol=tol)
    output = acq_restricted.scene.unpack(solution['x']), coverage
    if full_output:
        algo = solution['algorithm']
        algo.H = H
        if criterion:
            pack = PackOperator(mask, broadcast='rightward')
            algo.f = asoperator(f, shapeout=2)(pack)
        output += (algo, )
    return output
Exemplo n.º 15
0
def cg(A,
       b,
       x0=None,
       tol=1.e-5,
       maxiter=300,
       M=None,
       disp=False,
       callback=None):
    """ OpenMPI/MPI hybrid conjugate gradient solver with preconditioning. """

    A = asoperator(A)
    comm = A.commin or MPI.COMM_WORLD

    if M is None:
        M = IdentityOperator()
    M = asoperator(M)

    maxRelError = tol**2

    shape = b.shape
    x = np.empty(shape)
    d = np.empty(shape)
    q = np.empty(shape)
    r = np.empty(shape)
    s = np.empty(shape)
    xfinal = np.zeros(shape)

    if x0 is None:
        x[...] = 0
    else:
        x[...] = x0

    norm = norm2(b, comm=comm)
    if norm == 0:
        return xfinal, 0

    r[...] = b
    r -= A(x)
    epsilon = norm2(r, comm=comm) / norm
    minEpsilon = epsilon

    M(r, d)
    delta0 = dot(r, d, comm=comm)
    deltaNew = delta0

    for iter_ in xrange(maxiter):
        if epsilon <= maxRelError:
            break

        A(d, q)

        alpha = deltaNew / dot(d, q, comm=comm)
        x += alpha * d
        r -= alpha * q
        epsilon = norm2(r, comm=comm) / norm
        if disp:
            print '{0:4}: {1}'.format(iter_ + 1, np.sqrt(epsilon))

        if callback is not None:
            resid = np.sqrt(epsilon)
            callback(x)

        if epsilon < minEpsilon:
            xfinal[...] = x
            minEpsilon = epsilon

        M(r, s)

        deltaOld = deltaNew

        deltaNew = dot(r, s, comm=comm)
        beta = deltaNew / deltaOld
        d *= beta
        d += s

    minEpsilon = np.sqrt(minEpsilon)
    maxRelError = np.sqrt(maxRelError)

    return xfinal.reshape(b.shape), int(minEpsilon > maxRelError)
Exemplo n.º 16
0
def _tod2map(acq, tod, coverage_threshold, max_nbytes, callback,
             disp_pcg, maxiter, tol, criterion, full_output, save_map, hyper):
    # coverage normalization:
    # sum coverage = #detectors x #samplings for a uniform secondary beam
    H = acq.get_operator()
    coverage = H.T(ones(H.shapeout))
    if acq.scene.kind == 'IQU':
        coverage = coverage[..., 0]
    elif acq.scene.kind == 'QU':
        raise NotImplementedError()
    theta, phi = acq.instrument.detector.theta, acq.instrument.detector.phi
    ndetectors = acq.instrument.detector.comm.allreduce(
        np.sum(acq.instrument.secondary_beam(theta, phi)))
    nsamplings = acq.sampling.comm.allreduce(len(acq.sampling))
    coverage *= ndetectors * nsamplings / np.sum(coverage)
    cov = coverage[coverage > 0]
    i = np.argsort(cov)
    cdf = np.cumsum(cov[i])
    j = np.argmax(cdf >= coverage_threshold * cdf[-1])
    threshold = cov[i[j]]
    mask = coverage >= threshold
    rejected = 1 - np.sum(mask) / cov.size
    if acq.comm.rank == 0 and coverage_threshold > 0:
        print('Total coverage:', cdf[-1])
        print('Threshold coverage set to:', threshold)
        print('Fraction of rejected observed pixels:', rejected)
    header = OrderedDict()
    coverage = coverage.view(ndarraywrap)
    coverage.header = header
    header['thresrel'] = coverage_threshold, 'Relative coverage threshold'
    header['thresabs'] = threshold, 'Absolute coverage threshold'
    header['fracrej'] = rejected, 'Fraction of rejected observed pixels'

    acq_restricted = acq[..., mask]
    H = acq_restricted.get_operator()
    invNtt = acq_restricted.get_invntt_operator()
    M = (H.T * H * np.ones(H.shapein))[..., 0]
    preconditioner = DiagonalOperator(1/M, broadcast='rightward')
#    preconditioner = DiagonalOperator(1/coverage[mask], broadcast='rightward')
    nsamplings = acq.comm.allreduce(len(acq.sampling))
    npixels = np.sum(mask)

    A = H.T * invNtt * H / nsamplings
    if hyper != 0:
        L = HealpixLaplacianOperator(acq.scene.nside)
        L = L.restrict(mask, inplace=True).corestrict(mask, inplace=True)
        A = A - hyper / npixels / 4e5 * L

    if criterion:
        def f(x):
            Hx_y = H(x)
            Hx_y -= tod
            out = [np.dot(Hx_y.ravel(), invNtt(Hx_y).ravel()) / nsamplings]
            if hyper != 0:
                out += [-np.dot(x.ravel(),
                                hyper / npixels / 4e5 * L(x).ravel())]
            else:
                out += [0.]
            return out

        def callback(self):
            criteria = f(self.x)
            if len(criteria) == 1:
                details = ''
            else:
                fmt = ', '.join(len(criteria) * ['{:e}'])
                details = ' (' + fmt.format(*criteria) + ')'
            print('{:4}: {:e} {:e}{}'.format(self.niterations, self.error,
                                             sum(criteria), details))
            if not hasattr(self, 'history'):
                self.history = {}
                self.history['criterion'] = []
                self.history['error'] = []
                self.history['iteration'] = []
            self.history['criterion'].append(criteria)
            self.history['error'].append(self.error)
            self.history['iteration'].append(self.niterations)
            if save_map is not None and self.niterations in save_map:
                if not hasattr(self, 'xs'):
                    self.xs = {}
                self.xs[self.niterations] = self.x.copy()

    solution = pcg(A, H.T(invNtt(tod)) / nsamplings, M=preconditioner,
                   callback=callback, disp=disp_pcg, maxiter=maxiter, tol=tol)
    output = acq_restricted.scene.unpack(solution['x']), coverage
    if full_output:
        algo = solution['algorithm']
        algo.H = H
        if criterion:
            pack = PackOperator(mask, broadcast='rightward')
            algo.f = asoperator(f, shapeout=2)(pack)
        output += (algo,)
    return output