Added extror from logs and namelist

This commit is contained in:
Noe Brucy
2019-11-13 17:33:15 +01:00
parent 3986b1cdf4
commit ea6f9b6bdd
4 changed files with 563 additions and 249 deletions
+24 -13
View File
@@ -27,6 +27,9 @@ input_args.add_argument("-p", "--project",
help="specify project name (directory within the input directory)", help="specify project name (directory within the input directory)",
default="disk") default="disk")
input_args.add_argument("-c", "--config",
help="Path of a default config file",
default=None)
input_args.add_argument("-wo", "--which_inputs", input_args.add_argument("-wo", "--which_inputs",
choices=['all', 'id', 'time'], choices=['all', 'id', 'time'],
@@ -77,15 +80,19 @@ output_args.add_argument("--tag",
help="Add a special tag on output filemanes", help="Add a special tag on output filemanes",
default='') default='')
output_args.add_argument("--interactive",
help="Interactive mode : do not save data",
action='store_true')
output_args.add_argument("-owr", "--overwrite", output_args.add_argument("-owr", "--overwrite",
help="Overwrite outputs", help="Overwrite outputs",
action='store_true') action='store_true')
output_args.add_argument("-owrd", "--overwrite_dependencies", output_args.add_argument("-owrd", "--overwrite_dependencies",
help="Overwrite outputs for dependencies", help="Overwrite outputs for dependencies",
action='store_true', action='store_true',
default=None) default=False)
pp_args = parser.add_argument_group('postproc', "Post Processing configuration") pp_args = parser.add_argument_group('postproc', "Post Processing configuration")
@@ -118,7 +125,7 @@ pp_args.add_argument("--plot",
pp_args.add_argument("-plargs", "--plot_args", pp_args.add_argument("-plargs", "--plot_args",
help="Args to give to plot rules", help="Args to give to plot rules",
default=['x', 'y', 'z'], default=[None],
nargs='*') nargs='*')
pp_args.add_argument("-d", "--disk", pp_args.add_argument("-d", "--disk",
@@ -174,11 +181,15 @@ runs = args.runs
storage_in = args.input_path storage_in = args.input_path
storage_out = args.output_path storage_out = args.output_path
pp_params = Params() if args.config is None:
pp_params = default_params()
else:
pp_params = load_params(args.config)
pp_params.out.zoom = args.zoom pp_params.out.zoom = args.zoom
pp_params.out.tag = args.tag pp_params.out.tag = args.tag
pp_params.out.map_size = args.map_size pp_params.out.map_size = args.map_size
pp_params.out.interactive = args.interactive
pp_params.pymses.fft = args.fft pp_params.pymses.fft = args.fft
@@ -208,7 +219,6 @@ P.rcParams["errorbar.capsize"] = 4
# List of id that were successfully computed # List of id that were successfully computed
nums_success = dict() nums_success = dict()
# Go through all runs # Go through all runs
for run in runs: for run in runs:
path_suffix = project + '/' + run path_suffix = project + '/' + run
@@ -249,15 +259,11 @@ for run in runs:
while not success: while not success:
try: try:
if len(args.process) > 0 and len(args.plot) > 0: if len(args.process) > 0 :
pp = PostProcessor(run, num, pp_params=pp_params) pp = PostProcessor(run, num, pp_params=pp_params)
pp.process(args.process, args.process_args, pp.process(args.process, args.process_args,
overwrite=args.overwrite, overwrite_dep=args.overwrite_dependencies) overwrite=args.overwrite, overwrite_dep=args.overwrite_dependencies)
pltter = Plotter(filename=pp.filename)
pltter.plot(args.plot, args.plot_args,
overwrite=args.overwrite, overwrite_dep=args.overwrite_dependencies)
# If we are here, success ! # If we are here, success !
success = True success = True
nums_success[run].append(num) nums_success[run].append(num)
@@ -274,10 +280,15 @@ for run in runs:
else: else:
raise raise
if len(args.compare) > 0: path_in = storage_in + project
path_in = storage_in + project path_out = storage_out + project
path_out = storage_out + project
if len(args.plot) > 0:
pl = Plotter(path_in, runs, nums_success, path_out=path_out, pp_params=pp_params)
pl.process(args.plot, args.plot_args,
overwrite=args.overwrite, overwrite_dep=args.overwrite_dependencies)
if len(args.compare) > 0:
cc = Comparator(path_in, runs, nums_success, path_out=path_out, pp_params=pp_params) cc = Comparator(path_in, runs, nums_success, path_out=path_out, pp_params=pp_params)
cc.process(args.compare, args.compare_args, cc.process(args.compare, args.compare_args,
overwrite=args.overwrite, overwrite_dep=args.overwrite_dependencies) overwrite=args.overwrite, overwrite_dep=args.overwrite_dependencies)
+233 -101
View File
@@ -15,9 +15,10 @@ import matplotlib.patches as mpatches
from matplotlib.collections import PatchCollection from matplotlib.collections import PatchCollection
from functools import partial from functools import partial
from numpy.polynomial.polynomial import polyfit from numpy.polynomial.polynomial import polyfit
from scipy.ndimage.filters import gaussian_filter1d
from pp_params import * from pp_params import *
from postprocessor import Rule, BaseProcessor from postprocessor import *
P.rcParams['image.cmap']='plasma' P.rcParams['image.cmap']='plasma'
@@ -29,18 +30,12 @@ P.rcParams.update(tex_params)
class PlotRule(Rule): class PlotRule(Rule):
def plot(self, arg): def plot(self, save, arg, **kwargs):
return self.process_fn(arg) self.postproc.save = save
return self.process_fn(arg, **kwargs)
def is_valid(self, arg): def is_valid(self, arg):
save = self.postproc.save return arg in self.args_ok and self.is_valid_add(arg)
valid = True
for dep in self.dependencies:
if not arg is None:
valid = valid and dep + '_' + str(arg) in save
else:
valid = valid and dep in save
return arg in self.args_ok and valid and self.is_valid_add(arg)
class Plotter(BaseProcessor): class Plotter(BaseProcessor):
""" """
@@ -55,81 +50,139 @@ class Plotter(BaseProcessor):
G = 1. # Gravitational constant G = 1. # Gravitational constant
def __init__(self, filename=None, path_out='.', num=None, pp_params=Params()): def __init__(self, path, runs, nums, path_out=None, pp_params=default_params(), tag=None):
if type(pp_params) == str:
self.pp_params = load_params(pp_params)
else :
self.pp_params = pp_params self.pp_params = pp_params
if tag is not None:
self.pp_params.out.tag = tag
# Determining output directory # Determining output directory
if path_out is None: if (path_out is None):
if filename is None: self.path_out = path
self.path_out='.'
else:
self.path_out = os.path.dirname(filename)
else: else:
self.path_out = path_out self.path_out = path_out
# Find HDF5 file # Get postprocesor objets for each run
if filename is None: self.pp_runs = dict()
if not pp_params.out.tag == '': if not type(nums) == dict:
tag_name = '_' + pp_params.out.tag nums_tmp = nums
else : nums = dict()
tag_name = '' for run in runs:
self.filename = (self.path_out + '/postproc_' + nums[run] = nums_tmp
tag_name + format(num,'05') + '.h5')
else: for run in runs:
self.filename = filename path_run = path + '/' + run
path_out_run = path_out + '/' + run
self.pp_runs[run] = dict()
for num in nums[run]:
self.pp_runs[run][num] = PostProcessor(path_run, num, path_out_run, pp_params)
# Get comparator object
self.comp = Comparator(path, runs, nums, path_out, pp_params)
# save infos
self.runs = runs
self.nums = nums
self.log_id = "[plot {}] ".format(self.pp_params.out.tag) self.log_id = "[plot {}] ".format(self.pp_params.out.tag)
self.def_rules() self.def_rules()
def plot(self, to_plot_list, args=[None], overwrite=False): def _process_single(self, name, rule, arg, overwrite=False, just_done=[], **kwargs):
""" # Solve dependencies
Plot the data in to_plot_list and save them for dep in rule.dependencies:
""" if dep in self.comp.rules:
self.process(to_plot_list, args, overwrite, False) if type(rule.dependencies) == dict:
self.comp.process([dep], [rule.dependencies[dep]],
def _process_single(self, name, rule, arg, overwrite=False, overwrite_dep=False, just_done=[]): self.overwrite_dep)
done = self._plot_rule(name, rule, arg, overwrite)
return []
def _plot_rule(self, name, rule, arg, overwrite):
if not arg is None:
name_full = rule.group + '/' + name + '_' + str(arg)
else: else:
name_full = rule.group + '/' + name self.comp.process([dep], [arg], self.overwrite_dep, self.overwrite_dep)
else:
for run in self.runs:
for i, num in enumerate(self.nums[run]):
if type(rule.dependencies) == dict:
dep_arg = rule.dependencies[dep]
self.pp_runs[run][num].process([dep], [dep_arg],
self.overwrite_dep)
else:
self.pp_runs[run][num].process([dep], [arg],
self.overwrite_dep,
self.overwrite_dep)
# Process rule
done = self._process_rule(name, rule, arg, overwrite, just_done, **kwargs)
return just_done + [done]
def _process_rule(self, name, rule, arg, overwrite=False, just_done=[], **kwargs):
if not arg is None:
name_full = name + '_' + str(arg)
else:
name_full = name
if rule.is_valid(arg): if rule.is_valid(arg):
plot_filename = self._find_filename(name_full) if rule.kind == 'classic':
if overwrite or not os.path.exists(plot_filename): for run in self.runs:
rule.plot(arg) for i, num in enumerate(self.nums[run]):
P.tight_layout(pad=1) plot_filename = self._find_filename(name_full, run, num)
P.savefig(plot_filename) save = tables.open_file(self.pp_runs[run][num].filename)
P.close() try:
self._log("{} plotted".format(name_full), "SUCCESS") self._plot_rule(rule, save, arg, plot_filename, overwrite, **kwargs)
finally:
save.close()
else: else:
self._log("Plot {} is already done, skipping...".format(name_full)) if rule.kind == 'series' and len(self.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, **kwargs)
finally:
save.close()
else: else:
self._log("{} is not valid in this context".format(name_full), "ERROR") self._log("{} is not valid in this context".format(name_full), "ERROR")
def _plot_rule(self, rule, save, arg, plot_filename, overwrite, **kwargs):
if overwrite or not os.path.exists(plot_filename):
if not self.pp_params.out.interactive:
P.figure()
rule.plot(save, arg, **kwargs)
P.tight_layout(pad=1)
if not self.pp_params.out.interactive:
P.savefig(plot_filename)
P.close()
self._log("{} plotted".format(plot_filename), "SUCCESS")
else:
self._log("{} plotted".format(os.path.basename(plot_filename)), "SUCCESS")
else:
self._log("Plot {} is already done, skipping...".format(plot_filename))
def _find_filename(self, name_full):
def _find_filename(self, name_full, run=None, num=None):
if not self.pp_params.out.tag == '': if not self.pp_params.out.tag == '':
tag_name = '_' + self.pp_params.out.tag tag_name = '_' + self.pp_params.out.tag
else : else :
tag_name = '' tag_name = ''
if 'num' in self.save.root._v_attrs: if not run is None and not num is None:
num = self.save.root._v_attrs.num return (self.path_out + '/' + run + '/' + name_full +
return (self.path_out + '/' + name_full +
tag_name + '_' + format(num,'05') + tag_name + '_' + format(num,'05') +
self.pp_params.plot.out_ext) self.pp_params.plot.out_ext)
elif not run is None:
return (self.path_out + '/' + run + '/'
+ name_full + tag_name + self.pp_params.plot.out_ext)
else: else:
return self.path_out + '/' + name_full + tag_name + self.pp_params.plot.out_ext return self.path_out + '/' + name_full + tag_name + self.pp_params.plot.out_ext
def _plot_map(self, name, ax_los, label=None, cmap='plasma', vmin=None, vmax=None, overlays=[]): def _plot_map(self, name, ax_los, label=None, cmap='plasma', vmin=None, vmax=None, overlays=[]):
P.figure()
ax_h = self._axes_h[ax_los] ax_h = self._axes_h[ax_los]
ax_v = self._axes_v[ax_los] ax_v = self._axes_v[ax_los]
im_extent = self.save.root.maps._v_attrs.im_extent im_extent = self.save.root.maps._v_attrs.im_extent
@@ -201,8 +254,8 @@ class Plotter(BaseProcessor):
P.quiverkey(Q, 0.6, 0.98, max_v, P.quiverkey(Q, 0.6, 0.98, max_v,
r'$'+str(max_v)[0:4]+'$ (code)', labelpos='E', coordinates='figure') r'$'+str(max_v)[0:4]+'$ (code)', labelpos='E', coordinates='figure')
def _plot_radial(self, name, ax_los='z', label=None, xlog=False, ylog=False): def _plot_radial(self, name, label=None, xlog=False, ylog=False):
P.figure()
radial_bins = self.save.get_node('/radial/radial_bins_' + ax_los).read() radial_bins = self.save.get_node('/radial/radial_bins_' + ax_los).read()
bin_centers = 0.5 * (radial_bins[1:] + radial_bins[:-1]) bin_centers = 0.5 * (radial_bins[1:] + radial_bins[:-1])
mean_bin = self.save.get_node('/radial/{}_{}'.format(name, ax_los)).read() mean_bin = self.save.get_node('/radial/{}_{}'.format(name, ax_los)).read()
@@ -220,7 +273,7 @@ class Plotter(BaseProcessor):
P.ylabel(label) P.ylabel(label)
def _plot_hist(self, name, ax_los='z', label=None, ylog=False): def _plot_hist(self, name, ax_los='z', label=None, ylog=False):
P.figure()
pdf = self.save.get_node('/hist/' + name + '_' + ax_los) pdf = self.save.get_node('/hist/' + name + '_' + ax_los)
values, centers = pdf.read() values, centers = pdf.read()
width = centers[1] - centers[0] width = centers[1] - centers[0]
@@ -236,106 +289,185 @@ class Plotter(BaseProcessor):
P.ylim([None, 1.]) P.ylim([None, 1.])
def _plot(self, name_x, name_y, xlabel=None, ylabel=None, linearfit=False): def _plot(self, name_x, name_y, xlabel=None, ylabel=None,
P.figure() xunit=None, yunit=None,
linearfit=False, smooth=0,
nml_key=None, runs=None, **kwargs):
node_x = self.save.get_node(name_x) node_x = self.save.get_node(name_x)
node_y = self.save.get_node(name_y) node_y = self.save.get_node(name_y)
if xlabel is None: if xlabel is None:
if 'label' in node_x: if 'label' in node_x._v_attrs:
xlabel = name_x._vattrs.label xlabel = node_x._v_attrs.label
else: else:
xlabel = name_x xlabel = os.path.basename(name_x)
if ylabel is None: if ylabel is None:
if 'label' in node_y: if 'label' in node_y._v_attrs:
ylabel = name_y._vattrs.label ylabel = node_y._v_attrs.label
else: else:
ylabel = name_y ylabel = os.path.basename(name_y)
x = node_x.read() if 'unit' in node_x._v_attrs:
if node_y._v_attrs.CLASS == 'ARRAY': xunit_old = node_x._v_attrs.unit
y = node_y.read()
P.plot(x, y, fmt='*')
else: else:
y = node_y.mean.read() xunit_old = cst.none
yerr = node_y.std.read()
P.errorbar(x, y, yerr=y, fmt='*') if 'unit' in node_y._v_attrs:
yunit_old = node_y._v_attrs.unit
else:
yunit_old = cst.none
if xunit is None:
xunit = xunit_old
if yunit is None:
yunit = yunit_old
xlabel = xlabel + unit_str(xunit)
ylabel = ylabel + unit_str(yunit)
P.xlabel(xlabel) P.xlabel(xlabel)
P.ylabel(ylabel) P.ylabel(ylabel)
P.grid()
if node_y._v_attrs.CLASS == 'ARRAY':
x = node_x.read() * xunit_old.express(xunit)
y = node_y.read() * yunit_old.express(yunit)
if smooth > 0:
y = gaussian_filter1d(y, sigma=smooth)
yerr = None
P.plot(x, y, fmt='*', **kwargs)
elif 'mean' in node_y:
x = node_x.read() * xunit_old.express(xunit)
y = node_y.mean.read() * yunit_old.express(yunit)
if smooth > 0:
y = gaussian_filter1d(y, sigma=smooth)
yerr = node_y.std.read() * yunit_old.express(yunit)
P.errorbar(x, y, yerr=yerr, fmt='*', **kwargs)
else:
yerr = None
if runs is None:
runs = self.runs
for run in runs:
x_run, y_run = node_x[run], node_y[run]
x = x_run.read() * xunit_old.express(xunit)
y = y_run.read() * yunit_old.express(yunit)
if smooth > 0:
y = gaussian_filter1d(y, sigma=smooth)
if nml_key is None:
label_run = r"{}".format(self.save.root._v_attrs.attrs[y_run.name].label)
else:
prop_name = os.path.basename(nml_key)
prop_value = self.comp.get_nml(nml_key, run)
label_run = r"{} = {}".format(prop_name, prop_value)
P.plot(x, y, label=label_run, **kwargs)
P.legend()
if linearfit: if linearfit:
if node_y._v_attrs.CLASS == 'ARRAY': _overlay_linearfit(x, y, yerr)
(a, b, rho, _, stderr) = linregress(node_x.read(), node_y.read())
def _overlay_linearfit(x, y, yerr=None):
if yerr is None:
(a, b, rho, _, stderr) = linregress(x, y)
else: else:
c = polyfit(node_x.read(), node_y.mean.read(), 1, c = polyfit(x, y, 1,
w = [1.0 / ty for ty in node_y.std.read()], full=False) w = [1.0 / ty for ty in yerr], full=False)
b, a = c[0], c[1] b, a = c[0], c[1]
P.plot(x, a*y + b, '--', linewidth=1.5) P.plot(x, a*y + b, '--', linewidth=1.5)
P.grid()
def def_rules(self): def def_rules(self):
self.rules = { self.rules = {
'coldens' : PlotRule(self, lambda ax_los: 'coldens' : PlotRule(self, lambda ax_los:
self._plot_map('coldens', ax_los, label=r'$\Sigma$ (code)', vmin=0.01, vmax=100), self._plot_map('coldens', ax_los,
"Column density", ['/maps/coldens']), label=r'$\Sigma$ (code)', vmin=0.01, vmax=100),
"Column density", dependencies=['coldens']),
'rho' : PlotRule(self, lambda ax_los: 'rho' : PlotRule(self, lambda ax_los:
self._plot_map('rho', ax_los, label=r'$\rho$ (code)'), self._plot_map('rho', ax_los, label=r'$\rho$ (code)'),
"Density slice", ['/maps/rho']), "Density slice", dependencies=['rho']),
'coldens_l' : PlotRule(self, lambda ax_los: 'coldens_l' : PlotRule(self, lambda ax_los:
self._plot_map('coldens', ax_los, label=r'$\Sigma$ (code)', self._plot_map('coldens', ax_los,
vmin=0.01, vmax=100, overlays=[self._overlay_levels]), label=r'$\Sigma$ (code)',
"Column density", ['/maps/coldens', '/maps/levels']), vmin=0.01, vmax=100,
overlays=[self._overlay_levels]),
"Column density",
dependencies=['coldens', 'levels']),
'rho_v' : PlotRule(self, lambda ax_los: 'rho_v' : PlotRule(self, lambda ax_los:
self._plot_map('rho', ax_los, label=r'$\rho$ (code)', self._plot_map('rho', ax_los, label=r'$\rho$ (code)',
overlays=[self._overlay_speed]), overlays=[self._overlay_speed]),
"Density slice", ['/maps/rho', '/maps/speed_h', '/maps/speed_v']), "Density slice",
dependencies= ['rho', 'speed_h', 'speed_v']),
'jeans_ratio' : PlotRule(self, lambda ax_los: 'jeans_ratio' : PlotRule(self, lambda ax_los:
self._plot_map('jeans_ratio', ax_los, vmin=0.1, vmax=100, self._plot_map('jeans_ratio', ax_los, vmin=0.1, vmax=100,
cmap='RdBu_r', cmap='RdBu_r',
overlays=[self._overlay_levels]), overlays=[self._overlay_levels]),
"Jeans' lenght divided by the max resolution", "Jeans' lenght divided by the max resolution",
dependencies=['/maps/jeans_ratio', '/maps/levels']), dependencies=['jeans_ratio', 'levels']),
'Q' : PlotRule(self, lambda ax_los: 'Q' : PlotRule(self, lambda ax_los:
self._plot_map('rho', ax_los, label=r'$Q$', vmin=0.01, vmax=100, cmap='RdBu_r'), self._plot_map('rho', ax_los, label=r'$Q$',
vmin=0.01, vmax=100, cmap='RdBu_r'),
"Toomre Q parameter for a Keplerian disk", "Toomre Q parameter for a Keplerian disk",
dependencies=['/maps/Q'], args_ok=['z']) dependencies=['Q'], args_ok=['z'])
} }
averageables = ['coldens', 'rho', 'T', 'Q'] averageables = ['coldens', 'rho', 'T', 'Q']
for name in averageables: for name in averageables:
self.rules['rad_' + name] = PlotRule(self, partial(self._plot_radial, 'rad_avg_' + name, self.rules['rad_' + name] = PlotRule(self,
label=name, xlog=True, ylog=True), partial(self._plot_radial,
'rad_avg_' + name,
label=name,
xlog=True, ylog=True),
"Azimuthal average of {}".format(name), "Azimuthal average of {}".format(name),
dependencies=['/radial/radial_bins', '/radial/rad_avg_' + name], dependencies=['radial_bins', 'rad_avg_' + name],
args_ok=['z']) args_ok=['z'])
self.rules['fluct_' + name] = PlotRule(self, partial(self._plot_map, 'fluct_' + name, self.rules['fluct_' + name] = PlotRule(self,
partial(self._plot_map, 'fluct_' + name,
vmin=0.01, vmax=100, cmap='RdBu_r', vmin=0.01, vmax=100, cmap='RdBu_r',
label='{}/avg({})'.format(name, name)), label='{}/avg({})'.format(name, name)),
"Fluctuation wrt to average of {}".format(name), "Fluctuation wrt to average of {}".format(name),
dependencies=['/maps/fluct_' + name], dependencies=['fluct_' + name],
args_ok=['z']) args_ok=['z'])
self.rules['pdf_' + name] = PlotRule(self, partial(self._plot_hist, 'pdf_' + name, ylog=True, self.rules['pdf_' + name] = PlotRule(self, partial(self._plot_hist, 'pdf_' + name, ylog=True,
label='{}/avg({})'.format(name, name)), label='{}/avg({})'.format(name, name)),
"Probability density function of {} fluctuations".format(name), "Probability density function of {} fluctuations".format(name),
dependencies=['/hist/pdf_' + name], dependencies=['pdf_' + name],
args_ok=['z']) args_ok=['z'])
self.rules.update({ self.rules.update({
'kappa_beta' : PlotRule(self, partial(self._plot, '/comp/beta', '/comp/avg_pdf_slope_coldens', 'kappa_beta' : PlotRule(self, partial(self._plot,
'/comp/beta',
'/comp/avg_pdf_slope_coldens',
linearfit=True), linearfit=True),
args_ok=[None], dependencies=['/comp/beta', '/comp/avg_pdf_slope_coldens']), args_ok=[None], kind='comp',
'sink_mass' : PlotRule(self, partial(self._plot, '/series/time', '/series/sinks_mass', dependencies=['beta', 'avg_pdf_slope_coldens']),
linearfit=True), 'sink_mass' : PlotRule(self, partial(self._plot,
args_ok=[None], dependencies=['/series/time', '/series/sinks_mass']) '/series/sinks_from_log/time',
'/series/sinks_from_log/mass_sink',
ylabel="Mass of sinks",
xunit=cst.Myr,
yunit=cst.Msun),
args_ok=[None], kind='series',
dependencies=['sinks_from_log']),
'assfr' : PlotRule(self, partial(self._plot,
'/series/sfr_from_log/time',
'/series/sfr_from_log/sfr',
ylabel="Averaged surfacic SFR",
xunit=cst.Myr,
yunit=cst.ssfr),
args_ok=[None], kind='series',
dependencies=['sfr_from_log']),
'issfr' : PlotRule(self, partial(self._plot,
'/series/sinks_from_log/time',
'/series/sinks_from_log/issfr',
ylabel="Surfacic SFR",
xunit=cst.Myr,
yunit=cst.ssfr),
args_ok=[None], kind='series',
dependencies=['issfr'])
}) })
+274 -65
View File
@@ -2,25 +2,48 @@
import sys import sys
import os import os
import glob as glob
import tables import tables
import pymses import pymses
import numpy as np import numpy as np
from numpy.polynomial.polynomial import polyfit from numpy.polynomial.polynomial import polyfit
from scipy.stats import linregress
from pymses.sources.ramses import output from pymses.sources.ramses import output
from pymses.sources.hop.file_formats import * from pymses.sources.hop.file_formats import *
from pymses.analysis import Camera, raytracing, slicing, splatting from pymses.analysis import Camera, raytracing, slicing, splatting
from pymses.filters import CellsToPoints from pymses.filters import CellsToPoints
from pymses.analysis import ScalarOperator, FractionOperator, MaxLevelOperator from pymses.analysis import ScalarOperator, FractionOperator, MaxLevelOperator
from scipy.stats import linregress import pymses.utils.constants as cst
import f90nml
import bunch
from functools import partial from functools import partial
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from pp_params import * from pp_params import *
def unit_str(unit):
if unit == cst.none:
return ''
elif len(unit.name) > 0 :
return ' ({})'.format(unit.name)
else:
return ' ' + str(unit)
cst.ssfr = cst.create_unit('Msun/yr/pc^2',
base_unit=cst.Msun/cst.year/cst.pc**2,
descr="Surfacic SFR",
latex='M_{\astrosun}.yr^{-1}.pc^{-2}')
class Rule: class Rule:
def __init__(self, postproc, process, description='', group='', dependencies=[], args_ok=['x', 'y', 'z'], def __init__(self, postproc, process, description='',
is_valid=lambda arg:True): group='', dependencies=[], args_ok=['x', 'y', 'z'],
is_valid=lambda arg:True, kind='classic', unit=cst.none):
self.postproc = postproc self.postproc = postproc
self.process_fn = process self.process_fn = process
self.dependencies = dependencies self.dependencies = dependencies
@@ -28,12 +51,14 @@ class Rule:
self.group = group self.group = group
self.args_ok = args_ok self.args_ok = args_ok
self.description = description self.description = description
self.unit=unit
self.kind = kind
def process(self, arg): def process(self, arg, **kwargs):
if not arg is None: if not arg is None:
return self.process_fn(arg) return self.process_fn(arg, **kwargs)
else: else:
return self.process_fn() return self.process_fn(**kwargs)
def is_valid(self, arg): def is_valid(self, arg):
save = self.postproc.save save = self.postproc.save
@@ -55,7 +80,9 @@ class BaseProcessor:
log_id = "" log_id = ""
rules = dict() rules = dict()
data = dict()
filename = "" filename = ""
save = None
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
@@ -67,39 +94,45 @@ class BaseProcessor:
else: else:
print(self.log_id + string) print(self.log_id + string)
def process(self, to_process_list, args=[None], overwrite=False, overwrite_dep=None): def open(self):
self.save = tables.open_file(self.filename, mode="a")
def close(self):
self.save.close()
def process(self, to_process_list, args=[None], overwrite=False, overwrite_dep=False, **kwargs):
""" """
Render the data in to_process_list and save them Render the data in to_process_list and save them
""" """
if overwrite_dep is None:
overwrite_dep = overwrite
self.overwrite_dep = overwrite_dep self.overwrite_dep = overwrite_dep
just_done = [] # Computations done within this call just_done = [] # Computations done within this call
self.save = tables.open_file(self.filename, mode="a")
for name in to_process_list: for name in to_process_list:
if name in self.rules: if name in self.rules:
rule = self.rules[name] rule = self.rules[name]
for arg in args: for arg in args:
just_done = self._process_single(name, rule, arg, overwrite, just_done) just_done = self._process_single(name, rule, arg, overwrite, just_done, **kwargs)
else: else:
self._log("{} is unknown, allowed rules are {}".format(name, self.rules.keys()), "ERROR") self._log("{} is unknown, allowed rules are {}".format(name, self.rules.keys()), "ERROR")
self.save.close()
def _process_single(self, name, rule, arg, overwrite=False, just_done=[]): def _process_single(self, name, rule, arg, overwrite=False, just_done=[], **kwargs):
# Solve dependencies # Solve dependencies
for dep in rule.dependencies: for dep in rule.dependencies:
if dep in self.rules: if dep in self.rules:
rule_dep = self.rules[dep] rule_dep = self.rules[dep]
just_done = self._process_single(dep, rule_dep, arg, self.overwrite_dep, just_done) just_done = self._process_single(dep, rule_dep, arg, self.overwrite_dep,
just_done)
else: else:
self._log("Dependency {} for {} is unknown".format(dep, name), "ERROR") self._log("Dependency {} for {} is unknown".format(dep, name), "ERROR")
# Process rule # Process rule
done = self._process_rule(name, rule, arg, overwrite, just_done) self.open()
try:
done = self._process_rule(name, rule, arg, overwrite, just_done, **kwargs)
finally:
self.close()
return just_done + [done] return just_done + [done]
def _process_rule(self, name, rule, arg, overwrite=False, just_done=[]): def _process_rule(self, name, rule, arg, overwrite=False, just_done=[], **kwargs):
if not arg is None: if not arg is None:
name_full = rule.group + '/' + name + '_' + str(arg) name_full = rule.group + '/' + name + '_' + str(arg)
else: else:
@@ -107,10 +140,11 @@ class BaseProcessor:
if rule.is_valid(arg): if rule.is_valid(arg):
if not name_full in just_done: if not name_full in just_done:
if overwrite or not name_full in self.save: if (overwrite or
(not name_full in self.save and not name_full in self.data)):
self._log("Processing {}".format(name_full)) self._log("Processing {}".format(name_full))
data = rule.process(arg) data = rule.process(arg, **kwargs)
self._save_data(name_full, data, rule.description) self._save_data(name_full, data, rule.description, rule.unit)
self._log("Data for {} computed".format(name_full), "SUCCESS") self._log("Data for {} computed".format(name_full), "SUCCESS")
return name_full return name_full
else: else:
@@ -119,24 +153,43 @@ class BaseProcessor:
self._log("{} is not valid in this context".format(name_full), "ERROR") self._log("{} is not valid in this context".format(name_full), "ERROR")
def _save_data(self, name_full, data, description): def _save_data(self, name_full, data, description, unit):
""" """
Save data in the HDF5 structure, overwrite if necessary Save data in the HDF5 structure, overwrite if necessary
""" """
if name_full in self.save: if name_full in self.save:
self.save.remove_node(name_full, recursive=True) self.save.remove_node(name_full, recursive=True)
if not type(data) == dict: if type(data) == dict:
self.save.create_array(os.path.dirname(name_full), os.path.basename(name_full), if type(description) == str:
data, description, createparents=True) self.save.create_group(os.path.dirname(name_full),
os.path.basename(name_full),
description, createparents=True)
else: else:
self.save.create_group(os.path.dirname(name_full),
os.path.basename(name_full),
'', createparents=True)
if not type(unit) == dict:
self.save.get_node(name_full)._v_attrs.unit = unit
for key in data: for key in data:
if type(description) == dict: if type(description) == dict:
self.save.create_array(name_full, key, if type(unit) == dict:
data[key], description[key], createparents=True) self._save_data(name_full + '/' + key, data[key], description[key], unit[key])
else: else:
self.save.create_array(name_full, key, self._save_data(name_full + '/' + key, data[key], description[key], unit)
data[key], description, createparents=True) else:
if type(unit) == dict:
self._save_data(name_full + '/' + key, data[key], '', unit[key])
else:
self._save_data(name_full + '/' + key, data[key], '', unit)
else:
self.save.create_array(os.path.dirname(name_full),
os.path.basename(name_full),
data, description, createparents=True)
self.save.get_node(name_full).attrs.unit = unit
@abstractmethod @abstractmethod
def def_rules(self): def def_rules(self):
@@ -154,13 +207,17 @@ class PostProcessor(BaseProcessor):
G = 1. # Gravitational constant G = 1. # Gravitational constant
def __init__(self, path=None, num=None, path_out=None, pp_params=Params()): def __init__(self, path=None, num=None, path_out=None, pp_params=default_params()):
""" """
Creates the basic structures needed for the outputs Creates the basic structures needed for the outputs
""" """
if not path is None and not num is None: if not path is None and not num is None:
# TODO : Make possible to load the HDF5 file even without the original file # TODO : Make possible to load the HDF5 file even without the original file
if type(pp_params) == str:
self.pp_params = load_params(pp_params)
else :
self.pp_params = pp_params self.pp_params = pp_params
# Determining output directory # Determining output directory
@@ -175,6 +232,9 @@ class PostProcessor(BaseProcessor):
self.filename = (path_out + '/postproc_' + self.filename = (path_out + '/postproc_' +
tag_name + format(num,'05') + '.h5') tag_name + format(num,'05') + '.h5')
if not os.path.exists(path_out):
os.makedirs(path_out)
self.save = tables.open_file(self.filename, mode="a", self.save = tables.open_file(self.filename, mode="a",
title=os.path.basename(path)+ '_' + format(num,'05')) title=os.path.basename(path)+ '_' + format(num,'05'))
@@ -184,6 +244,13 @@ class PostProcessor(BaseProcessor):
self.num = num self.num = num
self._ro = pymses.RamsesOutput(path, num, order=pp_params.pymses.order) self._ro = pymses.RamsesOutput(path, num, order=pp_params.pymses.order)
self._amr = self._ro.amr_source(["rho","vel","P"]) self._amr = self._ro.amr_source(["rho","vel","P"])
self.info = self._ro.info.copy()
# Delete specific info
self.info.pop('dom_decomp_Hilbert_keys')
self.info.pop('nstep_coarse')
self.info.pop('dom_decomp')
self.info.pop('time')
# Density operator # Density operator
self._rho_op = ScalarOperator(lambda dset: dset["rho"], self._ro.info["unit_density"]) self._rho_op = ScalarOperator(lambda dset: dset["rho"], self._ro.info["unit_density"])
@@ -196,7 +263,7 @@ class PostProcessor(BaseProcessor):
# Set the extend of the image # Set the extend of the image
self._radius = 0.5 / pp_params.out.zoom self._radius = 0.5 / pp_params.out.zoom
self._lbox = self._ro.info['boxlen'] self._lbox = self.info['boxlen']
center = pp_params.out.center center = pp_params.out.center
im_extent = [(- self._radius + center[0]) * self._lbox, im_extent = [(- self._radius + center[0]) * self._lbox,
( self._radius + center[0]) * self._lbox, ( self._radius + center[0]) * self._lbox,
@@ -219,7 +286,6 @@ class PostProcessor(BaseProcessor):
self.save.root.maps._v_attrs.radius = self._radius self.save.root.maps._v_attrs.radius = self._radius
self.save.root.maps._v_attrs.im_extent = im_extent self.save.root.maps._v_attrs.im_extent = im_extent
# Initialize cameras # Initialize cameras
self._cam = dict() self._cam = dict()
for ax_los in self._ax_nb : # los = line of sight for ax_los in self._ax_nb : # los = line of sight
@@ -246,12 +312,15 @@ class PostProcessor(BaseProcessor):
Add additional metadata to the file Add additional metadata to the file
""" """
# Beta for the beta cooling # Label of the run in the label.txt file
if not (self.pp_params.disk.beta is None or self.pp_params.disk.beta == False): label_filename = self.path + '/' + self.pp_params.input.label_filename
if type(self.pp_params.disk.beta) == int: if os.path.exists(label_filename):
self.save.root._v_attrs.beta = self.pp_params.disk.beta label_file = open(label_filename, 'r')
self.label = label_file.readline()
label_file.close()
else: else:
self.save.root._v_attrs.beta = int(self.save.root._v_attrs.run.split('_')[1][4:]) self.label = self.run
self.save.root._v_attrs.label = self.label
def _coldens(self, ax_los): def _coldens(self, ax_los):
datamap = self._rt.process(self._cam[ax_los], surf_qty=True) datamap = self._rt.process(self._cam[ax_los], surf_qty=True)
@@ -482,27 +551,39 @@ class PostProcessor(BaseProcessor):
# Base rules # Base rules
'coldens' : Rule(self, self._coldens, "Column density", '/maps'), 'coldens' : Rule(self, self._coldens, "Column density", '/maps'),
'rho' : Rule(self, self._rho, "Density slice", '/maps'), 'rho' : Rule(self, self._rho, "Density slice", '/maps'),
'speed_h' : Rule(self, self._speed_h, "Horizontal speed slice wrt the line of sight", '/maps'), 'speed_h' : Rule(self, self._speed_h,
'speed_v' : Rule(self, self._speed_v, "Vertical speed slice wrt the line of sight", '/maps'), "Horizontal speed slice wrt the line of sight", '/maps'),
'T' : Rule(self, self._temperature, "Temperature slice", '/maps', dependencies=['rho']), 'speed_v' : Rule(self, self._speed_v,
'levels' : Rule(self, self._levels, "Max level within line of sight", '/maps'), "Vertical speed slice wrt the line of sight", '/maps'),
'jeans' : Rule(self, self._jeans, "Jeans lenght slice", '/maps', dependencies=['rho', 'T']), 'T' : Rule(self, self._temperature,
'jeans_ratio' : Rule(self, self._jeans_ratio, "Jeans' lenght divided by the max resolution", "Temperature slice", '/maps', dependencies=['rho']),
'levels' : Rule(self, self._levels,
"Max level within line of sight", '/maps'),
'jeans' : Rule(self, self._jeans,
"Jeans lenght slice", '/maps', dependencies=['rho', 'T']),
'jeans_ratio' : Rule(self, self._jeans_ratio,
"Jeans' lenght divided by the max resolution",
'/maps', dependencies=['jeans', 'levels']), '/maps', dependencies=['jeans', 'levels']),
'Q' : Rule(self, self._toomreQ_disk, "Toomre Q parameter for a Keplerian disk", '/maps', 'Q' : Rule(self, self._toomreQ_disk,
"Toomre Q parameter for a Keplerian disk", '/maps',
dependencies=['coldens'], args_ok=['z'], dependencies=['coldens'], args_ok=['z'],
is_valid=lambda _: self.pp_params.disk.on), is_valid=lambda _: self.pp_params.disk.on),
'sinks' : Rule(self, self._sinks, group="/datasets", args_ok=[None], 'sinks' : Rule(self, self._sinks, group="/datasets", args_ok=[None],
description={'Id': '', 'M':'[Msol]', 'dmf':'[Msol]', description={'Id': '', 'M':'[Msol]', 'dmf':'[Msol]',
'x': '', 'y': '', 'z': '', 'vx': '', 'vy': '', 'vz': '', 'x': '', 'y': '', 'z': '',
'rot_period':'[y]', 'lx':'|l|', 'ly':'|l|', 'lz':'|l|', 'vx': '', 'vy': '', 'vz': '',
'acc_rate':'[Msol/y]', 'acc_lum':'[Lsol]', 'age':'[y]', 'rot_period':'[y]',
'lx':'|l|', 'ly':'|l|', 'lz':'|l|',
'acc_rate':'[Msol/y]', 'acc_lum':'[Lsol]',
'age':'[y]',
'int_lum':'[Lsol]', 'Teff':'[K]'}), 'int_lum':'[Lsol]', 'Teff':'[K]'}),
# Helpers # Helpers
'radial_bins' : Rule(self, self._radial_bins, "Radial bins", '/radial', args_ok=['z']), 'radial_bins' : Rule(self, self._radial_bins,
"Radial bins", '/radial', args_ok=['z']),
'rr' : Rule(self, self._rr, "Coordinate map", '/maps', args_ok=['z']), 'rr' : Rule(self, self._rr, "Coordinate map", '/maps', args_ok=['z']),
'bins_on_map' : Rule(self, self._bins_on_map, "Convert map coordinates to bins", '/maps', 'bins_on_map' : Rule(self, self._bins_on_map,
"Convert map coordinates to bins", '/maps',
dependencies=['radial_bins', 'rr'], args_ok=['z']) dependencies=['radial_bins', 'rr'], args_ok=['z'])
} }
@@ -542,11 +623,14 @@ class Comparator(BaseProcessor):
Do comparaison between outputs and runs Do comparaison between outputs and runs
""" """
def __init__(self, path, runs, nums, path_out=None, pp_params=Params()): def __init__(self, path, runs, nums, path_out=None, pp_params=default_params()):
""" """
Creates the basic structures needed for the outputs Creates the basic structures needed for the outputs
""" """
if type(pp_params) == str:
self.pp_params = load_params(pp_params)
else :
self.pp_params = pp_params self.pp_params = pp_params
# Determining output directory # Determining output directory
@@ -570,16 +654,31 @@ class Comparator(BaseProcessor):
for run in runs: for run in runs:
nums[run] = nums_tmp nums[run] = nums_tmp
attrs = dict()
self.namelist = dict()
for run in runs: for run in runs:
path_run = path + '/' + run path_run = path + '/' + run
path_out_run = path_out + '/' + run path_out_run = path_out + '/' + run
self.pp_runs[run] = dict() self.pp_runs[run] = dict()
for num in nums[run]: for num in nums[run]:
self.pp_runs[run][num] = PostProcessor(path_run, num, path_out=path_out_run, pp_params=pp_params) self.pp_runs[run][num] = PostProcessor(path_run, num, path_out=path_out_run,
pp_params=pp_params)
h5file = tables.open_file(self.pp_runs[run][nums[run][0]].filename, 'r')
attrs[run] = h5file.root._v_attrs
h5file.close()
path_nml = path_run + '/' + self.pp_params.input.nml_filename
self.namelist[run] = bunch.bunchify(f90nml.read(path_nml))
self.info = self.pp_runs[runs[0]][nums[runs[0]][0]].info
# save metadata # save metadata
self.save.root._v_attrs.runs = runs self.save.root._v_attrs.runs = runs
self.save.root._v_attrs.nums = nums self.save.root._v_attrs.nums = nums
self.save.root._v_attrs.attrs = attrs
self.save.root._v_attrs.namelist = bunch.unbunchify(self.namelist)
# log info # log info
self.log_id = "[comp {}] ".format(self.pp_params.out.tag) self.log_id = "[comp {}] ".format(self.pp_params.out.tag)
@@ -593,7 +692,7 @@ class Comparator(BaseProcessor):
for run in self.save.root._v_attrs.runs: for run in self.save.root._v_attrs.runs:
series[run] = np.zeros(len(nums[run])) series[run] = np.zeros(len(nums[run]))
for i, num in enumerate(nums[run]): for i, num in enumerate(nums[run]):
series[run][i] = getter(self.pp_runs[run][num]) series[run][i] = getter(run, num)
return series return series
def _comp(self, name, getter): def _comp(self, name, getter):
@@ -602,7 +701,7 @@ class Comparator(BaseProcessor):
prop = np.zeros(len(runs)) prop = np.zeros(len(runs))
for i, run in enumerate(runs): for i, run in enumerate(runs):
num = nums[run][0] num = nums[run][0]
prop[i] = getter(self.pp_runs[run][num]) prop[i] = getter(run, num)
return prop return prop
def _time_avg(self, name): def _time_avg(self, name):
@@ -615,13 +714,21 @@ class Comparator(BaseProcessor):
std[i] = np.std(serie) std[i] = np.std(serie)
return {"mean": mean, "std": std} return {"mean": mean, "std": std}
def _get_attr(self, attr_name, pp): def get_attr(self, attr_name, run, num):
pp = self.pp_runs[run][num]
h5file = tables.open_file(pp.filename, "r") h5file = tables.open_file(pp.filename, "r")
attr = h5file.root._v_attrs[attr_name] attr = h5file.root._v_attrs[attr_name]
h5file.close() h5file.close()
return attr return attr
def _get_pdf_slope(self, name, pp): def get_nml(self, nml_key, run):
res = self.namelist[run]
for key in nml_key.split('/'):
res = res[key]
return res
def get_pdf_slope(self, name, run, num):
pp = self.pp_runs[run][num]
pp.process(['fit_pdf_' + name], ['z'], overwrite=self.overwrite_dep) pp.process(['fit_pdf_' + name], ['z'], overwrite=self.overwrite_dep)
h5file = tables.open_file(pp.filename, "r") h5file = tables.open_file(pp.filename, "r")
pdf = h5file.get_node('/hist/pdf_' + name +'_z') pdf = h5file.get_node('/hist/pdf_' + name +'_z')
@@ -629,34 +736,136 @@ class Comparator(BaseProcessor):
h5file.close() h5file.close()
return slope return slope
def _get_sinks_mass(self, pp): def get_sinks_mass(self, run, num):
pp = self.pp_runs[run][num]
pp.process(['sinks'], overwrite=self.overwrite_dep) pp.process(['sinks'], overwrite=self.overwrite_dep)
h5file = tables.open_file(pp.filename, "r") h5file = tables.open_file(pp.filename, "r")
sinks_mass = h5file.get_node('/datasets/sinks/M').read() sinks_mass = h5file.get_node('/datasets/sinks/M').read()
h5file.close() h5file.close()
return np.sum(sinks_mass) return np.sum(sinks_mass)
def _extract_sinks_from_log(self, series, log_filename, run):
cmd_grep = "grep 'Number of sink' {} -A 2".format(log_filename)
content = os.popen(cmd_grep).readlines()
for i in range(0, len(content), 4):
series['nb_sink'][run].append(np.int(content[i].split('=')[1]))
series['mass_sink'][run].append(np.float(content[i + 1].split('=')[1]))
series['time'][run].append(np.float(content[i + 2].split('=')[1]))
return series
def _extract_sfr_from_log(self, series, log_filename, run):
cmd_grep = "grep '\[SFR' {} ".format(log_filename)
content = os.popen(cmd_grep).readlines()
for i in range(0, len(content)):
time = np.float(content[i].split(']')[0].split('=')[1].split()[0])
sfr = np.float(content[i].split(']')[1].split('=')[1].split()[0])
series['time'][run].append(time)
series['sfr'][run].append(sfr)
return series
def _from_log(self, keys, extractor):
nums = self.save.root._v_attrs.nums
# Initialize series
series = dict()
for key in keys:
series[key] = dict()
for run in self.save.root._v_attrs.runs:
# Initialize list
for key in keys:
series[key][run] = []
# get one preprocessor
num = nums[run][0]
pp = self.pp_runs[run][num]
# Get list of run files
log_files = (pp.path + '/'
+ self.pp_params.input.log_prefix + '*')
# Parse files
for log_filename in glob.glob(log_files):
series = extractor(series, log_filename, run)
# Numpify the lists
for key in series:
series[key][run] = np.array(series[key][run])
# Sort the arrays
ind_sort = series['time'][run].argsort()
for key in series:
series[key][run] = series[key][run][ind_sort]
return series
def _ssfr_from_mass_sink(self):
time_unit = self.save.get_node('/series/sinks_from_log/time')._v_attrs.unit
mass_unit = self.save.get_node('/series/sinks_from_log/mass_sink')._v_attrs.unit
# Surface of the box in pc^2
surface = (self.info['unit_length'].express(cst.pc))**2
# WARNING : We do not multiply by boxlen since already done in 'unit_length'
ssfr = dict()
for run in self.save.root._v_attrs.runs:
time = self.save.get_node('/series/sinks_from_log/time/' + run).read()
time = time * time_unit.express(cst.year)
mass_sink = self.save.get_node('/series/sinks_from_log/mass_sink/' + run).read()
mass_sink = mass_sink * mass_unit.express(cst.Msun)
sfr = (mass_sink[1:] - mass_sink[:-1]) / (time[1:] - time[:-1])
ssfr[run] = np.zeros(len(mass_sink))
ssfr[run][1:] = sfr / surface
return ssfr
def def_rules(self): def def_rules(self):
averageables = ['coldens', 'rho', 'T', 'Q'] averageables = ['coldens', 'rho', 'T', 'Q']
self.rules = { self.rules = {
'beta' : Rule(self, lambda arg: self._comp("beta", partial(self._get_attr, 'beta')), group='/comp', # Read from log
args_ok = [None]), 'sinks_from_log' : Rule(self,
partial(self._from_log,
['time', 'mass_sink', 'nb_sink'],
self._extract_sinks_from_log),
group='/series', args_ok=[None],
unit={'time' : self.info['unit_time'],
'mass_sink' : cst.Msun,
'nb_sink' : cst.none}),
'issfr' : Rule(self,
self._ssfr_from_mass_sink,
group='/series/sinks_from_log', args_ok=[None],
unit=cst.ssfr,
description="Instantaneous surfacic star formation rate",
dependencies=['sinks_from_log']),
'sfr_from_log' : Rule(self,
partial(self._from_log,
['time', 'sfr'],
self._extract_sfr_from_log),
group='/series', args_ok=[None],
unit={'time' : cst.year,
'sfr' : cst.ssfr},
description={'time': 'Time',
'sfr' : 'Averaged surfacic star formation rate'}),
# Read from outputs
'time' : Rule(self, partial(self._time_series, "time",
partial(self.get_attr, 'time')),
group='/series', args_ok=[None]),
'time_pdf_slope' : Rule(self, 'time_pdf_slope' : Rule(self,
lambda name: self._time_series("pdf_slope_" + name, lambda name:
partial(self._get_pdf_slope, name)), self._time_series("pdf_slope_" + name,
partial(self.get_pdf_slope,
name)),
group='/series', args_ok = averageables), group='/series', args_ok = averageables),
'time_sinks_mass' : Rule(self, partial(self._time_series, "sinks", self._get_sinks_mass), # Averages and run properties
group='/series', args_ok=[None]),
'time' : Rule(self, partial(self._time_series, "time", partial(self._get_attr, 'time')),
group='/series', args_ok=[None]),
'avg_pdf_slope' : Rule(self, 'avg_pdf_slope' : Rule(self,
lambda name: self._time_avg("time_pdf_slope_" + name), lambda name:
self._time_avg("time_pdf_slope_" + name),
group='/comp', dependencies=['time_pdf_slope'], group='/comp', dependencies=['time_pdf_slope'],
args_ok=averageables, args_ok=averageables,
description={"mean": "Temporal average", "std": "Standard deviation"}) description={"mean": "Temporal average",
"std": "Standard deviation"}),
} }
def get_time(path, num): def get_time(path, num):
""" """
Return the time of the output (code units) Return the time of the output (code units)
+24 -62
View File
@@ -1,69 +1,31 @@
# coding: utf-8 # coding: utf-8
import numpy as np import numpy as np
import re
import bunch
import yaml
import os
class PlotParams: _dir_path = os.path.dirname(os.path.realpath(__file__))
"""
Plot parameters # Add support for '1e3' kind of float
""" _loader = yaml.SafeLoader
out_ext = '.jpeg' # extension for plots _loader.add_implicit_resolver(
put_title = False # Add a title to plot u'tag:yaml.org,2002:float',
ntick = 6 # Number of ticks for maps re.compile(u'''^(?:
set_lim = True # Set default limits [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
vel_red = 40 # Take point each vel_red for velocities |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
put_title = False |\\.[0-9_]+(?:[eE][-+][0-9]+)?
|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*
|[-+]?\\.(?:inf|Inf|INF)
|\\.(?:nan|NaN|NAN))$''', re.X),
list(u'-+0123456789.'))
class DiskParams: def load_params(filename):
""" with open(filename) as f:
Disk speficic parameters para_disk = yaml.load(f, Loader=_loader)
""" return bunch.bunchify(para_disk)
on = False # Enable specific disk analysis
pos_star = np.array([1., 1., 1.]) # Position of the central star
binning = "log" # Kind of binning (lin = linear, log = logarithmic)
nb_bin = 100 # Number of bins for averaged quantities
bin_in = 1e-3 # Outer radius of the inner bin
bin_out = 0.25 # Inner radius of the outer bin
rmin_pdf = 0.075 # Inner radius for PDF computation
rmax_pdf = 0.3 # Outer radius for PDF computation
beta = False # Beta cooling. Do nothing if False.
# If true, beta will be parsed,
# otherwise the value is read therre
class PdfParams:
"""
parameters for probability density functions
"""
nb_bin = 50 # Number of bins for the PDF
xmin_fit = 0. # Lower boundary of the fit
xmax_fit = 1.25 # Upper boundary of the fit
class PymsesParams:
"""
Parameters for Pymses reader
"""
order = '<' # In which order the output are read
fft = False # Quick and dirty rendering using FFT
class OutputParams:
"""
Parameters for post processing
"""
center = [0.5, 0.5, 0.5] # Center of the image
zoom = 1. # Zoom of the image
map_size = 512 # Size of the computed maps in pixel
tag = "" # Tag for the image
class Params:
"""
Strutured parameters for the post processing
"""
disk = DiskParams()
pdf = PdfParams
pymses = PymsesParams()
out = OutputParams()
plot = PlotParams()
def default_params():
return load_params(_dir_path + '/pp_params.yml')