https://github.com/cphyc/ppyv
Tool to project AMR datasets onto a position-position-velocity (PPV) cube for kinematics analysis.
https://github.com/cphyc/ppyv
Last synced: over 1 year ago
JSON representation
Tool to project AMR datasets onto a position-position-velocity (PPV) cube for kinematics analysis.
- Host: GitHub
- URL: https://github.com/cphyc/ppyv
- Owner: cphyc
- Created: 2024-11-21T12:08:03.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-11-22T17:47:04.000Z (over 1 year ago)
- Last Synced: 2025-02-02T13:43:16.464Z (over 1 year ago)
- Language: C++
- Size: 43.9 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
Awesome Lists containing this project
README
# PPyV
The PPyV package allows to project 3D AMR datasets onto a xyv cube.
The package is written in C++ and uses:
- the [Kokkos](https://github.com/kokkos/kokkos) library for parallelization on GPUs and CPUs,
- the [pybind11](https://github.com/pybind/pybind11) library to create a Python interface.
## Installation
### Requirements
The PPyV package requires:
- a C++17 compiler (GCC, clang, ...),
- cmake,
- a compiler for the GPU if compiling for that target.
## Installation
```bash
# Clone the repository
git clone https://github.com/cphyc/ppyv.git --recursive
# Pip install the package (single threaded)
pip install .
# Pip install the package (with OpenMP support)
pip install . -Ccmake.define.Kokkos_ENABLE_OPENMP=ON
# Pip install the package (with CUDA support)
pip install . -Ccmake.define.Kokkos_ENABLE_CUDA=ON
# Pip install the package (with CUDA support, using clang as compiler)
CC=clang CXX=clang++ pip install . -Ccmake.define.Kokkos_ENABLE_CUDA=ON
# Test import
python -c 'import ppyv'
```
## Note on compiling with CUDA
Refer to https://docs.nvidia.com/cuda/cuda-installation-guide-linux/#host-compiler-support-policy to check the compatibility of your compiler with CUDA. For example, CUDA 12.6 supports only GCC 6.x to 13.2 or Clang 7.x to 18.0.
# Usage
```python
from matplotlib import pyplot as plt
import numpy as np
import yt
from ppyv import ppyv
# Create velocity dispersion field
@yt.derived_field(
name=("gas", "velocity_dispersion"),
units="km/s",
sampling_type="cell",
validators=[yt.ValidateSpatial(ghost_zones=1)],
)
def velocity_dispersion(field, data):
m = (data["cell_mass"].to("Msun")).d
px = (m * data["velocity_x"].to("km/s")).d
py = (m * data["velocity_y"].to("km/s")).d
pz = (m * data["velocity_z"].to("km/s")).d
output = np.zeros_like(m)
for i in range(1, output.shape[0] - 1):
for j in range(1, output.shape[1] - 1):
for k in range(1, output.shape[2] - 1):
# Use 27 neighbours to estimate the velocity dispersion
sl = slice(i - 1, i + 2), slice(j - 1, j + 2), slice(k - 1, k + 2)
mtot = m[sl].sum(axis=(0, 1, 2))
varx = np.var(px[sl], axis=(0, 1, 2))
vary = np.var(py[sl], axis=(0, 1, 2))
varz = np.var(pz[sl], axis=(0, 1, 2))
output[i, j, k] = np.sqrt(varx + vary + varz) / mtot
return data.apply_units(output, "km/s")
Npix = 256
Npix_velocity = 256
# Load example dataset
ds = yt.load_sample("output_00080")
# Find the densest cell
ad = ds.all_data()
center = ds.arr(ad.argmax("density"))
# Create a sphere around it
r = ds.quan(400, "kpc")
sp = ds.sphere(center, r)
sp["velocity_dispersion"]
spp = ds.sphere(center, (5, "kpc"))
bulk_velocity = spp.quantities.bulk_velocity(use_gas=True, use_particles=False)
normal = sp.quantities.angular_momentum_vector(use_gas=True, use_particles=False)
normal = (normal / np.linalg.norm(normal)).d
# Extract data
xc = (np.stack([(sp[k]).to("kpc") for i, k in enumerate("xyz")], axis=1)).d
vc = np.stack([(sp[f"velocity_{k}"] - bulk_velocity[i]).to("km/s") for i, k in enumerate("xyz")], axis=1).d
dx = sp["dx"].to("kpc").d
sigma_v = sp["velocity_dispersion"].to("km/s").d
rho = sp["density"].to("mp/cm**3").d
# Parameters for the plot
vmin = -50
vmax =50
## Compute normal vectors
w = normal
u = np.cross(w, [1, 0, 0])
u /= np.linalg.norm(u)
v = np.cross(w, u)
v /= np.linalg.norm(v)
O = sp.center.to("kpc").d
print("================")
print(u, v, w)
print("================")
cube = ppyv.compute_hypercube(
pos=xc,
vel=vc,
dx=dx,
sigma_v=sigma_v,
weight=rho,
Npix=Npix,
Npix_velocity=Npix_velocity,
u=u,
v=v,
O=O,
width=2 * r.d,
vmin=vmin,
vmax=vmax,
)
fig, axes = plt.subplots(1, 3, figsize=(15, 5), constrained_layout=True)
norm = plt.matplotlib.colors.LogNorm()
axes[0].imshow(
cube.sum(axis=2).T,
origin="lower",
norm=norm,
extent=(-r.d, r.d, -r.d, r.d),
cmap="plasma",
)
axes[0].set(
xlabel=f"x [{r.units}]",
ylabel=f"y [{r.units}]",
)
sl = slice(Npix//4, 3*Npix//4)
axes[1].imshow(
cube[:, sl, :].sum(axis=1).T,
origin="lower",
extent=(-r.d, r.d, vmin, vmax),
norm=norm,
cmap="plasma",
)
axes[1].set_aspect("auto")
axes[1].set(
xlabel=f"x [{r.units}]",
ylabel="v [km/s]",
)
axes[2].imshow(
cube[sl, :, :].sum(axis=0).T,
origin="lower",
extent=(-r.d, r.d, vmin, vmax),
norm=norm,
cmap="plasma",
)
axes[2].set_aspect("auto")
axes[2].set(
xlabel=f"y [{r.units}]",
ylabel="v [km/s]",
)
# Create axis for colorbar
plt.colorbar(
plt.cm.ScalarMappable(norm=norm, cmap="plasma"),
ax=axes,
orientation="vertical",
fraction=0.05,
aspect=20,
)
plt.show()
```