Exemplo n.º 1
0
    def _load_gas_data(self):
        """If gas is present loads gas SFR/Metallicity/Temperatures."""
        if self.obj.simulation.ngas == 0:
            return
        
        sfr_unit = '%s/%s' % (self.obj.units['mass'], self.obj.units['time'])
        dustmass_unit = '%s' % (self.obj.units['mass'])

        sfr = self.obj.yt_dataset.arr(np.zeros(self.obj.simulation.ngas), sfr_unit)
        gZ  = self.obj.yt_dataset.arr(np.zeros(self.obj.simulation.ngas), '')        
        gT  = self.obj.yt_dataset.arr(np.zeros(self.obj.simulation.ngas), self.obj.units['temperature'])
        dustmass = self.obj.yt_dataset.arr(np.zeros(self.obj.simulation.ngas),'')
        #dustmass = self.obj.yt_dataset.arr(np.zeros(self.obj.simulation.ngas), '')#dustmass_unit)
            
        if has_property(self.obj, 'gas', 'sfr'):
            sfr = get_property(self.obj, 'sfr', 'gas').to(sfr_unit)

        if has_property(self.obj, 'gas', 'metallicity'):            
            gZ  = get_property(self.obj, 'metallicity', 'gas')

        if has_property(self.obj, 'gas', 'temperature'):
            gT  = get_property(self.obj, 'temperature', 'gas').to(self.obj.units['temperature'])

        
        if has_property(self.obj, 'gas', 'dustmass'):
            dustmass = get_property(self.obj,'dustmass','gas')
            #dustmass = get_property(self.obj,'dustmass','gas'))#.to(dustmass_unit)


        self.gsfr = sfr
        self.gZ   = gZ
        self.gT   = gT
        self.dustmass = self.obj.yt_dataset.arr(dustmass,'code_mass').in_units('Msun')
Exemplo n.º 2
0
    def _photometry_init(self):
        """Collect particle information for photometry"""
        from caesar.property_manager import get_property, ptype_ints

        memlog('Loading gas and star particles for photometry')
        self._determine_ptypes()

        self.pos = np.empty((0, 3), dtype=MY_DTYPE)
        self.vel = np.empty((0, 3), dtype=MY_DTYPE)
        self.mass = np.empty(0, dtype=MY_DTYPE)
        self.ptype = np.empty(0, dtype=np.int32)
        for ip, p in enumerate(['gas', 'star']):
            data = get_property(self.obj, 'pos',
                                p).to(self.obj.units['length'])
            self.pos = np.append(self.pos, data.d, axis=0)
            data = get_property(self.obj, 'vel',
                                p).to(self.obj.units['velocity'])
            self.vel = np.append(self.vel, data.d, axis=0)
            data = get_property(self.obj, 'mass', p).to(self.obj.units['mass'])
            self.mass = np.append(self.mass, data.d, axis=0)
            self.ptype = np.append(self.ptype,
                                   np.full(len(data),
                                           ptype_ints[p],
                                           dtype=np.int32),
                                   axis=0)
        self._assign_local_lists()
        self._assign_particle_counts()
        memlog('Loaded particle data')

        self._load_gas_data()
        self._load_star_data()
        memlog('Loaded gas and star data')
Exemplo n.º 3
0
    def _load_bh_data(self, select='all'):
        """If blackholes are present, loads BH_Mdot"""

        if select is 'all': 
            flag = [True]*self.obj.simulation.nbh
        else:
            flag = (select>=0)

        if has_property(self.obj, 'bh', 'bhmass'):
            self.bhmass     = self.obj.yt_dataset.arr(get_property(self.obj, 'bhmass', 'bh').d[flag]*1e10, 'Msun/h').to(self.obj.units['mass'])  # I don't know how to convert this automatically
            self.use_bhmass = True
        else:
            mylog.warning('No black holes found')
            self.use_bhmass = False

        if has_property(self.obj, 'bh', 'bhmdot') and self.use_bhmass:
            #units mutlitplied by ((All.UnitMass_in_g / SOLAR_MASS) / (All.UnitTime_in_s / SEC_PER_YEAR))
            bhmdot_unit = '10.22465727143273*Msun/h/yr'
            #bhmdot_unit = '15.036260693283424*Msun/yr'
            #bhmdot_unit = '%s/%s' %(self.obj.units['mass'], self.obj.units['time'])

            bhmdot      = get_property(self.obj, 'bhmdot', 'bh').d[flag] #of course  it is dimentionless
            bhmdot      = self.obj.yt_dataset.arr(bhmdot, bhmdot_unit).to('%s/%s' %(self.obj.units['mass'], self.obj.units['time']))
            self.bhmdot = bhmdot
            #mylog.info('BH_Mdot available, units=%s'%bhmdot_unit)
        else: 
            if self.use_bhmass: 
                mylog.warning('Black holes are there, but BH_Mdot not available!')
Exemplo n.º 4
0
    def _load_star_data(self, select='all'):
        """If star is present load Metallicity if present"""
        if self.obj.simulation.nstar == 0:
            return

        if select is 'all': 
            flag = [True]*self.obj.simulation.nstar
        else:
            flag = (select>=0)

        if has_property(self.obj, 'star', 'metallicity'):
            self.sZ  = get_property(self.obj, 'metallicity', 'star')[flag]
        elif has_property(self.obj, 'star', 'met_tng'):  # try Illustris/TNG alias
            self.sZ  = get_property(self.obj, 'met_tng', 'star')[flag]  
            #self.sZ  = np.sum(self.sZ.T[2:],axis=0)  # first two are H,He; the rest sum to give metallicity
            #self.sZ[self.sZ<0] = 0.  # some (very small) negative values, set to 0
        else:
            mylog.warning('Metallicity not found: setting all stars to solar=0.0134')
            self.sZ = 0.0134*np.ones(self.obj.simulation.nstar,dtype=MY_DTYPE)

        ds = self.obj.yt_dataset
        if has_property(self.obj, 'star', 'aform'):
            self.age  = get_property(self.obj, 'aform', 'star')[flag]  # a_exp at time of formation
        elif has_property(self.obj, 'star', 'aform_tng'):  # try Illustris/TNG alias
            self.age  = get_property(self.obj, 'aform_tng', 'star')[flag]  
            self.age  = abs(self.age)  # some negative values here too; not sure what to do?
        else:
            self.age = np.zeros(self.obj.simulation.nstar,dtype=MY_DTYPE)
            mylog.warning('Stellar age not found -- photometry will be incorrect!')
        if ds.cosmological_simulation:
            from yt.utilities.cosmology import Cosmology
            co = Cosmology(hubble_constant=ds.hubble_constant, omega_matter=ds.omega_matter, omega_lambda=ds.omega_lambda)
            self.age = (ds.current_time - co.t_from_z(1./self.age-1.)).in_units('Gyr').astype(MY_DTYPE)  # age at time of snapshot 
Exemplo n.º 5
0
    def _load_star_data(self):
        """If star is present load Metallicity if present"""
        if self.obj.simulation.nstar == 0:
            return

        if has_property(self.obj, 'star', 'metallicity'):
            self.sZ  = get_property(self.obj, 'metallicity', 'star')
Exemplo n.º 6
0
def reset_global_particle_IDs(obj):
    ''' Maps particle lists from currently loaded ID's to the ID's corresponding to the full snapshot '''

    # determine full particle numbers in snapshot
    from caesar.property_manager import has_ptype, get_property
    offset = np.zeros(len(obj.data_manager.ptypes) + 1, dtype=np.int64)
    for ip, p in enumerate(obj.data_manager.ptypes):
        if not has_ptype(obj, p):
            continue
        count = len(get_property(obj, 'mass', p))
        if p == 'gas':
            offset[ip + 1] = offset[ip] + obj.simulation.ngas
            obj.simulation.ngas = count
        elif p == 'star':
            offset[ip + 1] = offset[ip] + obj.simulation.nstar
            obj.simulation.nstar = count
        elif p == 'bh':
            offset[ip + 1] = offset[ip] + obj.simulation.nbh
            obj.simulation.nbh = count
        elif p == 'dust':
            offset[ip + 1] = offset[ip] + obj.simulation.ndust
            obj.simulation.ndust = count
        elif p == 'dm':
            offset[ip + 1] = offset[ip] + obj.simulation.ndm
            obj.simulation.ndm = count
        elif p == 'dm2':
            offset[ip + 1] = offset[ip] + obj.simulation.ndm2
            obj.simulation.ndm2 = count
        elif p == 'dm3':
            offset[ip + 1] = offset[ip] + obj.simulation.ndm3
            obj.simulation.ndm3 = count

    # reset lists
    for group_type in obj.group_types:
        group_list = 'obj.%s_list' % group_type
        for ip, p in enumerate(obj.data_manager.ptypes):
            if not has_ptype(obj, p):
                continue
            for group in eval(group_list):
                part_list = 'group.%s' % plist_dict[p]
                mylist = eval(part_list)
                mylist = obj.data_manager.indexes[mylist + offset[ip]]
                if p == 'gas': group.glist = mylist
                if p == 'star': group.slist = mylist
                if p == 'bh': group.bhlist = mylist
                if p == 'dust': group.dlist = mylist
                if p == 'dm': group.dmlist = mylist
                if p == 'dm2': group.dm2list = mylist
                if p == 'dm3': group.dm3list = mylist

    return
Exemplo n.º 7
0
    def _load_bh_data(self):
        """If blackholes are present, loads BH_Mdot"""
        from yt.funcs import mylog
        if has_property(self.obj, 'bh', 'bhmass'):
            self.bhmass     = self.obj.yt_dataset.arr(get_property(self.obj, 'bhmass', 'bh').d*1e10,
                                                      'Msun/h').to(self.obj.units['mass'])#I don't know how to convert this automatically
            self.use_bhmass = True
            mylog.info('BH_Mass available, units=1e10 Msun/h')
            mylog.info('Using BH_Mass instead of BH particle masses')
        else:
            mylog.info('Using BH particle mass')

        if has_property(self.obj, 'bh', 'bhmdot'):
            #units mutlitplied by ((All.UnitMass_in_g / SOLAR_MASS) / (All.UnitTime_in_s / SEC_PER_YEAR))
            bhmdot_unit = '10.22465727143273*Msun/h/yr'
            #bhmdot_unit = '15.036260693283424*Msun/yr'
            #bhmdot_unit = '%s/%s' %(self.obj.units['mass'], self.obj.units['time'])

            bhmdot      = get_property(self.obj, 'bhmdot', 'bh').d #of course  it is dimentionless
            bhmdot      = self.obj.yt_dataset.arr(bhmdot, bhmdot_unit).to('%s/%s' %(self.obj.units['mass'], self.obj.units['time']))
            self.bhmdot = bhmdot
            mylog.info('BH_Mdot available, units=%s'%bhmdot_unit)
        else: mylog.warning('BH_Mdot not available')
Exemplo n.º 8
0
def get_mean_interparticle_separation(obj):
    """Calculate the mean interparticle separation and Omega Baryon.

    Parameters
    ----------
    obj : :class:`main.CAESAR`
        Main caesar object.

    Returns
    -------
    mips : float
        Mean inter-particle separation used for calculating FOF's b
        parameter.

    """
    if hasattr(obj.simulation, 'mean_interparticle_separation'):
        return obj.simulation.mean_interparticle_separation

    if obj.yt_dataset.cosmological_simulation == 0:
        mylog.info(
            'Non-cosmological data set detected -- setting units as specified in fubar.py'
        )
        UT = obj.yt_dataset.current_time.to('s/h')
        UL = obj.yt_dataset.length_unit.to('cm/h')
        GRAV = obj.yt_dataset.quan(6.672e-8, 'cm**3/(g*s**2)')
    else:
        UT = obj.yt_dataset.time_unit.to('s/h') / obj.yt_dataset.scale_factor
        UL = obj.yt_dataset.length_unit.to('cmcm/h')
        GRAV = obj.yt_dataset.quan(6.672e-8, 'cmcm**3/(g*s**2)')

    UM = obj.yt_dataset.mass_unit.to('g/h')

    G = GRAV / UL**3 * UM * UT**2  ## to system units
    Hubble = obj.yt_dataset.quan(3.2407789e-18, 'h/s') * UT

    dmmass = get_property(obj, 'mass', 'dm').to('code_mass')
    ndm = len(dmmass)
    dmmass = np.sum(dmmass)

    #   Only need this when the second family (not low res one!) of dark matter particles is presented.
    #     if 'dm2' in obj.data_manager.ptypes:
    #         dmmass2 = get_property(obj, 'mass', 'dm2').to('code_mass')
    #         ndm     += len(dmmass2)
    #         dmmass  += np.sum(dmmass2)

    gmass = obj.yt_dataset.arr(np.array([0.0]), 'code_mass')
    smass = obj.yt_dataset.arr(np.array([0.0]), 'code_mass')
    bhmass = obj.yt_dataset.arr(np.array([0.0]), 'code_mass')
    dustmass = obj.yt_dataset.arr(np.array([0.0]), 'code_mass')

    from caesar.property_manager import has_ptype
    if has_ptype(obj, 'gas'):
        gmass = get_property(obj, 'mass', 'gas').to('code_mass')
    if has_ptype(obj, 'star'):
        smass = get_property(obj, 'mass', 'star').to('code_mass')
    if obj.data_manager.blackholes and has_ptype(obj, 'bh'):
        bhmass = get_property(obj, 'mass', 'bh').to('code_mass')
    if obj.data_manager.dust and has_ptype(obj, 'dust'):
        dustmass = get_property(obj, 'mass', 'dust').to('code_mass')
    bmass = np.sum(gmass) + np.sum(smass) + np.sum(bhmass) + np.sum(dustmass)
    """
    DM = obj.data_manager
    dmmass = DM.mass[DM.dmlist]
    gmass  = DM.mass[DM.glist]
    smass  = DM.mass[DM.slist]
    bhmass = DM.mass[DM.bhlist]

    ndm = len(dmmass)
    
    dmmass = obj.yt_dataset.quan(np.sum(dmmass), obj.units['mass']).to('code_mass')
    bmass  = obj.yt_dataset.quan(np.sum(gmass) + np.sum(smass) + np.sum(bhmass), obj.units['mass']).to('code_mass')
    """
    #if its an idealized simulation, then there's no cosmology and we just take z=0 Planck15 values
    if obj.yt_dataset.cosmological_simulation == 0:
        from astropy.cosmology import Planck15
        Om = Planck15.Om0
        Ob = Planck15.Ob0
    else:
        Om = obj.yt_dataset.cosmology.omega_matter
        Ob = (bmass / (bmass + dmmass) * Om).d

    rhodm = ((Om - Ob) * 3.0 * Hubble**2 / (8.0 * np.pi * G)).d
    rhodm = obj.yt_dataset.quan(rhodm, 'code_mass/code_length**3')

    mips = ((dmmass / ndm / rhodm)**(1. / 3.)).to(obj.units['length'])
    efres = int(obj.simulation.boxsize.d / mips.d)

    obj.simulation.omega_baryon = float(Ob)
    obj.simulation.effective_resolution = efres
    obj.simulation.mean_interparticle_separation = mips

    mylog.info('Calculated Omega_Baryon=%g and %d^3 effective resolution' %
               (Ob, efres))

    return obj.simulation.mean_interparticle_separation
Exemplo n.º 9
0
    def _load_gas_data(self, select='all'):
        """If gas is present loads gas SFR, metallicities, temperatures, nH.
           If select is not 'all', return all particles with select>=0 """

        if self.obj.simulation.ngas == 0:
            return

        sfr_unit = '%s/%s' % (self.obj.units['mass'], self.obj.units['time'])
        dustmass_unit = '%s' % (self.obj.units['mass'])
        gnh_unit = '1/%s**3' % (self.obj.units['length'])

        sfr = self.obj.yt_dataset.arr(
            np.zeros(self.obj.simulation.ngas, dtype=MY_DTYPE), sfr_unit)
        gZ = self.obj.yt_dataset.arr(
            np.zeros(self.obj.simulation.ngas, dtype=MY_DTYPE), '')
        gT = self.obj.yt_dataset.arr(
            np.zeros(self.obj.simulation.ngas, dtype=MY_DTYPE),
            self.obj.units['temperature'])
        gnh = self.obj.yt_dataset.arr(
            np.zeros(self.obj.simulation.ngas, dtype=MY_DTYPE), gnh_unit)
        dustmass = self.obj.yt_dataset.arr(
            np.zeros(self.obj.simulation.ngas, dtype=MY_DTYPE), '')
        gfHI = self.obj.yt_dataset.arr(
            np.zeros(self.obj.simulation.ngas, dtype=MY_DTYPE), '')
        gfH2 = self.obj.yt_dataset.arr(
            np.zeros(self.obj.simulation.ngas, dtype=MY_DTYPE), '')
        ghsml = self.obj.yt_dataset.arr(
            np.zeros(self.obj.simulation.ngas, dtype=MY_DTYPE),
            self.obj.units['length'])
        #dustmass = self.obj.yt_dataset.arr(np.zeros(self.obj.simulation.ngas), '')#dustmass_unit)

        if isinstance(select, str) and select == 'all':
            flag = [True] * self.obj.simulation.ngas
        else:
            flag = (select >= 0)

        if has_property(self.obj, 'gas', 'sfr'):
            sfr = get_property(self.obj, 'sfr', 'gas')[flag].to(sfr_unit)

        if has_property(self.obj, 'gas', 'metallicity'):
            gZ = get_property(self.obj, 'metallicity', 'gas')[flag]
        elif has_property(self.obj, 'gas', 'met_tng'):
            gZ = get_property(self.obj, 'met_tng',
                              'gas')[flag]  # for Illustris, array of mets
        else:
            mylog.warning(
                'Metallicity not found: setting all gas to solar=0.0134')
            gZ = 0.0134 * np.ones(self.obj.simulation.nstar, dtype=MY_DTYPE)

        if has_property(self.obj, 'gas', 'nh'):
            gfHI = get_property(self.obj, 'nh', 'gas')[flag]
        else:
            mylog.warning(
                'HI fractions not found in snapshot, will compute later')

        if has_property(self.obj, 'gas', 'fh2'):
            gfH2 = get_property(self.obj, 'fh2', 'gas')[flag]
        else:
            mylog.warning(
                'H2 fractions not found in snapshot, will compute later')

        if has_property(self.obj, 'gas', 'temperature'):
            gT = get_property(self.obj, 'temperature',
                              'gas')[flag].to(self.obj.units['temperature'])

        if has_property(self.obj, 'gas', 'hsml'):
            ghsml = get_property(self.obj, 'hsml',
                                 'gas')[flag].to(self.obj.units['length'])

        if has_property(self.obj, 'gas', 'rho'):
            from astropy import constants as const
            from yt import YTQuantity
            redshift = self.obj.simulation.redshift
            m_p = YTQuantity.from_astropy(const.m_p)
            gnh = get_property(self.obj, 'rho',
                               'gas')[flag].in_cgs() * 0.76 / m_p.in_cgs()

        if has_property(self.obj, 'gas', 'dustmass'):
            dustmass = get_property(self.obj, 'dustmass', 'gas')[flag]
        else:
            mylog.warning('Dust masses not found in snapshot')

        self.gsfr = sfr
        self.gZ = gZ
        self.gT = gT
        self.gnh = gnh
        self.gfHI = gfHI
        self.gfH2 = gfH2
        self.hsml = ghsml
        self.dustmass = self.obj.yt_dataset.arr(dustmass,
                                                'code_mass').in_units('Msun')
        self.dustmass.dtype = MY_DTYPE
Exemplo n.º 10
0
def get_IC_pos(group,
               ic_ds,
               radius_type,
               search_factor=2.5,
               return_mask=False):
    """Get the initial dark matter positions of a ``CAESAR`` halo.

    If called on a galaxy, it will return the IC DM positions of the
    parent halo.
    
    Parameters
    ----------
    group : :class:`group.Group`
        Group we are querying.
    ic_ds : yt dataset
        The initial condition dataset via ``yt.load()``
    search_factor : float, optional
        How far from the center to select DM particles (defaults to 2.5).
    return_mask : bool, optional
        Return initial condition positions from 0-->1 rather than raw 
        data.  Useful for writing a MUSIC mask file.
    
    Returns
    -------
    ic_dmpos : np.ndarray
        DM positions of this object in the initial condition file.
    
    """
    from caesar.property_manager import ptype_aliases, get_property, DatasetType
    from caesar.periodic_kdtree import PeriodicCKDTree

    ic_ds_type = ic_ds.__class__.__name__
    if ic_ds_type not in ptype_aliases:
        raise NotImplementedError('%s not yet supported' % ic_ds_type)
    if group.obj.yt_dataset.domain_width[0].d != ic_ds.domain_width[0].d:
        raise Exception(
            'IC and SNAP boxes do not match! (%f vs %f)' %
            (ic_ds.domain_width[0].d, group.obj.yt_dataset.domain_width[0].d))
    if str(ic_ds.length_unit) != str(group.obj.yt_dataset.length_unit):
        raise Exception('LENGTH UNIT MISMATCH! '\
                        'This may arise from loading the snap/IC '\
                        'incorrectly and WILL cause problems with '\
                        'the matching process. (%s vs %s)' %
                        (str(ic_ds.length_unit), str(group.obj.yt_dataset.length_unit)))

    if group.obj_type == 'halo':
        obj = group
    elif group.obj_type == 'galaxy':
        if group.halo is None:
            mylog.warning('Galaxy %d has no halo!' % group.GroupID)
            return
        obj = group.halo

    search_params = dict(
        pos=obj.pos.in_units('code_length').d,
        r=obj.radii[radius_type].in_units('code_length').d * search_factor,
    )

    box = ic_ds.domain_width[0].d
    bounds = np.array([box, box, box])

    dmpids = get_property(obj.obj, 'pid', 'dm').d
    dmpos = get_property(obj.obj, 'pos', 'dm').d

    dm_TREE = PeriodicCKDTree(bounds, dmpos)

    valid = dm_TREE.query_ball_point(search_params['pos'], search_params['r'])
    search_params['ids'] = dmpids[valid]

    ic_ds_type = DatasetType(ic_ds)
    ic_dmpos = ic_ds_type.get_property('dm', 'pos').d
    ic_dmpids = ic_ds_type.get_property('dm', 'pid').d

    matches = np.in1d(ic_dmpids, search_params['ids'], assume_unique=True)
    nmatches = len(np.where(matches)[0])
    nvalid = len(valid)
    if nmatches != nvalid:
        raise Exception('Could not match all particles! '\
                        'Only %0.2f%% particles matched.' %
                        (float(nmatches)/float(nvalid) * 100.0))

    mylog.info('MATCHED %d particles from %s %d in %s' %
               (nmatches, obj.obj_type, obj.GroupID, ic_ds.basename))
    mylog.info('Returning %0.2f%% of the total DM from the sim' %
               (float(nmatches) / float(len(ic_dmpids)) * 100.0))

    matched_pos = ic_dmpos[matches]

    if return_mask:
        matched_pos /= box

    return matched_pos