Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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