Beispiel #1
0
 def __init__(self, title, maxval):
     self._pbar = tqdm(leave=True, total=maxval, desc=title)
     self.i = 0
Beispiel #2
0
def fubar(obj, group_type, **kwargs):
    """Group finding procedure.

    FUBAR stands for Friends-of-friends Unbinding after Rockstar; the
    name is no longer valid, but it stuck.  Here we perform an FOF
    operation for each grouping and create the master caesar lists.

    For halos we consider dark matter + gas + stars.  For galaxies
    however, we only consider high density gas and stars (dust and
    blackholes if included).

    For clouds we consider all gas particles.
    
    Parameters
    ----------
    obj : :class:`main.CAESAR`
        Main caesar object.
    group_type : str
        Can be either 'halo', 'galaxy' or 'cloud'; determines what objects
        we find with FOF.

    """

    #pdb.set_trace()
    pos = obj.data_manager.pos

    unbind = False
    unbind_str = 'unbind_%s' % group_types[group_type]
    if unbind_str in obj._kwargs and \
        isinstance(obj._kwargs[unbind_str], bool):
        unbind = obj._kwargs[unbind_str]
    setattr(obj.simulation, unbind_str, unbind)

    if group_type == 'galaxy':
        if not obj.simulation.baryons_present:
            return

        if ('fof6d' in obj._kwargs and obj._kwargs['fof6d'] == True):

            #set default parameters
            mingrp = 16
            LL_factor = 0.02
            vel_LL = 1.0
            nproc = 1
            LL = get_mean_interparticle_separation(obj) * get_b(
                obj, group_type)  # get MIS and omega_baryon
            if ('fof6d_mingrp' in obj._kwargs
                    and obj._kwargs['fof6d_mingrp'] is not None):
                mingrp = obj._kwargs['fof6d_mingrp']
            if ('fof6d_LL_factor' in obj._kwargs
                    and obj._kwargs['fof6d_LL_factor'] is not None):
                LL_factor = obj._kwargs['fof6d_LL_factor']
            if ('fof6d_vel_LL' in obj._kwargs
                    and obj._kwargs['fof6d_vel_LL'] is not None):
                vel_LL = obj._kwargs['fof6d_vel_LL']
            if ('nproc' in obj._kwargs and obj._kwargs['nproc'] is not None):
                nproc = obj._kwargs['nproc']

            snapname = ('%s/%s' %
                        (obj.simulation.fullpath, obj.simulation.basename))
            mylog.info("Running FOF6D")
            nparts, gas_index, star_index, bh_index = run_fof_6d(
                snapname, mingrp, LL_factor, vel_LL, nproc)
            fof_tags = np.concatenate((gas_index, star_index, bh_index))
            high_rho_indexes = get_high_density_gas_indexes(obj)
            if ('fof6d_outfile' in obj._kwargs):
                fof6d_file = obj._kwargs['fof6d_outfile']
                mylog.info('Writing fof6d particle group info to %s' %
                           fof6d_file)
                with h5py.File(
                        fof6d_file,
                        'w') as hf:  # overwrites existing fof6d group file
                    hf.create_dataset('nparts', data=nparts, compression=1)
                    hf.create_dataset('gas_index',
                                      data=gas_index,
                                      compression=1)
                    hf.create_dataset('star_index',
                                      data=star_index,
                                      compression=1)
                    hf.create_dataset('bh_index', data=bh_index, compression=1)
                    hf.close()
            #assert(obj.simulation.ngas == len(gas_index)) & (obj.simulation.nstar == len(star_index)) & (obj.simulation.nbh == len(bh_index)),'[fubar/fubar]: Assertion failed: Wrong number of particles in fof6d calculation'

        elif ('fof6d_file' in obj._kwargs
              and obj._kwargs['fof6d_file'] is not None):
            # use galaxy info from fof6d hdf5 file
            fof6d_file = obj._kwargs['fof6d_file']
            LL = get_mean_interparticle_separation(obj) * get_b(
                obj, group_type)  # get MIS and omega_baryon
            import os
            if os.path.isfile(fof6d_file):
                mylog.info('Galaxy IDs from fof6d file %s' % fof6d_file)
            else:
                mylog.info('fof6d file %s not found!' % fof6d_file)
            hf = h5py.File(fof6d_file, 'r')
            npfof6d = hf['nparts']
            assert (obj.simulation.ngas == npfof6d[0]) & (
                obj.simulation.nstar == npfof6d[1]
            ) & (
                obj.simulation.nbh == npfof6d[2]
            ), 'Assertion failed: Wrong number of particles in fof6d file: %s' % npfof6d
            gas_indexes = hf['gas_index']
            star_indexes = hf['star_index']
            bh_indexes = hf['bh_index']
            fof_tags = np.concatenate((gas_indexes, star_indexes, bh_indexes))

        else:
            # here we want to perform 3D FOF on high density gas + stars
            mylog.info('Groups based on YT 3DFOF')
            high_rho_indexes = get_high_density_gas_indexes(obj)
            pos0 = pos
            pos = np.concatenate(
                (pos0[obj.data_manager.glist][high_rho_indexes],
                 pos0[obj.data_manager.slist]))
            if obj.data_manager.blackholes:
                pos = np.concatenate((pos, pos0[obj.data_manager.bhlist]))
            if obj.data_manager.dust:
                pos = np.concatenate((pos, pos0[obj.data_manager.dlist]))
            LL = get_mean_interparticle_separation(obj) * get_b(
                obj, group_type)
            fof_tags = fof(obj, pos, LL, group_type=group_type)
            gtags = np.full(obj.simulation.ngas, -1, dtype=np.int64)
            gtags[high_rho_indexes] = fof_tags[0:len(high_rho_indexes)]
            fof_tags = np.concatenate(
                (gtags, fof_tags[len(high_rho_indexes)::]))

    elif group_type == 'cloud':

        #don't run if there's no baryons
        if not obj.simulation.baryons_present:
            return

        #also don't run if fofclouds isn't set
        if ('fofclouds' not in obj._kwargs) or (obj._kwargs['fofclouds']
                                                == False):
            mylog.warning(
                'No clouds: fofclouds either not set, or is set to false: not performing 3D group search for GMCs'
            )
            return

        # here we want to perform FOF on all gas
        pos = pos[obj.data_manager.glist]
        LL = get_mean_interparticle_separation(obj) * get_b(obj, group_type)
        if ('ll_cloud' in obj._kwargs) and isinstance(obj._kwargs['ll_cloud'],
                                                      (int, float)):
            LL = obj._ds.quan(float(obj._kwargs['ll_cloud']), 'kpccm')
        fof_tags = fof(obj, pos, LL, group_type=group_type)

    elif group_type == 'halo':
        if ('fof_from_snap' in obj._kwargs
                and obj._kwargs['fof_from_snap'] == 1):
            mylog.info('Using Halo fof ID from snapshots')
            fof_tags = obj.data_manager.haloid - 1
        else:
            LL = get_mean_interparticle_separation(obj) * get_b(
                obj, group_type)
            fof_tags = fof(obj, pos, LL, group_type=group_type, **kwargs)
        #print 'fof_tags',len(fof_tags[fof_tags>=0]),max(fof_tags),np.shape(fof_tags),fof_tags[fof_tags>=0]

    else:
        mylog.warning('group-type %s not recognized' % group_type)

    tag_sort = np.argsort(fof_tags)

    unique_groupIDs = np.unique(fof_tags)
    groupings = {}
    for GroupID in unique_groupIDs:
        if GroupID < 0: continue
        groupings[GroupID] = create_new_group(obj, group_type)

    if len(groupings) == 0:
        mylog.warning('No %s found!' % group_types[group_type])
        return

    tags = fof_tags

    nparts = len(tags)
    for i in range(0, nparts):
        index = tag_sort[i]
        tag = tags[index]
        if tag < 0: continue
        groupings[tag]._append_global_index(index)

    if unbind: mylog.info('Unbinding %s' % group_types[group_type])

    for v in tqdm(groupings.values(),
                  total=len(groupings),
                  desc='Processing %s' % group_types[group_type]):
        v._process_group()

    n_invalid = 0
    group_list = []
    for v in six.itervalues(groupings):
        if not v._valid:
            n_invalid += 1
            continue
        group_list.append(v)

    mylog.info('Disregarding %d invalid %s (%d left)' %
               (n_invalid, group_types[group_type], len(group_list)))

    # sort by mass
    group_list.sort(key=lambda x: x.masses['total'], reverse=True)
    for i in range(0, len(group_list)):
        group_list[i].GroupID = i

    # initialize global lists
    glist = np.full(obj.simulation.ngas, -1, dtype=np.int32)
    slist = np.full(obj.simulation.nstar, -1, dtype=np.int32)
    dmlist = np.full(obj.simulation.ndm, -1, dtype=np.int32)
    if 'dm2' in obj.data_manager.ptypes:
        dm2list = np.full(obj.simulation.ndm2, -1, dtype=np.int32)
    if 'dm3' in obj.data_manager.ptypes:
        dm3list = np.full(obj.simulation.ndm3, -1, dtype=np.int32)
    bhlist = np.full(obj.simulation.nbh, -1, dtype=np.int32)
    dlist = np.full(obj.simulation.ndust, -1, dtype=np.int32)

    for group in group_list:
        glist[group.glist] = group.GroupID
        slist[group.slist] = group.GroupID
        dmlist[group.dmlist] = group.GroupID
        if 'dm2' in obj.data_manager.ptypes:
            dm2list[group.dm2list] = group.GroupID
        if 'dm3' in obj.data_manager.ptypes:
            dm3list[group.dm3list] = group.GroupID
        bhlist[group.bhlist] = group.GroupID
        dlist[group.dlist] = group.GroupID

        if not hasattr(group, 'unbound_indexes'):
            continue

        glist[group.unbound_indexes[ptype_ints['gas']]] = -2
        slist[group.unbound_indexes[ptype_ints['star']]] = -2
        dmlist[group.unbound_indexes[ptype_ints['dm']]] = -2
        if 'dm2' in obj.data_manager.ptypes:
            dm2list[group.unbound_indexes[ptype_ints['dm2']]] = -2
        if 'dm3' in obj.data_manager.ptypes:
            dm3list[group.unbound_indexes[ptype_ints['dm3']]] = -2
        bhlist[group.unbound_indexes[ptype_ints['bh']]] = -2
        dlist[group.unbound_indexes[ptype_ints['dust']]] = -2

    setattr(obj.global_particle_lists, '%s_glist' % group_type, glist)
    setattr(obj.global_particle_lists, '%s_slist' % group_type, slist)
    setattr(obj.global_particle_lists, '%s_dmlist' % group_type, dmlist)
    if 'dm2' in obj.data_manager.ptypes:
        setattr(obj.global_particle_lists, '%s_dm2list' % group_type, dm2list)
    if 'dm3' in obj.data_manager.ptypes:
        setattr(obj.global_particle_lists, '%s_dm3list' % group_type, dm3list)
    setattr(obj.global_particle_lists, '%s_bhlist' % group_type, bhlist)
    setattr(obj.global_particle_lists, '%s_dlist' % group_type, dlist)

    calculate_local_densities(obj, group_list)

    if group_type == 'halo':
        obj.halos = group_list
        obj.nhalos = len(obj.halos)
        #for ig in range(obj.nhalos):
        #    if ig < 5: print('%d: dm %g gas %g star %g bh %g [%g %g %g] r200 %g vc %g sig %g %g %g'%(ig,np.log10(obj.halos[ig].masses['dm']),np.log10(obj.halos[ig].masses['gas']),np.log10(obj.halos[ig].masses['stellar']),np.log10(obj.halos[ig].masses['bh']),obj.halos[ig].pos[0],obj.halos[ig].pos[1],obj.halos[ig].pos[2],obj.halos[ig].radii['r500c'],obj.halos[ig].virial_quantities['circular_velocity'],obj.halos[ig].velocity_dispersions['gas'],obj.halos[ig].velocity_dispersions['stellar'],obj.halos[ig].velocity_dispersions['dm']))
    elif group_type == 'galaxy':
        obj.galaxies = group_list
        obj.ngalaxies = len(obj.galaxies)
    if group_type == 'cloud':
        obj.clouds = group_list
        obj.nclouds = len(obj.clouds)