Skip to content

Commit

Permalink
Merge pull request #11 from SWIFTSIM/nohf
Browse files Browse the repository at this point in the history
Support for no-halo-catalogue mode and cookbook example for spherical aperture selection.
  • Loading branch information
kyleaoman authored Oct 13, 2023
2 parents 5b0858c + d14da8e commit 1eafcd6
Show file tree
Hide file tree
Showing 11 changed files with 510 additions and 60 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion codemeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
"codeRepository": [
"https://github.com/SWIFTSIM/swiftgalaxy",
],
"version": "1.0.4",
"version": "1.0.5",
"license": "https://spdx.org/licenses/GPL-3.0-only.html",
}
46 changes: 46 additions & 0 deletions docs/source/halo_finders/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,49 @@ Entrepreneurial users may also create their own helper class inheriting from :cl
+ :meth:`~swiftgalaxy.halo_finders._HaloFinder.velocity_centre`: return the coordinates (as a :class:`~swiftsimio.objects.cosmo_array`) to be used as the bulk velocity of the galaxy of interest (implemented with the `@property` decorator).

In addition, it is recommended to expose the properties computed by the halo finder, masked to the values corresponding to the object of interest. To make this intuitive for users, the syntax to access attributes of the galaxy of interest should preferably match the syntax used for the library conventionally used to read outputs of that halo finder, if it exists. For instance, for Velociraptor this is implemented via ``__getattr__`` (dot syntax), which simply exposes the usual interface (with a mask to pick out the galaxy of interest).

Using swiftgalaxy without a halo catalogue
------------------------------------------

A helper class called :class:`swiftgalaxy.halo_finders.Standalone` is provided so that the features of :mod:`swiftgalaxy` that aren't directly tied to a halo catalogue (e.g. spherical and cylindrical coordinates, consistent coordinate frame, etc.) can be used when no supported halo catalogue is available.

Often the most pragmatic way to create a selection of particles using :class:`~swiftgalaxy.halo_finders.Standalone` is to first select a spatial region guaranteed to contain the particles of interest and then create the final mask programatically using :class:`~swiftgalaxy.reader.SWIFTGalaxy`'s masking features. For example, suppose that you know that there is a galaxy with its centre at (2, 2, 2) Mpc and that you eventually want to select all particles in a spherical aperture 1 Mpc in radius around this point. Start with a cubic spatial mask enclosing this region:

.. code-block:: python
from swiftgalaxy import SWIFTGalaxy, Standalone, MaskCollection
from swiftsimio import cosmo_array
import unyt as u
sg = SWIFTGalaxy(
"my_snapshot.hdf5",
Standalone(
centre=cosmo_array([2.0, 2.0, 2.0], u.Mpc),
velocity_centre=cosmo_array([0.0, 0.0, 0.0], u.km / u.s),
spatial_offsets=cosmo_array([[-1.0, 1.0], [-1.0, 1.0], [-1.0, 1.0]], u.Mpc),
extra_mask=None, # we'll define the exact set of particles later
)
)
You can next define the masks selecting particles in your desired spherical aperture, using :class:`~swiftgalaxy.reader.SWIFTGalaxy`'s convenient spherical coordinates feature, and store them in a :class:`~swiftgalaxy.masks.MaskCollection`:

.. code-block:: python
mask_collection = MaskCollection(
gas=sg.gas.spherical_coordinates.r < 1 * u.Mpc,
dark_matter=sg.dark_matter.spherical_coordinates.r < 1 * u.Mpc,
stars=sg.stars.spherical_coordinates.r < 1 * u.Mpc,
black_holes=sg.black_holes.spherical_coordinates.r < 1 * u.Mpc,
)
Finally, apply the mask to the ``sg`` object:

.. code-block:: python
sg.mask_particles(mask_collection)
You're now ready to proceed with analysis of the particles in the 1 Mpc spherical aperture using this ``sg`` object.

.. note::

:meth:`~swiftgalaxy.reader.SWIFTGalaxy.mask_particles` applies the masks in-place. The mask could also be applied with the :meth:`~swiftgalaxy.reader.SWIFTGalaxy.__getattr__` method (i.e. in square brackets), but this returns a copy of the :class:`~swiftgalaxy.reader.SWIFTGalaxy` object. If memory efficiency is a concern, prefer the :meth:`~swiftgalaxy.reader.SWIFTGalaxy.mask_particles` approach.
40 changes: 40 additions & 0 deletions docs/source/masking/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,43 @@ As may be intuitively expected, individual particle arrays can be masked on-the-
sg.gas.masses[gasmask]
This returns a masked copy of the individual particle array, so does not imply the same level of potentially expensive copy operations discussed above. While it is possible to assign the result back to the particle array (e.g. ``sg.gas.masses = sg.gas.masses[gasmask]``), this is inadvisable since it will break the consistency between the shapes of the particle arrays for that particle type. After doing this, some operations, such as attempting to mask the :class:`~swiftgalaxy.reader.SWIFTGalaxy` again, are then likely to raise an exception.

Cookbook: all particles in a spherical aperture
-----------------------------------------------

One of :mod:`swiftgalaxy`'s features is that it can conveniently provide a set of particles that a halo finder has identified as belonging to a galaxy (or other object). However, in some cases this might not be the selection of particles that you want. When the desired particles include some that are not identified as members by the halo finder, a modified approach is needed. For example, let's suppose that you want to select *all* simulation particles within a 1 Mpc aperture of a galaxy's centre, regardless of their membership status according to the halo finder. For illustration we'll take a galaxy picked from a :class:`~swiftgalaxy.halo_finders.Velociraptor` catalogue. The first step is to override the default ``extra_mask="bound_only"`` behaviour with ``extra_mask=None``. We also need to override the default spatial selection from the simulation, because the 1 Mpc spherical region of interest might extend beyond the region occupied by member particles as defined by the halo finder, which is all that the default spatial selection is guaranteed to enclose:

.. code-block:: python
sg = SWIFTGalaxy(
"my_snapshot.hdf5",
Velociraptor(
"halos", # name of output files excluding extension (e.g. 'halos.properties', etc.)
halo_index=3, # pick the 4th galaxy (i.e. indexed from 0) in the catalogue array
extra_mask=None, # select all particles in the spatially selected region (for now)
custom_spatial_offsets=cosmo_array([[-1, 1], [-1, 1], [-1, 1]], u.Mpc), # relative to centre
),
)
You can next define the masks selecting particles in your desired spherical aperture, using :class:`~swiftgalaxy.reader.SWIFTGalaxy`'s convenient spherical coordinates feature, and store them in a :class:`~swiftgalaxy.masks.MaskCollection`:

.. code-block:: python
mask_collection = MaskCollection(
gas=sg.gas.spherical_coordinates.r < 1 * u.Mpc,
dark_matter=sg.dark_matter.spherical_coordinates.r < 1 * u.Mpc,
stars=sg.stars.spherical_coordinates.r < 1 * u.Mpc,
black_holes=sg.black_holes.spherical_coordinates.r < 1 * u.Mpc,
)
Finally, apply the mask to the ``sg`` object:

.. code-block:: python
sg.mask_particles(mask_collection)
You're now ready to proceed with analysis of the particles in the 1 Mpc spherical aperture using this ``sg`` object.

.. note::

:meth:`~swiftgalaxy.reader.SWIFTGalaxy.mask_particles` applies the masks in-place. The mask could also be applied with the :meth:`~swiftgalaxy.reader.SWIFTGalaxy.__getattr__` method (i.e. in square brackets), but this returns a copy of the :class:`~swiftgalaxy.reader.SWIFTGalaxy` object. If memory efficiency is a concern, prefer the :meth:`~swiftgalaxy.reader.SWIFTGalaxy.mask_particles` approach.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "swiftgalaxy"
version="1.0.4"
version="1.0.5"
authors = [
{ name="Kyle Oman", email="kyle.a.oman@durham.ac.uk" },
]
Expand Down
2 changes: 1 addition & 1 deletion swiftgalaxy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .reader import SWIFTGalaxy
from .halo_finders import Velociraptor, Caesar
from .halo_finders import Velociraptor, Caesar, Standalone
from .masks import MaskCollection
from .__version__ import __version__

Expand Down
2 changes: 1 addition & 1 deletion swiftgalaxy/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.0.4"
__version__ = "1.0.5"
Loading

0 comments on commit 1eafcd6

Please sign in to comment.