mirror of
https://github.com/Richard-Sti/csiborgtools.git
synced 2025-01-03 03:04:15 +00:00
43ebf660ee
* Update priors * Update submit * Update README * Relax width of calibration priors * Relax width of calibration priors * Update smooth scales * Update settings * Update README * Update submit * Add names * Update nb * Fix bug * Update script * Move files * Small bug fix * Add script * Add script * Add script * Add more power * Update script * Quick fix * Rm blank line * Update nb * Update nb * Update nb
158 lines
4.8 KiB
Python
158 lines
4.8 KiB
Python
# Copyright (C) 2024 Richard Stiskalek
|
|
# This program is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by the
|
|
# Free Software Foundation; either version 3 of the License, or (at your
|
|
# option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
# Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
"""
|
|
NOTE: The script is far from finished or written well.
|
|
"""
|
|
from os.path import join
|
|
import numpy as np
|
|
|
|
import csiborgtools
|
|
from h5py import File
|
|
|
|
|
|
|
|
from sklearn.neighbors import NearestNeighbors
|
|
from numba import jit
|
|
from scipy.stats import binned_statistic
|
|
|
|
|
|
###
|
|
|
|
def find_indxs(rtree, r, radius):
|
|
"""
|
|
Find the indices of points that are within a given radius of a given
|
|
point `r`.
|
|
"""
|
|
if isinstance(r, (int, float)):
|
|
r = np.array(r)
|
|
|
|
return rtree.radius_neighbors(
|
|
r.reshape(-1, 1), radius=radius, return_distance=False, )[0]
|
|
|
|
@jit(nopython=True)
|
|
def dot_product_norm(x1_norm, x2_norm):
|
|
"""Dot product of two normalised 1D vectors."""
|
|
return x1_norm[0] * x2_norm[0] + x1_norm[1] * x2_norm[1] + x1_norm[2] * x2_norm[2] # noqa
|
|
|
|
|
|
|
|
@jit(nopython=True)
|
|
def get_angdist_vrad_product(i_comb, j_comb, pos_norm, vrad, r, rbin_i, rbin_j):
|
|
# TODO: Add itself?
|
|
len_i = len(i_comb)
|
|
len_j = len(j_comb)
|
|
|
|
cos_angdist_values = np.full(len_i * len_j, np.nan)
|
|
vrad_product = np.full(len_i * len_j, np.nan)
|
|
weights = np.full(len_i * len_j, np.nan)
|
|
|
|
k = 0
|
|
for i in range(len_i):
|
|
pos_norm_i = pos_norm[i_comb[i]]
|
|
vrad_i = vrad[i_comb[i]]
|
|
w_i = (rbin_i / r[i_comb[i]])**2
|
|
for j in range(len_j):
|
|
cos_angdist_values[k] = dot_product_norm(pos_norm_i, pos_norm[j_comb[j]])
|
|
|
|
# Product of the peculiar velocities
|
|
vrad_product[k] = vrad_i * vrad[j_comb[j]]
|
|
# Weight the product
|
|
w = w_i * (rbin_j / r[j_comb[j]])**2
|
|
vrad_product[k] *= w
|
|
|
|
weights[k] = w
|
|
|
|
k += 1
|
|
|
|
return cos_angdist_values, vrad_product, weights
|
|
|
|
|
|
def main(out_summed_product, out_weights, ri, rj, angular_bins, pos, vel, observer, rmax):
|
|
# Centre the positions at the observer
|
|
pos = np.copy(pos) - observer
|
|
r = np.linalg.norm(pos, axis=1)
|
|
mask = r < rmax
|
|
|
|
# Select only the haloes within the radial range
|
|
pos = pos[mask]
|
|
vel = vel[mask]
|
|
r = r[mask]
|
|
|
|
# Create a KDTree for the radial positions
|
|
rtree = NearestNeighbors().fit(r.reshape(-1, 1))
|
|
|
|
# Calculate the radial velocity and the normalised position vector
|
|
pos_norm = pos / r[:, None]
|
|
vrad = np.sum(vel * pos_norm, axis=1)
|
|
|
|
# TODO: eventually here loop over the radii
|
|
# for ....
|
|
dr = 2.5
|
|
i_indxs = find_indxs(rtree, ri, radius=dr)
|
|
j_indxs = find_indxs(rtree, rj, radius=dr)
|
|
|
|
# Calculate the cosine of the angular distance and the product of the
|
|
# radial velocities for each pair of points.
|
|
cos_angdist, vrad_product, weights = get_angdist_vrad_product(
|
|
i_indxs, j_indxs, pos_norm, vrad, r, ri, rj)
|
|
|
|
out_summed_product += binned_statistic(
|
|
cos_angdist, vrad_product, bins=angular_bins, statistic="sum")[0]
|
|
|
|
out_weights += binned_statistic(
|
|
cos_angdist, weights, bins=angular_bins, statistic="sum")[0]
|
|
|
|
return out_summed_product, out_weights
|
|
|
|
|
|
if __name__ == "__main__":
|
|
fdir = "/mnt/extraspace/rstiskalek/BBF/Quijote_C_ij"
|
|
|
|
rmax = 150
|
|
nradial = 20
|
|
nangular = 40
|
|
ncatalogue = 1
|
|
|
|
# NOTE check this
|
|
radial_bins = np.linspace(0, rmax, nradial + 1)
|
|
angular_bins = np.linspace(-1, 1, nangular + 1)
|
|
|
|
summed_product = np.zeros(nangular)
|
|
weights = np.zeros(nangular)
|
|
|
|
fiducial_observers = csiborgtools.read.fiducial_observers(1000, rmax)
|
|
|
|
ri = 100
|
|
rj = 120
|
|
|
|
# for i in trange(ncatalogue, desc="Catalogues"):
|
|
for i in [30]:
|
|
cat = csiborgtools.read.QuijoteCatalogue(i)
|
|
|
|
for j in range(len(fiducial_observers)):
|
|
# Loop over all the fiducial observers in this simulation
|
|
observer = fiducial_observers[j]
|
|
summed_product, weights = main(
|
|
summed_product, weights, ri, rj, angular_bins,
|
|
cat["cartesian_pos"], cat["cartesian_vel"], observer, rmax)
|
|
|
|
|
|
# TODO: Save
|
|
fname = join(fdir, "test.h5")
|
|
print(f"Saving to `{fname}`.")
|
|
with File(fname, 'w') as f:
|
|
f.create_dataset("summed_product", data=summed_product)
|
|
f.create_dataset("weights", data=weights)
|
|
f.create_dataset("angular_bins", data=angular_bins)
|