[postprocessor] add rule for radial sigma and 2D pwspec
This commit is contained in:
+11
@@ -1689,6 +1689,17 @@ class Plotter(Aggregator, BaseProcessor):
|
|||||||
dependencies=["radial_centers", "rad_mwavg_" + name],
|
dependencies=["radial_centers", "rad_mwavg_" + name],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.rules["dispersion_rad_" + name] = PlotRule(
|
||||||
|
self,
|
||||||
|
partial(
|
||||||
|
self._plot,
|
||||||
|
"/radial/radial_centers",
|
||||||
|
"/radial/dispersion_rad_" + name,
|
||||||
|
),
|
||||||
|
"Radial dispersion of {}".format(name),
|
||||||
|
dependencies=["radial_centers", "dispersion_rad_" + name],
|
||||||
|
)
|
||||||
|
|
||||||
self.rules["avg_map_" + name] = PlotRule(
|
self.rules["avg_map_" + name] = PlotRule(
|
||||||
self,
|
self,
|
||||||
partial(self._plot_map, "avg_map_" + name),
|
partial(self._plot_map, "avg_map_" + name),
|
||||||
|
|||||||
+78
-1
@@ -28,6 +28,7 @@ from pymses.analysis import (
|
|||||||
from pymses.filters import CellsToPoints, RegionFilter
|
from pymses.filters import CellsToPoints, RegionFilter
|
||||||
|
|
||||||
from fil_finder import FilFinder2D
|
from fil_finder import FilFinder2D
|
||||||
|
from scipy import fft
|
||||||
import pspec_new
|
import pspec_new
|
||||||
|
|
||||||
|
|
||||||
@@ -163,7 +164,39 @@ def find_center(distance, skeleton, i_center, j_center, i, j):
|
|||||||
return i_center[i, j], j_center[i, j]
|
return i_center[i, j], j_center[i, j]
|
||||||
|
|
||||||
|
|
||||||
# PostProcessor class
|
# Power spectrum helpers
|
||||||
|
|
||||||
|
|
||||||
|
def pspec(map2D):
|
||||||
|
"""
|
||||||
|
Computes the 2D powerspectrum of a 2D map
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
map2D : square map to compute the fft from
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Resolution of the map
|
||||||
|
n = map2D.shape[0]
|
||||||
|
assert map2D.shape[1] == n
|
||||||
|
|
||||||
|
# Create bin array for the wavenumber k
|
||||||
|
# (Take into account the symmetry)
|
||||||
|
kbins = np.linspace(0, n // 2, n // 4)
|
||||||
|
k_alias = np.arange(n, dtype=np.float64)
|
||||||
|
k = np.where(k_alias >= n // 2, k_alias - n, k_alias)
|
||||||
|
kx, ky = np.meshgrid(k, k, indexing="ij")
|
||||||
|
# Compute map of k
|
||||||
|
kmap = np.sqrt(kx ** 2 + ky ** 2)
|
||||||
|
# Compute fft
|
||||||
|
fmap = fft.fft2(map2D)
|
||||||
|
# Compute the power map from the fft
|
||||||
|
pmap = pspec_new.pcube(fmap)
|
||||||
|
# Use the power map and the fft to compute the powerspectrum
|
||||||
|
# This is typically an histogram of k weighted by the fourier transform value
|
||||||
|
pspec, kbins, pspec2, fbins = pspec_new.pspectrum(pmap, kmap, kbins, 1, 0)
|
||||||
|
# Return bin center and power spectrum
|
||||||
|
return 0.5 * (kbins[1:] + kbins[:-1]), pspec
|
||||||
|
|
||||||
|
|
||||||
class PostProcessor(HDF5Container):
|
class PostProcessor(HDF5Container):
|
||||||
@@ -1054,6 +1087,42 @@ class PostProcessor(HDF5Container):
|
|||||||
avg_map = self.get_value("/maps/avg_map_" + name + "_" + ax_los)
|
avg_map = self.get_value("/maps/avg_map_" + name + "_" + ax_los)
|
||||||
return dmap / avg_map
|
return dmap / avg_map
|
||||||
|
|
||||||
|
def _dispersion_rad(self, name, ax_los="z"):
|
||||||
|
"""
|
||||||
|
Computes the dispersion in radial bins of the quantity `name`
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
|
||||||
|
name : name of 2D map of a scalar quantity
|
||||||
|
ax_los : axis of the line of sight
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 1. Get full storage names for the map and its azimuthal avererage
|
||||||
|
map_name = f"/maps/{name}_{ax_los}"
|
||||||
|
avg_map_name = f"/maps/avg_map_{name}_{ax_los}"
|
||||||
|
|
||||||
|
# 2. Get maps from the storage
|
||||||
|
dmap = self.get_value(map_name)
|
||||||
|
avgmap = self.get_value(avg_map_name)
|
||||||
|
|
||||||
|
# 3. Get radial bins and centers
|
||||||
|
bins_on_map = self.get_value(f"/maps/bins_on_map_{ax_los}")
|
||||||
|
centers = self.get_value(f"/radial/radial_centers_{ax_los}")
|
||||||
|
|
||||||
|
# 4. Initialize dispersion array
|
||||||
|
sigma = np.zeros(len(centers))
|
||||||
|
|
||||||
|
# 5. Compute RMS in each bin
|
||||||
|
for j in range(len(centers)):
|
||||||
|
mask_bin = bins_on_map == j
|
||||||
|
sigma[j] = np.sqrt(
|
||||||
|
np.sum((dmap[mask_bin] - avgmap[mask_bin]) ** 2) / np.sum(mask_bin)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 6. Returns computed RMS
|
||||||
|
return sigma
|
||||||
|
|
||||||
def _rad_fluct_pdf(self, name, ax_los="z", mass_weighted=False):
|
def _rad_fluct_pdf(self, name, ax_los="z", mass_weighted=False):
|
||||||
if mass_weighted:
|
if mass_weighted:
|
||||||
fluct_map = self.get_value("/maps/mwfluct_" + name + "_" + ax_los)
|
fluct_map = self.get_value("/maps/mwfluct_" + name + "_" + ax_los)
|
||||||
@@ -1784,6 +1853,14 @@ class PostProcessor(HDF5Container):
|
|||||||
"/maps",
|
"/maps",
|
||||||
dependencies=[name, "avg_map_" + name],
|
dependencies=[name, "avg_map_" + name],
|
||||||
)
|
)
|
||||||
|
self.rules["dispersion_rad_" + name] = Rule(
|
||||||
|
self,
|
||||||
|
partial(self._dispersion_rad, name),
|
||||||
|
"radial RMS of {}".format(name),
|
||||||
|
"/radial",
|
||||||
|
dependencies=[name, "avg_map_" + name],
|
||||||
|
unit=unit,
|
||||||
|
)
|
||||||
self.rules["mwfluct_" + name] = Rule(
|
self.rules["mwfluct_" + name] = Rule(
|
||||||
self,
|
self,
|
||||||
partial(self._fluct_map, name, mass_weigthed=True),
|
partial(self._fluct_map, name, mass_weigthed=True),
|
||||||
|
|||||||
Reference in New Issue
Block a user