Add filaments postproc, improve units detection, add automatic map rules, add selection

This commit is contained in:
Noe Brucy
2020-10-16 17:44:34 +02:00
parent 013aab911e
commit e05477cb7a
7 changed files with 867 additions and 211 deletions
+205 -62
View File
@@ -30,7 +30,7 @@ import pspec_read
P.rcParams["image.cmap"] = "plasma"
P.rcParams["savefig.dpi"] = 400
tex_params = {"text.latex.preamble": [r"\usepackage{amsmath}"]}
tex_params = {"text.latex.preamble": r"\usepackage{amsmath}"}
P.rcParams.update(tex_params)
@@ -73,7 +73,7 @@ class Plotter(Aggregator, BaseProcessor):
label_convert = {
"turb_rms": "$f_{rms}$",
"beta": "$\\beta$",
"beta_cool": "$\\beta_{c}$",
"beta_cool": "$\\beta$",
"dens0": "$n_0$",
"coldens0": "$\Sigma_0$",
"sfr_avg_window": "window",
@@ -122,16 +122,20 @@ class Plotter(Aggregator, BaseProcessor):
# Select runs
if selector is None:
selector = RunSelector(path, in_runs, in_nums, self.pp_params, **kwargs)
self.selector = RunSelector(
path, in_runs, in_nums, self.pp_params, **kwargs
)
else:
self.selector = selector
# Save infos
self.path = path
self.runs = selector.runs
self.nums = selector.nums
self.runs = self.selector.runs
self.nums = self.selector.nums
# Get comparator object
self.comp = Comparator(
path, self.runs, self.nums, path_out, self.pp_params, selector=selector
path, self.runs, self.nums, path_out, self.pp_params, selector=self.selector
)
# Get postprocesor objets for each run
@@ -182,26 +186,38 @@ class Plotter(Aggregator, BaseProcessor):
Open storage and figure if needed before processing a rule
"""
if not arg is None:
name_full = name + "_" + str(arg)
name_full = (
name
+ "_"
+ str(arg)
.replace(" ", "")
.replace("[", "")
.replace("]", "")
.replace(",", "_")
)
else:
name_full = name
if rule.is_valid(arg):
if rule.kind == "classic" or rule.kind == "runs":
try:
if rule.kind == "classic" or rule.kind == "cells":
if "select" in kwargs:
select = kwargs.pop("select")
runs, nums = self.selector.select(**select)
elif "runs" in kwargs:
runs = kwargs.pop("runs")
if isinstance(runs, RunSelector):
nums = runs.nums
runs = runs.runs
except KeyError:
else:
nums = self.nums
else:
runs = self.runs
nums = self.nums
i = 0
for run in runs:
files = []
if rule.kind == "classic":
nums = self.nums[run]
else:
nums = [None]
for num in nums:
for num in nums[run]:
plot_filename = self._find_filename(name_full, run, num)
if from_cells or rule.kind == "cells":
@@ -229,6 +245,7 @@ class Plotter(Aggregator, BaseProcessor):
"'LocatableAxes' object does not support indexing",
"'AxesSubplot' object does not support indexing",
"'AxesSubplot' object is not subscriptable",
"'Axes' object is not subscriptable",
"'LocatableAxes' object is not subscriptable",
]:
self._plot_rule(
@@ -260,18 +277,61 @@ class Plotter(Aggregator, BaseProcessor):
i = i + 1
files.append(plot_filename)
else:
if "select" in kwargs and not "runs" in kwargs:
select = kwargs.pop("select")
runs, nums = self.selector.select(**select)
if not rule.kind == "runs":
kwargs["runs"] = runs
elif rule.kind == "runs" and "runs" in kwargs:
runs = kwargs.pop("runs")
else:
runs = self.runs
if ax is None:
ax = P.gca()
if rule.kind == "series" and len(self.runs) == 1:
if rule.kind == "series" and len(runs) == 1:
run = self.runs[0]
plot_filename = self._find_filename(name_full, run)
else:
plot_filename = self._find_filename(name_full)
save = tables.open_file(self.comp.filename, "r")
try:
self._plot_rule(
rule, save, arg, plot_filename, overwrite, ax, **kwargs
)
if rule.kind == "runs":
for i, run in enumerate(runs):
try:
self._plot_rule(
rule,
save,
arg,
plot_filename,
overwrite,
ax=ax[i],
run=run,
**kwargs,
)
except TypeError as e:
if str(e) in [
"'LocatableAxes' object does not support indexing",
"'AxesSubplot' object does not support indexing",
"'AxesSubplot' object is not subscriptable",
"'Axes' object is not subscriptable",
"'LocatableAxes' object is not subscriptable",
]:
self._plot_rule(
rule,
save,
arg,
plot_filename,
overwrite,
ax=ax,
run=run,
**kwargs,
)
else:
self._plot_rule(
rule, save, arg, plot_filename, overwrite, ax, **kwargs
)
finally:
save.close()
else:
@@ -284,15 +344,20 @@ class Plotter(Aggregator, BaseProcessor):
P.sca(ax)
if self._needs_computation(overwrite, plot_filename):
rule.plot(save, arg, **kwargs)
P.tight_layout(pad=1)
if not self.pp_params.out.interactive:
P.tight_layout(pad=1)
if self.pp_params.out.save:
P.savefig(plot_filename)
P.close()
self._log("{} plotted".format(plot_filename), "SUCCESS")
else:
self._log(
"{} plotted".format(os.path.basename(plot_filename)), "SUCCESS"
)
if not self.pp_params.out.interactive:
P.close()
else:
self._log("Plot {} is already done, skipping...".format(plot_filename))
@@ -452,8 +517,7 @@ class Plotter(Aggregator, BaseProcessor):
dmap, extent=im_extent, origin="lower", norm=norm, cmap=cmap, **kwargs
)
P.locator_params(axis=ax_h, nbins=self.pp_params.plot.ntick)
P.locator_params(axis=ax_v, nbins=self.pp_params.plot.ntick)
P.locator_params(axis="both", nbins=self.pp_params.plot.ntick)
P.xlabel(self._ax_title[ax_h] + unit_str(unit_space))
P.ylabel(self._ax_title[ax_v] + unit_str(unit_space))
@@ -680,7 +744,6 @@ class Plotter(Aggregator, BaseProcessor):
P.xscale("log")
if ylog:
P.yscale("log")
P.plot(bin_centers, mean_bin, **kwargs)
if not ylabel is None:
P.ylabel(ylabel)
@@ -700,6 +763,8 @@ class Plotter(Aggregator, BaseProcessor):
P.title(title)
P.plot(bin_centers, mean_bin, label=title, **kwargs)
def _plot_hist(
self,
name,
@@ -743,7 +808,7 @@ class Plotter(Aggregator, BaseProcessor):
xlabel, unit_old, unit = self._ax_label_unit(node, label, unit, unit_coeff)
if "mean" in node:
index = node["runs"].read().index(run)
index = node["runs"].read().index(run.encode())
values, centers = node["mean"].read()[index]
else:
values, centers = node.read()
@@ -949,9 +1014,15 @@ class Plotter(Aggregator, BaseProcessor):
)
if not run is None:
label = self._label_run(run, node_y, label, nml_key)
base_line, _, _ = P.errorbar(
x, y, yerr=[y - yerr_min, yerr_max - y], label=label, **kwargs
)
if yerr_kind is None:
yerr = None
(base_line,) = P.plot(x, y, label=label, **kwargs)
else:
base_line, _, _ = P.errorbar(
x, y, yerr=[y - yerr_min, yerr_max - y], label=label, **kwargs
)
else:
if runs is None:
runs = self.runs
@@ -1067,7 +1138,7 @@ class Plotter(Aggregator, BaseProcessor):
def overlay_kennicutt(self, n0, step):
"""
Add an overlay : kennicutt mass accretion
Add an overlay : Kennicutt mass accretion
"""
P.grid(False)
ylim = P.ylim()
@@ -1085,6 +1156,20 @@ class Plotter(Aggregator, BaseProcessor):
P.xlim(tmin, tmax)
P.ylim(ylim)
def _gen_from_log(self, logrule, name, description="Generated"):
self.rules[name] = PlotRule(
self,
partial(
self._plot,
"/series/" + logrule + "/time",
"/series/" + logrule + "/" + name,
xunit=cst.Myr,
),
description=description,
kind="series",
dependencies=[logrule],
)
def def_rules(self):
"""
This is where rules are defined
@@ -1105,6 +1190,16 @@ class Plotter(Aggregator, BaseProcessor):
"Column density map",
dependencies=["coldens"],
),
"T": PlotRule(
self,
partial(
self._plot_map,
"T",
label=r"$T$",
),
"Temperature map",
dependencies=["T"],
),
"alpha_disk": PlotRule(
self,
partial(self._plot_map, "alpha_disk", label=r"$\alpha$"),
@@ -1139,18 +1234,6 @@ class Plotter(Aggregator, BaseProcessor):
"Radial speed",
dependencies=["vr"],
),
"P_avg": PlotRule(
self,
partial(self._plot_map, "P_avg", label=r"$P$"),
"Pressure (average)",
dependencies=["P_avg"],
),
"rho_avg": PlotRule(
self,
partial(self._plot_map, "rho_avg", label=r"$\rho$"),
"Density (average)",
dependencies=["rho_avg"],
),
"rho": PlotRule(
self,
partial(
@@ -1242,6 +1325,12 @@ class Plotter(Aggregator, BaseProcessor):
"$\rho$-PDF",
dependencies=["rho_pdf"],
),
"rho_pdf_mw": PlotRule(
self,
partial(self._plot_hist, "rho_pdf_mw"),
"Mass weighted $\rho$-PDF",
dependencies=["rho_pdf_mw"],
),
"cos_pdf": PlotRule(
self,
partial(self._plot_hist, "cos_pdf"),
@@ -1335,10 +1424,23 @@ class Plotter(Aggregator, BaseProcessor):
xunit=cst.Myr,
yunit=cst.Msun,
),
"Mass of the sinks against time",
"Mass of the sinks as a function of time",
kind="series",
dependencies=["sinks_from_log"],
),
"ssm": PlotRule(
self,
partial(
self._plot,
"/series/sinks_from_log/time",
"/series/sinks_from_log/ssm",
xunit=cst.Myr,
yunit=cst.Msun / cst.pc ** 2,
),
"Mass of the sinks as a function of time divided by surface",
kind="series",
dependencies=["ssm"],
),
"assfr": PlotRule(
self,
partial(
@@ -1422,12 +1524,25 @@ class Plotter(Aggregator, BaseProcessor):
"/series/time",
"/series/time_mwa_B_int",
xunit=cst.Myr,
yunit=cst.T,
yunit=cst.uG,
),
"Magnetic intensity average",
kind="series",
dependencies=["time_mwa_B_int"],
),
"mass": PlotRule(
self,
partial(
self._plot,
"/series/time",
"/series/time_mass",
xunit=cst.Myr,
yunit=cst.Msun,
),
"Total mass in the box",
kind="series",
dependencies=["time_mass"],
),
"max_fluct_coldens": PlotRule(
self,
partial(
@@ -1459,13 +1574,7 @@ class Plotter(Aggregator, BaseProcessor):
for name in averageables:
self.rules["rad_" + name] = PlotRule(
self,
partial(
self._plot_radial,
"rad_avg_" + name,
label=name,
xlog=True,
ylog=True,
),
partial(self._plot_radial, "rad_avg_" + name, xlog=True, ylog=True),
"Azimuthal average of {}".format(name),
dependencies=["radial_bins", "rad_avg_" + name],
)
@@ -1473,12 +1582,7 @@ class Plotter(Aggregator, BaseProcessor):
self.rules["fluct_" + name] = PlotRule(
self,
partial(
self._plot_map,
"fluct_" + name,
vmin=0.01,
vmax=100,
cmap="RdBu_r",
label="{}/avg({})".format(name, name),
self._plot_map, "fluct_" + name, vmin=0.01, vmax=100, cmap="RdBu_r"
),
"Fluctuation of {}".format(name),
dependencies=["fluct_" + name],
@@ -1486,12 +1590,7 @@ class Plotter(Aggregator, BaseProcessor):
self.rules["pdf_" + name] = PlotRule(
self,
partial(
self._plot_hist,
"pdf_" + name,
ylog=True,
label="{}/avg({})".format(name, name),
),
partial(self._plot_hist, "pdf_" + name, ylog=True),
"Probability density function of {} fluctuations".format(name),
dependencies=["fit_pdf_" + name],
)
@@ -1506,6 +1605,50 @@ class Plotter(Aggregator, BaseProcessor):
dependencies=[group],
)
for name in ["step", "mcons", "econs", "epot", "ekin", "eint", "emag"]:
self._gen_from_log("cons_from_log", name)
# Generic rules directly from Ramses fields
for field in self.pp_params.pymses.variables:
def generic_rule(name):
self.rules["slice_" + name] = PlotRule(
self,
partial(self._plot_map, "slice_" + name),
"{} slice".format(name),
dependencies=["slice_" + name],
)
self.rules[name + "_mwavg"] = PlotRule(
self,
partial(self._plot_map, name + "_mwavg"),
"Ax mass-weighted averaged {}".format(name),
dependencies=[name + "_mwavg"],
)
self.rules[name + "_avg"] = PlotRule(
self,
partial(self._plot_map, name + "_avg"),
"Ax averaged {}".format(name),
dependencies=[name + "_avg"],
)
# special for vectors
if field in ["g", "vel"]:
# Components
for i, dir in enumerate(["x", "y", "z"]):
generic_rule(field + "x")
# Radial
generic_rule(field + "r")
# Othoradial
generic_rule(field + "phi")
# Norm
generic_rule(field + "_norm")
else:
generic_rule(field)
# Dict of overlays
self.overlays = {
"B": self._overlay_B,