age = np.array([],dtype="float64") pot = np.array([],dtype="float64") for parttype in parttype_list: ids = rs.read_block(snapname,"ID ",parttype=parttype) all_ids = np.append(all_ids, ids) types = np.append(types, np.zeros(len(ids))+parttype) ngas = (types == 0).sum() ndm = (types == 1).sum() nstar = (types == 4).sum() maxid = np.max(all_ids) all_bound_ids = readsubf.subf_ids(base,snapnum,0, 0, long_ids=True,read_all=True).SubIDs rev = np.zeros(maxid+1) - 1 rev[all_bound_ids] = np.arange(len(all_bound_ids),dtype="uint32") r = rev[all_ids] index1 = r > -1 index2 = np.argsort(r[index1]) #================================================================= # List which blocks are in the snapshot: rs.list_blocks(snapname+".0.hdf5") print "\n Are these the required blocks?" raw_input("Press Enter to continue...")
if myrank==0: #read positions and IDs of DM particles: sort the IDs array DM_pos=readsnap.read_block(snapshot_fname,"POS ",parttype=-1) DM_ids=readsnap.read_block(snapshot_fname,"ID ",parttype=-1) print len(DM_ids),np.min(DM_ids),np.max(DM_ids) sorted_ids=DM_ids.argsort(axis=0) del DM_ids #the particle whose ID is N is located in the position sorted_ids[N] #i.e. DM_ids[sorted_ids[N]]=N #the position of the particle whose ID is N would be: #DM_pos[sorted_ids[N]] #read the IDs of the particles belonging to the CDM halos halos_ID=readsubf.subf_ids(groups_fname,groups_number,0,0, long_ids=True,read_all=True) IDs=halos_ID.SubIDs del halos_ID print 'subhalos IDs=',np.min(IDs),np.max(IDs) #read CDM halos information halos=readsubf.subfind_catalog(groups_fname,groups_number, group_veldisp=True,masstab=True, long_ids=True,swap=False) if mass_criteria=='t200': halos_mass=halos.group_m_tophat200*1e10 #masses in Msun/h halos_radius=halos.group_r_tophat200 #radius in kpc/h elif mass_criteria=='m200': halos_mass=halos.group_m_mean200*1e10 #masses in Msun/h halos_radius=halos.group_r_mean200 #radius in kpc/h
def hod(snapshot_fname, groups_fname, groups_number, min_mass, max_mass, fiducial_density, M1, alpha, mass_criteria, verbose=False): thres = 1e-3 #controls the max relative error to accept a galaxy density #read the header and obtain the boxsize head = readsnap.snapshot_header(snapshot_fname) BoxSize = head.boxsize #BoxSize in kpc/h #read positions and IDs of DM particles: sort the IDs array DM_pos = readsnap.read_block(snapshot_fname, "POS ", parttype=-1) #kpc/h DM_ids = readsnap.read_block(snapshot_fname, "ID ", parttype=-1) - 1 sorted_ids = DM_ids.argsort(axis=0) #the particle whose ID is N is located in the position sorted_ids[N] #i.e. DM_ids[sorted_ids[N]]=N #the position of the particle whose ID is N would be: #DM_pos[sorted_ids[N]] #read the IDs of the particles belonging to the CDM halos halos_ID = readsubf.subf_ids(groups_fname, groups_number, 0, 0, long_ids=True, read_all=True) IDs = halos_ID.SubIDs - 1 del halos_ID #read CDM halos information halos = readsubf.subfind_catalog(groups_fname, groups_number, group_veldisp=True, masstab=True, long_ids=True, swap=False) if mass_criteria == 't200': halos_mass = halos.group_m_tophat200 * 1e10 #masses in Msun/h halos_radius = halos.group_r_tophat200 #radius in kpc/h elif mass_criteria == 'm200': halos_mass = halos.group_m_mean200 * 1e10 #masses in Msun/h halos_radius = halos.group_r_mean200 #radius in kpc/h elif mass_criteria == 'c200': halos_mass = halos.group_m_crit200 * 1e10 #masses in Msun/h halos_radius = halos.group_r_crit200 #radius in kpc/h else: print('bad mass_criteria') sys.exit() halos_pos = halos.group_pos #positions in kpc/h halos_len = halos.group_len halos_offset = halos.group_offset halos_indexes = np.where((halos_mass > min_mass) & (halos_mass < max_mass))[0] del halos if verbose: print(' ') print('total halos found=', halos_pos.shape[0]) print('halos number density=', len(halos_pos) / (BoxSize * 1e-3)**3) #keep only the halos in the given mass range halo_mass = halos_mass[halos_indexes] halo_pos = halos_pos[halos_indexes] halo_radius = halos_radius[halos_indexes] halo_len = halos_len[halos_indexes] halo_offset = halos_offset[halos_indexes] del halos_indexes ##### COMPUTE Mmin GIVEN M1 & alpha ##### i = 0 max_iterations = 20 #maximum number of iterations Mmin1 = min_mass Mmin2 = max_mass while (i < max_iterations): Mmin = 0.5 * (Mmin1 + Mmin2) #estimation of the HOD parameter Mmin total_galaxies = 0 inside = np.where(halo_mass > Mmin)[0] #take all galaxies with M>Mmin mass = halo_mass[ inside] #only halos with M>Mmin have central/satellites total_galaxies = mass.shape[0] + np.sum((mass / M1)**alpha) mean_density = total_galaxies * 1.0 / (BoxSize * 1e-3)**3 #galaxies/(Mpc/h)^3 if (np.absolute( (mean_density - fiducial_density) / fiducial_density) < thres): i = max_iterations elif (mean_density > fiducial_density): Mmin1 = Mmin else: Mmin2 = Mmin i += 1 if verbose: print(' ') print('Mmin=', Mmin) print('average number of galaxies=', total_galaxies) print('average galaxy density=', mean_density) ######################################### #just halos with M>Mmin; the rest do not host central/satellite galaxies inside = np.where(halo_mass > Mmin)[0] halo_mass = halo_mass[inside] halo_pos = halo_pos[inside] halo_radius = halo_radius[inside] halo_len = halo_len[inside] halo_offset = halo_offset[inside] del inside #compute number of satellites in each halo using the Poisson distribution N_mean_sat = (halo_mass / M1)**alpha #mean number of satellites N_sat = np.empty(len(N_mean_sat), dtype=np.int32) for i in range(len(N_sat)): N_sat[i] = np.random.poisson(N_mean_sat[i]) N_tot = np.sum(N_sat) + len( halo_mass) #total number of galaxies in the catalogue if verbose: print(' ') print(np.min(halo_mass), '< M_halo <', np.max(halo_mass)) print('total number of galaxies=', N_tot) print('galaxy number density=', N_tot / (BoxSize * 1e-3)**3) #put satellites following the distribution of dark matter in groups if verbose: print(' ') print('Creating mock catalogue ...', ) pos_galaxies = np.empty((N_tot, 3), dtype=np.float32) #index: variable that go through halos (may be several galaxies in a halo) #i: variable that go through all (central/satellites) galaxies #count: find number of galaxies that lie beyond its host halo virial radius index = 0 count = 0 i = 0 while (index < halo_mass.shape[0]): position = halo_pos[index] #position of the DM halo radius = halo_radius[index] #radius of the DM halo #save the position of the central galaxy pos_galaxies[i] = position i += 1 #if halo contains satellites, save their positions Nsat = N_sat[index] if Nsat > 0: offset = halo_offset[index] length = halo_len[index] idss = sorted_ids[IDs[offset:offset + length]] #compute the distances to the halo center keeping those with R<Rvir pos = DM_pos[ idss] #positions of the particles belonging to the halo posc = pos - position #this is to populate correctly halos closer to box boundaries if np.any((position + radius > BoxSize) + (position - radius < 0.0)): inside = np.where(posc[:, 0] > BoxSize / 2.0)[0] posc[inside, 0] -= BoxSize inside = np.where(posc[:, 0] < -BoxSize / 2.0)[0] posc[inside, 0] += BoxSize inside = np.where(posc[:, 1] > BoxSize / 2.0)[0] posc[inside, 1] -= BoxSize inside = np.where(posc[:, 1] < -BoxSize / 2.0)[0] posc[inside, 1] += BoxSize inside = np.where(posc[:, 2] > BoxSize / 2.0)[0] posc[inside, 2] -= BoxSize inside = np.where(posc[:, 2] < -BoxSize / 2.0)[0] posc[inside, 2] += BoxSize radii = np.sqrt(posc[:, 0]**2 + posc[:, 1]**2 + posc[:, 2]**2) inside = np.where(radii < radius)[0] selected = random.sample(inside, Nsat) pos = pos[selected] #aditional, not esential check. Can be comment out posc = pos - position if np.any((posc > BoxSize / 2.0) + (posc < -BoxSize / 2.0)): inside = np.where(posc[:, 0] > BoxSize / 2.0)[0] posc[inside, 0] -= BoxSize inside = np.where(posc[:, 0] < -BoxSize / 2.0)[0] posc[inside, 0] += BoxSize inside = np.where(posc[:, 1] > BoxSize / 2.0)[0] posc[inside, 1] -= BoxSize inside = np.where(posc[:, 1] < -BoxSize / 2.0)[0] posc[inside, 1] += BoxSize inside = np.where(posc[:, 2] > BoxSize / 2.0)[0] posc[inside, 2] -= BoxSize inside = np.where(posc[:, 2] < -BoxSize / 2.0)[0] posc[inside, 2] += BoxSize r_max = np.max( np.sqrt(posc[:, 0]**2 + posc[:, 1]**2 + posc[:, 2]**2)) if r_max > radius: #check no particles beyond Rv selected print(position) print(radius) print(pos) count += 1 for j in range(Nsat): pos_galaxies[i] = pos[j] i += 1 index += 1 if verbose: print('done') #some final checks if i != N_tot: print('some galaxies missing:') print('register', i, 'galaxies out of', N_tot) if count > 0: print('error:', count, 'particles beyond the virial radius selected') return pos_galaxies
DM_pos = readsnap.read_block(snapshot_fname,"POS ",parttype=-1) #kpc/h DM_vel = readsnap.read_block(snapshot_fname,"VEL ",parttype=-1) #km/s #IDs should go from 0 to N-1, instead from 1 to N DM_ids = readsnap.read_block(snapshot_fname,"ID ",parttype=-1)-1 if np.min(DM_ids)!=0 or np.max(DM_ids)!=(len(DM_pos)-1): print 'Error!!!!'; print 'IDs should go from 0 to N-1' print len(DM_ids),np.min(DM_ids),np.max(DM_ids) sorted_ids = DM_ids.argsort(axis=0); del DM_ids #the particle whose ID is N is located in the position sorted_ids[N] #i.e. DM_ids[sorted_ids[N]]=N #the position of the particle whose ID is N would be: #DM_pos[sorted_ids[N]] #read the IDs of the particles belonging to the CDM halos #again the IDs should go from 0 to N-1 halos_ID = readsubf.subf_ids(groups_fname,groups_number,0,0, long_ids=True,read_all=True) IDs = halos_ID.SubIDs-1; del halos_ID print 'subhalos IDs =[',np.min(IDs),'-',np.max(IDs),']' #read CDM halos information halos = readsubf.subfind_catalog(groups_fname,groups_number, group_veldisp=True,masstab=True, long_ids=True,swap=False) if mass_criteria=='t200': halos_mass = halos.group_m_tophat200*1e10 #masses in Msun/h halos_radius = halos.group_r_tophat200 #radius in kpc/h elif mass_criteria=='m200': halos_mass = halos.group_m_mean200*1e10 #masses in Msun/h halos_radius = halos.group_r_mean200 #radius in kpc/h elif mass_criteria=='c200': halos_mass = halos.group_m_crit200*1e10 #masses in Msun/h
def hod(snapshot_fname,groups_fname,groups_number,min_mass,max_mass, fiducial_density,M1,alpha,mass_criteria,verbose=False): thres=1e-3 #controls the max relative error to accept a galaxy density #read the header and obtain the boxsize head=readsnap.snapshot_header(snapshot_fname) BoxSize=head.boxsize #BoxSize in kpc/h #read positions and IDs of DM particles: sort the IDs array DM_pos=readsnap.read_block(snapshot_fname,"POS ",parttype=-1) #kpc/h DM_ids=readsnap.read_block(snapshot_fname,"ID ",parttype=-1)-1 sorted_ids=DM_ids.argsort(axis=0) #the particle whose ID is N is located in the position sorted_ids[N] #i.e. DM_ids[sorted_ids[N]]=N #the position of the particle whose ID is N would be: #DM_pos[sorted_ids[N]] #read the IDs of the particles belonging to the CDM halos halos_ID=readsubf.subf_ids(groups_fname,groups_number,0,0, long_ids=True,read_all=True) IDs=halos_ID.SubIDs-1 del halos_ID #read CDM halos information halos=readsubf.subfind_catalog(groups_fname,groups_number, group_veldisp=True,masstab=True, long_ids=True,swap=False) if mass_criteria=='t200': halos_mass=halos.group_m_tophat200*1e10 #masses in Msun/h halos_radius=halos.group_r_tophat200 #radius in kpc/h elif mass_criteria=='m200': halos_mass=halos.group_m_mean200*1e10 #masses in Msun/h halos_radius=halos.group_r_mean200 #radius in kpc/h elif mass_criteria=='c200': halos_mass=halos.group_m_crit200*1e10 #masses in Msun/h halos_radius=halos.group_r_crit200 #radius in kpc/h else: print 'bad mass_criteria' sys.exit() halos_pos=halos.group_pos #positions in kpc/h halos_len=halos.group_len halos_offset=halos.group_offset halos_indexes=np.where((halos_mass>min_mass) & (halos_mass<max_mass))[0] del halos if verbose: print ' ' print 'total halos found=',halos_pos.shape[0] print 'halos number density=',len(halos_pos)/(BoxSize*1e-3)**3 #keep only the halos in the given mass range halo_mass=halos_mass[halos_indexes] halo_pos=halos_pos[halos_indexes] halo_radius=halos_radius[halos_indexes] halo_len=halos_len[halos_indexes] halo_offset=halos_offset[halos_indexes] del halos_indexes ##### COMPUTE Mmin GIVEN M1 & alpha ##### i=0; max_iterations=20 #maximum number of iterations Mmin1=min_mass; Mmin2=max_mass while (i<max_iterations): Mmin=0.5*(Mmin1+Mmin2) #estimation of the HOD parameter Mmin total_galaxies=0 inside=np.where(halo_mass>Mmin)[0] #take all galaxies with M>Mmin mass=halo_mass[inside] #only halos with M>Mmin have central/satellites total_galaxies=mass.shape[0]+np.sum((mass/M1)**alpha) mean_density=total_galaxies*1.0/(BoxSize*1e-3)**3 #galaxies/(Mpc/h)^3 if (np.absolute((mean_density-fiducial_density)/fiducial_density)<thres): i=max_iterations elif (mean_density>fiducial_density): Mmin1=Mmin else: Mmin2=Mmin i+=1 if verbose: print ' ' print 'Mmin=',Mmin print 'average number of galaxies=',total_galaxies print 'average galaxy density=',mean_density ######################################### #just halos with M>Mmin; the rest do not host central/satellite galaxies inside=np.where(halo_mass>Mmin)[0] halo_mass=halo_mass[inside] halo_pos=halo_pos[inside] halo_radius=halo_radius[inside] halo_len=halo_len[inside] halo_offset=halo_offset[inside] del inside #compute number of satellites in each halo using the Poisson distribution N_mean_sat=(halo_mass/M1)**alpha #mean number of satellites N_sat=np.empty(len(N_mean_sat),dtype=np.int32) for i in range(len(N_sat)): N_sat[i]=np.random.poisson(N_mean_sat[i]) N_tot=np.sum(N_sat)+len(halo_mass) #total number of galaxies in the catalogue if verbose: print ' ' print np.min(halo_mass),'< M_halo <',np.max(halo_mass) print 'total number of galaxies=',N_tot print 'galaxy number density=',N_tot/(BoxSize*1e-3)**3 #put satellites following the distribution of dark matter in groups if verbose: print ' ' print 'Creating mock catalogue ...', pos_galaxies=np.empty((N_tot,3),dtype=np.float32) #index: variable that go through halos (may be several galaxies in a halo) #i: variable that go through all (central/satellites) galaxies #count: find number of galaxies that lie beyond its host halo virial radius index=0; count=0; i=0 while (index<halo_mass.shape[0]): position=halo_pos[index] #position of the DM halo radius=halo_radius[index] #radius of the DM halo #save the position of the central galaxy pos_galaxies[i]=position; i+=1 #if halo contains satellites, save their positions Nsat=N_sat[index] if Nsat>0: offset=halo_offset[index] length=halo_len[index] idss=sorted_ids[IDs[offset:offset+length]] #compute the distances to the halo center keeping those with R<Rvir pos=DM_pos[idss] #positions of the particles belonging to the halo posc=pos-position #this is to populate correctly halos closer to box boundaries if np.any((position+radius>BoxSize) + (position-radius<0.0)): inside=np.where(posc[:,0]>BoxSize/2.0)[0] posc[inside,0]-=BoxSize inside=np.where(posc[:,0]<-BoxSize/2.0)[0] posc[inside,0]+=BoxSize inside=np.where(posc[:,1]>BoxSize/2.0)[0] posc[inside,1]-=BoxSize inside=np.where(posc[:,1]<-BoxSize/2.0)[0] posc[inside,1]+=BoxSize inside=np.where(posc[:,2]>BoxSize/2.0)[0] posc[inside,2]-=BoxSize inside=np.where(posc[:,2]<-BoxSize/2.0)[0] posc[inside,2]+=BoxSize radii=np.sqrt(posc[:,0]**2+posc[:,1]**2+posc[:,2]**2) inside=np.where(radii<radius)[0] selected=random.sample(inside,Nsat) pos=pos[selected] #aditional, not esential check. Can be comment out posc=pos-position if np.any((posc>BoxSize/2.0) + (posc<-BoxSize/2.0)): inside=np.where(posc[:,0]>BoxSize/2.0)[0] posc[inside,0]-=BoxSize inside=np.where(posc[:,0]<-BoxSize/2.0)[0] posc[inside,0]+=BoxSize inside=np.where(posc[:,1]>BoxSize/2.0)[0] posc[inside,1]-=BoxSize inside=np.where(posc[:,1]<-BoxSize/2.0)[0] posc[inside,1]+=BoxSize inside=np.where(posc[:,2]>BoxSize/2.0)[0] posc[inside,2]-=BoxSize inside=np.where(posc[:,2]<-BoxSize/2.0)[0] posc[inside,2]+=BoxSize r_max=np.max(np.sqrt(posc[:,0]**2+posc[:,1]**2+posc[:,2]**2)) if r_max>radius: #check no particles beyond Rv selected print position print radius print pos count+=1 for j in range(Nsat): pos_galaxies[i]=pos[j]; i+=1 index+=1 if verbose: print 'done' #some final checks if i!=N_tot: print 'some galaxies missing:' print 'register',i,'galaxies out of',N_tot if count>0: print 'error:',count,'particles beyond the virial radius selected' return pos_galaxies
def load_subhalos(base_list,snapnum): import numpy as np import readsubf global cat, N_subs, subhalo_Offset, subhalo_Len, subhalo_Pos, subhalo_VelDisp, \ subhalo_Vel, subhalo_Vmax, subhalo_GrNr, subhalo_Parent, subhalo_CM, subhalo_VmaxRad, \ subhalo_IDMostBound, subhalo_Mass, subhalo_Spin, subhalo_HmassRad, subhalo_IDs cat = [0]*len(base_list) N_subs = [0]*len(base_list) subhalo_Offset = [0]*len(base_list) subhalo_Len = [0]*len(base_list) subhalo_Pos = [0]*len(base_list) subhalo_VelDisp = [0]*len(base_list) subhalo_Vel = [0]*len(base_list) subhalo_Vmax = [0]*len(base_list) subhalo_GrNr = [0]*len(base_list) subhalo_Parent = [0]*len(base_list) subhalo_CM = [0]*len(base_list) subhalo_VmaxRad = [0]*len(base_list) subhalo_IDMostBound = [0]*len(base_list) subhalo_Mass = [0]*len(base_list) subhalo_Spin = [0]*len(base_list) subhalo_HmassRad = [0]*len(base_list) subhalo_IDs = [0]*len(base_list) global TEST TEST = [0]*len(base_list) for i in np.arange(len(base_list)): cat[i] = readsubf.subfind_catalog(base_list[i],snapnum,masstab=True) N_subs[i] = cat[i].nsubs TEST[i] = cat[i].group_firstsub print str(N_subs[i])+ " subhalos!" subhalo_Offset[i] = np.zeros(N_subs[i]) subhalo_Len[i] = np.zeros(N_subs[i]) subhalo_Pos[i] = np.zeros([N_subs[i],3]) subhalo_VelDisp[i] = np.zeros(N_subs[i]) subhalo_Vel[i] = np.zeros([N_subs[i],3]) subhalo_Vmax[i] = np.zeros(N_subs[i]) subhalo_GrNr[i] = np.zeros(N_subs[i]) subhalo_Parent[i] = np.zeros(N_subs[i]) subhalo_CM[i] = np.zeros([N_subs[i],3]) subhalo_VmaxRad[i] = np.zeros(N_subs[i]) subhalo_IDMostBound[i] = np.zeros(N_subs[i]) subhalo_Mass[i] = np.zeros(N_subs[i]) subhalo_Spin[i] = np.zeros([N_subs[i],3]) subhalo_HmassRad[i] = np.zeros(N_subs[i]) subhalo_IDs[i] = [0]*N_subs[i] all_ids = readsubf.subf_ids(base_list[i],snapnum,0, 0, long_ids=True,read_all=True).SubIDs for j in np.arange(N_subs[i]): subhalo_Offset[i][j] = cat[i].sub_offset[j] subhalo_Len[i][j] = cat[i].sub_len[j] subhalo_Pos[i][j] = cat[i].sub_pos[j] subhalo_VelDisp[i][j] = cat[i].sub_veldisp[j] subhalo_Vel[i][j] = cat[i].sub_vel[j] subhalo_Vmax[i][j] = cat[i].sub_vmax[j] subhalo_GrNr[i][j] = cat[i].sub_grnr[j] subhalo_Parent[i][j] = cat[i].sub_parent[j] subhalo_CM[i][j] = cat[i].sub_cm[j] subhalo_VmaxRad[i][j] = cat[i].sub_vmaxrad[j] subhalo_IDMostBound[i][j] = cat[i].sub_id_mostbound[j] subhalo_Mass[i][j] = cat[i].sub_mass[j] subhalo_Spin[i][j] = cat[i].sub_spin[j] subhalo_HmassRad[i][j] = cat[i].sub_halfmassrad[j] subhalo_IDs[i][j] = all_ids[subhalo_Offset[i][j]:subhalo_Offset[i][j]]