Dealing with Fragments
During a simulation run, halos sometimes come within the FoF linking length (i.e. merge), but later disassociate again. Since we generally assume that halos don’t split, these “wrongly” merged halos are disentangled in a post-processing step, and labeled as fragments during the time they were part of a “combined” FoF group.
However, some of the halo properties are only calculated once for each FoF group on-the-fly during the simulation, e.g. the SOD properties. Therefore, the SOD property is only known for the “major” fragment in a split FoF group, and not for the “minor” fragments. It is important to keep this in mind whenever dealing with properties that are not aware of the fragment status.
HaccyTrees includes some functionality that attempts to correct those properties for minor fragments, discussed further below.
Identifying Fragments
The fragment status is encoded in the fof_halo_tag
, which is composed of the
original FoF tag that was assigned on-the-fly, as well as the fragment index.
Index 0 corresponds to the “main” or “major” fragment, for which we can assume
that the SOD properties are correct. Minor fragments will have a fragment index
larger than 0.
The fof_halo_tag
for fragments is constructed with the following scheme:
The two components can be extracted with the function
split_fragment_tag()
, which can be applied to all negative
fof_halo_tag
to find the original FoF tag as well as the fragment index.
Note
Since the merger-tree forests for large simulations are split among multiple files, determined by the positions of the root halos at z=0, it is not guaranteed that the main fragment is in the same file as the minor fragments, in case belong to distinct trees (i.e. they don’t share the same root halo / they never merge). The affected fragments will all be located at the boundary of the file extent, i.e. their main fragment can be found in the file that covers the neighboring subvolume.
Properties of Minor Fragments
As previously noted, some quantities are only computed once per FoF group and normally only apply for the main fragment in a split FoF halo (fragment index 0). However, minor fragments will be assigned the same value, which generally is not correct.
One can either mask out these affected branches by identifying the minor
fragments (see previous section) or attempt to “correct” the properties by
looking at the properties before and after the halo became a minor fragment and
doing some sort of interplolation inbetween. The function
fix_fragment_properties()
provides two kind of corrections that can be
applied to all minor fragments in a forest, either by linearly interpolating
between the starting and ending value, or by setting the properties to a
constant value.
As an example, here is how one would “correct” the SOD mass, radius, and concentration:
%%time
forest, progenitor_array = haccytrees.mergertrees.read_forest(
"/data/a/cpac/mbuehlmann/LastJourney/forest/m000p.forest.000.hdf5",
'LastJourney', nchunks=20, chunknum=0)
CPU times: user 558 ms, sys: 1.04 s, total: 1.6 s
Wall time: 1.6 s
%%time
haccytrees.mergertrees.fix_fragment_properties(
forest,
['sod_halo_mass', 'sod_halo_radius', 'sod_halo_cdelta'],
inplace=False, suffix='_fragfix_const', interpolation='constant_reverse',
mask_negative=False
)
haccytrees.mergertrees.fix_fragment_properties(
forest,
['sod_halo_mass', 'sod_halo_radius', 'sod_halo_cdelta'],
inplace=False,
suffix='_fragfix_lin',
interpolation='linear',
mask_negative=True
)
CPU times: user 817 ms, sys: 80.3 ms, total: 898 ms
Wall time: 896 ms
After these function calls, additional arrays are added to the forest, suffixed
with _fragfix_lin
and _fragfix_const
. For the following figure, we pick
a halo in the Last Journey simulation that is fragmented at snapshot number 95
and plot the evolution of the tree_node_mass
, sod_halo_mass
,
sod_halo_radius
, and sod_halo_cdelta
for the major fragment and a minor
fragment:
Evolution of the tree-node mass, SOD mass, SOD radius, and SOD concentration (from top to bottom) of the major and a minor fragment branch. The time where the two halos share the same FoF group is highlighted in grey. Blue and orange lines show the constant and linear corrections for the minor fragment.
Node that in the original catalog, the SOD properties of the minor fragment have
the same value as the ones of the major fragment, by construction. After
applying the corrections, the SOD mass and SOD radius are either linearly
interpolated or set to a constant value (the quantities that the halo has once
it becomes the major fragment or an independant halo). Since cdelta == -1
when the minor fragment becomes independant, no interpolation is done (since we
set mask_negative=True
), but instead cdelta
is set to -1 throughout the
minor-fragment phase.
Not that the minor and major fragments eventually merge.
References
- haccytrees.mergertrees.split_fragment_tag(tag)[source]
Extracting the original fof_tag and fragment index from fragments
- Parameters:
tag (int) – the fof_tag of the fragment, has to be negative by definition
- Returns:
fof_tag – the original fof_tag of the FoF halo the fragment is associated with
fragment_idx – the index / enumeration of the fragment (0 == main fragment)
- Return type:
Tuple[int, int]
Notes
This function can also be used with numpy arrays directly
- haccytrees.mergertrees.fix_fragment_properties(forest, keys, *, inplace=True, suffix='_fragfix', interpolation='constant_reverse', mask_negative=False)[source]
Correct properties of minor fragments
The SOD data stored in the merger tree forest files will be wrong for fragmented FoF groups, if the halo is not the major fragment of this group. This function attempts to fix those values by either linearly interpolate or setting the SOD properties to a constant value during the times when a halo is a minor fragment.
- Parameters:
forest (Mapping[str, ndarray]) – the full merger tree forest data
keys (List[str]) – list of the columns to which the correction should be applied
inplace (bool) – if True, the column will be updated in-place, otherwise, a new array will be created with the original name and suffix appended
suffix (str) – if not in-place, the new array will be named
old_column + suffix
interpolation (str) –
the type of correction to apply. Currently supported are:
"constant_reverse"
: set the properties to the value the halo has when becoming a non-minor-fragment or independent (“reverse” in time)"linear"
: linearly interpolate (in snapshot-space) the property values from before and after being a minor fragment
mask_negative (bool) – if True, will not attempt to do a linear interpolation if either the starting or ending value is negative, e.g. for an invalid concentration parameter. Instead, the property will be set to the negative value during the minor-fragment phase.
- Return type:
None
Examples
>>> haccytrees.mergertrees.fix_fragment_properties(forest, ... ['sod_halo_mass', 'sod_halo_radius', 'sod_halo_cdelta'], ... inplace=False, ... suffix='_fragfix_const', ... interpolation='constant_reverse') >>> haccytrees.mergertrees.fix_fragment_properties(forest, ... ['sod_halo_mass', 'sod_halo_radius', 'sod_halo_cdelta'], ... inplace=False, ... suffix='_fragfix_lin', ... interpolation='linear', ... mask_negative=True)