In [ ]:
import sys
sys.path.append("/mnt/aureum/kcchan_rec/ding_post_mess/jupyter_mess/aureum")
import wx_iter_funcs as wif
import numpy as np
from matplotlib.colors import LogNorm
import matplotlib.pyplot as plt
import matplotlib
from importlib import reload
import os
import matplotlib
os.environ['PATH'] = '/software/texlive-20240311/bin/x86_64-linux:' + os.environ['PATH']
matplotlib.rc_file('/software/mess_config/beauty/matplotlibrc_dingBeauty_v3.9.3')
如何从粒子数据开始,计算某个snap的功率谱?¶
0. 读取粒子数据(内存占用较大,后续你最好丢slurm去跑就行)¶
PS: 这里我只是用我自己跑的一个N体举例,对DM做简单CIC,我们Weighting全部设置1就行,因为它们的质量都相同
In [ ]:
import h5py
_snap_path = "/Raid6/2/luantch/sim_workspace/1024/BAO/L1000_N1024/snap_BAO_020.hdf5"
with h5py.File(_snap_path, 'r') as snap:
_header = snap['Header']
z = _header.attrs['Redshift']
boxsize = _header.attrs['BoxSize']
_data_dm = snap['PartType1']
pos = _data_dm['Coordinates'][:]
print(f'Redshift = {z:.4f}')
print(f'BoxSize = {boxsize:.2f}')
print(f'Particle Num = {pos.shape[0]}')
Redshift = 1.1144 BoxSize = 1000.00 Particle Num = 1073741824
1. 粒子转场(pylians完成)¶
In [ ]:
import MAS_library as MASL
def pylians_CIC_weight(pos, grid, BoxSize, W, MAS='CIC', use_mean=True, verbose=True):
_pos = pos.astype(np.float32)
_cube = np.zeros((grid,grid,grid), dtype=np.float32)
MASL.MA(_pos.astype(np.float32), _cube, BoxSize, MAS, W, verbose=verbose)
if use_mean:
_cube /= np.mean(_cube, dtype=np.float32)
if verbose: print(_cube.min(), _cube.max(), _cube.mean())
return _cube
In [ ]:
## Construct Weighting arr, here we set all to unity.
w_arr = np.zeros_like(pos[:,0])
w_arr += 1.
In [ ]:
%%time
Ng = 512 # Here we do CIC on (512, 512, 512) GridMesh
cube_mean = wif.pylians_CIC_weight(pos, Ng, boxsize, w_arr, MAS='CIC', use_mean=True, verbose=False)
CPU times: user 49.6 s, sys: 2min 44s, total: 3min 33s Wall time: 3min 33s
In [ ]:
print(cube_mean.mean())
print(cube_mean.min())
print(cube_mean.max())
1.0000001 0.017697573 343.68887
👆 你可以对所有你需要的snap,都先做转场的操作,然后保存出去,后面就方便多了可以直接使用了,给你一个我运行batch转snap到场的实操路径,你可以参考一下,
/Raid6/2/luantch/sim_workspace/1024/BAO/L1000_N1024/field_out/R4.3_gen_field_Gadget4_LEAN.py,这个脚本负责按照snap号读取粒子数据,然后在对应的文件夹里生成场的数据保存,而负责执行它的slurm提交脚本就是:
/Raid6/2/luantch/sim_workspace/1024/BAO/L1000_N1024/field_out/run_genfield.sh,
你可以看一下,看如果有需要的话改成满足自己需求的脚本执行即可
2. 计算功率谱(nbodykit完成)¶
In [ ]:
import nbodykit.lab as nb
def cal_pk(cube, boxsize, kmin, dk, mode='1d'):
# _field = nb.ArrayMesh(cube/cube.mean()-1., BoxSize=boxsize)
_field = nb.ArrayMesh(cube, BoxSize=boxsize) # Here we use the original cube, but not delta cube.
_pk=nb.FFTPower(_field, mode=mode, dk=dk, kmin=kmin).power
return {'k': _pk['k'], 'power': _pk['power'].real}
In [ ]:
%%time
# Configure kmin and dk according to the requirements of your simulation snapshot.
_pk_dict = cal_pk(cube_mean, boxsize=boxsize, kmin=0.00628, dk=0.01)
CPU times: user 17.7 s, sys: 6.59 s, total: 24.3 s Wall time: 24.2 s
In [ ]:
plt.figure(figsize=(6,5), dpi=100)
plt.loglog(_pk_dict['k'], _pk_dict['power'])
plt.xlabel(r'$k \ [{h\,\rm Mpc^{-1}}]$',fontsize=18)
plt.ylabel(r'$P(k) \ [(\mathrm{Mpc}/h)^3]$', fontsize=18)
Out[ ]:
Text(0, 0.5, '$P(k) \\ [(\\mathrm{Mpc}/h)^3]$')