Пример #1
0
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...")

Пример #2
0
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
Пример #5
0
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
Пример #6
0
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]]