def get_lightcone_subvolume(lightcone, redshifts, central_z, \ depth_mhz=None, depth_mpc=None, odd_num_cells=True, \ subtract_mean=True, fov_Mpc=None): ''' Extract a subvolume from a lightcone, at a given central redshift, and with a given depth. The depth can be specified in Mpc or MHz. You must give exactly one of these parameters. Parameters: * ligthcone (numpy array): the lightcone * redshifts (numpy array): the redshifts along the LOS * central_z (float): the central redshift of the subvolume * depth_mhz (float): the depth of the subvolume in MHz * depth_mpc (float): the depth of the subvolume in Mpc * odd_num_cells (bool): if true, the depth of the box will always be an odd number of cells. This avoids problems with power spectrum calculations. * subtract_mean (bool): if true, subtract the mean of the signal (Default: True) * fov_Mpc (float): the FoV size in Mpc Returns: Tuple with (subvolume, dims) where dims is a tuple with the dimensions of the subvolume in Mpc ''' assert len(np.nonzero([depth_mhz, depth_mpc])) == 1 if fov_Mpc == None: fov_Mpc = conv.LB central_nu = cm.z_to_nu(central_z) if depth_mpc != None: #Depth is given in Mpc central_dist = cm.nu_to_cdist(central_nu) low_z = cm.cdist_to_z(central_dist-depth_mpc/2.) high_z = cm.cdist_to_z(central_dist+depth_mpc/2.) else: #Depth is given in MHz low_z = cm.nu_to_z(central_nu+depth_mhz/2.) high_z = cm.nu_to_z(central_nu-depth_mhz/2.) if low_z < redshifts.min(): raise Exception('Lowest z is outside range') if high_z > redshifts.max(): raise Exception('Highest z is outside range') low_n = int(find_idx(redshifts, low_z)) high_n = int(find_idx(redshifts, high_z)) if (high_n-low_n) % 2 == 0 and odd_num_cells: high_n += 1 subbox = lightcone[:,:,low_n:high_n] if subtract_mean: subbox = st.subtract_mean_signal(subbox, los_axis=2) box_depth = float(subbox.shape[2])/lightcone.shape[1]*fov_Mpc box_dims = (fov_Mpc, fov_Mpc, box_depth) return subbox, box_dims
def get_lightcone_subvolume(lightcone, redshifts, central_z, \ depth_mhz=None, depth_mpc=None, odd_num_cells=True, \ subtract_mean=True, fov_Mpc=None): ''' Extract a subvolume from a lightcone, at a given central redshift, and with a given depth. The depth can be specified in Mpc or MHz. You must give exactly one of these parameters. Parameters: * ligthcone (numpy array): the lightcone * redshifts (numpy array): the redshifts along the LOS * central_z (float): the central redshift of the subvolume * depth_mhz (float): the depth of the subvolume in MHz * depth_mpc (float): the depth of the subvolume in Mpc * odd_num_cells (bool): if true, the depth of the box will always be an odd number of cells. This avoids problems with power spectrum calculations. * subtract_mean (bool): if true, subtract the mean of the signal (Default: True) * fov_Mpc (float): the FoV size in Mpc Returns: Tuple with (subvolume, dims) where dims is a tuple with the dimensions of the subvolume in Mpc ''' assert len(np.nonzero([depth_mhz, depth_mpc])) == 1 if fov_Mpc == None: fov_Mpc = conv.LB central_nu = cm.z_to_nu(central_z) if depth_mpc != None: #Depth is given in Mpc central_dist = cm.nu_to_cdist(central_nu) low_z = cm.cdist_to_z(central_dist - depth_mpc / 2.) high_z = cm.cdist_to_z(central_dist + depth_mpc / 2.) else: #Depth is given in MHz low_z = cm.nu_to_z(central_nu + depth_mhz / 2.) high_z = cm.nu_to_z(central_nu - depth_mhz / 2.) if low_z < redshifts.min(): raise Exception('Lowest z is outside range') if high_z > redshifts.max(): raise Exception('Highest z is outside range') low_n = int(find_idx(redshifts, low_z)) high_n = int(find_idx(redshifts, high_z)) if (high_n - low_n) % 2 == 0 and odd_num_cells: high_n += 1 subbox = lightcone[:, :, low_n:high_n] if subtract_mean: subbox = st.subtract_mean_signal(subbox, los_axis=2) box_depth = float(subbox.shape[2]) / lightcone.shape[1] * fov_Mpc box_dims = (fov_Mpc, fov_Mpc, box_depth) return subbox, box_dims
def smooth_lightcone_tophat(lightcone, redshifts, dz): output_lightcone = np.zeros(lightcone.shape) for i in xrange(output_lightcone.shape[2]): z_out_low = redshifts[i]-dz[i]/2 z_out_high = redshifts[i]+dz[i]/2 idx_low = int(np.ceil(find_idx(redshifts, z_out_low))) idx_high = int(np.ceil(find_idx(redshifts, z_out_high))) output_lightcone[:,:,i] = np.mean(lightcone[:,:,idx_low:idx_high+1], axis=2) return output_lightcone
def smooth_lightcone_tophat(lightcone, redshifts, dz): output_lightcone = np.zeros(lightcone.shape) for i in xrange(output_lightcone.shape[2]): z_out_low = redshifts[i] - dz[i] / 2 z_out_high = redshifts[i] + dz[i] / 2 idx_low = int(np.ceil(find_idx(redshifts, z_out_low))) idx_high = int(np.ceil(find_idx(redshifts, z_out_high))) output_lightcone[:, :, i] = np.mean(lightcone[:, :, idx_low:idx_high + 1], axis=2) return output_lightcone
def bin_lightcone_in_mpc(lightcone, frequencies, cell_size_mpc): ''' Bin a lightcone in Mpc slices along the LoS ''' distances = cm.nu_to_cdist(frequencies) n_output_cells = (distances[-1] - distances[0]) / cell_size_mpc output_distances = np.arange(distances[0], distances[-1], cell_size_mpc) output_lightcone = np.zeros( (lightcone.shape[0], lightcone.shape[1], n_output_cells)) #Bin in Mpc by smoothing and indexing smooth_scale = np.round(len(frequencies) / n_output_cells) tophat3d = np.ones((1, 1, smooth_scale)) tophat3d /= np.sum(tophat3d) lightcone_smoothed = scipy.signal.fftconvolve(lightcone, tophat3d, mode='same') for i in range(output_lightcone.shape[2]): idx = hf.find_idx(distances, output_distances[i]) output_lightcone[:, :, i] = lightcone_smoothed[:, :, idx] output_redshifts = cm.cdist_to_z(output_distances) return output_lightcone, output_redshifts
def bin_lightcone_in_frequency(lightcone, z_low, box_size_mpc, dnu): ''' Bin a lightcone in frequency bins. Parameters: * lightcone (numpy array): the lightcone in length units * z_low (float): the lowest redshift of the lightcone * box_size_mpc (float): the side of the lightcone in Mpc * dnu (float): the width of the frequency bins in MHz Returns: The lightcone, binned in frequencies with high frequencies first The frequencies along the line of sight in MHz ''' #Figure out dimensions and make output volume cell_size = box_size_mpc / lightcone.shape[0] distances = cm.z_to_cdist(z_low) + np.arange( lightcone.shape[2]) * cell_size input_redshifts = cm.cdist_to_z(distances) input_frequencies = cm.z_to_nu(input_redshifts) nu1 = input_frequencies[0] nu2 = input_frequencies[-1] output_frequencies = np.arange(nu1, nu2, -dnu) output_lightcone = np.zeros((lightcone.shape[0], lightcone.shape[1], \ len(output_frequencies))) #Bin in frequencies by smoothing and indexing max_cell_size = cm.nu_to_cdist(output_frequencies[-1]) - cm.nu_to_cdist( output_frequencies[-2]) smooth_scale = np.round(max_cell_size / cell_size) if smooth_scale < 1: smooth_scale = 1 hf.print_msg('Smooth along LoS with scale %f' % smooth_scale) tophat3d = np.ones((1, 1, smooth_scale)) tophat3d /= np.sum(tophat3d) lightcone_smoothed = scipy.signal.fftconvolve(lightcone, tophat3d, mode='same') for i in range(output_lightcone.shape[2]): nu = output_frequencies[i] idx = hf.find_idx(input_frequencies, nu) output_lightcone[:, :, i] = lightcone_smoothed[:, :, idx] return output_lightcone, output_frequencies
def bin_lightcone_in_frequency(lightcone, z_low, box_size_mpc, dnu): ''' Bin a lightcone in frequency bins. Parameters: * lightcone (numpy array): the lightcone in length units * z_low (float): the lowest redshift of the lightcone * box_size_mpc (float): the side of the lightcone in Mpc * dnu (float): the width of the frequency bins in MHz Returns: The lightcone, binned in frequencies with high frequencies first The frequencies along the line of sight in MHz ''' #Figure out dimensions and make output volume cell_size = box_size_mpc/lightcone.shape[0] distances = cm.z_to_cdist(z_low) + np.arange(lightcone.shape[2])*cell_size input_redshifts = cm.cdist_to_z(distances) input_frequencies = cm.z_to_nu(input_redshifts) nu1 = input_frequencies[0] nu2 = input_frequencies[-1] output_frequencies = np.arange(nu1, nu2, -dnu) output_lightcone = np.zeros((lightcone.shape[0], lightcone.shape[1], \ len(output_frequencies))) #Bin in frequencies by smoothing and indexing max_cell_size = cm.nu_to_cdist(output_frequencies[-1])-cm.nu_to_cdist(output_frequencies[-2]) smooth_scale = np.round(max_cell_size/cell_size) if smooth_scale < 1: smooth_scale = 1 hf.print_msg('Smooth along LoS with scale %f' % smooth_scale) tophat3d = np.ones((1,1,smooth_scale)) tophat3d /= np.sum(tophat3d) lightcone_smoothed = fftconvolve(lightcone, tophat3d) for i in range(output_lightcone.shape[2]): nu = output_frequencies[i] idx = hf.find_idx(input_frequencies, nu) output_lightcone[:,:,i] = lightcone_smoothed[:,:,idx] return output_lightcone, output_frequencies
def bin_lightcone_in_mpc(lightcone, frequencies, cell_size_mpc): ''' Bin a lightcone in Mpc slices along the LoS ''' distances = cm.nu_to_cdist(frequencies) n_output_cells = (distances[-1]-distances[0])/cell_size_mpc output_distances = np.arange(distances[0], distances[-1], cell_size_mpc) output_lightcone = np.zeros((lightcone.shape[0], lightcone.shape[1], n_output_cells)) #Bin in Mpc by smoothing and indexing smooth_scale = np.round(len(frequencies)/n_output_cells) tophat3d = np.ones((1,1,smooth_scale)) tophat3d /= np.sum(tophat3d) lightcone_smoothed = fftconvolve(lightcone, tophat3d, mode='same') for i in range(output_lightcone.shape[2]): idx = hf.find_idx(distances, output_distances[i]) output_lightcone[:,:,i] = lightcone_smoothed[:,:,idx] output_redshifts = cm.cdist_to_z(output_distances) return output_lightcone, output_redshifts