def test_extrapolate(self): self.Beam = beam.GaussianBeam(self.width, self.frequencies, extrapolate=False) self.assertRaises(Exception, self.Beam.beam_function, 1.0, 6) self.Beam = beam.GaussianBeam(self.width, self.frequencies, extrapolate=True) # Compare FWHM=1 to FWHM = 1/4. Just check normalization. self.assertAlmostEqual(float(self.Beam.beam_function(0, 5.0)), float(self.Beam.beam_function(0, -2.5)) / 4**2)
def test_left_apply_map_norm(self): self.Beam = beam.GaussianBeam(0.2, None) self.map[3, 6, 8] = 1.0 self.map[9, 13, 6] = 2.0 self.map[2, 13, 6] = 1.0 conv_map = self.Beam.apply(self.map) self.assertAlmostEqual(sp.sum(self.map.flat_view()), sp.sum(conv_map.flat_view()), 4)
def test_checks_axes(self): self.op.axes = ('freq', 'ra', 'dec', 'mode1', 'mode2') self.Beam = beam.GaussianBeam([0.2, 0.3], [600, 900]) self.assertRaises(ce.DataError, self.Beam.apply, self.op, right_apply=True) conv_op = self.Beam.apply(self.op) self.assertEqual(conv_op.axes, ('freq', 'ra', 'dec', 'mode1', 'mode2'))
def setUp(self): self.width = (5 + sp.arange(6, dtype=float)) / 5 # between, 1 and 2. self.frequencies = sp.arange(6, dtype=float) self.Beam = beam.GaussianBeam(self.width, self.frequencies) # 1/r^3 correlation function. n = 50 r = sp.arange(n) r[0] = 0.1 self.corr = 1.0 / r[:, None]**2 / r self.corr *= 1.0 / n**3
def test_radial_transform(self): Beam = beam.GaussianBeam(self.width, self.frequencies) width = 6.0 factor = width / 2.0 transform = Beam.radial_transform(width) r = sp.arange(1.5, 6) self.assertTrue( sp.allclose(transform(r), sp.sin(r * factor) / r / factor)) self.assertAlmostEqual(transform(0), 1.0)
def test_apply_right(self): self.op[0, 9, 8, 6, 4] = 2.0 self.op[1, 11, 7, 11, 8] = 2.0 self.op[1, 11, 7, 8, 6] = 1.0 self.map[1, 11, 8] = 2.0 self.map[1, 8, 6] = 1.0 self.Beam = beam.GaussianBeam([0.2, 0.3], [600, 900]) conv_op = self.Beam.apply(self.op, right_apply=True) conv_map = self.Beam.apply(self.map) self.assertAlmostEqual(sp.sum(self.op), sp.sum(conv_op), 3) self.assertTrue(sp.allclose(conv_op[:, 11, 7, :, :], conv_map))
def test_wrap(self): self.Beam = beam.GaussianBeam(0.2, None) self.map[5, 0, 0] = 1.0 conv_map = self.Beam.apply(self.map, wrap=True) self.assertAlmostEqual(sp.sum(self.map.flat_view()), sp.sum(conv_map.flat_view()), 4) self.assertNotAlmostEqual(conv_map[5, 0, 0], 1.0, 3) self.assertNotAlmostEqual(conv_map[5, -1, 0], 0, 3) self.assertNotAlmostEqual(conv_map[5, -1, -1], 0, 3) self.assertAlmostEqual(conv_map[5, -1, 0], conv_map[5, 0, -1]) self.assertAlmostEqual(conv_map[5, -1, -1], conv_map[5, 1, 1])
def test_left_apply_map_vals(self): self.Beam = beam.GaussianBeam(0.2, None) self.map[3, 2, 13] = 1.0 self.map[3, 19, 13] = 1.0 conv_map = self.Beam.apply(self.map) self.assertNotAlmostEqual(conv_map[3, 1, 13], 0, 3) # Check Isotropy self.assertAlmostEqual(conv_map[3, 1, 13], conv_map[3, 3, 13]) self.assertAlmostEqual(conv_map[3, 1, 13], conv_map[3, 2, 12]) self.assertAlmostEqual(conv_map[3, 1, 13], conv_map[3, 2, 14]) # Check 0 lag amplitude. sig = 0.2 / 2 / sp.sqrt(2 * sp.log(2)) self.assertAlmostEqual(conv_map[3, 2, 13], 0.075**2 / (2 * sp.pi * sig**2))
def test_windows(self): Beam = beam.GaussianBeam(self.width, self.frequencies) # Radial window. window, limits = Beam.radial_real_space_window(4.0, 8.0, True) self.assertTrue(sp.allclose(window(sp.array([-6.0, 6, -10.0])), 0)) self.assertTrue( sp.allclose(window(sp.array([-2.0, -1.0, 2.0, 0])), 1 / 8.0)) df = 0.01 self.assertAlmostEqual( sp.sum(window(sp.arange(limits[0], limits[1], df))) * df, 1.0) # Angular window. window, limits = Beam.angular_real_space_window(3.0, 5.0, True) dr = 0.0001 r = sp.arange(limits[0], limits[1], dr) self.assertAlmostEqual( sp.sum(window(r) * r * 2.0 * sp.pi) * dr, 1.0, 4)
def test_beam_function(self): self.Beam = beam.GaussianBeam(self.width, self.frequencies) # Check a case calculated by hand (FWHM=1 here). self.assertAlmostEqual(self.Beam.beam_function(1.0, 5.0), 0.0551589, 6) # Check that the delta r dependance is right. norm = self.Beam.beam_function(0, 3.0) self.assertAlmostEqual( sp.log(self.Beam.beam_function(0.6, 3.0) / norm), sp.log(self.Beam.beam_function(1.2, 3.0) / norm) / 4) # Check that it works if I give an array. self.Beam.beam_function(sp.arange(5.0), 5.0) # Or 2 arrays of the same length. self.Beam.beam_function(sp.arange(5), sp.arange(5)) # But fails if they are different lengths. self.assertRaises(ValueError, self.Beam.beam_function, sp.arange(5), sp.arange(6))
def convolve_by_beam(self): r"""this produces self.sim_map_withbeam""" print "convolving simulation by beam" beamobj = beam.GaussianBeam(self.beam_data, self.beam_freq) self.sim_map_withbeam = beamobj.apply(self.sim_map)
def execute(self, nprocesses=1) : """Function that does all the work. Parameters ---------- nprocesses : int Number of threads to use. So far this program is not threaded. this argument is only included for compatibility with other modules. """ params = self.params #### Front end. Read in the power spectrum, convert it to 2d correlation # function, etc. # corr_function = f(params['unit_system'], params['power_file_name'], # params['power_format']) # Temporary face correlation to make the rest of the code run. corr_function = lambda rho, f : (1.0e6/(rho**2 + 0.001) /(abs(f) + 1.0e3)) #### Units. Figure out the axes in the proper units etc. # Start by getting the map from which we will be getting our axes. map = algebra.open_memmap(params["map_file"], mode='r') map = algebra.make_vect(map) if map.axes != ('freq', 'ra', 'dec') : raise ce.DataError("Expeceted map to be in freq-ra-dec space.") # Next figure out all the axes. nfreq = map.shape[0] nra = map.shape[1] ndec = map.shape[2] freq = map.get_axis('freq') ra = map.get_axis('ra')*sp.cos(sp.pi*map.info['dec_centre']/180.0) dec = map.get_axis('dec') # Coordinate dependant conversion factors. system = params['unit_system'] if system == "deg-freq" : z = freq z_width = sp.ones(nfreq)*map.info['freq_delta'] Drho_Ddeg = sp.ones(nfreq) elif system == "Mpc/h-Mpc/h" : # Do a bunch of cosmology dependant stuff. # Not written yet, so bail here. return else : raise ValueError('Unit system must be one of "deg-freq", ' '"Mpc/h-Mpc/h", "deg-log_freq" or "Mpc/h-mu".') # Get the beam object. # The following is temporary. Eventually need to read beam data from # file. beam_freq = sp.arange(600.0e6, 1000.0e6, 50.0e6) beam_width = 0.3*600.0e6/beam_freq Beam = beam.GaussianBeam(beam_width, beam_freq) # Figure out the range of angular lags we need to consider in our # coordinate system. # First the max lag. # This is inefficient if the range of Drho_Ddeg is very wide. max_lag = (max(ra) - min(ra))**2 + (max(dec) - min(dec))**2 max_lag = sp.sqrt(max_lag)*max(Drho_Ddeg) # Figure out the minimum lag step. lag_step = min([abs(map.info['ra_delta']) * sp.cos(sp.pi*map.info['dec_centre']/180.0), abs(map.info['dec_delta'])]) if max_lag/lag_step > 10*(ndec + nra) : raise RunTimeError("Dynamic range is very large. There will be " "too many integrals to do.") # There is probably a more efficient lag binning than this... peicewise # linear then log? divisions = 10.0 lag = sp.arange(0.0, max_lag + lag_step/divisions, lag_step/divisions) sq_lag = lag**2 nlag = len(lag) #### Integral. Loop over all possible lags and do the integral. # Allowcate memory for all f,f',lag combinations. integrals = sp.empty((nfreq, nfreq, nlag), dtype=float) if self.feedback >= 2 : print "Starting integrals." for find1 in xrange(nfreq) : for find2 in xrange(nfreq) : for lind in xrange(nlag) : # Get separation in radial direction. delta_z = abs(z[find1] - z[find2]) # Get the window functions. W, rho_limits = Beam.angular_real_space_window(freq[find1], freq[find2], return_limits=True) Q, z_limits = Beam.radial_real_space_window(z_width[find1], z_width[find2], return_limits=True) # Construct the integrand. int = integrand(corr_function, W, Q, lag[lind], delta_z) # Integrate. # Reiman sum is the most efficient integration algorithm # known to mankind. z_vals = sp.arange(z_limits[0], z_limits[1], (z_limits[1] - z_limits[0])/20) z_vals = z_vals[None, :] rho_vals = sp.arange(rho_limits[0], rho_limits[1], (rho_limits[1] - rho_limits[0])/20) rho_vals = rho_vals[:, None] result = (sp.sum(int(rho_vals, z_vals)) * (z_limits[1] - z_limits[0])/20 * (rho_limits[1] - rho_limits[0])/20) # Store the result. integrals[find1, find2, lind] = result if self.feedback >= 2 : print "Integrals done." #### Assignment. Allocate memory, loop over elements and assign. # Allowcate memory and build final coraviance matrix object. covariance = algebra.open_memmap(params["out_file_name"], mode='w+', dtype=float, shape=(nfreq, nra, ndec, nfreq, nra, ndec)) covariance = algebra.make_mat(covariance, axis_names=("freq", "ra", "dec","freq", "ra", "dec"), row_axes=(0, 1, 2), col_axes=(3, 4, 5)) covariance.copy_axis_info(map) # Make a matrix of angular pairwise lags. sq_angles = (dec[None, :, None, None] - dec[None, None, None, :])**2 sq_angles = sq_angles + \ (ra[:, None, None, None] - ra[None, None, :, None])**2 if self.feedback >= 2 : print "Filling covariance matrix by interpolation." # Now fill in the elements by interpolating integrals. for find1 in xrange(nfreq) : for find2 in xrange(nfreq) : # The pairwise angular lags in the unit system. this_sq_lag = (sq_angles*(Drho_Ddeg[find1] + Drho_Ddeg[find2])**2/4) # The interpolation function. Perhaps there is a better # algorithm than cubic? interpolator = interpolate.interp1d(sq_lag, integrals[find1,find2,:], bounds_error=True, kind='cubic') covariance[find1,:,:,find2,:,:] = interpolator(this_sq_lag) del covariance, map if self.feedback >= 2 : print "Done"
def test_freq_independant(self): self.Beam = beam.GaussianBeam(1.0) self.assertAlmostEqual(self.Beam.beam_function(1.0, 2.0), 0.0551589, 6) self.assertAlmostEqual(self.Beam.beam_function(1.0, None), 0.0551589, 6)
def test_checks_axes(self): self.map.axes = ('freq', 'lat', 'long') self.Beam = beam.GaussianBeam(0.2, None) self.assertRaises(ce.DataError, self.Beam.apply, self.map)