def __init__(self, title, maxval): self._pbar = tqdm(leave=True, total=maxval, desc=title) self.i = 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)