Ejemplo n.º 1
0
    def test_el_steps(self):

        scs = ScanStrategy(duration=200)
        scs.set_el_steps(10, steps=np.arange(5))

        nsteps = int(np.ceil(scs.mlen / float(scs.step_dict['period'])))
        self.assertEqual(nsteps, 20)

        for step in range(12):
            el = next(scs.el_step_gen)
            scs.step_dict['step'] = el
            self.assertEqual(el, step % 5)

        self.assertEqual(scs.step_dict['step'], el)
        scs.step_dict['remainder'] = 100
        scs.reset_el_steps()
        self.assertEqual(scs.step_dict['step'], 0)
        self.assertEqual(scs.step_dict['remainder'], 0)

        for step in range(nsteps):
            el = next(scs.el_step_gen)
            self.assertEqual(el, step % 5)

        scs.reset_el_steps()
        self.assertEqual(next(scs.el_step_gen), 0)
        self.assertEqual(next(scs.el_step_gen), 1)
Ejemplo n.º 2
0
    def test_init_detpair2(self):
        '''
        Check if function works with only A beam.
        '''
        
        mmax = 3
        nside = 16
        scs = ScanStrategy()
        
        beam_a = Beam(fwhm=0., btype='Gaussian', mmax=mmax)
        beam_b = None

        init_spinmaps_opts = dict(max_spin=5, nside_spin=nside,
                                  verbose=False)

        scs.init_detpair(self.alm, beam_a, beam_b=beam_b,
                         **init_spinmaps_opts)

        # Test for correct shapes.
        # Note empty lists evaluate to False
        self.assertFalse(scs.spinmaps['ghosts'])
        
        func, func_c = scs.spinmaps['main_beam']['maps']
        self.assertEqual(func.shape, (mmax + 1, 12 * nside ** 2))
        self.assertEqual(func_c.shape, (2 * mmax + 1, 12 * nside ** 2))
Ejemplo n.º 3
0
    def test_init_spinmaps_old_new(self):

        # Test if spinmaps with are consistent between old and new
        # implementation of HWP.

        def rand_alm(lmax):
            alm = np.empty(hp.Alm.getsize(lmax), dtype=np.complex128)
            alm[:] = np.random.randn(hp.Alm.getsize(lmax))
            alm += 1j * np.random.randn(hp.Alm.getsize(lmax))
            # Make m=0 modes real.
            alm[:lmax+1] = np.real(alm[:lmax+1])
            return alm

        lmax = 4
        alm = tuple([rand_alm(lmax) for i in range(3)])

        blmI = np.array([0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                        dtype=np.complex128)
        blmm2 = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
                         dtype=np.complex128)
        blmp2 = np.zeros_like(blmm2)
        blm = (blmI, blmm2, blmp2)
        nside = 32
        max_spin = 3

        spinmaps_old = ScanStrategy._init_spinmaps(alm, blm, max_spin, nside,
                                            symmetric=False, hwp_mueller=None)

        hwp_mueller = np.asarray([[1, 0, 0, 0],
                                  [0, 1, 0, 0],
                                  [0, 0, -1, 0],
                                  [0, 0, 0, -1]])
        spinmaps_new = ScanStrategy._init_spinmaps(alm, blm, max_spin, nside,
                                     symmetric=False, hwp_mueller=hwp_mueller)

        np.testing.assert_almost_equal(spinmaps_old['s0a0']['maps'],
                                       spinmaps_new['s0a0']['maps'])
        
        zero_map = np.zeros(hp.nside2npix(nside))
        np.testing.assert_almost_equal(spinmaps_old['s2a4']['maps'][0], zero_map)
        np.testing.assert_almost_equal(spinmaps_old['s2a4']['maps'][1], zero_map)
        np.testing.assert_almost_equal(spinmaps_old['s2a4']['maps'][2], zero_map)
        np.testing.assert_almost_equal(spinmaps_old['s2a4']['maps'][3], zero_map)
        np.testing.assert_almost_equal(spinmaps_old['s2a4']['maps'][4], zero_map)        
        np.testing.assert_almost_equal(spinmaps_old['s2a4']['maps'][6], zero_map)        

        np.testing.assert_almost_equal(spinmaps_new['s2a4']['maps'][0], zero_map)
        np.testing.assert_almost_equal(spinmaps_new['s2a4']['maps'][1], zero_map)        
        np.testing.assert_almost_equal(spinmaps_new['s2a4']['maps'][2], zero_map)
        np.testing.assert_almost_equal(spinmaps_new['s2a4']['maps'][3], zero_map)
        np.testing.assert_almost_equal(spinmaps_new['s2a4']['maps'][4], zero_map)
        np.testing.assert_almost_equal(spinmaps_new['s2a4']['maps'][6], zero_map)        
        
        np.testing.assert_almost_equal(spinmaps_old['s2a4']['maps'][5],
                                       spinmaps_new['s2a4']['maps'][5])
Ejemplo n.º 4
0
    def test_init_detpair(self):
        '''
        Check if spinmaps are correctly created.
        '''

        mmax = 3
        nside = 16
        scs = ScanStrategy(duration=1, sample_rate=10)

        beam_a = Beam(fwhm=0., btype='Gaussian', mmax=mmax)
        beam_b = Beam(fwhm=0., btype='Gaussian', mmax=mmax)

        init_spinmaps_opts = dict(max_spin=5, nside_spin=nside)

        scs.init_detpair(self.alm, beam_a, beam_b=beam_b,
                         **init_spinmaps_opts)

        # We expect a spinmaps attribute (dict) with
        # main_beam key that contains a list of [func, func_c]
        # where func has shape (mmax + 1, 12nside**2) and
        # func_c has shape (2 mmax + 1, 12nside**2).
        # We expect an empty list for the ghosts.

        # Note empty lists evaluate to False
        self.assertFalse(scs.spinmaps['ghosts'])

        func = scs.spinmaps['main_beam']['s0a0']['maps']
        func_c = scs.spinmaps['main_beam']['s2a4']['maps']
        self.assertEqual(func.shape, (mmax + 1, 12 * nside ** 2))
        self.assertEqual(func_c.shape, (2 * mmax + 1, 12 * nside ** 2))

        # Since we have a infinitely narrow Gaussian the convolved
        # maps should just match the input (up to healpix quadrature
        # wonkyness).
        input_map = hp.alm2map(self.alm, nside, verbose=False) # I, Q, U
        zero_map = np.zeros_like(input_map[0])
        np.testing.assert_array_almost_equal(input_map[0],
                                             func[0], decimal=6)
        # s = 2 Pol map should be Q \pm i U
        np.testing.assert_array_almost_equal(input_map[1] + 1j * input_map[2],
                                             func_c[mmax + 2], decimal=6)

        # Test if rest of maps are zero.
        for i in range(1, mmax + 1):
            np.testing.assert_array_almost_equal(zero_map,
                                                 func[i], decimal=6)

        for i in range(1, 2 * mmax + 1):
            if i == mmax + 2:
                continue
            print(i)
            np.testing.assert_array_almost_equal(zero_map,
                                                 func_c[i], decimal=6)
Ejemplo n.º 5
0
    def test_spinmaps_complex(self):

        # Test if spinmaps_complex returns to spinmaps_real
        # in case where sky and beam B-modes are zero.

        def rand_alm(lmax):
            alm = np.empty(hp.Alm.getsize(lmax), dtype=np.complex128)
            alm[:] = np.random.randn(hp.Alm.getsize(lmax))
            alm += 1j * np.random.randn(hp.Alm.getsize(lmax))
            # Make m=0 modes real.
            alm[:lmax+1] = np.real(alm[:lmax+1])
            return alm

        lmax = 10
        almE, almB = tuple([rand_alm(lmax) for i in range(2)])
        blmE, blmB = tuple([rand_alm(lmax) for i in range(2)])
        spin_values = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
        nside = 32

        spinmaps = ScanStrategy._spinmaps_complex(almE, almB*0, blmE, blmB*0,
                                                spin_values, nside)

        for spin in range(6):
            sidx_pos = spin + 5
            sidx_neg = 5 - spin
            np.testing.assert_almost_equal(spinmaps[sidx_pos],
                                   np.conj(spinmaps[sidx_neg]))
Ejemplo n.º 6
0
    def test_init_no_sample_rate(self):

        # Test if we can also init without specifying mlen.
        scs = ScanStrategy(duration=5, num_samples=100)

        #  nsamp = mlen * sample_rate
        self.assertEqual(scs.mlen, 5)
        self.assertEqual(scs.fsamp, 20)
        self.assertEqual(scs.nsamp, 100)
Ejemplo n.º 7
0
    def test_init_zero_duration(self):

        # Sample rate should be zero
        scs = ScanStrategy(duration=0, sample_rate=10)

        #  nsamp = mlen * sample_rate
        self.assertEqual(scs.mlen, 0)
        self.assertEqual(scs.fsamp, 0)
        self.assertEqual(scs.nsamp, 0)
Ejemplo n.º 8
0
    def test_init(self):

        scs = ScanStrategy(duration=200, sample_rate=10)
        self.assertEqual(scs.mlen, 200)
        self.assertEqual(scs.fsamp, 10.)
        self.assertEqual(scs.nsamp, 2000)

        self.assertRaises(AttributeError, setattr, scs, 'fsamp', 1)
        self.assertRaises(AttributeError, setattr, scs, 'mlen', 1)
        self.assertRaises(AttributeError, setattr, scs, 'nsamp', 1)
Ejemplo n.º 9
0
    def test_init(self):

        scs = ScanStrategy(duration=200, sample_rate=10)
        self.assertEqual(scs.mlen, 200)
        self.assertEqual(scs.fsamp, 10.)
        self.assertEqual(scs.nsamp, 2000)

        # Test if we are unable to change scan parameters after init.
        self.assertRaises(AttributeError, setattr, scs, 'fsamp', 1)
        self.assertRaises(AttributeError, setattr, scs, 'mlen', 1)
        self.assertRaises(AttributeError, setattr, scs, 'nsamp', 1)
Ejemplo n.º 10
0
    def test_chunks(self):
        '''Test the _chunk2idx function. '''

        mlen = 100  # so 1000 samples
        chunksize = 30
        rot_period = 1.2  # Note, seconds.
        scs = ScanStrategy(duration=mlen, sample_rate=10)

        scs.partition_mission(chunksize=chunksize)

        self.assertEqual(len(scs.chunks),
                         int(np.ceil(scs.nsamp / float(chunksize))))

        # Take single chunk and subdivide it and check whether we
        # can correctly access a chunk-sized array.
        scs.set_instr_rot(period=rot_period)

        for chunk in scs.chunks:

            scs.rotate_instr()
            subchunks = scs.subpart_chunk(chunk)

            chunklen = chunk['end'] - chunk['start']

            # Start with zero array, let every subchunk add ones
            # to its slice, then test if resulting array is one
            # everywhere.
            arr = np.zeros(chunklen, dtype=int)

            for subchunk in subchunks:

                self.assertEqual(subchunk['cidx'], chunk['cidx'])
                self.assertTrue(subchunk['start'] >= chunk['start'])
                self.assertTrue(subchunk['end'] <= chunk['end'])

                qidx_start, qidx_end = scs._chunk2idx(**subchunk)

                arr[qidx_start:qidx_end] += 1

            np.testing.assert_array_equal(arr, np.ones_like(arr))
Ejemplo n.º 11
0
    def test_interpolate(self):
        '''
        Compare interpoted TOD to raw for extremely bandlimited 
        input such that should agree relatively well.
        '''

        mlen = 60
        mmax = 2
        ra0 = -10
        dec0 = -57.5
        fwhm = 100
        nside = 128
        az_throw = 10

        scs = ScanStrategy(duration=mlen, sample_rate=10, location='spole')

        # Create a 1 x 1 square grid of Gaussian beams.
        scs.create_focal_plane(nrow=1,
                               ncol=1,
                               fov=4,
                               lmax=self.lmax,
                               fwhm=fwhm)

        # Generate timestreams, bin them and store as attributes.
        scs.scan_instrument_mpi(self.alm,
                                verbose=0,
                                ra0=ra0,
                                dec0=dec0,
                                az_throw=az_throw,
                                scan_speed=2.,
                                nside_spin=nside,
                                max_spin=mmax,
                                binning=False)

        tod_raw = scs.tod.copy()

        scs.scan_instrument_mpi(self.alm,
                                verbose=0,
                                ra0=ra0,
                                dec0=dec0,
                                az_throw=az_throw,
                                scan_speed=2.,
                                nside_spin=nside,
                                max_spin=mmax,
                                reuse_spinmaps=False,
                                interp=True,
                                binning=False)

        np.testing.assert_array_almost_equal(tod_raw, scs.tod, decimal=0)
Ejemplo n.º 12
0
    def test_preview_pointing_input(self):

        # Test if scan_instrument_mpi works with preview_pointing
        # option set.

        scs = ScanStrategy(duration=1, sample_rate=10, location='spole')

        # Should raise error if alm is None with preview_pointing not set.
        alm = None
        with self.assertRaises(TypeError):
            scs.scan_instrument_mpi(alm, verbose=0,
                                    preview_pointing=False)

        # Should not raise error if alm is provided and preview_pointing set.
        alm = self.alm
        scs.scan_instrument_mpi(alm, verbose=0,
                                preview_pointing=True)
Ejemplo n.º 13
0
    def test_init_err(self):

        # Test if init raises erorrs when user does not
        # provide enough info.
        with self.assertRaises(ValueError):
            ScanStrategy(duration=5)
        with self.assertRaises(ValueError):
            ScanStrategy(num_samples=5)
        with self.assertRaises(ValueError):
            ScanStrategy(sample_rate=5)

        # Or if nsamp = mlen * sample_rate is not satisfied.
        with self.assertRaises(ValueError):
            ScanStrategy(duration=10, sample_rate=20, num_samples=100)

        # Or when sample_rate is zero or negative.
        with self.assertRaises(ValueError):
            ScanStrategy(sample_rate=0, duration=10)

        with self.assertRaises(ValueError):
            ScanStrategy(sample_rate=-2, duration=10)
Ejemplo n.º 14
0
    def test_scan_ghosts_map(self):
        '''
        Perform a (low resolution) scan with two detectors, 
        compare map to detector + ghost.
        '''

        mlen = 10 * 60
        rot_period = 120
        mmax = 2
        ra0 = -10
        dec0 = -57.5
        fwhm = 200
        nside = 256
        az_throw = 10

        scs = ScanStrategy(duration=mlen, sample_rate=10, location='spole')

        # Create two Gaussian (main) beams.
        beam_opts = dict(az=0,
                         el=0,
                         polang=28,
                         fwhm=fwhm,
                         lmax=self.lmax,
                         symmetric=True)
        ghost_opts = dict(az=0,
                          el=0,
                          polang=28,
                          fwhm=fwhm,
                          lmax=self.lmax,
                          symmetric=True,
                          amplitude=1)

        scs.add_to_focal_plane(Beam(**beam_opts))
        scs.add_to_focal_plane(Beam(**ghost_opts))

        # Allocate and assign parameters for mapmaking.
        scs.allocate_maps(nside=nside)

        # Set HWP rotation.
        scs.set_hwp_mod(mode='continuous', freq=3.)

        # Generate timestreams, bin them and store as attributes.
        scs.scan_instrument_mpi(self.alm,
                                verbose=0,
                                ra0=ra0,
                                dec0=dec0,
                                az_throw=az_throw,
                                scan_speed=2.,
                                binning=False,
                                nside_spin=nside,
                                max_spin=mmax,
                                save_tod=True)

        tod = scs.data(scs.chunks[0], beam=scs.beams[0][0], data_type='tod')
        tod += scs.data(scs.chunks[0], beam=scs.beams[1][0], data_type='tod')
        tod = tod.copy()

        # Solve for the maps.
        maps, cond = scs.solve_for_map(fill=np.nan)

        # To supress warnings
        cond[~np.isfinite(cond)] = 10

        # Repeat with single beam + ghost.
        scs.remove_from_focal_plane(scs.beams[1][0])
        scs.beams[0][0].create_ghost(**ghost_opts)

        scs.reset_hwp_mod()

        scs.scan_instrument_mpi(self.alm,
                                verbose=0,
                                ra0=ra0,
                                dec0=dec0,
                                az_throw=az_throw,
                                scan_speed=2.,
                                binning=False,
                                nside_spin=nside,
                                max_spin=mmax,
                                save_tod=True)

        tod_w_ghost = scs.data(scs.chunks[0],
                               beam=scs.beams[0][0],
                               data_type='tod')

        # Sum TOD of two beams must match TOD of single beam + ghost.
        np.testing.assert_array_almost_equal(tod, tod_w_ghost, decimal=10)

        # Maps must match.
        maps_w_ghost, cond_w_ghost = scs.solve_for_map(fill=np.nan)

        # To supress warnings
        cond_w_ghost[~np.isfinite(cond_w_ghost)] = 10

        np.testing.assert_array_almost_equal(maps[0, cond < 2.5],
                                             maps_w_ghost[0,
                                                          cond_w_ghost < 2.5],
                                             decimal=10)

        np.testing.assert_array_almost_equal(maps[1, cond < 2.5],
                                             maps_w_ghost[1,
                                                          cond_w_ghost < 2.5],
                                             decimal=10)

        np.testing.assert_array_almost_equal(maps[2, cond < 2.5],
                                             maps_w_ghost[2,
                                                          cond_w_ghost < 2.5],
                                             decimal=10)
Ejemplo n.º 15
0
    def test_scan_spole_hwp_mueller(self):
        '''
        Perform a (low resolution) scan with a HWP mueller matrix 
        specified and see if TOD make sense.
        '''

        mlen = 10 * 60
        rot_period = 120
        mmax = 2
        ra0=-10
        dec0=-57.5
        fwhm = 200
        nside = 128
        az_throw = 10
        polang = 20.

        ces_opts = dict(ra0=ra0, dec0=dec0, az_throw=az_throw,
                        scan_speed=2.)

        scs = ScanStrategy(duration=mlen, sample_rate=10, location='spole')

        # Create a 1 x 1 square grid of Gaussian beams.
        scs.create_focal_plane(nrow=1, ncol=1, fov=4,
                               lmax=self.lmax, fwhm=fwhm,
                               polang=polang)
        beam = scs.beams[0][0]
        hwp_mueller = np.asarray([[1, 0, 0, 0],
                                  [0, 1, 0, 0],
                                  [0, 0, -1, 0],
                                  [0, 0, 0, -1]])
        beam.hwp_mueller = hwp_mueller
        scs.init_detpair(self.alm, beam, nside_spin=nside,
                                   max_spin=mmax)
        scs.partition_mission()

        chunk = scs.chunks[0]
        ces_opts.update(chunk)

        # Populate boresight.
        scs.constant_el_scan(**ces_opts)

        # Turn on HWP
        scs.set_hwp_mod(mode='continuous', freq=1., start_ang=0)
        scs.rotate_hwp(**chunk)
        tod, pix, nside_out, pa, hwp_ang = scs.scan(beam,
                        return_tod=True, return_point=True, **chunk)

        # Construct TOD manually.
        polang = beam.polang
        maps_sm = np.asarray(hp.alm2map(self.alm, nside, verbose=False,
                                        fwhm=np.radians(beam.fwhm / 60.)))

        np.testing.assert_almost_equal(maps_sm[0],
                                       scs.spinmaps['main_beam']['s0a0']['maps'][0])
        q = np.real(scs.spinmaps['main_beam']['s2a4']['maps'][mmax + 2])
        u = np.imag(scs.spinmaps['main_beam']['s2a4']['maps'][mmax + 2])
        np.testing.assert_almost_equal(maps_sm[1], q)
        np.testing.assert_almost_equal(maps_sm[2], u)

        tod_man = maps_sm[0][pix]
        tod_man += (maps_sm[1][pix] \
                    * np.cos(2 * np.radians(pa - polang - 2 * hwp_ang)))
        tod_man += (maps_sm[2][pix] \
                    * np.sin(2 * np.radians(pa - polang - 2 * hwp_ang)))

        np.testing.assert_almost_equal(tod, tod_man)
Ejemplo n.º 16
0
    def test_scan_spole_bin(self):
        '''
        Perform a (low resolution) scan, bin and compare
        to input.
        '''

        mlen = 10 * 60
        rot_period = 120
        mmax = 2
        ra0 = -10
        dec0 = -57.5
        fwhm = 200
        nside = 256
        az_throw = 10

        scs = ScanStrategy(duration=mlen, sample_rate=10, location='spole')

        # Create a 1 x 2 square grid of Gaussian beams.
        scs.create_focal_plane(nrow=1,
                               ncol=2,
                               fov=4,
                               lmax=self.lmax,
                               fwhm=fwhm)

        # Allocate and assign parameters for mapmaking.
        scs.allocate_maps(nside=nside)

        # set instrument rotation.
        scs.set_instr_rot(period=rot_period, angles=[68, 113, 248, 293])

        # Set elevation stepping.
        scs.set_el_steps(rot_period, steps=[0, 2, 4])

        # Set HWP rotation.
        scs.set_hwp_mod(mode='continuous', freq=3.)

        # Generate timestreams, bin them and store as attributes.
        scs.scan_instrument_mpi(self.alm,
                                verbose=0,
                                ra0=ra0,
                                dec0=dec0,
                                az_throw=az_throw,
                                scan_speed=2.,
                                nside_spin=nside,
                                max_spin=mmax)

        # Solve for the maps.
        maps, cond = scs.solve_for_map(fill=np.nan)

        alm = hp.smoothalm(self.alm,
                           fwhm=np.radians(fwhm / 60.),
                           verbose=False)
        maps_raw = np.asarray(hp.alm2map(self.alm, nside, verbose=False))

        cond[~np.isfinite(cond)] = 10

        np.testing.assert_array_almost_equal(maps_raw[0, cond < 2.5],
                                             maps[0, cond < 2.5],
                                             decimal=10)

        np.testing.assert_array_almost_equal(maps_raw[1, cond < 2.5],
                                             maps[1, cond < 2.5],
                                             decimal=10)

        np.testing.assert_array_almost_equal(maps_raw[2, cond < 2.5],
                                             maps[2, cond < 2.5],
                                             decimal=10)
Ejemplo n.º 17
0
    def test_scan_spole(self):
        '''
        Perform a (low resolution) scan and see if TOD make sense.
        '''

        mlen = 10 * 60
        rot_period = 120
        mmax = 2
        ra0 = -10
        dec0 = -57.5
        fwhm = 200
        nside = 256
        az_throw = 10
        polang = 20.

        ces_opts = dict(ra0=ra0, dec0=dec0, az_throw=az_throw, scan_speed=2.)

        scs = ScanStrategy(duration=mlen, sample_rate=10, location='spole')

        # Create a 1 x 1 square grid of Gaussian beams.
        scs.create_focal_plane(nrow=1,
                               ncol=1,
                               fov=4,
                               lmax=self.lmax,
                               fwhm=fwhm,
                               polang=polang)
        beam = scs.beams[0][0]
        scs.init_detpair(self.alm, beam, nside_spin=nside, max_spin=mmax)
        scs.partition_mission()

        chunk = scs.chunks[0]
        ces_opts.update(chunk)

        # Populate boresight.
        scs.constant_el_scan(**ces_opts)

        # Test without returning anything (default behaviour).
        scs.scan(beam, **chunk)

        tod = scs.scan(beam, return_tod=True, **chunk)
        self.assertEqual(tod.size, chunk['end'] - chunk['start'])

        pix, nside_out, pa, hwp_ang = scs.scan(beam,
                                               return_point=True,
                                               **chunk)
        self.assertEqual(pix.size, tod.size)
        self.assertEqual(nside, nside_out)
        self.assertEqual(pa.size, tod.size)
        self.assertEqual(hwp_ang, 0)

        # Turn on HWP
        scs.set_hwp_mod(mode='continuous', freq=1., start_ang=0)
        scs.rotate_hwp(**chunk)
        tod2, pix2, nside_out2, pa2, hwp_ang2 = scs.scan(beam,
                                                         return_tod=True,
                                                         return_point=True,
                                                         **chunk)
        np.testing.assert_almost_equal(pix, pix2)
        np.testing.assert_almost_equal(pix, pix2)
        np.testing.assert_almost_equal(pa, pa2)
        self.assertTrue(np.any(np.not_equal(tod, tod2)), True)
        self.assertEqual(nside_out, nside_out2)
        self.assertEqual(hwp_ang2.size, tod.size)

        # Construct TOD manually.
        polang = beam.polang
        maps_sm = np.asarray(
            hp.alm2map(self.alm,
                       nside,
                       verbose=False,
                       fwhm=np.radians(beam.fwhm / 60.)))

        np.testing.assert_almost_equal(maps_sm[0],
                                       scs.spinmaps['main_beam']['maps'][0][0])
        q = np.real(scs.spinmaps['main_beam']['maps'][1][mmax + 2])
        u = np.imag(scs.spinmaps['main_beam']['maps'][1][mmax + 2])
        np.testing.assert_almost_equal(maps_sm[1], q)
        np.testing.assert_almost_equal(maps_sm[2], u)

        tod_man = maps_sm[0][pix]
        tod_man += (maps_sm[1][pix] \
                    * np.cos(-2 * np.radians(pa + polang + 2 * hwp_ang2)))
        tod_man += (maps_sm[2][pix] \
                    * np.sin(-2 * np.radians(pa + polang + 2 * hwp_ang2)))

        np.testing.assert_almost_equal(tod2, tod_man)
Ejemplo n.º 18
0
def single_detector(nsamp=1000,
                    lmax=700,
                    fwhm=30.,
                    ra0=-10,
                    dec0=-57.5,
                    az_throw=50,
                    scan_speed=2.8,
                    rot_period=4.5 * 60 * 60,
                    mmax=5,
                    nside_spin=512):
    '''
    Generates a timeline for a set of individual detectors scanning the sky. The
    spatial response of these detectors is described by a 1) Gaussian, 2) an
    elliptical Gaussian and, 3) a beam map derived by physical optics.

    Arguments
    ---------

    nsamp : int (default : 1000)
        The length of the generated timestreams in number of samples

    '''

    # Load up alm
    ell, cls = get_cls()
    np.random.seed(39)
    alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True)  # uK

    # create Beam properties and pickle (this is just to test load_focal_plane)
    import tempfile
    import shutil
    import pickle
    opj = os.path.join

    blm_dir = os.path.abspath(
        opj(os.path.dirname(__file__), '../tests/test_data/example_blms'))
    po_file = opj(blm_dir, 'blm_hp_X1T1R1C8A_800_800.npy')
    eg_file = opj(blm_dir, 'blm_hp_eg_X1T1R1C8A_800_800.npy')

    tmp_dir = tempfile.mkdtemp()

    beam_file = opj(tmp_dir, 'beam_opts.pkl')
    beam_opts = dict(
        az=0,
        el=0,
        polang=0.,
        btype='Gaussian',
        name='X1T1R1C8',
        fwhm=32.2,
        lmax=800,
        mmax=800,
        amplitude=1.,
        po_file=po_file,
        eg_file=eg_file,
        deconv_q=True,  # blm are SH coeff from hp.alm2map
        normalize=True)

    with open(beam_file, 'wb') as handle:
        pickle.dump(beam_opts, handle, protocol=pickle.HIGHEST_PROTOCOL)

    # init scan strategy and instrument
    ss = ScanStrategy(
        nsamp / 10.,  # mission duration in sec.
        sample_rate=10,  # 10 Hz sample rate
        location='spole')  # South pole instrument

    ss.load_focal_plane(tmp_dir, no_pairs=True)

    # remove tmp dir and contents
    shutil.rmtree(tmp_dir)

    # init plot
    fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)

    # Generate timestreams with Gaussian beams and plot them
    ss.scan_instrument_mpi(alm,
                           verbose=1,
                           ra0=ra0,
                           dec0=dec0,
                           az_throw=az_throw,
                           nside_spin=nside_spin,
                           max_spin=mmax,
                           binning=False)
    ax1.plot(ss.tod, label='sym. Gaussian', linewidth=0.7)

    gauss_tod = ss.tod.copy()

    # Generate timestreams with elliptical Gaussian beams and plot them
    ss.beams[0][0].btype = 'EG'
    ss.scan_instrument_mpi(alm,
                           verbose=1,
                           ra0=ra0,
                           dec0=dec0,
                           az_throw=az_throw,
                           nside_spin=nside_spin,
                           max_spin=mmax,
                           binning=False)
    ax1.plot(ss.tod, label='ell. Gaussian', linewidth=0.7)

    eg_tod = ss.tod.copy()

    # Generate timestreams with Physical Optics beams and plot them
    ss.beams[0][0].btype = 'PO'
    ss.scan_instrument_mpi(alm,
                           verbose=1,
                           ra0=ra0,
                           dec0=dec0,
                           az_throw=az_throw,
                           nside_spin=nside_spin,
                           max_spin=mmax,
                           binning=False)
    ax1.plot(ss.tod, label='PO', linewidth=0.7)

    po_tod = ss.tod.copy()

    ax2.plot(eg_tod - gauss_tod, label='EG - G', linewidth=0.7)
    ax2.plot(po_tod - gauss_tod, label='PO - G', linewidth=0.7)

    ax1.legend()
    ax2.legend()
    ax1.set_ylabel(r'Signal [$\mu K_{\mathrm{CMB}}$]')
    ax2.set_ylabel(r'Difference [$\mu K_{\mathrm{CMB}}$]')
    ax2.set_xlabel('Sample number')
    fig.savefig('../scratch/img/sdet_tod.png')

    plt.close()
Ejemplo n.º 19
0
def test_ghosts(lmax=700,
                mmax=5,
                fwhm=43,
                ra0=-10,
                dec0=-57.5,
                az_throw=50,
                scan_speed=2.8,
                rot_period=4.5 * 60 * 60,
                hwp_mode=None):
    '''
    Similar test to `scan_bicep`, but includes reflected ghosts

    Simulates a 24h BICEP2-like scan strategy
    using a random LCDM realisation and a 3 x 3 grid
    of Gaussian beams pairs. Bins tods into maps and
    compares to smoothed input maps (no pair-
    differencing). MPI-enabled.

    Keyword arguments
    ---------

    lmax : int,
        bandlimit (default : 700)
    mmax : int,
        assumed azimuthal bandlimit beams (symmetric in this example
        so 2 would suffice) (default : 5)
    fwhm : float,
        The beam FWHM in arcmin (default : 40)
    ra0 : float,
        Ra coord of centre region (default : -10)
    dec0 : float,  (default : -57.5)
        Ra coord of centre region
    az_throw : float,
        Scan width in azimuth (in degrees) (default : 50)
    scan_speed : float,
        Scan speed in deg/s (default : 1)
    rot_period : float,
        The instrument rotation period in sec
        (default : 600)
    hwp_mode : str, None
        HWP modulation mode, either "continuous",
        "stepped" or None. Use freq of 1 or 1/10800 Hz
        respectively (default : None)
    '''

    mlen = 24 * 60 * 60  # hardcoded mission length

    # Create LCDM realization
    ell, cls = get_cls()
    np.random.seed(25)  # make sure all MPI ranks use the same seed
    alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True)  # uK

    b2 = ScanStrategy(
        mlen,  # mission duration in sec.
        sample_rate=12.01,  # sample rate in Hz
        location='spole')  # Instrument at south pole

    # Create a 3 x 3 square grid of Gaussian beams
    b2.create_focal_plane(nrow=3, ncol=3, fov=5, lmax=lmax, fwhm=fwhm)

    # Create reflected ghosts for every detector
    # We create two ghosts per detector. They overlap
    # but have different fwhm. First ghost is just a
    # scaled down version of the main beam, the second
    # has a much wider Gaussian shape.
    # After this initialization, the code takes
    # the ghosts into account without modifications
    b2.create_reflected_ghosts(b2.beams,
                               amplitude=0.01,
                               ghost_tag='ghost_1',
                               dead=False)
    b2.create_reflected_ghosts(b2.beams,
                               amplitude=0.01,
                               fwhm=100,
                               ghost_tag='ghost_2',
                               dead=False)

    # calculate tods in two chunks
    b2.partition_mission(0.5 * b2.nsamp)

    # Allocate and assign parameters for mapmaking
    b2.allocate_maps(nside=256)

    # set instrument rotation
    b2.set_instr_rot(period=rot_period, angles=[68, 113, 248, 293])

    # Set HWP rotation
    if hwp_mode == 'continuous':
        b2.set_hwp_mod(mode='continuous', freq=1.)
    elif hwp_mode == 'stepped':
        b2.set_hwp_mod(mode='stepped', freq=1 / (3 * 60 * 60.))

    # Generate timestreams, bin them and store as attributes
    b2.scan_instrument_mpi(alm,
                           verbose=1,
                           ra0=ra0,
                           dec0=dec0,
                           az_throw=az_throw,
                           nside_spin=256,
                           max_spin=mmax)

    # Solve for the maps
    maps, cond = b2.solve_for_map(fill=np.nan)

    # Plotting
    if b2.mpi_rank == 0:
        print('plotting results')

        cart_opts = dict(
            rot=[ra0, dec0, 0],
            lonra=[-min(0.5 * az_throw, 90),
                   min(0.5 * az_throw, 90)],
            latra=[-min(0.375 * az_throw, 45),
                   min(0.375 * az_throw, 45)],
            unit=r'[$\mu K_{\mathrm{CMB}}$]')

        # plot rescanned maps
        plot_iqu(maps,
                 '../scratch/img/',
                 'rescan_ghost',
                 sym_limits=[250, 5, 5],
                 plot_func=hp.cartview,
                 **cart_opts)

        # plot smoothed input maps
        nside = hp.get_nside(maps[0])
        hp.smoothalm(alm, fwhm=np.radians(fwhm / 60.), verbose=False)
        maps_raw = hp.alm2map(alm, nside, verbose=False)

        plot_iqu(maps_raw,
                 '../scratch/img/',
                 'raw_ghost',
                 sym_limits=[250, 5, 5],
                 plot_func=hp.cartview,
                 **cart_opts)

        # plot difference maps
        for arr in maps_raw:
            # replace stupid UNSEEN crap
            arr[arr == hp.UNSEEN] = np.nan

        diff = maps_raw - maps

        plot_iqu(diff,
                 '../scratch/img/',
                 'diff_ghost',
                 sym_limits=[1e+1, 1e-1, 1e-1],
                 plot_func=hp.cartview,
                 **cart_opts)

        # plot condition number map
        cart_opts.pop('unit', None)

        plot_map(cond,
                 '../scratch/img/',
                 'cond_ghost',
                 min=2,
                 max=5,
                 unit='condition number',
                 plot_func=hp.cartview,
                 **cart_opts)

        # plot input spectrum
        cls[3][cls[3] <= 0.] *= -1.
        dell = ell * (ell + 1) / 2. / np.pi
        plt.figure()
        for i, label in enumerate(['TT', 'EE', 'BB', 'TE']):
            plt.semilogy(ell, dell * cls[i], label=label)

        plt.legend()
        plt.ylabel(r'$D_{\ell}$ [$\mu K^2_{\mathrm{CMB}}$]')
        plt.xlabel(r'Multipole [$\ell$]')
        plt.savefig('../scratch/img/cls_ghost.png')
        plt.close()
Ejemplo n.º 20
0
def scan_atacama(lmax=700,
                 mmax=5,
                 fwhm=40,
                 mlen=48 * 60 * 60,
                 nrow=3,
                 ncol=3,
                 fov=5.0,
                 ra0=[-10, 170],
                 dec0=[-57.5, 0],
                 el_min=45.,
                 cut_el_min=False,
                 az_throw=50,
                 scan_speed=1,
                 rot_period=0,
                 hwp_mode='continuous'):
    '''
    Simulates 48h of an atacama-based telescope with a 3 x 3 grid
    of Gaussian beams pairs. Prefers to scan the bicep patch but
    will try to scan the ABS_B patch if the first is not visible.

    Keyword arguments
    ---------

    lmax : int
        bandlimit (default : 700)
    mmax : int
        assumed azimuthal bandlimit beams (symmetric in this example
        so 2 would suffice) (default : 5)
    fwhm : float
        The beam FWHM in arcmin (default : 40)
    mlen : int
        The mission length [seconds] (default : 48 * 60 * 60)
    nrow : int
        Number of detectors along row direction (default : 3)
    ncol : int
        Number of detectors along column direction (default : 3)
    fov : float
        The field of view in degrees (default : 5.0)
    ra0 : float, array-like
        Ra coord of centre region (default : [-10., 85.])
    dec0 : float, array-like
        Ra coord of centre region (default : [-57.5, 0.])
    el_min : float
        Minimum elevation range [deg] (default : 45)
    cut_el_min: bool
            If True, excludes timelines where el would be less than el_min
    az_throw : float
        Scan width in azimuth (in degrees) (default : 10)
    scan_speed : float
        Scan speed in deg/s (default : 1)
    rot_period : float
        The instrument rotation period in sec
        (default : 600)
    hwp_mode : str, None
        HWP modulation mode, either "continuous",
        "stepped" or None. Use freq of 1 or 1/10800 Hz
        respectively (default : continuous)
    '''

    # hardcoded mission length

    # Create LCDM realization
    ell, cls = get_cls()
    np.random.seed(25)  # make sure all MPI ranks use the same seed
    alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True)  # uK

    ac = ScanStrategy(
        mlen,  # mission duration in sec.
        sample_rate=12.01,  # sample rate in Hz
        location='atacama')  # Instrument at south pole

    # Create a 3 x 3 square grid of Gaussian beams
    ac.create_focal_plane(nrow=nrow, ncol=ncol, fov=fov, lmax=lmax, fwhm=fwhm)

    # calculate tods in two chunks
    ac.partition_mission(0.5 * ac.mlen * ac.fsamp)

    # Allocate and assign parameters for mapmaking
    ac.allocate_maps(nside=256)

    # set instrument rotation
    ac.set_instr_rot(period=rot_period)

    # Set HWP rotation
    if hwp_mode == 'continuous':
        ac.set_hwp_mod(mode='continuous', freq=1.)
    elif hwp_mode == 'stepped':
        ac.set_hwp_mod(mode='stepped', freq=1 / (3 * 60 * 60.))

    # Generate timestreams, bin them and store as attributes
    ac.scan_instrument_mpi(alm,
                           verbose=2,
                           ra0=ra0,
                           dec0=dec0,
                           az_throw=az_throw,
                           nside_spin=256,
                           el_min=el_min,
                           cut_el_min=cut_el_min,
                           create_memmap=True)

    # Solve for the maps
    maps, cond = ac.solve_for_map(fill=np.nan)

    # Plotting
    if ac.mpi_rank == 0:
        print('plotting results')
        img_out_path = '../scratch/img/'

        moll_opts = dict(unit=r'[$\mu K_{\mathrm{CMB}}$]')

        # plot rescanned maps
        plot_iqu(maps,
                 img_out_path,
                 'rescan_atacama',
                 sym_limits=[250, 5, 5],
                 plot_func=hp.mollview,
                 **moll_opts)

        # plot smoothed input maps
        nside = hp.get_nside(maps[0])
        hp.smoothalm(alm, fwhm=np.radians(fwhm / 60.), verbose=False)
        maps_raw = hp.alm2map(alm, nside, verbose=False)

        plot_iqu(maps_raw,
                 img_out_path,
                 'raw_atacama',
                 sym_limits=[250, 5, 5],
                 plot_func=hp.mollview,
                 **moll_opts)

        # plot difference maps
        for arr in maps_raw:
            # replace stupid UNSEEN crap
            arr[arr == hp.UNSEEN] = np.nan

        diff = maps_raw - maps

        plot_iqu(diff,
                 img_out_path,
                 'diff_atacama',
                 sym_limits=[1e-6, 1e-6, 1e-6],
                 plot_func=hp.mollview,
                 **moll_opts)

        # plot condition number map
        moll_opts.pop('unit', None)

        plot_map(cond,
                 img_out_path,
                 'cond_atacama',
                 min=2,
                 max=5,
                 unit='condition number',
                 plot_func=hp.mollview,
                 **moll_opts)

        # plot input spectrum
        cls[3][cls[3] <= 0.] *= -1.
        dell = ell * (ell + 1) / 2. / np.pi
        plt.figure()
        for i, label in enumerate(['TT', 'EE', 'BB', 'TE']):
            plt.semilogy(ell, dell * cls[i], label=label)

        plt.legend()
        plt.ylabel(r'$D_{\ell}$ [$\mu K^2_{\mathrm{CMB}}$]')
        plt.xlabel(r'Multipole [$\ell$]')
        plt.savefig('../scratch/img/cls_atacama.png')
        plt.close()

        print("Results written to {}".format(os.path.abspath(img_out_path)))
Ejemplo n.º 21
0
def test_satellite_scan(lmax=700,
                        mmax=2,
                        fwhm=43,
                        ra0=-10,
                        dec0=-57.5,
                        az_throw=50,
                        scan_speed=2.8,
                        hwp_mode=None,
                        alpha=45.,
                        beta=45.,
                        alpha_period=5400.,
                        beta_period=600.,
                        delta_az=0.,
                        delta_el=0.,
                        delta_psi=0.,
                        jitter_amp=1.0):
    '''
    Simulates a satellite scan strategy 
    using a random LCDM realisation and a 3 x 3 grid
    of Gaussian beams pairs. Bins tods into maps and
    compares to smoothed input maps (no pair-
    differencing). MPI-enabled.

    Keyword arguments
    ---------

    lmax : int,
        bandlimit (default : 700)
    mmax : int, 
        assumed azimuthal bandlimit beams (symmetric in this example
        so 2 would suffice) (default : 2)
    fwhm : float,
        The beam FWHM in arcmin (default : 40)
    ra0 : float,
        Ra coord of centre region (default : -10)
    dec0 : float,  (default : -57.5)
        Ra coord of centre region
    az_throw : float,
        Scan width in azimuth (in degrees) (default : 50)
    scan_speed : float,
        Scan speed in deg/s (default : 1)
    hwp_mode : str, None
        HWP modulation mode, either "continuous",
        "stepped" or None. Use freq of 1 or 1/10800 Hz
        respectively (default : None)
    '''

    print('Simulating a satellite...')
    mlen = 3 * 24 * 60 * 60  # hardcoded mission length

    # Create LCDM realization
    ell, cls = get_cls()
    np.random.seed(25)  # make sure all MPI ranks use the same seed
    alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True)  # uK

    sat = ScanStrategy(
        mlen,  # mission duration in sec.
        external_pointing=True,  # Telling code to use non-standard scanning
        sample_rate=12.01,  # sample rate in Hz
        location='space')  # Instrument at south pole

    # Create a 3 x 3 square grid of Gaussian beams
    sat.create_focal_plane(nrow=7, ncol=7, fov=15, lmax=lmax, fwhm=fwhm)

    # calculate tods in two chunks
    sat.partition_mission(0.5 * sat.nsamp)

    # Allocate and assign parameters for mapmaking
    sat.allocate_maps(nside=256)

    scan_opts = dict(q_bore_func=sat.satellite_scan,
                     ctime_func=sat.satellite_ctime,
                     q_bore_kwargs=dict(),
                     ctime_kwargs=dict())

    # Generate timestreams, bin them and store as attributes
    sat.scan_instrument_mpi(alm,
                            verbose=1,
                            ra0=ra0,
                            dec0=dec0,
                            az_throw=az_throw,
                            nside_spin=256,
                            max_spin=mmax,
                            **scan_opts)

    # Solve for the maps
    maps, cond, proj = sat.solve_for_map(fill=np.nan, return_proj=True)

    # Plotting
    if sat.mpi_rank == 0:
        print('plotting results')

        cart_opts = dict(unit=r'[$\mu K_{\mathrm{CMB}}$]')

        # plot rescanned maps

        plot_iqu(maps,
                 '../scratch/img/',
                 'rescan_satellite',
                 sym_limits=[250, 5, 5],
                 plot_func=hp.mollview,
                 **cart_opts)

        # plot smoothed input maps
        nside = hp.get_nside(maps[0])
        hp.smoothalm(alm, fwhm=np.radians(fwhm / 60.), verbose=False)
        maps_raw = hp.alm2map(alm, nside, verbose=False)

        plot_iqu(maps_raw,
                 '../scratch/img/',
                 'raw_satellite',
                 sym_limits=[250, 5, 5],
                 plot_func=hp.mollview,
                 **cart_opts)

        # plot difference maps
        for arr in maps_raw:
            # replace stupid UNSEEN crap
            arr[arr == hp.UNSEEN] = np.nan

        diff = maps_raw - maps

        plot_iqu(diff,
                 '../scratch/img/',
                 'diff_satellite',
                 sym_limits=[1e-6, 1e-6, 1e-6],
                 plot_func=hp.mollview,
                 **cart_opts)

        # plot condition number map
        cart_opts.pop('unit', None)

        plot_map(cond,
                 '../scratch/img/',
                 'cond_satellite',
                 min=2,
                 max=5,
                 unit='condition number',
                 plot_func=hp.mollview,
                 **cart_opts)

        plot_map(proj[0],
                 '../scratch/img/',
                 'hits_satellite',
                 unit='Hits',
                 plot_func=hp.mollview,
                 **cart_opts)
Ejemplo n.º 22
0
def idea_jon():

    nside_spin = 512
    ra0 = 0
    dec0 = -90
    az_throw = 10
    max_spin = 5
    fwhm = 32.2
    scan_opts = dict(verbose=1,
                     ra0=ra0,
                     dec0=dec0,
                     az_throw=az_throw,
                     nside_spin=nside_spin,
                     max_spin=max_spin,
                     binning=True)

    lmax = 800

    alm = tools.gauss_blm(1e-5, lmax, pol=False)
    ell = np.arange(lmax + 1)
    fl = np.sqrt((2 * ell + 1) / 4. / np.pi)
    hp.almxfl(alm, fl, mmax=None, inplace=True)
    fm = (-1)**(hp.Alm.getlm(lmax)[1])
    alm *= fm
    alm = tools.get_copol_blm(alm)

    # create Beam properties and pickle (this is just to test load_focal_plane)
    import tempfile
    import shutil
    import pickle
    opj = os.path.join

    blm_dir = os.path.abspath(
        opj(os.path.dirname(__file__), '../tests/test_data/example_blms'))
    po_file = opj(blm_dir, 'blm_hp_X1T1R1C8A_800_800.npy')
    eg_file = opj(blm_dir, 'blm_hp_eg_X1T1R1C8A_800_800.npy')

    tmp_dir = tempfile.mkdtemp()

    beam_file = opj(tmp_dir, 'beam_opts.pkl')
    beam_opts = dict(az=0,
                     el=0,
                     polang=0.,
                     btype='Gaussian',
                     name='X1T1R1C8',
                     fwhm=fwhm,
                     lmax=800,
                     mmax=800,
                     amplitude=1.,
                     po_file=po_file,
                     eg_file=eg_file)

    with open(beam_file, 'wb') as handle:
        pickle.dump(beam_opts, handle, protocol=pickle.HIGHEST_PROTOCOL)

    # init scan strategy and instrument
    ss = ScanStrategy(
        1.,  # mission duration in sec.
        sample_rate=10000,
        location='spole')

    ss.allocate_maps(nside=1024)
    ss.load_focal_plane(tmp_dir, no_pairs=True)

    # remove tmp dir and contents
    shutil.rmtree(tmp_dir)

    ss.set_el_steps(0.01, steps=np.linspace(-10, 10, 100))

    # Generate maps with Gaussian beams
    ss.scan_instrument_mpi(alm, **scan_opts)
    ss.reset_el_steps()

    # Solve for the maps
    maps_g, cond_g = ss.solve_for_map(fill=np.nan)

    # Generate maps with elliptical Gaussian beams
    ss.allocate_maps(nside=1024)
    ss.beams[0][0].btype = 'EG'
    ss.scan_instrument_mpi(alm, **scan_opts)
    ss.reset_el_steps()

    # Solve for the maps
    maps_eg, cond_eg = ss.solve_for_map(fill=np.nan)

    # Generate map with Physical Optics beams and plot them
    ss.allocate_maps(nside=1024)
    ss.beams[0][0].btype = 'PO'
    ss.scan_instrument_mpi(alm, **scan_opts)
    ss.reset_el_steps()

    # Solve for the maps
    maps_po, cond_po = ss.solve_for_map(fill=np.nan)

    # Plotting
    print('plotting results')

    cart_opts = dict(  #rot=[ra0, dec0, 0],
        lonra=[-min(0.5 * az_throw, 10),
               min(0.5 * az_throw, 10)],
        latra=[-min(0.375 * az_throw, 10),
               min(0.375 * az_throw, 10)],
        unit=r'[$\mu K_{\mathrm{CMB}}$]')

    # plot smoothed input maps
    nside = hp.get_nside(maps_g[0])
    hp.smoothalm(alm, fwhm=np.radians(fwhm / 60.), verbose=False)
    maps_raw = hp.alm2map(alm, nside, verbose=False)

    plot_iqu(maps_raw,
             '../scratch/img/',
             'raw_delta',
             sym_limits=[1, 1, 1],
             plot_func=hp.cartview,
             **cart_opts)
Ejemplo n.º 23
0
def scan(lmax=500, nside=512, mmax=2):
    '''Time scanning single detector.'''

    os.environ["OMP_NUM_THREADS"] = "10"
    import numpy as np
    import healpy as hp
    from beamconv import ScanStrategy
    from beamconv import Beam

    ndays_range = np.logspace(np.log10(0.001), np.log10(50), 15)
    lmax = lmax
    nside = nside
    freq = 100.

    timings = np.ones((ndays_range.size), dtype=float)
    timings_cpu = np.ones((ndays_range.size), dtype=float)

    S = ScanStrategy(duration=24 * 3600, sample_rate=freq)
    beam_opts = dict(az=1,
                     el=1,
                     polang=10.,
                     fwhm=40,
                     btype='Gaussian',
                     lmax=lmax,
                     symmetric=mmax == 0)

    beam = Beam(**beam_opts)
    S.add_to_focal_plane(beam)
    alm = np.zeros((3, hp.Alm.getsize(lmax=lmax)), dtype=np.complex128)
    print('init detpair...')
    S.init_detpair(alm,
                   beam,
                   beam_b=None,
                   nside_spin=nside,
                   max_spin=mmax,
                   verbose=True)
    print('...done')

    spinmaps = copy.deepcopy(S.spinmaps)

    # Calculate q_bore for 0.1 day of scanning and reuse this.
    const_el_opts = dict(az_throw=50., scan_speed=10., dec0=-70.)
    S.partition_mission()
    print('cons_el_scan...')
    const_el_opts.update(dict(start=0, end=int(24 * 3600 * 100 * 0.1)))
    S.constant_el_scan(**const_el_opts)
    print('...done')

    q_bore_day = S.q_bore
    ctime_day = S.ctime

    for nidx, ndays in enumerate(ndays_range):

        duration = ndays * 24 * 3600
        nsamp = duration * freq

        S = ScanStrategy(duration=duration,
                         sample_rate=freq,
                         external_pointing=True)
        S.add_to_focal_plane(beam)

        S.partition_mission()

        q_bore = np.repeat(q_bore_day, np.ceil(10 * ndays), axis=0)
        ctime = np.repeat(q_bore_day, np.ceil(10 * ndays))

        def q_bore_func(start=None, end=None, q_bore=None):
            return q_bore[int(start):int(end), :]

        def ctime_func(start=None, end=None, ctime=None):
            return ctime[int(start):int(end)]

        S.spinmaps = spinmaps
        t0 = time.time()
        t0c = time.clock()
        S.scan_instrument_mpi(alm,
                              binning=False,
                              reuse_spinmaps=True,
                              interp=False,
                              q_bore_func=q_bore_func,
                              ctime_func=ctime_func,
                              q_bore_kwargs={'q_bore': q_bore},
                              ctime_kwargs={'ctime': ctime},
                              start=0,
                              end=int(nsamp),
                              cidx=0)
        t1 = time.time()
        t1c = time.clock()
        print t1 - t0
        print t1c - t0c

        timings[nidx] = t1 - t0
        timings_cpu[nidx] = t1c - t0c

    np.save(
        './scan_timing_lmax{}_nside{}_mmax{}.npy'.format(lmax, nside, mmax),
        timings)
    np.save(
        './scan_timing_cpu_lmax{}_nside{}_mmax{}.npy'.format(
            lmax, nside, mmax), timings_cpu)
    np.save('./scan_ndays_lmax{}_nside{}_mmax{}.npy'.format(lmax, nside, mmax),
            ndays_range)
Ejemplo n.º 24
0
    def test_offset_beam_pol(self):

        mlen = 20 # mission length
        sample_rate = 10
        location='spole'
        lmax = self.lmax
        fwhm = 300
        nside_spin = 256
        #polang = 30
        #az_off = 20
        #el_off = 40

        polang = 90
        az_off = 20
        el_off = 0

        alm = (self.alm[0]*0., self.alm[1], self.alm[2])

        ss = ScanStrategy(mlen, sample_rate=sample_rate,
                          location=location)

        # Create single detector.
        ss.create_focal_plane(nrow=1, ncol=1, fov=0, no_pairs=True,
                              polang=polang, lmax=lmax, fwhm=fwhm)

        # Move detector away from boresight.
        ss.beams[0][0].az = az_off
        ss.beams[0][0].el = el_off

        # Start instrument rotated.
        rot_period =  ss.mlen
        ss.set_instr_rot(period=rot_period, start_ang=45)

        #ss.set_hwp_mod(mode='stepped', freq=1/20., start_ang=45,
        #               angles=[34, 12, 67])

        ss.partition_mission()
        ss.scan_instrument_mpi(alm, binning=False, nside_spin=nside_spin,
                               max_spin=2, interp=True)

        # Store the tod and pixel indices made with symmetric beam.
        tod_sym = ss.tod.copy()

        # Now repeat with asymmetric beam and no detector offset.
        # Set offsets to zero such that tods are generated using
        # only the boresight pointing.
        ss.beams[0][0].az = 0
        ss.beams[0][0].el = 0
        ss.beams[0][0].polang = 0

        # Convert beam spin modes to E and B modes and rotate them
        # create blm again, scan_instrument_mpi detetes blms when done
        ss.beams[0][0].gen_gaussian_blm()
        blm = ss.beams[0][0].blm
        blmI = blm[0].copy()
        blmE, blmB = tools.spin2eb(blm[1], blm[2])

        # Rotate blm to match centroid.
        # Note that rotate_alm uses the ZYZ euler convention.
        # Note that we include polang here as first rotation.
        q_off = ss.det_offset(az_off, el_off, polang)
        ra, dec, pa = ss.quat2radecpa(q_off)

        # We need to to apply these changes to the angles.
        phi = np.radians(ra)
        theta = np.radians(90 - dec)
        psi = np.radians(-pa)

        print('angles', psi, theta, phi)
        # rotate blm
        hp.rotate_alm([blmI, blmE, blmB], psi, theta, phi, lmax=lmax, mmax=lmax)

        # convert beam coeff. back to spin representation.
        blmm2, blmp2 = tools.eb2spin(blmE, blmB)
        ss.beams[0][0].blm = (blmI, blmm2, blmp2)

        ss.reset_instr_rot()
        ss.reset_hwp_mod()

        ss.scan_instrument_mpi(alm, binning=False, nside_spin=nside_spin,
                               max_spin=lmax, interp=True)

        # TODs must agree at least at 2% per sample.
        print('tod_sym', tod_sym[::10])
        print('ss.tod', ss.tod[::10])
        np.testing.assert_equal(np.abs(ss.tod - tod_sym) < 0.02 * np.std(tod_sym),
                                np.full(tod_sym.size, True))
Ejemplo n.º 25
0
    def test_preview_pointing(self):

        # With preview_pointing set, expect correct proj matrix,
        # but vec vector should be zero.

        mlen = 6 * 60
        rot_period = 30
        step_period = rot_period * 2
        mmax = 2
        ra0=-10
        dec0=-57.5
        fwhm = 10
        nside_out = 32
        az_throw = 10
        scan_speed = 2 # deg / s.

        scs = ScanStrategy(duration=mlen, sample_rate=10, location='spole')

        # Create a 1 x 2 square grid of Gaussian beams.
        scs.create_focal_plane(nrow=1, ncol=2, fov=2,
                              lmax=self.lmax, fwhm=fwhm)

        # Allocate and assign parameters for mapmaking.
        scs.allocate_maps(nside=nside_out)

        # set instrument rotation.
        scs.set_instr_rot(period=rot_period, angles=[68, 113, 248, 293])

        # Set elevation stepping.
        scs.set_el_steps(step_period, steps=[0, 1, 2])

        # Set HWP rotation.
        scs.set_hwp_mod(mode='continuous', freq=3.)

        # First run with preview_pointing set
        alm = None
        preview_pointing = True
        # Generate timestreams, bin them and store as attributes.
        scs.scan_instrument_mpi(alm, verbose=0, ra0=ra0,
                                dec0=dec0, az_throw=az_throw,
                                scan_speed=scan_speed,
                                nside_spin=nside_out,
                                max_spin=mmax,
                                preview_pointing=preview_pointing)

        # Vec should be zero
        np.testing.assert_array_equal(scs.vec, np.zeros((3, 12 * nside_out ** 2)))
        # Save for comparison
        vec_prev = scs.vec
        proj_prev = scs.proj

        # Now run again in default way.
        # Create new dest arrays.
        scs.allocate_maps(nside=nside_out)

        scs.reset_instr_rot()
        scs.reset_hwp_mod()
        scs.reset_el_steps()

        alm = self.alm
        preview_pointing = False

        # Generate timestreams, bin them and store as attributes.
        scs.scan_instrument_mpi(alm, verbose=0, ra0=ra0,
                                dec0=dec0, az_throw=az_throw,
                                scan_speed=scan_speed,
                                nside_spin=nside_out,
                                max_spin=mmax,
                                preview_pointing=preview_pointing)

        # Vec should not be zero now.
        np.testing.assert_equal(np.any(scs.vec), True)

        # Proj should be identical.
        np.testing.assert_array_almost_equal(scs.proj, proj_prev, decimal=9)

        # Run one more time with a ghost. Ghost should not change proj.
        # Create new dest arrays.
        scs.allocate_maps(nside=nside_out)

        alm = self.alm
        preview_pointing = False

        scs.reset_instr_rot()
        scs.reset_hwp_mod()
        scs.reset_el_steps()

        ghost_opts = dict(az=10, el=10, polang=28, fwhm=fwhm, lmax=self.lmax,
                          symmetric=True, amplitude=1)

        scs.beams[0][0].create_ghost(**ghost_opts)

        # Generate timestreams, bin them and store as attributes.
        scs.scan_instrument_mpi(alm, verbose=0, ra0=ra0,
                                dec0=dec0, az_throw=az_throw,
                                scan_speed=scan_speed,
                                nside_spin=nside_out,
                                max_spin=mmax,
                                preview_pointing=preview_pointing)

        # Vec should not be zero now.
        np.testing.assert_equal(np.any(scs.vec), True)

        # Proj should be identical.
        np.testing.assert_array_almost_equal(scs.proj, proj_prev, decimal=9)
Ejemplo n.º 26
0
def Scan_maps(nside, alms, lmax, Freq, Own_Stack=True, ideal_hwp=False):
    '''
    Scanning simulation, store the output map, the blm, the tod, and the 
    condition number in the output directory.
    ---------
    nside: int
        the nside of the map
    alms : array-like
        array of alm arrays that
        share lmax and mmax. For each frequency we have three healpy alm array
    lmax: int
        The bandlmit.
    Freq: array-like 
        frequency at which one want to compute the sky

    Keyword arguments
    -----------------
    ideal_hwp : bool
        If True: it is considered an ideal HWP,
        if Flase: it is considered a real HWP.
        (default : False)
    '''

    po_file = opj(blm_dir,
                  'pix0000_90_hwpproj_v5_f1p6_6p0mm_mfreq_lineard_hdpe.npy')
    #eg_file = opj(blm_dir, 'blm_hp_eg_X1T1R1C8A_800_800.npy')
    beam_file = 'pix0000_90_hwpproj_v5_f1p6_6p0mm_mfreq_lineard_hdpe.pkl'

    hwp = Beam().hwp()

    if Own_Stack:
        thicknesses = np.array([0.427, 4.930, 0.427])
        indices = np.array([[1., 1.], [1.02, 1.02], [1., 1.]])
        losses = np.array([[0., 0.], [1e-4, 1e-4], [0., 0.]])
        angles = np.array([0., 0., 0.])
        hwp.stack_builder(thicknesses=thicknesses,
                          indices=indices,
                          losses=losses,
                          angles=angles)
    else:
        hwp.choose_HWP_model('SPIDER_95')

    beam_opts = dict(
        az=0,
        el=0,
        polang=0.,
        btype='PO',
        fwhm=32.2,
        lmax=lmax,
        mmax=4,
        amplitude=1.,
        po_file=po_file,
        #eg_file=eg_file,
        deconv_q=True,  # blm are SH coeff from hp.alm2map
        normalize=True,
        hwp=hwp)

    with open(beam_file, 'wb') as handle:
        pickle.dump(beam_opts, handle, protocol=pickle.HIGHEST_PROTOCOL)

    beam = Beam(**beam_opts)

    ### SCAN OPTIONS
    # duration = nsamp/sample_rate
    nsamp = 864000
    fsamp = 10
    mlen = nsamp / fsamp
    lmax = lmax
    mmax = 4
    ra0 = -10
    dec0 = -57.5
    az_throw = 50
    scan_speed = 2.8
    rot_period = 4.5 * 60 * 60
    nside_spin = nside
    # scan the given sky and return the results as maps;

    filefolder = opj(dir_out, 'Output_maps/')
    for freq, alm in zip(Freq, alms):

        ss = ScanStrategy(mlen, sample_rate=fsamp, location='atacama')

        # Add the detectors to the focal plane; 9 detector pairs used in this case
        ss.create_focal_plane(nrow=4, ncol=4, fov=3, **beam_opts)

        # Use a half-wave plate. Other options one can use is to add an elevation
        # pattern or a periodic instrument rotation as, for example:
        # ss.set_instr_rot(period=rot_period, angles=[68, 113, 248, 293])
        # and ss.set_el_steps(step_period, steps=[-4, -3, -2, -1, 0, 1, 2, 3, 4, 4])
        ss.set_hwp_mod(mode='continuous', freq=1.)
        # scan the given sky and return the results as maps;
        ss.allocate_maps(nside=nside)
        if ideal_hwp:
            ss.scan_instrument_mpi(alm,
                                   verbose=1,
                                   ra0=ra0,
                                   dec0=dec0,
                                   az_throw=az_throw,
                                   nside_spin=nside_spin,
                                   max_spin=mmax,
                                   binning=True,
                                   hwp_status='ideal')
        else:
            ss.scan_instrument_mpi(alm,
                                   verbose=1,
                                   ra0=ra0,
                                   dec0=dec0,
                                   az_throw=az_throw,
                                   nside_spin=nside_spin,
                                   max_spin=mmax,
                                   binning=True)

        tod = ss.tod
        maps, cond = ss.solve_for_map(fill=np.nan)
        blm = np.asarray(beam.blm).copy()

        # We need to divide out sqrt(4pi / (2 ell + 1)) to get
        # correctly normlized spherical harmonic coeffients.
        ell = np.arange(hp.Alm.getlmax(blm[0].size))
        q_ell = np.sqrt(4. * np.pi / (2 * ell + 1))
        blm[0] = hp.almxfl(blm[0], 1 / q_ell)
        blm[1] = hp.almxfl(blm[1], 1 / q_ell)
        blm[2] = hp.almxfl(blm[2], 1 / q_ell)

        # print(np.shape(alm))
        # print(np.shape(alms))
        # print(np.shape(maps))
        # print(np.shape(cond))

        # maps = [maps[0], maps[1], maps[2]]

        hp.write_map(opj(dir_out,
                         'Output_maps/Bconv_' + str(freq) + 'GHz.fits'),
                     maps,
                     overwrite=True)
        hp.write_map(opj(dir_out,
                         'Output_maps/Cond_Numb_' + str(freq) + 'GHz.fits'),
                     cond,
                     overwrite=True)
        np.save(os.path.join(dir_out, 'blms/blm_' + str(freq) + 'GHz.npy'),
                blm)
        np.save(os.path.join(dir_out, 'tods/tod_' + str(freq) + 'GHz.npy'),
                tod)
Ejemplo n.º 27
0
    def test_cross_talk(self):
        '''Test if the cross-talk is performing as it should.'''

        mlen = 10 * 60
        rot_period = 120
        mmax = 2
        ra0 = -10
        dec0 = -57.5
        fwhm = 200
        nside = 256
        az_throw = 10

        scs = ScanStrategy(duration=mlen, sample_rate=10, location='spole')

        # Single pair.
        scs.create_focal_plane(nrow=1,
                               ncol=1,
                               fov=0,
                               lmax=self.lmax,
                               fwhm=fwhm)

        # Allocate and assign parameters for mapmaking.
        scs.allocate_maps(nside=nside)

        # set instrument rotation.
        scs.set_instr_rot(period=rot_period, angles=[12, 14, 248, 293])

        # Set elevation stepping.
        scs.set_el_steps(rot_period, steps=[0, 2, 4, 8, 10])

        # Set HWP rotation.
        scs.set_hwp_mod(mode='stepped', freq=3.)

        beam_a, beam_b = scs.beams[0]

        scs.init_detpair(self.alm,
                         beam_a,
                         beam_b=beam_b,
                         nside_spin=nside,
                         verbose=False)

        # Generate timestreams, bin them and store as attributes.
        scs.scan_instrument_mpi(self.alm,
                                verbose=0,
                                ra0=ra0,
                                dec0=dec0,
                                az_throw=az_throw,
                                scan_speed=2.,
                                max_spin=mmax,
                                reuse_spinmaps=True,
                                save_tod=True,
                                binning=False,
                                ctalk=0.0)

        tod_a = scs.data(scs.chunks[0], beam=beam_a, data_type='tod').copy()
        tod_b = scs.data(scs.chunks[0], beam=beam_b, data_type='tod').copy()

        # Redo with cross-talk
        ctalk = 0.5

        scs.reset_instr_rot()
        scs.reset_hwp_mod()
        scs.reset_el_steps()

        scs.scan_instrument_mpi(self.alm,
                                verbose=0,
                                ra0=ra0,
                                dec0=dec0,
                                az_throw=az_throw,
                                scan_speed=2.,
                                max_spin=mmax,
                                reuse_spinmaps=True,
                                save_tod=True,
                                binning=False,
                                ctalk=ctalk)

        tod_ac = scs.data(scs.chunks[0], beam=beam_a, data_type='tod')
        tod_bc = scs.data(scs.chunks[0], beam=beam_b, data_type='tod')

        np.testing.assert_array_almost_equal(tod_ac, tod_a + ctalk * tod_b)
        np.testing.assert_array_almost_equal(tod_bc, tod_b + ctalk * tod_a)

        # Redo with less cross-talk
        ctalk = 0.000001

        scs.reset_instr_rot()
        scs.reset_hwp_mod()
        scs.reset_el_steps()

        scs.scan_instrument_mpi(self.alm,
                                verbose=0,
                                ra0=ra0,
                                dec0=dec0,
                                az_throw=az_throw,
                                scan_speed=2.,
                                max_spin=mmax,
                                reuse_spinmaps=True,
                                save_tod=True,
                                binning=False,
                                ctalk=ctalk)

        tod_acs = scs.data(scs.chunks[0], beam=beam_a, data_type='tod')
        tod_bcs = scs.data(scs.chunks[0], beam=beam_b, data_type='tod')

        np.testing.assert_array_almost_equal(tod_acs, tod_a + ctalk * tod_b)
        np.testing.assert_array_almost_equal(tod_bcs, tod_b + ctalk * tod_a)

        np.testing.assert_raises(AssertionError, np.testing.assert_array_equal,
                                 tod_ac, tod_acs)
        np.testing.assert_raises(AssertionError, np.testing.assert_array_equal,
                                 tod_bc, tod_bcs)
Ejemplo n.º 28
0
def offset_beam_ghost(az_off=0,
                      el_off=0,
                      polang=0,
                      lmax=100,
                      fwhm=200,
                      hwp_freq=25.,
                      pol_only=True):
    '''
    Script that scans LCDM realization of sky with a detector
    on the boresight that has no main beam but a full-amplitude
    ghost at the specified offset eam. The signal is then binned
    using the boresight pointing and compared to a map made by
    a symmetric Gaussian beam that has been rotated away from
    the boresight. Results should agree.

    Keyword arguments
    ---------

    az_off : float,
        Azimuthal location of detector relative to boresight
        (default : 0.)
    el_off : float,
        Elevation location of detector relative to boresight
        (default : 0.)
    polang : float,
        Detector polarization angle in degrees (defined for
        unrotated detector as offset from meridian)
        (default : 0)
    lmax : int,
        Maximum multipole number, (default : 200)
    fwhm : float,
        The beam FWHM used in this analysis in arcmin
        (default : 100)
    hwp_freq : float,
        HWP spin frequency (continuous mode) (default : 25.)
    pol_only : bool,
        Set unpolarized sky signal to zero (default : True)
    '''

    # Load up alm and blm
    ell, cls = get_cls()
    np.random.seed(30)
    alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True)  # uK

    if pol_only:
        alm = (alm[0] * 0., alm[1], alm[2])

    # init scan strategy and instrument
    mlen = 240  # mission length
    ss = ScanStrategy(
        mlen,  # mission duration in sec.
        sample_rate=1,  # sample rate in Hz
        location='spole')  # South pole instrument

    # create single detector on boresight
    ss.create_focal_plane(nrow=1,
                          ncol=1,
                          fov=0,
                          no_pairs=True,
                          polang=polang,
                          lmax=lmax,
                          fwhm=fwhm,
                          scatter=True)

    try:
        beam = ss.beams[0][0]

        # set main beam to zero
        beam.amplitude = 0.

        # create Gaussian beam (would be done by code anyway otherwise)
        beam.gen_gaussian_blm()

        #explicitely set offset to zero
        beam.az = 0.
        beam.el = 0.
        beam.polang = 0.

        # create full-amplitude ghost
        beam.create_ghost(az=az_off, el=el_off, polang=polang, amplitude=1.)
        ghost = beam.ghosts[0]
        ghost.gen_gaussian_blm()

    except IndexError as e:
        if ss.mpi_rank != 0:
            pass
        else:
            raise e

    # Start instrument rotated (just to make things complicated)
    rot_period = ss.mlen
    ss.set_instr_rot(period=rot_period, start_ang=45)

    # Set HWP rotation
    ss.set_hwp_mod(mode='stepped',
                   freq=1 / 20.,
                   start_ang=45,
                   angles=[34, 12, 67])

    # calculate tod in one go (beam is symmetric so mmax=2 suffices)
    ss.partition_mission()
    ss.scan_instrument_mpi(alm,
                           binning=False,
                           nside_spin=512,
                           max_spin=2,
                           verbose=2)

    # Store the tod and pixel indices made with ghost
    try:
        tod_ghost = ss.tod.copy()
        pix_ghost = ss.pix.copy()
    except AttributeError as e:
        if ss.mpi_rank != 0:
            pass
        else:
            raise e

    # now repeat with asymmetric beam and no detector offset
    # set offsets to zero such that tods are generated using
    # only the boresight pointing.
    try:
        beam = ss.beams[0][0]
        beam.amplitude = 1.
        beam.gen_gaussian_blm()

        # Convert beam spin modes to E and B modes and rotate them
        blm = beam.blm
        blmI = blm[0].copy()
        blmE, blmB = tools.spin2eb(blm[1], blm[2])

        # Rotate blm to match centroid.
        # Note that rotate_alm uses the ZYZ euler convention.
        # Note that we include polang here as first rotation.
        q_off = ss.det_offset(az_off, el_off, polang)
        ra, dec, pa = ss.quat2radecpa(q_off)

        # convert between healpy and math angle conventions
        phi = np.radians(ra)
        theta = np.radians(90 - dec)
        psi = np.radians(-pa)

        # rotate blm
        hp.rotate_alm([blmI, blmE, blmB],
                      psi,
                      theta,
                      phi,
                      lmax=lmax,
                      mmax=lmax)

        # convert beam coeff. back to spin representation.
        blmm2, blmp2 = tools.eb2spin(blmE, blmB)
        beam.blm = (blmI, blmm2, blmp2)

        # kill ghost
        ghost.dead = True
        # spinmaps will still be created, so make as painless as possible
        ghost.lmax = 1
        ghost.mmax = 0

    except IndexError as e:
        if ss.mpi_rank != 0:
            pass
        else:
            raise e

    # reset instr. rot and hwp modulation
    ss.reset_instr_rot()
    ss.reset_hwp_mod()

    ss.scan_instrument_mpi(alm,
                           binning=False,
                           nside_spin=512,
                           verbose=2,
                           max_spin=lmax)  # now we use all spin modes

    # Figure comparing the raw detector timelines for the two versions
    # For subpixel offsets, the bottom plot shows you that sudden shifts
    # in the differenced tods are due to the pointing for the symmetric
    # case hitting a different pixel than the boresight pointing.
    if ss.mpi_rank == 0:
        plt.figure()
        gs = gridspec.GridSpec(5, 9)
        ax1 = plt.subplot(gs[:2, :6])
        ax2 = plt.subplot(gs[2:4, :6])
        ax3 = plt.subplot(gs[-1, :6])
        ax4 = plt.subplot(gs[:, 6:])

        samples = np.arange(tod_ghost.size)
        ax1.plot(samples, ss.tod, label='Asymmetric Gaussian', linewidth=0.7)
        ax1.plot(samples, tod_ghost, label='Ghost', linewidth=0.7, alpha=0.5)
        ax1.legend()

        ax1.tick_params(labelbottom='off')
        sigdiff = ss.tod - tod_ghost
        ax2.plot(samples, sigdiff, ls='None', marker='.', markersize=2.)
        ax2.tick_params(labelbottom='off')
        ax3.plot(samples, (pix_ghost - ss.pix).astype(bool).astype(int),
                 ls='None',
                 marker='.',
                 markersize=2.)
        ax1.set_ylabel(r'Signal [$\mu K_{\mathrm{CMB}}$]')
        ax2.set_ylabel(r'asym-sym. [$\mu K_{\mathrm{CMB}}$]')
        ax3.set_xlabel('Sample number')
        ax3.set_ylabel('different pixel?')
        ax3.set_ylim([-0.25, 1.25])
        ax3.set_yticks([0, 1])

        ax4.hist(sigdiff, 128, label='Difference')
        ax4.set_xlabel(r'Difference [$\mu K_{\mathrm{CMB}}$]')
        ax4.tick_params(labelleft='off')

        plt.savefig('../scratch/img/tods_ghost.png')
        plt.close()
Ejemplo n.º 29
0
def offset_beam_interp(az_off=0, el_off=0, polang=0, lmax=100,
                fwhm=200, hwp_freq=25., pol_only=True):
    '''
    Script that scans LCDM realization of sky with a symmetric
    Gaussian beam that has been rotated away from the boresight.
    This means that the beam is highly asymmetric. Scanning using
    interpolation.

    Keyword arguments
    -----------------
    az_off : float,
        Azimuthal location of detector relative to boresight
        (default : 0.)
    el_off : float,
        Elevation location of detector relative to boresight
        (default : 0.)
    polang : float,
        Detector polarization angle in degrees (defined for
        unrotated detector as offset from meridian)
        (default : 0)
    lmax : int,
        Maximum multipole number, (default : 200)
    fwhm : float,
        The beam FWHM used in this analysis [arcmin]
        (default : 100)
    hwp_freq : float,
        HWP spin frequency (continuous mode) (default : 25.)
    pol_only : bool,
        Set unpolarized sky signal to zero (default : True)
    '''

    # Load up alm and blm
    ell, cls = get_cls()
    np.random.seed(30)
    alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True) # uK

    if pol_only:
        alm = (alm[0]*0., alm[1], alm[2])

    # init scan strategy and instrument
    mlen = 240 # mission length
    ss = ScanStrategy(mlen, # mission duration in sec.
                      sample_rate=1, # sample rate in Hz
                      location='spole') # South pole instrument

    # create single detector
    ss.create_focal_plane(nrow=1, ncol=1, fov=0, no_pairs=True,
                          polang=polang, lmax=lmax, fwhm=fwhm,
                          scatter=True)

    # move detector away from boresight
    try:
        ss.beams[0][0].az = az_off
        ss.beams[0][0].el = el_off
    except IndexError as e:
        if ss.mpi_rank != 0:
            pass
        else:
            raise e

    # Start instrument rotated (just to make things complicated)
    rot_period =  ss.mlen
    ss.set_instr_rot(period=rot_period, start_ang=45)

    # Set HWP rotation
    ss.set_hwp_mod(mode='stepped', freq=1/20., start_ang=45,
                   angles=[34, 12, 67])

    # calculate tod in one go (beam is symmetric so mmax=2 suffices)
    ss.partition_mission()
    ss.scan_instrument_mpi(alm, binning=False, nside_spin=512,
                           max_spin=2, interp=True)

    # Store the tod made with symmetric beam
    try:
        tod_sym = ss.tod.copy()
    except AttributeError as e:
        if ss.mpi_rank != 0:
            pass
        else:
            raise e
    
    # now repeat with asymmetric beam and no detector offset
    # set offsets to zero such that tods are generated using
    # only the boresight pointing.
    try:
        ss.beams[0][0].az = 0
        ss.beams[0][0].el = 0
        ss.beams[0][0].polang = 0

        # Convert beam spin modes to E and B modes and rotate them
        # create blm again, scan_instrument_mpi detetes blms when done
        ss.beams[0][0].gen_gaussian_blm()
        blm = ss.beams[0][0].blm
        blmI = blm[0].copy()
        blmE, blmB = tools.spin2eb(blm[1], blm[2])

        # Rotate blm to match centroid.
        # Note that rotate_alm uses the ZYZ euler convention.
        # Note that we include polang here as first rotation.
        q_off = ss.det_offset(az_off, el_off, polang)
        ra, dec, pa = ss.quat2radecpa(q_off)

        # convert between healpy and math angle conventions
        phi = np.radians(ra)
        theta = np.radians(90 - dec)
        psi = np.radians(-pa)

        # rotate blm
        hp.rotate_alm([blmI, blmE, blmB], psi, theta, phi, lmax=lmax, mmax=lmax)

        # convert beam coeff. back to spin representation.
        blmm2, blmp2 = tools.eb2spin(blmE, blmB)
        ss.beams[0][0].blm = (blmI, blmm2, blmp2)

    except IndexError as e:
        if ss.mpi_rank != 0:
            pass
        else:
            raise e

    ss.reset_instr_rot()
    ss.reset_hwp_mod()
    
    # Now we use all spin modes.
    ss.scan_instrument_mpi(alm, binning=False, nside_spin=512,
                           max_spin=lmax, interp=True) 

    if ss.mpi_rank == 0:
        plt.figure()
        gs = gridspec.GridSpec(5, 9)
        ax1 = plt.subplot(gs[:2, :6])
        ax2 = plt.subplot(gs[2:4, :6])
        ax4 = plt.subplot(gs[:, 6:])

        samples = np.arange(tod_sym.size)
        ax1.plot(samples, ss.tod, label='Asymmetric Gaussian', linewidth=0.7)
        ax1.plot(samples, tod_sym, label='Symmetric Gaussian', linewidth=0.7,
                 alpha=0.5)
        ax1.legend()

        ax1.tick_params(labelbottom='off')
        sigdiff = ss.tod - tod_sym
        ax2.plot(samples, sigdiff,ls='None', marker='.', markersize=2.)
        ax2.tick_params(labelbottom='off')
        ax1.set_ylabel(r'Signal [$\mu K_{\mathrm{CMB}}$]')
        ax2.set_ylabel(r'asym-sym. [$\mu K_{\mathrm{CMB}}$]')
        ax2.set_xlabel('Sample number')

        ax4.hist(sigdiff, 128, label='Difference')
        ax4.set_xlabel(r'Difference [$\mu K_{\mathrm{CMB}}$]')
        ax4.tick_params(labelleft='off')

        plt.savefig('../scratch/img/tods_interp.png', dpi=250)
        plt.close()
Ejemplo n.º 30
0
def t_lmax():
    '''Time init_detpair as function of lmax, mmax.'''

    os.environ["OMP_NUM_THREADS"] = "1"
    import numpy as np
    import healpy as hp
    from beamconv import ScanStrategy
    from beamconv import Beam

    scan_opts = dict(duration=3600, sample_rate=100)
    mmax_range = np.array([0, 2, 5, 8], dtype=int)
    lmax_range = np.logspace(np.log10(500), np.log10(3000), 8, dtype=int)
    nsides = np.ones_like(lmax_range) * np.nan
    nside_range = 2**np.arange(15)

    timings = np.ones((mmax_range.size, lmax_range.size)) * np.nan
    timings_cpu = np.ones((mmax_range.size, lmax_range.size)) * np.nan

    alm = np.zeros((3, hp.Alm.getsize(lmax=4000)), dtype=np.complex128)

    S = ScanStrategy(**scan_opts)

    for lidx, lmax in enumerate(lmax_range):

        nside = nside_range[np.digitize(0.5 * lmax, nside_range)]
        nsides[lidx] = nside

        for midx, mmax in enumerate(mmax_range):

            beam_opts = dict(az=0,
                             el=0,
                             polang=0,
                             fwhm=40,
                             btype='Gaussian',
                             lmax=lmax,
                             symmetric=mmax == 0)

            beam = Beam(**beam_opts)
            beam.blm

            t0 = time.time()
            t0c = time.clock()
            S.init_detpair(alm,
                           beam,
                           beam_b=None,
                           nside_spin=nside,
                           max_spin=mmax,
                           verbose=False)
            t1 = time.time()
            t1c = time.clock()

            print('{}, {}, {}: {}'.format(lmax, mmax, nside, t1 - t0))
            print('{}, {}, {}: {}'.format(lmax, mmax, nside, t1c - t0c))

            timings[midx, lidx] = t1 - t0
            timings_cpu[midx, lidx] = t1c - t0c

    np.save('./timings.npy', timings)
    np.save('./timings_cpu.npy', timings_cpu)
    np.save('./lmax_range.npy', lmax_range)
    np.save('./mmax_range.npy', mmax_range)
    np.save('./nsides.npy', nsides)