Add possibility to launch an external rule

+ some plotter improvements
+ some namelist improvements
+ add datacube extraction
This commit is contained in:
Noe Brucy
2022-08-23 10:10:42 +02:00
parent fcfd7a8dab
commit cdafe5cb61
5 changed files with 207 additions and 167 deletions
+69 -58
View File
@@ -27,6 +27,7 @@ from pymses.analysis import (
raytracing,
slicing,
splatting,
cube3d,
)
from pymses.filters import CellsToPoints, RegionFilter
from pymses.sources.hop.hop import HOP
@@ -41,6 +42,7 @@ from baseprocessor import (
HDF5Container,
Rule,
norm_getter,
oct_norm_getter,
simple_getter,
vect_getter,
oct_vect_getter,
@@ -379,6 +381,14 @@ class SnapshotProcessor(HDF5Container):
else:
self.fil = None
# Convert time unit
if isinstance(unit_time, str):
factor = self.get_nml(unit_time)
unit_time = U.Unit(
name=os.path.basename(unit_time),
base_unit=self.info["unit_time"],
coeff=factor)
time_in_right_unit = self.time * self.info["unit_time"].express(unit_time)
self.snapshot = Snapshot(
name=str(self.num),
@@ -636,6 +646,46 @@ class SnapshotProcessor(HDF5Container):
""" Azimuthal velocity """
return self.oct_getter_vect_phi(dset, "vel")
def datacube(self, getter, level=None, unit=U.none):
"""
Return a datacube of the source box.
Parameters
----------
getter : callable
A callable that extract the wanted data from a pymses dataset
unit : U.Unit
Unit of the resulting dataset
Returns
-------
A numpy array containing the slice
"""
unit = self._get_units(unit)
operator = ScalarOperator(getter, unit)
extractor = cube3d.CubeExtractor(self._amr, operator)
if level is None:
level = self.get_nml("amr_params/levelmin")
size = 1.0
cam = Camera(
center=self.params.pymses.center,
line_of_sight_axis="z",
region_size=[size, size],
distance=size / 2.0,
far_cut_depth=size / 2.0,
up_vector="y",
map_max_size=2 ** level,
)
cube = extractor.process(
cam, cube_size=1.0, resolution=2 ** level
).data
return cube
def slice(self, getter, ax_los="z", z=0.0, unit=U.none):
"""
Slice process function.
@@ -664,7 +714,8 @@ class SnapshotProcessor(HDF5Container):
datamap = slicing.SliceMap(self._amr, self._cam[ax_los], op, z=z)
return datamap.map.T
def ax_avg(self, getter, ax_los, unit=U.none, mass_weighted=True, surf_qty=False):
def ax_avg(self, oct_getter, ax_los, unit=U.none, mass_weighted=True, surf_qty=False):
"""
Map of the average of a quantity (given by getter) along an axis (ax_los)
Returns 2D array if getter returns a scalar quantity
@@ -673,12 +724,12 @@ class SnapshotProcessor(HDF5Container):
"""
unit = self._get_units(unit)
if surf_qty:
op = ScalarOperator(getter, unit)
op = ScalarOperator(oct_getter, unit)
else:
if mass_weighted:
def num(dset):
value = getter(dset)
value = oct_getter(dset)
rho = getter_rho(dset)
return rho * value
@@ -688,7 +739,7 @@ class SnapshotProcessor(HDF5Container):
else: # Volume weighted
def num(dset):
value = getter(dset)
value = oct_getter(dset)
return value
def denum(dset):
@@ -779,9 +830,11 @@ class SnapshotProcessor(HDF5Container):
self.unload_cells()
return data
def vol_pdf(self, getter, bins=100, logbins=False, weight_func=vol_func):
def vol_pdf(self, getter, bins=100, old_unit=None, unit=None, logbins=False, weight_func=vol_func):
self.load_cells()
data = getter(self.cells)
if old_unit is not None and unit is not None:
data *= old_unit.express(unit)
if logbins:
data = np.log10(data)
weights = weight_func(self.cells)
@@ -987,7 +1040,7 @@ class SnapshotProcessor(HDF5Container):
dmap_omega = rt_omega.process(self._cam[ax_los]).map.T
return dmap_omega
def _toomreQ_disk(self, ax_los, omega_approx=True, G1_units=True, coarsen_factor=1):
def _toomreQ_disk(self, ax_los, omega_approx=False, G1_units=False, coarsen_factor=1):
"""
Compute the Toomre Q parameter
"""
@@ -1347,6 +1400,8 @@ class SnapshotProcessor(HDF5Container):
for key in header:
if units[header.index(key)] == "m":
df[key] = df[key] * self.info["unit_mass"].express(U.Msun)
if "M" in df:
df["msink"] = df["M"]
else:
header = [
"id",
@@ -1369,6 +1424,7 @@ class SnapshotProcessor(HDF5Container):
"Teff",
]
df = pd.read_csv(csv_name, header=None, names=header)
return {key: df[key].values for key in df}
def _pspec(self, overwrite_file=False, **kwargs):
@@ -1566,7 +1622,7 @@ class SnapshotProcessor(HDF5Container):
# sort it and apply the sorting to the coordinates
# this means that the particules of group 1 are written first then of group 2 etc...
ind_sort = np.argsort(group_ids)
cells_group = val_mat[ind_sort]
cells_group = cells_group[ind_sort]
cells_group[6] = group_ids[ind_sort]
# Make it a pandas' DataFrame
@@ -1587,14 +1643,12 @@ class SnapshotProcessor(HDF5Container):
self.rules = {
# Base rules
"coldens": Rule(
self,
self._coldens,
"Column density",
"/maps",
unit=self.info["unit_density"] * self.info["unit_length"],
),
"T_mwavg": Rule(
self,
partial(
self.ax_avg,
getter_T,
@@ -1606,7 +1660,6 @@ class SnapshotProcessor(HDF5Container):
unit=self.info["unit_pressure"] / self.info["unit_density"],
),
"omega_mwavg": Rule(
self,
partial(self._omega_average),
"Ax mass-weighted averaged azimuthal of angular frequency",
"/maps",
@@ -1614,7 +1667,6 @@ class SnapshotProcessor(HDF5Container):
/ (self.info["unit_length"] / self.lbox),
),
"alpha_disk": Rule(
self,
self._alpha_disk,
"Map of the Shakura&Sunaev alpha parameter for disks",
"/maps",
@@ -1627,7 +1679,6 @@ class SnapshotProcessor(HDF5Container):
],
),
"alpha_grav": Rule(
self,
self._alpha_grav,
"Map of the graviational contrib to\
Shakura&Sunaev alpha parameter for disks",
@@ -1636,39 +1687,33 @@ class SnapshotProcessor(HDF5Container):
dependencies=["avg_map_coldens", "avg_map_T_mwavg"],
),
"T": Rule(
self,
self._temperature,
"Temperature slice",
"/maps",
dependencies=["slice_rho"],
unit=self.info["unit_pressure"] / self.info["unit_density"],
),
"levels": Rule(
self, self._levels, "Max level within line of sight", "/maps"
"levels": Rule(self._levels, "Max level within line of sight", "/maps"
),
"jeans": Rule(
self,
self._jeans,
"Jeans length slice",
"/maps",
dependencies=["slice_rho", "T"],
),
"jeans_ratio": Rule(
self,
self._jeans_ratio,
"Jeans' length divided by the max resolution",
"/maps",
dependencies=["jeans", "levels"],
),
"Q": Rule(
self,
self._toomreQ_disk,
"Toomre Q parameter for a Keplerian disk",
"/maps",
dependencies=["coldens", "T_mwavg", "omega_mwavg"],
),
"sinks": Rule(
self,
self._sinks,
group="/datasets",
unit={
@@ -1702,20 +1747,17 @@ class SnapshotProcessor(HDF5Container):
"vz_gas": "unit_velocity",
},
),
"pspec": Rule(self, self._pspec, "Power spectrum", "/hdf5"),
"write_particles": Rule(
self, self._write_particles, "Particles file", "/hdf5"
"pspec": Rule(self._pspec, "Power spectrum", "/hdf5"),
"write_particles": Rule(self._write_particles, "Particles file", "/hdf5"
),
"write_cells": Rule(self, self._write_cells, "Cells file", "/hdf5"),
"write_cells": Rule(self._write_cells, "Cells file", "/hdf5"),
"filaments": Rule(
self,
self._filaments,
"Filaments",
"/datasets",
dependencies={self.params.filaments.datamap: "z"},
),
"filaments_forces": Rule(
self,
self._filaments_forces,
"Filaments",
"/datasets",
@@ -1730,14 +1772,12 @@ class SnapshotProcessor(HDF5Container):
),
# Helpers
"radial_bins": Rule(
self,
self._radial_bins,
"Radial bins",
"/radial",
unit=self.info["unit_length"] / self.lbox,
),
"radial_centers": Rule(
self,
self._radial_centers,
"Centers of radial bins",
"/radial",
@@ -1745,21 +1785,18 @@ class SnapshotProcessor(HDF5Container):
unit=self.info["unit_length"] / self.lbox,
),
"rr": Rule(
self,
self._rr,
"Coordinate map",
"/maps",
unit=self.info["unit_length"] / self.lbox,
),
"bins_on_map": Rule(
self,
self._bins_on_map,
"Convert map coordinates to bins",
"/maps",
dependencies=["radial_bins", "rr"],
),
"B_int": Rule(
self,
self._B_int,
"Magnetic intensity slice",
"/maps",
@@ -1768,14 +1805,12 @@ class SnapshotProcessor(HDF5Container):
),
# PDF
"rho_pdf": Rule(
self,
partial(self.vol_pdf, partial(simple_getter, "rho"), logbins=True),
"Global rho-PDF",
"/hist",
unit=self.info["unit_density"],
),
"rho_pdf_mw": Rule(
self,
partial(
self.vol_pdf,
partial(simple_getter, "rho"),
@@ -1787,14 +1822,12 @@ class SnapshotProcessor(HDF5Container):
unit=self.info["unit_density"],
),
"T_pdf": Rule(
self,
partial(self.vol_pdf, getter_T, logbins=True),
"Global T-PDF",
"/hist",
unit=self.info["unit_pressure"] / self.info["unit_density"],
),
"cos_pdf": Rule(
self,
partial(self.cos_vfluct_B),
"Global cos fluctuation-PDF",
"/hist",
@@ -1802,14 +1835,12 @@ class SnapshotProcessor(HDF5Container):
unit=U.none,
),
"Brho": Rule(
self,
self._Brho,
"Average of B as a function of rho",
"/datasets",
unit={"rho": self.info["unit_density"], "B": self.info["unit_mag"]},
),
"Ek_Eb_rho": Rule(
self,
self._Ek_Eb_rho,
"Average of Ek/Eb as a function of rho",
"/datasets",
@@ -1818,14 +1849,12 @@ class SnapshotProcessor(HDF5Container):
),
# Profiles
"axis": Rule(
self,
partial(self._get_axis),
"Axis",
"/profile",
unit=self.info["unit_length"],
),
"rho_prof": Rule(
self,
partial(self._plane_avg_uniform, partial(simple_getter, "rho")),
"Rho profile",
"/profile",
@@ -1834,28 +1863,24 @@ class SnapshotProcessor(HDF5Container):
),
# globals
"time_num": Rule(
self,
lambda: self.info["time"],
"Time",
"/globals",
unit=self.info["unit_time"],
),
"mass": Rule(
self,
partial(self.sum, mass_func, mass_weighted=False),
"Total mass",
"/globals",
unit=self.info["unit_density"] * self.info["unit_length"] ** 3,
),
"mwa_speed": Rule(
self,
partial(self.vol_avg, partial(simple_getter, "vel")),
"Mass weighted speed average",
"/globals",
unit=self.info["unit_velocity"],
),
"mwa_sigma": Rule(
self,
self._mwa_sigma,
"Mass weighted speed average",
"/globals",
@@ -1863,7 +1888,6 @@ class SnapshotProcessor(HDF5Container):
unit=self.info["unit_velocity"],
),
"mwa_B_int": Rule(
self,
partial(self.vol_avg, getter_B_int),
"Mass weighted Magnetic intensity average",
"/globals",
@@ -1888,7 +1912,6 @@ class SnapshotProcessor(HDF5Container):
oct_getter = getter
self.rules["slice_" + name] = Rule(
self,
partial(self.slice, getter, z=0.0, unit=unit),
"{} slice".format(name),
"/maps",
@@ -1896,7 +1919,6 @@ class SnapshotProcessor(HDF5Container):
)
self.rules[name + "_mwavg"] = Rule(
self,
partial(self.ax_avg, oct_getter, mass_weighted=True, unit=unit),
"Ax mass-weighted averaged {}".format(name),
"/maps",
@@ -1904,7 +1926,6 @@ class SnapshotProcessor(HDF5Container):
)
self.rules[name + "_avg"] = Rule(
self,
partial(self.ax_avg, oct_getter, mass_weighted=False, unit=unit),
"Ax averaged {}".format(name),
"/maps",
@@ -1944,7 +1965,8 @@ class SnapshotProcessor(HDF5Container):
# Norm
generic_rule(
field + "_norm", partial(norm_getter, field), self.unit_key[field]
field + "_norm", partial(norm_getter, field), self.unit_key[field],
oct_getter=partial(oct_norm_getter, field)
)
else:
@@ -1958,7 +1980,6 @@ class SnapshotProcessor(HDF5Container):
self.rules["rad_avg_" + name] = Rule(
self,
partial(self._rad_avg, name),
"Azimuthal average of {}".format(name),
"/radial",
@@ -1966,7 +1987,6 @@ class SnapshotProcessor(HDF5Container):
unit=unit,
)
self.rules["rad_mwavg_" + name] = Rule(
self,
partial(self._rad_avg, name, mass_weighted=True),
"Mass weighted azimuthal average of {}".format(name),
"/radial",
@@ -1974,7 +1994,6 @@ class SnapshotProcessor(HDF5Container):
unit=unit,
)
self.rules["rad_avg_map_" + name] = Rule(
self,
partial(self._rad_avg_map, name),
"Interpolated map of azimuthal average of {}".format(name),
"/maps",
@@ -1982,7 +2001,6 @@ class SnapshotProcessor(HDF5Container):
unit=unit,
)
self.rules["rad_mwavg_map_" + name] = Rule(
self,
partial(self._rad_avg_map, name, mass_weighted=True),
"Interpolated map of azimuthal average of {}".format(name),
"/maps",
@@ -1990,14 +2008,12 @@ class SnapshotProcessor(HDF5Container):
unit=unit,
)
self.rules["fluct_" + name] = Rule(
self,
partial(self._fluct_map, name),
"Fluctuation wrt to average of {}".format(name),
"/maps",
dependencies=[name, "rad_avg_map_" + name],
)
self.rules["dispersion_rad_" + name] = Rule(
self,
partial(self._dispersion_rad, name),
"radial RMS of {}".format(name),
"/radial",
@@ -2005,21 +2021,18 @@ class SnapshotProcessor(HDF5Container):
unit=unit,
)
self.rules["mwfluct_" + name] = Rule(
self,
partial(self._fluct_map, name, mass_weigthed=True),
"Fluctuation wrt to mass weighted average of {}".format(name),
"/maps",
dependencies=[name, "rad_mwavg_map_" + name],
)
self.rules["fluct_pdf_" + name] = Rule(
self,
partial(self._rad_fluct_pdf, name),
"Probability density function of {} fluctuations".format(name),
"/hist",
dependencies=["rr", "fluct_" + name],
)
self.rules["fluct_mwpdf_" + name] = Rule(
self,
partial(self._rad_fluct_pdf, name, mass_weigthed=True),
"Probability density function of {} mass weighted fluctuations".format(
name
@@ -2028,7 +2041,6 @@ class SnapshotProcessor(HDF5Container):
dependencies=["rr", "mwfluct_" + name],
)
self.rules["fit_fluct_pdf_" + name] = Rule(
self,
partial(self._fit_pdf, name),
"Fit the PDF of {} fluctuations".format(name),
"/hist",
@@ -2038,7 +2050,6 @@ class SnapshotProcessor(HDF5Container):
unit_bin = self.rules[name_bin].unit
if name_bin is not name:
self.rules["mbb_" + name + "_" + name_bin] = Rule(
self,
partial(self.mean_by_bins, name_bin, name),
"Mean of {} by bins of {}".format(name, name_bin),
"/hist",