Beispiel #1
0
def distribute_observation(detectors, observations, rank=None,
                           comm=MPI.COMM_WORLD):
    
    size  = comm.Get_size()
    if size == 1:
        return detectors.copy(), list(observations)

    if rank is None:
        rank = comm.Get_rank()
    nthreads = openmp_num_threads()
    ndetectors = np.sum(~detectors)
    nobservations = len(observations)

    # number of observations. They should approximatively be of the same length
    nx = nobservations

    # number of detectors, grouped by the number of cpu cores
    ny = int(np.ceil(ndetectors / nthreads))

    # we start with the minimum blocksize and increase it until we find a
    # configuration that covers all the observations
    blocksize = int(np.ceil(nx * ny / size))
    while True:
        # by looping over x first, we favor larger numbers of detectors and
        # fewer numbers of observations per processor, to minimise inter-
        # processor communication in case of correlations between
        # detectors
        for xblocksize in range(1, blocksize+1):
            if blocksize / xblocksize != blocksize // xblocksize:
                continue
            yblocksize = int(blocksize // xblocksize)
            nx_block = int(np.ceil(nx / xblocksize))
            ny_block = int(np.ceil(ny / yblocksize))
            if nx_block * ny_block <= size:
                break
        if nx_block * ny_block <= size:
            break
        blocksize += 1

    ix = rank // ny_block
    iy = rank %  ny_block

    # check that the processor has something to do
    if ix >= nx_block:
        idetector = slice(0,0)
        iobservation = slice(0,0)
    else:
        idetector    = slice(iy * yblocksize * nthreads, (iy+1) * yblocksize * \
                             nthreads)
        iobservation = slice(ix * xblocksize, (ix+1) * xblocksize)

    detectors_ = detectors.copy()
    igood = np.where(~detectors_.ravel())[0]
    detectors_.ravel()[igood[0:idetector.start]] = True
    detectors_.ravel()[igood[idetector.stop:]] = True
    observations_ = observations[iobservation]

    return detectors_, observations_
Beispiel #2
0
    def get_projection_operator(self, sampling, scene, i_band=None, verbose=True):
        """
        Return the peak sampling operator.

        Parameters
        ----------
        sampling : QubicSampling
            The pointing information.
        scene : QubicScene
            The observed scene.
        verbose : bool, optional
            If true, display information about the memory allocation.

        """
        if not isinstance(scene.nu, float) and i_band == None:
            mask = [self.detector.index < 2295//2,
                    self.detector.index > 2295//2]
            dtype = self.synthetic_beam.dtype
            if scene.nside > 8192:
                dtype_index = np.dtype(np.int64)
            else:
                dtype_index = np.dtype(np.int32)
            theta0, phi, vals = _peak_angles_fraction(self, scene, self.synthetic_beam.fraction, 0)
            theta1, phi, vals = _peak_angles_fraction(self, scene, self.synthetic_beam.fraction, 1)
            ncolmax = max(theta0.shape[-1], theta1.shape[-1])

            cls = {'I'  : FSRMatrix,
                   'QU' : FSRRotation2dMatrix,
                   'IQU': FSRRotation3dMatrix}[scene.kind]
            ndims = len(scene.kind)
            s = cls((len(self) * len(sampling) * ndims, 12 * scene.nside**2 * ndims),
                    ncolmax=ncolmax, 
                    dtype=dtype,
                    dtype_index=dtype_index,
                    verbose=verbose)
            for i in [0, 1]:
                focal_plane = self[mask[i]]
                p = focal_plane.get_projection_operator(sampling, scene, i_band=i)
                smask = np.multiply.outer(mask[i], np.ones(len(sampling)), dtype=bool)
                smask = np.asarray(smask).reshape(-1)
                s.data[smask, :p.matrix.data.shape[-1]] = p.matrix.data
#                set_trace()
#                sh = s.data[mask[i], p.matrix.data.shape[-1]:].shape
#                tp = {'I'   : "int, float",
#                      'IQ'  : "int, float, float",
#                      'IQU' : "int, float, float, float"}[scene.kind]
#                s.data[mask[i], p.matrix.data.shape[-1]:] = np.ones(sh, dtype=tp) 
            shapeout = {'I'   : (len(self), len(sampling)),
                        'IQ'  : (len(self), len(sampling), 2),
                        'IQU' : (len(self), len(sampling), 3)}[scene.kind]
            return ProjectionOperator(s, shapeout=shapeout)
        else:
            rotation = sampling.cartesian_galactic2instrument
            dtype = self.synthetic_beam.dtype
            fraction = self.synthetic_beam.fraction
            ndetectors = len(self)
            ntimes = len(sampling)
            nside = scene.nside

            theta, phi, vals = _peak_angles_fraction(self, scene, fraction, i_band)
            ncolmax = theta.shape[-1]
            thetaphi = _pack_vector(theta, phi)  # (ndetectors, ncolmax, 2)
            direction = Spherical2CartesianOperator('zenith,azimuth')(thetaphi)
            e_nf = direction[:, None, :, :]
            if nside > 8192:
                dtype_index = np.dtype(np.int64)
            else:
                dtype_index = np.dtype(np.int32)

            cls = {'I': FSRMatrix,
                'QU': FSRRotation2dMatrix,
                'IQU': FSRRotation3dMatrix}[scene.kind]
            ndims = len(scene.kind)
            s = cls((ndetectors * ntimes * ndims, 12 * nside**2 * ndims),
                    ncolmax=ncolmax, dtype=dtype, dtype_index=dtype_index,
                    verbose=verbose)

            index = s.data.index.reshape((ndetectors, ntimes, ncolmax))

            nthreads = openmp_num_threads()
            try:
                import mkl
                mkl.set_num_threads(1)
            except:
                pass

            def func_thread(i):
                # e_nf[i] shape: (1, ncolmax, 3)
                # e_ni shape: (ntimes, ncolmax, 3)
                e_ni = rotation.T(e_nf[i].swapaxes(0, 1)).swapaxes(0, 1)
                index[i] = Cartesian2HealpixOperator(nside)(e_ni)

            pool = Pool(nthreads)
            pool.map(func_thread, xrange(ndetectors))
            pool.close()
            pool.join()

            try:
                mkl.set_num_threads(nthreads)
            except:
                pass

            if scene.kind == 'I':
                value = s.data.value.reshape(ndetectors, ntimes, ncolmax)
                value[...] = vals[:, None, :]
                shapeout = (ndetectors, ntimes)
            else:
                func = 'pointing_matrix_rot{0}d_i{1}_m{2}'.format(
                    ndims, dtype_index.itemsize, dtype.itemsize)
                try:
                    getattr(flib.polarization, func)(
                        rotation.data.T, direction.T, s.data.ravel().view(np.int8),
                        vals.T)
                except AttributeError:
                    raise TypeError(
                        'The projection matrix cannot be created with types: {0} a'
                        'nd {1}.'.format(dtype, dtype_index))
                if scene.kind == 'QU':
                    shapeout = (ndetectors, ntimes, 2)
                else:
                    shapeout = (ndetectors, ntimes, 3)

            return ProjectionOperator(s, shapeout=shapeout)
                               product)
from pyoperators.utils.mpi import MPI, distribute_shape, distribute_shapes
from pysimulators import Map
from pysimulators.acquisitionmodels import (block_diagonal, PointingMatrix,
         ProjectionInMemoryOperator, ProjectionOnFlyOperator)
from pysimulators.wcsutils import fitsheader2shape, str2fitsheader

from . import tamasisfortran as tmf
from . import var
from .utils import diff, diffT, diffTdiff, shift
from .mpiutils import gather_fitsheader_if_needed, scatter_fitsheader

try:
    import fftw3
    MAX_FFTW_NUM_THREADS = 1 if fftw3.planning.lib_threads is None \
        else openmp_num_threads()
except ImportError:
    print('Warning: Library PyFFTW3 is not installed.')
except:
    print('Warning: Problem loading PyFFTW3.')

__all__ = [
    'CompressionAverage', # obsolete
    'CompressionAverageOperator',
    'MPIDistributionLocalOperator',
    'DdTdd', # Obsolete
    'DdTddOperator',
    'DiscreteDifference', # obsolete
    'DiscreteDifferenceOperator',
    'DownSamplingOperator',
    'FftHalfComplexOperator',