Beispiel #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
Beispiel #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
Beispiel #3
0
def observational_lightcone_to_physical(observational_lightcone, input_freqs,
                                        input_dtheta):
    '''
    Interpolate a lightcone volume measured in observational (angle/frequency)
    units into  physical (length) units. The output resolution will be set
    to the coarest one, as determined either by the angular or the frequency
    resolution. The lightcone must have the LoS as the last index, with 
    frequencies decreasing along the LoS.
    
    Parameters:
        * observational_lightcone (numpy array): the input lightcone volume
        * input_freqs (numpy array): the frequency in MHz of each slice along the 
            line of sight of the input
        * input_dheta (float): the angular size of a cell in arcmin
        
    Returns:
        * The output volume
        * The redshifts along the LoS of the output
        * The output cell size in Mpc
    '''
    assert input_freqs[0] > input_freqs[-1]
    assert observational_lightcone.shape[0] == observational_lightcone.shape[1]

    #Determine new cell size - set either by frequency or angle.
    #The FoV size in Mpc is set by the lowest redshift
    dnu = input_freqs[0] - input_freqs[1]
    z_low = cm.nu_to_z(input_freqs[0])
    fov_deg = observational_lightcone.shape[0] * input_dtheta / 60.
    fov_mpc = fov_deg / cm.angular_size_comoving(1., z_low)
    cell_size_perp = fov_mpc / observational_lightcone.shape[0]
    cell_size_par = cm.nu_to_cdist(input_freqs[-1]) - cm.nu_to_cdist(
        input_freqs[-2])
    output_cell_size = max([cell_size_par, cell_size_perp])
    hf.print_msg('Making physical lightcone with cell size %.2f Mpc' %
                 output_cell_size)
    #Go through each slice along frequency axis. Cut off excess and
    #interpolate down to correct resolution
    n_cells_perp = int(fov_mpc / output_cell_size)
    output_volume_par = np.zeros(
        (n_cells_perp, n_cells_perp, observational_lightcone.shape[2]))
    for i in range(output_volume_par.shape[2]):
        z = cm.nu_to_z(input_freqs[i])
        output_volume_par[:,:,i] = angular_slice_to_physical(observational_lightcone[:,:,i],\
                                                    z, slice_size_deg=fov_deg, output_cell_size=output_cell_size,\
                                                    output_size_mpc=fov_mpc, order=2)
    #Bin along frequency axis
    output_volume, output_redshifts = bin_lightcone_in_mpc(output_volume_par, \
                                                input_freqs, output_cell_size)

    return output_volume, output_redshifts, output_cell_size
def observational_lightcone_to_physical(observational_lightcone, input_freqs, input_dtheta):
    '''
    Interpolate a lightcone volume measured in observational (angle/frequency)
    units into  physical (length) units. The output resolution will be set
    to the coarest one, as determined either by the angular or the frequency
    resolution. The lightcone must have the LoS as the last index, with 
    frequencies decreasing along the LoS.
    
    Parameters:
        * observational_lightcone (numpy array): the input lightcone volume
        * input_freqs (numpy array): the frequency in MHz of each slice along the 
            line of sight of the input
        * input_dheta (float): the angular size of a cell in arcmin
        
    Returns:
        * The output volume
        * The redshifts along the LoS of the output
        * The output cell size in Mpc
    '''
    assert input_freqs[0] > input_freqs[-1]
    assert observational_lightcone.shape[0] == observational_lightcone.shape[1]
    
    #Determine new cell size - set either by frequency or angle.
    #The FoV size in Mpc is set by the lowest redshift
    dnu = input_freqs[0]-input_freqs[1]
    z_low = cm.nu_to_z(input_freqs[0])
    fov_deg = observational_lightcone.shape[0]*input_dtheta/60.
    fov_mpc = fov_deg/cm.angular_size_comoving(1., z_low)
    cell_size_perp = fov_mpc/observational_lightcone.shape[0]
    cell_size_par = cm.nu_to_cdist(input_freqs[-1])-cm.nu_to_cdist(input_freqs[-2])
    output_cell_size = max([cell_size_par, cell_size_perp])
    hf.print_msg('Making physical lightcone with cell size %.2f Mpc' % output_cell_size)
    #Go through each slice along frequency axis. Cut off excess and 
    #interpolate down to correct resolution
    n_cells_perp = int(fov_mpc/output_cell_size)
    output_volume_par = np.zeros((n_cells_perp, n_cells_perp, observational_lightcone.shape[2]))
    for i in range(output_volume_par.shape[2]):
        z = cm.nu_to_z(input_freqs[i])
        output_volume_par[:,:,i] = angular_slice_to_physical(observational_lightcone[:,:,i],\
                                                    z, slice_size_deg=fov_deg, output_cell_size=output_cell_size,\
                                                    output_size_mpc=fov_mpc, order=2)
    #Bin along frequency axis
    output_volume, output_redshifts = bin_lightcone_in_mpc(output_volume_par, \
                                                input_freqs, output_cell_size)
    
    return output_volume, output_redshifts, output_cell_size
Beispiel #5
0
def physical_lightcone_to_observational(physical_lightcone,
                                        input_z_low,
                                        output_dnu,
                                        output_dtheta,
                                        input_box_size_mpc=None):
    '''
    Interpolate a lightcone volume from physical (length) units
    to observational (angle/frequency) units.
    
    Parameters:
        * physical_lightcone (numpy array): the lightcone volume
        * input_z_low (float): the lowest redshift of the input lightcone
        * output_dnu (float): the frequency resolution of the output volume in MHz
        * output_dtheta (float): the angular resolution of the output in arcmin
        * input_box_size_mpc (float): the size of the input FoV in Mpc.
            If None (default), this will be set to conv.LB
            
    Returns:
        * The output volume as a numpy array
        * The output frequencies in MHz as an array of floats
    '''
    if input_box_size_mpc == None:
        input_box_size_mpc = conv.LB

    #For each output redshift: average the corresponding slices
    hf.print_msg('Making observational lightcone...')
    hf.print_msg('Binning in frequency...')
    lightcone_freq, output_freqs = bin_lightcone_in_frequency(physical_lightcone,\
                                                         input_z_low, input_box_size_mpc, output_dnu)
    #Calculate the FoV in degrees at lowest z (largest one)
    fov_deg = cm.angular_size_comoving(input_box_size_mpc, input_z_low)
    #Calculate dimensions of output volume
    n_cells_theta = fov_deg * 60. / output_dtheta
    n_cells_nu = len(output_freqs)
    #Go through each slice and make angular slices for each one
    hf.print_msg('Binning in angle...')
    output_volume = np.zeros((n_cells_theta, n_cells_theta, n_cells_nu))
    for i in range(n_cells_nu):
        if i % 10 == 0:
            hf.print_msg('Slice %d of %d' % (i, n_cells_nu))
        z = cm.nu_to_z(output_freqs[i])
        output_volume[:,:,i] = physical_slice_to_angular(lightcone_freq[:,:,i], z, \
                                        slice_size_mpc=input_box_size_mpc, fov_deg=fov_deg,\
                                        dtheta=output_dtheta, order=2)

    return output_volume, output_freqs
def physical_lightcone_to_observational(physical_lightcone, input_z_low, output_dnu, output_dtheta, input_box_size_mpc=None):
    '''
    Interpolate a lightcone volume from physical (length) units
    to observational (angle/frequency) units.
    
    Parameters:
        * physical_lightcone (numpy array): the lightcone volume
        * input_z_low (float): the lowest redshift of the input lightcone
        * output_dnu (float): the frequency resolution of the output volume in MHz
        * output_dtheta (float): the angular resolution of the output in arcmin
        * input_box_size_mpc (float): the size of the input FoV in Mpc.
            If None (default), this will be set to conv.LB
            
    Returns:
        * The output volume as a numpy array
        * The output frequencies in MHz as an array of floats
    '''
    if input_box_size_mpc == None:
        input_box_size_mpc = conv.LB
    
    #For each output redshift: average the corresponding slices
    hf.print_msg('Making observational lightcone...')
    hf.print_msg('Binning in frequency...')
    lightcone_freq, output_freqs = bin_lightcone_in_frequency(physical_lightcone,\
                                                         input_z_low, input_box_size_mpc, output_dnu)
    #Calculate the FoV in degrees at lowest z (largest one)
    fov_deg = cm.angular_size_comoving(input_box_size_mpc, input_z_low)
    #Calculate dimensions of output volume
    n_cells_theta = fov_deg*60./output_dtheta
    n_cells_nu = len(output_freqs)
    #Go through each slice and make angular slices for each one
    hf.print_msg('Binning in angle...')
    output_volume = np.zeros((n_cells_theta, n_cells_theta, n_cells_nu))
    for i in range(n_cells_nu):
        if i%10 == 0:
            hf.print_msg('Slice %d of %d' % (i, n_cells_nu))
        z = cm.nu_to_z(output_freqs[i])
        output_volume[:,:,i] = physical_slice_to_angular(lightcone_freq[:,:,i], z, \
                                        slice_size_mpc=input_box_size_mpc, fov_deg=fov_deg,\
                                        dtheta=output_dtheta, order=2)
        
    return output_volume, output_freqs