Esempio n. 1
0
def galaxy_ang_mom(gal_id, basePath, snapNum, reduced=True):
    """
    Parameters
    ----------
    gal_id : int
    basepath : string
    snapNum : int
    Lbox : array_like
    reduced : bool
    Returns
    -------
    eig_vals, eig_vecs
    """

    # load galaxy position (most bound particle)
    gal_positions = loadSubhalos(basePath, snapNum, fields=['SubhaloPos'
                                                            ]) / 1000.0
    gal_position = gal_positions[gal_id]

    # half mass radius
    gal_rhalfs = loadSubhalos(
        basePath, snapNum, fields=['SubhaloHalfmassRadType'])[:, 4] / 1000.0
    gal_rhalf = gal_rhalfs[gal_id]

    # load stellar particles
    ptcl_coords = loadSubhalo(
        basePath, snapNum, gal_id, 4, fields=['Coordinates']) / 1000.0
    ptcl_masses = loadSubhalo(basePath, snapNum, gal_id, 4,
                              fields=['Masses']) * 10.0**10
    ptcl_vels = loadSubhalo(basePath,
                            snapNum,
                            gal_id,
                            4,
                            fields=['Velocities'])
    sf_time = loadSubhalo(basePath,
                          snapNum,
                          gal_id,
                          4,
                          fields=['GFM_StellarFormationTime'])
    is_a_star = (sf_time >= 0.0)  # don't use wind particles

    # account for PBCs
    dx = ptcl_coords[:, 0] - gal_position[0]
    dy = ptcl_coords[:, 1] - gal_position[1]
    dz = ptcl_coords[:, 2] - gal_position[2]

    ptcl_coords = np.vstack((dx, dy, dz)).T

    r = np.sqrt(np.sum(ptcl_coords**2, axis=1)) / gal_rhalf
    mask = (r <= 10.0) & (is_a_star)

    L = specific_angular_momentum(ptcl_coords[mask], ptcl_vels[mask],
                                  ptcl_masses[mask])

    mag_L = np.sqrt(np.sum(L**2, axis=-1))

    return L, mag_L, L / mag_L
Esempio n. 2
0
def particle_selection(gal_id, ptcl_coords, galaxy_table, basePath, snapNum, radial_mask=True, num_r_half=10):
    """
    Apply the selection criteria to galaxy particles

    Returns
    -------
    mask : numpy.array
       boolean array of shape (nptcls,)
    """

    # don't use wind particles
    sf_time = loadSubhalo(basePath, snapNum, gal_id, 4, fields=['GFM_StellarFormationTime'])
    star_mask = (sf_time>=0.0) # don't use wind particles

    # get the half mass radius
    gal_rhalfs = galaxy_table['SubhaloHalfmassRadType'][:,4]/1000.0
    gal_rhalf = gal_rhalfs[gal_id]

    # use only particles within 2 * R_half
    r = np.sqrt(np.sum(ptcl_coords**2, axis=1))/gal_rhalf
    if radial_mask:
        radial_mask = (r<=num_r_half)
    else:
        radial_mask = np.array([True]*len(star_mask))

    return (radial_mask) & (star_mask)
Esempio n. 3
0
def getData(basepath, snapNum, subhaloNum, parttype):
    '''
    Given snapNum, subhaloNum, and particle type, return the position vector, 
      velocity vector, and mass vector for all particles.
    Return in units of kpc, km/s, M_sun.
    '''
    fields = ['Coordinates', 'Velocities', 'ParticleIDs']
    if parttype in [0, 4]:
        fields.append('Masses')
        fields.append('GFM_Metallicity')
    if parttype == 4:
        fields.append('GFM_StellarPhotometrics')
    data = loadSubhalo(basepath, snapNum, subhaloNum, parttype, fields=fields)
    if parttype == 1:
        data['Masses'] = np.ones(len(data['Coordinates']))*MdarkPart
    data['Coordinates'] /= h0
    # z = snap2z(snapNum)
    # data['Coordinates'] /= (1 + z) # don't forget redshift
    if parttype in [0,4]:
        data['Masses'] *= massUnit

    subhalo = loadSingle(basepath, snapNum, subhaloID=subhaloNum)
    data['HalfMassRad'] = subhalo['SubhaloHalfmassRadType'][parttype] / h0 # / (1 + z)
    data['SubhaloPos'] = subhalo['SubhaloPos'] / h0

    return data
Esempio n. 4
0
def galaxy_circularity(gal_id, galaxy_table, basePath, snapNum, Lbox, num_r_half):
    """
    Parameters
    ----------
    gal_id : int

    basepath : string

    snapNum : int

    Lbox : array_like

    reduced : bool

    Returns
    -------
    eig_vals, eig_vecs
    """

    # choose a 'center' for each galaxy
    gal_position = galaxy_center(gal_id, galaxy_table)

    # load stellar particle positions and masses
    ptcl_coords = loadSubhalo(basePath, snapNum, gal_id, 4, fields=['Coordinates'])/1000.0
    ptcl_vels = loadSubhalo(basePath, snapNum, gal_id, 4, fields=['Velocities'])
    ptcl_masses = loadSubhalo(basePath, snapNum, gal_id, 4, fields=['Masses'])*10.0**10

    # center and account for PBCs
    ptcl_coords = format_particles(gal_position, ptcl_coords, Lbox)

    # use center of mass velocity to subtract bulk velocity
    ptcl_vels = format_velocities(ptcl_vels, ptcl_masses, basePath, snapNum)

    # use a subset of particles
    ptcl_mask = particle_selection(gal_id, ptcl_coords, galaxy_table, basePath, snapNum, radial_mask=True, num_r_half=num_r_half)

    # specific angular momentum of the system
    L = specific_angular_momentum(ptcl_coords[ptcl_mask], ptcl_vels[ptcl_mask], ptcl_masses[ptcl_mask])

    # fraction of stellar mass with circularity > a threshold
    f_disk = disk_fraction(ptcl_coords[ptcl_mask], ptcl_vels[ptcl_mask], ptcl_masses[ptcl_mask], L, e_thresh=0.7)

    return f_disk, L
def halo_shape(halo_id,
               halo_table,
               basePath,
               snapNum,
               Lbox,
               shape_type='reduced'):
    """
    Parameters
    ----------
    halo_id : int

    basepath : string

    snapNum : int

    Lbox : array_like

    shape_type : string

    Returns
    -------
    eig_vals, eig_vecs
    """

    # choose a 'center' for each galaxy
    halo_position = halo_center(halo_id, halo_table)

    # load stellar particle positions and masses
    ptcl_coords = loadSubhalo(
        basePath, snapNum, halo_id, 1, fields=['Coordinates']) / 1000.0

    # center and account for PBCs
    ptcl_coords = format_particles(halo_position, ptcl_coords, Lbox)

    if shape_type == 'reduced':
        I = reduced_inertia_tensors(ptcl_coords)
    elif shape_type == 'non-reduced':
        I = inertia_tensors(ptcl_coords)
    elif shape_type == 'iterative':
        I = iterative_inertia_tensors_3D(ptcl_coords, rtol=0.01, niter_max=10)
    else:
        msg = ('tensor calculation type not recognized.')
        raise ValueError(msg)

    evals, evecs = np.linalg.eigh(I)
    evals = np.sqrt(evals)

    return evals[0], evecs[0]
def galaxy_circularity(gal_id, galaxy_table, basePath, snapNum, Lbox,
                       num_r_half, m_dm):
    """
    Parameters
    ----------
    gal_id : int

    basepath : string

    snapNum : int

    Lbox : array_like

    reduced : bool

    Returns
    -------
    eig_vals, eig_vecs
    """

    # choose a 'center' for each galaxy
    gal_position = galaxy_center(gal_id, galaxy_table)

    # load stellar particle positions and masses
    ptcl_coords = loadSubhalo(
        basePath, snapNum, gal_id, 4, fields=['Coordinates']) / 1000.0
    ptcl_vels = loadSubhalo(basePath,
                            snapNum,
                            gal_id,
                            4,
                            fields=['Velocities'])
    ptcl_masses = loadSubhalo(basePath, snapNum, gal_id, 4,
                              fields=['Masses']) * 10.0**10

    # load all particles positions and masses
    all_ptcl_coords = loadSubhaloAll(
        basePath, snapNum, gal_id, field='Coordinates') / 1000.0
    all_ptcl_masses = loadSubhaloAll(
        basePath, snapNum, gal_id, field='Masses', m_dm=m_dm) * 10.0**10

    # center and account for PBCs
    ptcl_coords = format_particles(gal_position, ptcl_coords, Lbox)
    all_ptcl_coords = format_particles(gal_position, all_ptcl_coords, Lbox)

    # use center of mass velocity to subtract bulk velocity
    ptcl_vels = format_velocities(ptcl_vels, ptcl_masses, basePath, snapNum)

    # use a subset of particles for stellar properties
    ptcl_mask = particle_selection(gal_id,
                                   ptcl_coords,
                                   galaxy_table,
                                   basePath,
                                   snapNum,
                                   radial_mask=True,
                                   num_r_half=num_r_half)

    # specific angular momentum of the stellar system (use selected disk stars)
    L = specific_angular_momentum(ptcl_coords[ptcl_mask], ptcl_vels[ptcl_mask],
                                  ptcl_masses[ptcl_mask])

    # radial position of stellar particles
    r = np.sqrt(np.sum(ptcl_coords * ptcl_coords, axis=-1))

    # circular velocity at the radial position of stellar particles
    v_circs = circular_velocity(r, all_ptcl_coords, all_ptcl_masses)

    # circularity parameter for stellar particles
    epsilons = circularity(ptcl_coords, ptcl_vels, ptcl_masses, v_circs, L)

    # fraction of stellar mass with circularity > a threshold (use selected disk stars)
    f_disk = disk_fraction(ptcl_masses[ptcl_mask],
                           epsilons[ptcl_mask],
                           disk_threshold=0.7)

    return f_disk, L
def loadSubhaloAll(basePath, snapNum, gal_id, field, m_dm=None):
    """
    Load particles/cells (of all types) for a single field.

    Parameters
    ----------
    basePath :

    snapNum :

    gal_id : int

    field : string

    m_dm : float
        dark matter particle mass

    Returns
    -------
    result : numpy.array

    Notes
    -----
    This is a simple wrapper around the illustris_python.loadSubhalo() function.
    """

    ptypes = [0, 1, 4, 5]

    # must hard code in various behaviour for different fields
    fields = ['Coordinates', 'Masses']
    if field not in fields:
        msg = ('field must be one of:', fields)
        raise ValueError(msg)

    # since all dm particle masses are the same,
    # this quantity isn't stored in the table.
    if (field == 'Masses') & (m_dm is None):
        msg = ('dm particle mass must be passed if field==Masses')
        raise ValueError(msg)

    data = []
    for ptype in ptypes:

        # create dm mass array
        if (ptype == 1) & (field == 'Masses'):
            x = loadSubhalo(basePath,
                            snapNum,
                            gal_id,
                            ptype,
                            fields=['ParticleIDs'])
            # if no particles are found, loadSubhalo returns {'count': 0}
            if type(x) is dict:
                x = []
            x = np.array([m_dm] * len(x), dtype='float32') / 10.0**10
        else:
            x = loadSubhalo(basePath, snapNum, gal_id, ptype, fields=[field])

        # if no particles are found, loadSubhalo returns {'count': 0}
        if type(x) is dict:
            pass
        else:
            data.append(x)

    if field in [fields[1]]:
        return np.hstack(tuple(data))
    else:
        return np.vstack(tuple(data))
def galaxy_shape(gal_id,
                 galaxy_table,
                 basePath,
                 snapNum,
                 Lbox,
                 shape_type='reduced'):
    """
    Parameters
    ----------
    gal_id : int

    basepath : string

    snapNum : int

    Lbox : array_like

    reduced : bool

    Returns
    -------
    eig_vals, eig_vecs
    """

    # choose a 'center' for each galaxy
    gal_position = galaxy_center(gal_id, galaxy_table)

    # load stellar particle positions and masses
    ptcl_coords = loadSubhalo(
        basePath, snapNum, gal_id, 4, fields=['Coordinates']) / 1000.0
    ptcl_masses = loadSubhalo(basePath, snapNum, gal_id, 4,
                              fields=['Masses']) * 10.0**10

    # center and account for PBCs
    ptcl_coords = format_particles(gal_position, ptcl_coords, Lbox)

    # make a selection cut on the particles
    if shape_type == 'non-reduced':
        ptcl_mask = particle_selection(gal_id,
                                       ptcl_coords,
                                       galaxy_table,
                                       basePath,
                                       snapNum,
                                       radial_mask=True)
    else:
        ptcl_mask = particle_selection(gal_id,
                                       ptcl_coords,
                                       galaxy_table,
                                       basePath,
                                       snapNum,
                                       radial_mask=True)

    if shape_type == 'reduced':
        I = reduced_inertia_tensors(ptcl_coords[ptcl_mask],
                                    ptcl_masses[ptcl_mask])
    elif shape_type == 'non-reduced':
        I = inertia_tensors(ptcl_coords[ptcl_mask], ptcl_masses[ptcl_mask])
    elif shape_type == 'iterative':
        I = iterative_inertia_tensors_3D(ptcl_coords[ptcl_mask],
                                         ptcl_masses[ptcl_mask],
                                         rtol=0.01,
                                         niter_max=10)
    else:
        msg = ('tensor calculation type not recognized.')
        raise ValueError(msg)

    evals, evecs = np.linalg.eigh(I)
    evals = np.sqrt(evals)

    return evals[0], evecs[0]