Read Subfind Data
Gadget
contains an on-the-fly halo-finder as described in Springel et al (2001) or Dolag et al (2009). This sections provides an overview of the functions you can use to work with this output. Please note that you need to compile Gadget
with WRITE_SUB_IN_SNAP_FORMAT
to use this functionality.
Please note that since subfind files are equivalent to snapshot files you can use the same functions as in if you Read Snapshot Data.
Reading the header
As in the normal snapshot the subfind output also contains a HEAD
block with useful information. You can read the header of the subfind output into a GadgetIO.SubfindHeader
object by using
GadgetIO.read_subfind_header
— Functionread_subfind_header(filename::String)
Reads the header of a subfind file or file base (without .0, .1, etc.) into a SubfindHeader
struct.
The subfind header contains the fields
Name | Meaning |
---|---|
nhalos::Int32 | number of halos in the output file |
nsubhalos::Int32 | number of subhalos in the output file |
nfof::Int32 | number of particles in the FoF |
ngroups::Int32 | number of large groups in the output file |
time::Float64 | time / scale factor of the simulation |
z::Float64 | redshift of the simulation |
tothalos::UInt32 | total number of halos over all output files |
totsubhalos::UInt32 | total number of subhalos over all output files |
totfof::UInt32 | total number of particles in the FoF |
totgroups::UInt32 | 1 if simulation was run with cooling, else 0 |
num_files::Int32 | number of files over which subfind data is distributed |
boxsize::Float64 | total size of the simulation box |
omega_0::Float64 | Omega matter |
omega_l::Float64 | Omega dark enery |
h0::Float64 | little h |
flag_doubleprecision::Int32 | 1 if snapshot is in double precision, else 0 |
flag_ic_info::Int32 | 1 if initial snapshot file contains an info block, else 0 |
Reading the subfind files
For convenience you can use a helper function provided by GadgetIO.jl
to read the block of the subfind output. Since each of the blocks is only relevant for either halos, subhalos, FoF or large groups you don't need to define a particly type, aka halo type in this case.
GadgetIO.read_subfind
— Functionread_subfind(filename::String, blockname::String)
Example
To read e.g. the virial radius of halos use
R_vir = read_subfind(filename, "RVIR")
read_subfind(filename::String, blockname::String, ids::AbstractVector{<:Integer}; return_haloid::Bool=false)
Reads the block at the given subfind indices (ids
, 0-indexed).
If return_haloid
is true
, returns a tuple of the block array and the corresponding HaloID
s.
Example
# Read the virial masses of the first four halos in subfind:
mvir = read_subfind(filebase, "MVIR", [0, 1, 2, 3])
# or:
mvir, haloids = read_subfind(filebase, "MVIR", [0, 1, 2, 3]; return_haloid=true)
Filtered read-in
If you want to read specific halos from the subfind output you can use the function
GadgetIO.filter_subfind
— Functionfilter_subfind(sub_base::String, filter_function::Function, files=nothing)
Filters all entries in a subfind file that fulfill the 'filter_funcion' requirements and returns a Vector
of HaloIDs.
Examples
# load packages
using GadgetIO, GadgetUnits
# define filter function
function find_mvir_gt_1e15(filename)
h = read_header(filename)
GU = GadgetPhysical(h) # unit conversion
# read Mvir and convert to solar masses
M = read_subfind(filename, "MVIR") .* GU.m_msun
return findall(M .> 1.0e15)
end
# basename of subfind output (without .*)
sub_base = /path/to/groups_000/sub_000
# get relevant halos from first 10 files
halo_ids = filter_subfind(sub_base, find_mvir_gt_1e15, 0:9)
This will return an array of HaloID
s which contain the fields
Name | Meaning |
---|---|
file::Int64 | number of the subfile that contains the halo, e.g. "sub_000.2" |
id::Int64 | position in the block |
Saving/Loading HaloIDs
If you do complex filtering and want to save the result you can use
GadgetIO.save_halo_ids
— Functionsave_halo_ids(filename::String, halo_ids::Vector{HaloID})
Writes a Vector
of HaloIDs to a files.
and load them the next time with
GadgetIO.load_halo_ids
— Functionsave_halo_ids(filename::String)
Loads a Vector
of HaloIDs from a file.
If you want to use HaloID
s with read_blocks_filtered
you can convert convert the HaloID
s to read_positions
by using
GadgetIO.halo_ids_to_read_positions
— Functionhalo_ids_to_read_positions(halo_ids::Vector{HaloID})
Convert a Vector
of HaloID
s to a dictionary of read_positions
. To be used with read_blocks_filtered
.
Reading halo properties
GadgetIO.read_halo_prop
— Functionread_halo_prop(sub_base, haloid::HaloID, blockname::AbstractString; verbose::Bool=true)
Get halo property from block blockname
by halo id. Returns an array or scalar depending on the block type.
read_halo_prop(sub_base, i_global::Integer, blockname::AbstractString; verbose::Bool=true)
Get halo property from block blockname
by global halo index i_global
(zero-based index).
read_halo_prop(sub_base, blocks::AbstractVector{<:AbstractString}, haloids::AbstractVector{HaloID}; verbose::Bool=true)
Get halo properties defined by an Array
of blocks for an Array
of HaloID
s. Please note that this only works if all blocks are of the same halo type. Returns a dictionary with all requested blocks.
read_halo_prop(sub_base, blocks::AbstractVector{<:AbstractString}, haloid::HaloID; verbose::Bool=true)
Get halo properties defined by an Array
of blocks for a HaloID
. Please note that this only works if all blocks are of the same halo type. Returns a dictionary with all requested blocks.
read_halo_prop(sub_base, block::AbstractString, haloids::AbstractVector{HaloID}; verbose::Bool=true)
Get halo properties defined by the block for an Array
of HaloID
s. Returns an array with the requested block.
read_halo_prop(sub_base, blocks::AbstractVector{<:AbstractString}, i_global::AbstractVector{<:Integer}; verbose::Bool=true)
Get halo properties defined by an Array
of blocks for an Array
of global indices. Please note that this only works if all blocks are of the same halo type. Returns a dictionary with all requested blocks.
read_halo_prop(sub_base, blocks::AbstractVector{<:AbstractString}, i_global::Integer; verbose::Bool=true)
Get halo properties defined by an Array
of blocks for a global index. Please note that this only works if all blocks are of the same halo type. Returns a dictionary with all requested blocks.
read_halo_prop(sub_base, block::AbstractString, i_global::AbstractVector{<:Integer}; verbose::Bool=true)
Get halo properties defined by the block for an Array
of global indices. Returns an array with the requested block.
By HaloID
You can read any property of the halo that passed the filter_function
(see Filtered read-in) by using read_halo_prop
with an individual HaloID
read_halo_prop(sub_base, blockname::AbstractString, haloid::HaloID; verbose::Bool=true)
So if you want to read e.g. the virial radius for the first halo that passed your filter_function
mvir = read_halo_prop(filebase, "MVIR", filtered_subfind[1])
HaloID
s can also be obtained in a vector of all halos by setting the keyword parameter return_haloid
to true
:
mvir, haloids = read_subfind(filename, "MVIR"; return_haloid=true)
You can also read single or multiple blocks at once for single or multiple HaloID
s.
# multiple blocks, multiple HaloIDs -> returns Dict with blocks as keys
read_halo_prop(sub_base, blocks::AbstractVector{<:AbstractString}, haloids::AbstractVector{HaloID}; verbose::Bool=true)
# multiple blocks, single HaloID -> returns Dict with blocks as keys
read_halo_prop(sub_base, blocks::AbstractVector{<:AbstractString}, haloid::HaloID; verbose::Bool=true)
# single block, multiple HaloIDs -> returns vector of block
read_halo_prop(sub_base, block::AbstractString, haloids::AbstractVector{HaloID}; verbose::Bool=true)
Please note: These functions will return the result ordered by increasing HaloID
s, which may not be the order of the Vector{HaloID}
you put in!
By global halo index
If you have a global index of a halo from subfind (0-indexed, increasing over all subfiles of the subfind outputs), you can also read a halo's properties from subfind. To read a halo property from such a global halo index and convert it to a HaloID
you can use
GadgetIO.read_halo_prop_and_id
— Functionread_halo_prop_and_id(sub_base, blockname::AbstractString, i_global::Integer; verbose::Bool=true)
Get halo property and HaloID
from block blockname
by global halo index i_global
(zero-based index). nfiles
should generally be set to h.num_files
, obtained from read_header
. When nfiles is not passed, it is read automatically from the header.
To only obtain the property use
read_halo_prop(sub_base, blockname::AbstractString, i_global::Integer; verbose::Bool=true)
So for example if you have the global halo id i_global
and want to read the corresponding virial mass you can use one of the two following lines (note that it is faster to read properties via the HaloID since only a single file has to be read for that):
mvir, halo_id = read_halo_prop_and_id(filebase, "MVIR", i_global)
mvir = read_halo_prop(filebase, "MVIR", i_global)
To read the properties of multiple halos for which the halo indices are available, use one of the following two lines (to read the virial masses of the first four halos in subfind):
mvir = read_subfind(filebase, "MVIR", [0, 1, 2, 3])
mvir = read_subfind(filebase, "MVIR", 0:3)
mvir, haloids = read_subfind(filebase, "MVIR", [0, 1, 2, 3]; return_haloid=true)
The results are returned in the order of the given indices.
Again you can also read single or multiple blocks at once for single or multiple indices.
# multiple blocks, multiple indices -> returns Dict with blocks as keys
read_halo_prop(sub_base, blocks::AbstractVector{<:AbstractString}, i_global::AbstractVector{<:Integer}; verbose::Bool=true)
# multiple blocks, single index -> returns Dict with blocks as keys
read_halo_prop(sub_base, blocks::AbstractVector{<:AbstractString}, i_global::Integer; verbose::Bool=true)
# single block, multiple indices -> returns vector of block
read_halo_prop(sub_base, block::AbstractString, i_global::AbstractVector{<:Integer}; verbose::Bool=true)
Please note: These functions will return the result ordered by increasing indices, which may not be the order of the Vector{i_global}
you put in!
Converting global halo indices to HaloIDs
If you want to convert global halo indices to HaloID
s use
GadgetIO.global_idxs_to_halo_id
— Functionglobal_idxs_to_halo_id(sub_base::String, idxs::Vector{<:Integer};
parttype::Integer=0)
Converts global halo indices to HaloID
s.
global_idxs_to_halo_id(sub_base::String, offset::Integer, n_to_read::Integer;
parttype::Integer=0)
Converts a given number of indices defined by offset
and n_to_read
to HaloID
s.
You can then save the HaloID
s with Saving/Loading HaloIDs or convert them to read_positions
with halo_ids_to_read_positions
.
Reading particles in a halo
If you want to read all particles associated with a FoF halo you can do this with the function
GadgetIO.read_particles_in_halo
— Functionread_particles_in_halo(snap_base::String, blocks::Array{String},
sub_base::String, halo::HaloID;
radius::Union{Real,Nothing}=nothing,
rad_scale::Real=1.0, halo_type::Integer=1,
parttype::Integer=0, verbose::Bool=true,
use_keys::Bool=true)
Reads all particles of type parttype
that are contained in a halo defined by its HaloID
. If radius
is given (in simulation units), particles are read within at least this radius times rad_scale
. Otherwise, R200, RMEA, or RHMS times rad_scale
is used depending on halo_type
(1, 1, and 2, respectively). Returns a Dict
with each of the blocks
as entries.
read_particles_in_halo( snap_base::String, block::String,
sub_base::String, halo::HaloID;
kwargs...)
Reads all particles of type parttype
that are contained in a halo defined by its HaloID
. If radius
is given (in simulation units), particles are read within at least this radius times rad_scale
. Otherwise, R200, RMEA, or RHMS times rad_scale
is used depending on halo_type
(1, 1, and 2, respectively). Returns an Array
with the requested block
.
This reads all blocks defined in blocks
for the halo
into a dictionary. snap_base
and sub_base
should point to the snap and subfind filebase as in other functions, or the files if you only have one file. The HaloID
point to the selected halo. halo_type
should be set to 1
for halos and 2
for subhalos. If you didn't get all the particles you were looking for it might be that the search radius for the read-in was too small. rad_scale
defines the multiplication factor for the search radius. For halos the default search radius is $r_{200}$ and for subhalos it's the half-mass radius.