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 calc_dt_lightcone(xfrac, dens, lowest_z, los_axis=2): ''' Calculate the differential brightness temperature assuming T_s >> T_CMB for lightcone data. Parameters: * xfrac (string or numpy array): the name of the ionization fraction file (must be cbin), or the xfrac lightcone data * dens (string or numpy array): the name of the density file (must be cbin), or the density data * lowest_z (float): the lowest redshift of the lightcone volume * los_axis = 2 (int): the line-of-sight axis Returns: The differential brightness temperature as a numpy array with the same dimensions as xfrac. ''' try: xfrac = read_cbin(xfrac) except Exception: pass try: dens = read_cbin(dens) except: pass dens = dens.astype('float64') cell_size = conv.LB / xfrac.shape[(los_axis + 1) % 3] cdist_low = cosmology.z_to_cdist(lowest_z) cdist = np.arange(xfrac.shape[los_axis]) * cell_size + cdist_low z = cosmology.cdist_to_z(cdist) return _dt(dens, xfrac, z)
def calc_dt_lightcone(xfrac, dens, lowest_z, los_axis=2): """ Calculate the differential brightness temperature assuming T_s >> T_CMB for lightcone data. Parameters: * xfrac (string or numpy array): the name of the ionization fraction file (must be cbin), or the xfrac lightcone data * dens (string or numpy array): the name of the density file (must be cbin), or the density data * lowest_z (float): the lowest redshift of the lightcone volume * los_axis = 2 (int): the line-of-sight axis Returns: The differential brightness temperature as a numpy array with the same dimensions as xfrac. """ try: xfrac = read_cbin(xfrac) except Exception: pass try: dens = read_cbin(dens) except: pass dens = dens.astype("float64") cell_size = conv.LB / xfrac.shape[(los_axis + 1) % 3] cdist_low = cosmology.z_to_cdist(lowest_z) cdist = np.arange(xfrac.shape[los_axis]) * cell_size + cdist_low z = cosmology.cdist_to_z(cdist) return _dt(dens, xfrac, z)
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 smooth_lightcone(lightcone, z_array, box_size_mpc=False, max_baseline=2., ratio=1.): """ This smooths in both angular and frequency direction assuming both to be smoothed by same scale. Parameters: * lightcone (numpy array): The lightcone that is to be smoothed. * z_array (float) : The lowest value of the redshift in the lightcone or the whole redshift array. * box_size_mpc (float) : The box size in Mpc. Default value is determined from the box size set for the simulation (set_sim_constants) * max_baseline (float) : The maximun baseline of the telescope in km. Default value is set as 2 km (SKA core). * ratio (int) : It is the ratio of smoothing scale in frequency direction and the angular direction (Default value: 1). Returns: * (Smoothed_lightcone, redshifts) """ if (not box_size_mpc): box_size_mpc=conv.LB if(z_array.shape[0] == lightcone.shape[2]): input_redshifts = z_array.copy() else: z_low = z_array cell_size = 1.0*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) output_dtheta = (1+input_redshifts)*21e-5/max_baseline output_ang_res = output_dtheta*cm.z_to_cdist(input_redshifts) output_dz = ratio*output_ang_res/const.c for i in xrange(len(output_dz)): output_dz[i] = output_dz[i] * hubble_parameter(input_redshifts[i]) output_lightcone = smooth_lightcone_tophat(lightcone, input_redshifts, output_dz) output_lightcone = smooth_lightcone_gauss(output_lightcone, output_ang_res*lightcone.shape[0]/box_size_mpc) return output_lightcone, input_redshifts
def calc_dt_full_lightcone(xfrac, temp, dens, lowest_z, los_axis=2, correct=True): ''' Calculate the differential brightness temperature assuming only that Lyman alpha is fully coupled so T_s = T_k (NOT T_s >> T_CMB) for lightcone data. UNTESTED Parameters: * xfrac (string or numpy array): the name of the ionization fraction file (must be cbin), or the xfrac lightcone data * temp (string or numpy array): the name of the temperature file (must be cbin), or the temp lightcone data * dens (string or numpy array): the name of the density file (must be cbin), or the density data * lowest_z (float): the lowest redshift of the lightcone volume * los_axis = 2 (int): the line-of-sight axis * correct = True (bool): if true include a correction for partially ionized cells. Returns: The differential brightness temperature as a numpy array with the same dimensions as xfrac. ''' try: xfrac = read_cbin(xfrac) except Exception: pass try: temp = read_cbin(temp) except Exception: pass try: dens = read_cbin(dens) except: pass dens = dens.astype('float64') cell_size = conv.LB / xfrac.shape[(los_axis + 1) % 3] cdist_low = cosmology.z_to_cdist(lowest_z) cdist = np.arange(xfrac.shape[los_axis]) * cell_size + cdist_low z = cosmology.cdist_to_z(cdist) print "Redshift: ", str(z) return _dt_full(dens, xfrac, temp, z, correct)
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 calc_dt_full_lightcone(xfrac, temp, dens, lowest_z, los_axis = 2, correct=True): ''' Calculate the differential brightness temperature assuming only that Lyman alpha is fully coupled so T_s = T_k (NOT T_s >> T_CMB) for lightcone data. UNTESTED Parameters: * xfrac (string or numpy array): the name of the ionization fraction file (must be cbin), or the xfrac lightcone data * temp (string or numpy array): the name of the temperature file (must be cbin), or the temp lightcone data * dens (string or numpy array): the name of the density file (must be cbin), or the density data * lowest_z (float): the lowest redshift of the lightcone volume * los_axis = 2 (int): the line-of-sight axis * correct = True (bool): if true include a correction for partially ionized cells. Returns: The differential brightness temperature as a numpy array with the same dimensions as xfrac. ''' try: xfrac = read_cbin(xfrac) except Exception: pass try: temp = read_cbin(temp) except Exception: pass try: dens = read_cbin(dens) except: pass dens = dens.astype('float64') cell_size = conv.LB/xfrac.shape[(los_axis+1)%3] cdist_low = cosmology.z_to_cdist(lowest_z) cdist = np.arange(xfrac.shape[los_axis])*cell_size + cdist_low z = cosmology.cdist_to_z(cdist) print "Redshift: ", str(z) return _dt_full(dens, xfrac,temp, z, correct)
def smooth_lightcone(lightcone, z_array, box_size_mpc=False, max_baseline=2., ratio=1.): """ This smooths in both angular and frequency direction assuming both to be smoothed by same scale. Parameters: * lightcone (numpy array): The lightcone that is to be smoothed. * z_array (float) : The lowest value of the redshift in the lightcone or the whole redshift array. * box_size_mpc (float) : The box size in Mpc. Default value is determined from the box size set for the simulation (set_sim_constants) * max_baseline (float) : The maximun baseline of the telescope in km. Default value is set as 2 km (SKA core). * ratio (int) : It is the ratio of smoothing scale in frequency direction and the angular direction (Default value: 1). Returns: * (Smoothed_lightcone, redshifts) """ if (not box_size_mpc): box_size_mpc = conv.LB if (z_array.shape[0] == lightcone.shape[2]): input_redshifts = z_array.copy() else: z_low = z_array cell_size = 1.0 * 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) output_dtheta = (1 + input_redshifts) * 21e-5 / max_baseline output_ang_res = output_dtheta * cm.z_to_cdist(input_redshifts) output_dz = ratio * output_ang_res / const.c for i in xrange(len(output_dz)): output_dz[i] = output_dz[i] * hubble_parameter(input_redshifts[i]) output_lightcone = smooth_lightcone_tophat(lightcone, input_redshifts, output_dz) output_lightcone = smooth_lightcone_gauss( output_lightcone, output_ang_res * lightcone.shape[0] / box_size_mpc) return output_lightcone, input_redshifts
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